Files
dusklight/src/d/d_camera.cpp
T
Irastris fb9178cac9 Implement unlocked framerates via interpolation (#315)
* Disable waitForTick and waitBlanking

* Initial frame interpolation implementation

* Initial batch of speed fixes

* Fix Iron Boots

* Strip dead code once used for debugging

* Interpolate shadows

* Revert overzealous/redundant lookups

* Fix JUTFader

* Fix field map cursor

* Fix various particle effects

* Fix Midna when riding Wolf Link

* Fix title logo

* Title Logo 2: Electric Boogaloo

* Fixed grass and flowers

* "Unlock Framerate" config option (WIP)

* Wrap more things in TARGET_PC

* Finish wrapping things in TARGET_PC

* Missed one

* Disable dComIfGd_drawXluListInvisible when interpolating

---------

Co-authored-by: Luke Street <luke@street.dev>
2026-04-11 01:06:25 -06:00

11301 lines
368 KiB
C++

#include "d/dolzel.h" // IWYU pragma: keep
#include "d/d_camera.h"
#include "SSystem/SComponent/c_counter.h"
#include "SSystem/SComponent/c_math.h"
#include "d/actor/d_a_alink.h"
#include "d/actor/d_a_boomerang.h"
#include "d/actor/d_a_horse.h"
#include "d/actor/d_a_midna.h"
#include "d/actor/d_a_tag_mhint.h"
#include "d/actor/d_a_tag_mstop.h"
#include "d/actor/d_a_tag_mwait.h"
#include "d/d_bg_s_sph_chk.h"
#include "d/d_com_inf_actor.h"
#include "d/d_com_inf_game.h"
#include "d/d_debug_viewer.h"
#include "d/d_demo.h"
#include "d/d_s_play.h"
#include "f_op/f_op_camera.h"
#include "m_Do/m_Do_controller_pad.h"
#include "m_Do/m_Do_graphic.h"
#include "m_Do/m_Do_lib.h"
#include "dusk/frame_interpolation.h"
#include <cmath>
#include <cstring>
#if DEBUG
#include "d/d_debug_pad.h"
#include "d/d_debug_camera.h"
#endif
namespace {
static f32 limitf(f32 value, f32 min, f32 max) {
if (value > max) {
return max;
} else if (value < min) {
return min;
}
return value;
}
static inline f32 rangef(f32 value1, f32 value2, f32 ratio) {
return value1 + (value2 - value1) * ratio;
}
inline static bool is_player(fopAc_ac_c* actor) {
return fopAcM_GetName(actor) == fpcNm_ALINK_e || fopAcM_GetName(actor) == fpcNm_ALINK_e;
}
static void hideActor(fopAc_ac_c* actor) {
if (is_player(actor)) {
dComIfGp_onCameraAttentionStatus(0, 2);
daPy_py_c* player = (daPy_py_c*)actor;
if (player->checkHorseRide()) {
daHorse_c* horse = dComIfGp_getHorseActor();
fopAcM_OnStatus(horse, fopAcStts_NODRAW_e);
}
} else {
fopAcM_OnStatus(actor, fopAcStts_NODRAW_e);
}
}
static bool defaultRadius(f32 param_0, f32 param_1, f32* param_2) {
f32 var_f31;
f32 var_f30;
if (param_0 < param_1) {
var_f31 = param_0;
var_f30 = param_1;
} else {
var_f30 = param_0;
var_f31 = param_1;
}
if (*param_2 > var_f30) {
*param_2 = var_f30;
return false;
}
if (*param_2 < var_f31) {
*param_2 = var_f31;
return false;
}
return true;
}
static bool posInLine2D(cXyz* param_0, cXyz* param_1, cXyz* param_2) {
if (param_0->x <= param_1->x) {
if (param_2->x < param_0->x)
return false;
if (param_2->x > param_1->x)
return false;
} else {
if (param_2->x <= param_1->x)
return false;
if (param_2->x >= param_0->x)
return false;
}
if (param_0->z <= param_1->z) {
if (param_2->z < param_0->z)
return false;
if (param_2->z > param_1->z)
return false;
} else {
if (param_2->z <= param_1->z)
return false;
if (param_2->z >= param_0->z)
return false;
}
return true;
}
static cXyz relationalPos2(fopAc_ac_c* i_actor1, fopAc_ac_c* i_actor2, cXyz* param_2, f32 param_3,
cSAngle param_4) {
if (i_actor1 == NULL || i_actor2 == NULL) {
OS_REPORT("camera: error: actor NULL in relationalPos() \n");
return cXyz::Zero;
} else {
cXyz pos1 = i_actor1->attention_info.position;
cXyz pos2 = i_actor2->attention_info.position;
cXyz pos_diff = pos2 - pos1;
cSGlobe diff_globe(pos_diff);
pos_diff.normalize();
pos1 -= pos_diff * i_actor1->attention_info.field_0xa;
pos2 += pos_diff * i_actor2->attention_info.field_0xa;
cXyz mid = pos1 + (pos2 - pos1) * 0.5f;
cXyz vec = *param_2;
cSAngle angle = param_4 - diff_globe.U();
if (angle < cSAngle::_0) {
vec.x = -vec.x;
}
cSGlobe globe2(vec);
globe2.U(diff_globe.U() + globe2.U());
diff_globe.R(0.5f * diff_globe.R() * angle.Cos() * param_3);
cXyz ret = mid + diff_globe.Xyz() + globe2.Xyz();
return ret;
}
}
inline static cSAngle sAngleY(cXyz& i_vec) {
return cM_atan2s(i_vec.x, i_vec.z);
}
} // namespace
int dCamMapToolData::Set(s32 param_0, s32 roomNo, fopAc_ac_c* param_2, u16 param_3, u8 param_4) {
if ((param_3 & 0xFF) > mPriority) {
return 0;
}
stage_camera_class* room_cam = dComIfGp_getRoomCamera(roomNo);
stage_arrow_class* room_arrow = dComIfGp_getRoomArrow(roomNo);
if (room_cam != NULL && param_0 >= 0 && param_0 < room_cam->num) {
Clr();
mCameraIndex = param_0;
mCamData = room_cam->m_entries[mCameraIndex];
mFlags = (mCamData.field_0x14 >> 0xE) & 3;
if (param_3 & 0x8000) {
mFlags |= (u8)0x10;
}
if (mCamData.field_0x14 & (u16)0x2000) {
mCamData.field_0x14 |= (u16)0xC000;
} else {
mCamData.field_0x14 &= (u16)~0xC000;
}
mArrowIndex = mCamData.m_arrow_idx;
if (room_arrow != NULL && mArrowIndex >= 0 && mArrowIndex < room_arrow->num) {
mArrowData = room_arrow->m_entries[mArrowIndex];
}
mpActor = param_2;
mPathId = param_4;
mPriority = param_3 & 0xFF;
return 1;
}
return 0;
}
engine_fn dCamera_c::engine_tbl[] = {
&dCamera_c::letCamera, &dCamera_c::chaseCamera, &dCamera_c::lockonCamera,
&dCamera_c::talktoCamera, &dCamera_c::subjectCamera, &dCamera_c::fixedPositionCamera,
&dCamera_c::fixedFrameCamera, &dCamera_c::towerCamera, &dCamera_c::rideCamera,
&dCamera_c::manualCamera, &dCamera_c::eventCamera, &dCamera_c::hookshotCamera,
&dCamera_c::colosseumCamera, &dCamera_c::observeCamera, &dCamera_c::magneCamera,
&dCamera_c::railCamera, &dCamera_c::paraRailCamera, &dCamera_c::oneSideCamera,
&dCamera_c::test1Camera, &dCamera_c::test2Camera,
};
namespace {
inline static int get_camera_id(camera_class* i_camera) {
return fopCamM_GetParam(i_camera);
}
inline static int get_controller_id(camera_class* i_camera) {
return dComIfGp_getCameraPlayer1ID(get_camera_id(i_camera));
}
inline static fopAc_ac_c* get_player_actor(camera_class* i_camera) {
return dComIfGp_getPlayer(dComIfGp_getCameraPlayer1ID(get_camera_id(i_camera)));
}
inline static dDlst_window_c* get_window(int param_0) {
return dComIfGp_getWindow(dComIfGp_getCameraWinID(param_0));
}
inline static dDlst_window_c* get_window(camera_class* i_camera) {
return dComIfGp_getWindow(dComIfGp_getCameraWinID(get_camera_id(i_camera)));
}
inline static fopAc_ac_c* get_boomerang_actor(fopAc_ac_c* i_actor) {
if (is_player(i_actor)) {
return static_cast<daAlink_c*>(i_actor)->getThrowBoomerangActor();
} else {
return NULL;
}
}
inline static cSAngle sAngleX(cXyz& i_vec) {
return cSAngle(cM_atan2s(i_vec.y, i_vec.z));
}
inline static bool lineCollisionCheck(cXyz param_0, cXyz param_1, fopAc_ac_c* param_2,
fopAc_ac_c* param_3, fopAc_ac_c* param_4) {
return dComIfG_Ccsp()->ChkCamera(param_0, param_1, 15.0f, param_2, param_3, param_4);
}
inline static f32 playerMaxSpeed() {
return 40.0f;
}
} // namespace
dCamera_c::dCamera_c(camera_class* i_camera) : mCamParam(0) {
initialize(i_camera, get_player_actor(i_camera), get_camera_id(i_camera),
get_controller_id(i_camera));
}
dCamera_c::~dCamera_c() {
if (!daPy_py_c::checkPeepEndSceneChange()) {
dComIfGs_getTurnRestart().setCameraCtr(mCenter);
dComIfGs_getTurnRestart().setCameraEye(mEye);
dComIfGs_getTurnRestart().setCameraUp(mUp);
dComIfGs_getTurnRestart().setCameraFvy(mFovy);
fopAc_ac_c::setStopStatus(0);
}
}
enum SpecialType {
/* 0x00 */ CAM_TYPE_FIELD_S,
/* 0x01 */ CAM_TYPE_EVENT,
/* 0x02 */ CAM_TYPE_WATER,
/* 0x03 */ CAM_TYPE_SCOPE,
/* 0x04 */ CAM_TYPE_CANOE,
/* 0x05 */ CAM_TYPE_HORSE_T,
/* 0x06 */ CAM_TYPE_BOARD,
/* 0x07 */ CAM_TYPE_07,
/* 0x08 */ CAM_TYPE_KEEP,
/* 0x09 */ CAM_TYPE_RODEO,
/* 0x0A */ CAM_TYPE_MAGNE_BOOTS,
/* 0x0B */ CAM_TYPE_MAGNE_WALL,
/* 0x0C */ CAM_TYPE_MAGNE_ROOF,
/* 0x0D */ CAM_TYPE_WATER_SURF,
/* 0x0E */ CAM_TYPE_ROTARY,
/* 0x0F */ CAM_TYPE_STREET,
/* 0x10 */ CAM_TYPE_STREET_N,
/* 0x11 */ CAM_TYPE_STREET_P,
/* 0x12 */ CAM_TYPE_RAMPART_2,
/* 0x13 */ CAM_TYPE_ALLAY,
/* 0x14 */ CAM_TYPE_ALLAY_R,
/* 0x15 */ CAM_TYPE_ALLAY_R2,
/* 0x16 */ CAM_TYPE_ALLAY_S,
/* 0x17 */ CAM_TYPE_ALLAY_N,
/* 0x18 */ CAM_TYPE_ALLAY_R3,
/* 0x19 */ CAM_TYPE_HOOK_WALL,
/* 0x1A */ CAM_TYPE_HOOK_ROOF,
/* 0x1B */ CAM_TYPE_HOOK_ACTOR,
/* 0x1C */ CAM_TYPE_SPINNER,
/* 0x1D */ CAM_TYPE_GORON_JUMP,
/* 0x1E */ CAM_TYPE_GOAT_BATTLE,
/* 0x1F */ CAM_TYPE_BOAR,
/* 0x20 */ CAM_TYPE_COCCO_JUMP,
/* 0x21 */ CAM_TYPE_ROOF_HUNG,
/* 0x22 */ CAM_TYPE_COPY_ROD_HALL,
/* 0x23 */ CAM_TYPE_MIDNA_TAG,
/* 0x24 */ CAM_TYPE_WARP_OBJ,
/* 0x25 */ CAM_TYPE_LV9_GZELDA_TRI,
/* 0x26 */ CAM_TYPE_TEPPEI_HOOK,
/* 0x27 */ CAM_TYPE_LV4_BOSS_SPJP,
/* 0x28 */ CAM_TYPE_LV7_BOSS,
/* 0x29 */ CAM_TYPE_PEEP,
};
namespace {
static int specialType[42];
static int Stage;
#if WIDESCREEN_SUPPORT
static f32 WideTurnSaving = 0.86f + OREG_F(1);
#endif
inline static u32 check_owner_action(u32 param_0, u32 param_1) {
return dComIfGp_checkPlayerStatus0(param_0, param_1);
}
inline static u32 check_owner_action1(u32 param_0, u32 param_1) {
return dComIfGp_checkPlayerStatus1(param_0, param_1);
}
inline static bool isPlayerCharging(u32 param_0) {
return check_owner_action(param_0, 0x40000000);
}
inline static void setComStat(u32 param_0) {
dComIfGp_onCameraAttentionStatus(0, param_0);
}
inline static BOOL getComStat(u32 param_0) {
return dComIfGp_getCameraAttentionStatus(0) & param_0;
}
inline static void clrComStat(u32 param_0) {
dComIfGp_offCameraAttentionStatus(0, param_0);
}
inline static void setComZoomScale(f32 param_0) {
dComIfGp_setCameraZoomScale(0, param_0);
}
inline static void setComZoomForcus(f32 param_0) {
dComIfGp_setCameraZoomForcus(0, param_0);
}
} // namespace
void dCamera_c::initialize(camera_class* i_camera, fopAc_ac_c* i_player, u32 i_cameraID,
u32 i_padID) {
const char* fileName = dComIfGp_getCameraParamFileName(0);
void* objRes = dComIfG_getObjectRes(fileName, "camtype.dat");
char* typeData = (char*)objRes;
mCamTypeData = (dCamera_type_data*)(typeData + 8);
mCamTypeNum = BSWAP32(*(int*)(typeData + 4));
field_0x0 = i_camera;
field_0x20 = 1;
field_0x21 = 0;
mCurState = 0;
mpPlayerActor = i_player;
mCameraID = i_cameraID;
mPadID = i_padID;
initMonitor();
initPad();
mFocusLine.Init();
mRoomCtx.mRoomNo = dComIfGp_roomControl_getStayNo();
const char* stage_name = dComIfGp_getStartStageName();
if (strcmp(stage_name, "D_MN01A") == 0) {
Stage = 0x68;
} else if (strcmp(stage_name, "D_MN10A") == 0) {
Stage = 0x69;
} else if (strcmp(stage_name, "D_MN11A") == 0) {
Stage = 0x6A;
} else if (strcmp(stage_name, "D_MN04A") == 0) {
Stage = 0x66;
} else if (strcmp(stage_name, "D_MN05A") == 0) {
Stage = 0x65;
} else if (strcmp(stage_name, "D_MN07A") == 0) {
Stage = 0x6B;
}
specialType[CAM_TYPE_FIELD_S] = GetCameraTypeFromCameraName("FieldS");
specialType[CAM_TYPE_EVENT] = GetCameraTypeFromCameraName("Event");
specialType[CAM_TYPE_WATER] = GetCameraTypeFromCameraName("Water");
specialType[CAM_TYPE_SCOPE] = GetCameraTypeFromCameraName("Scope");
specialType[CAM_TYPE_WATER_SURF] = GetCameraTypeFromCameraName("WaterSurf");
specialType[CAM_TYPE_HORSE_T] = GetCameraTypeFromCameraName("HorseT");
specialType[CAM_TYPE_BOARD] = GetCameraTypeFromCameraName("Board");
specialType[CAM_TYPE_CANOE] = GetCameraTypeFromCameraName("Canoe");
specialType[CAM_TYPE_KEEP] = GetCameraTypeFromCameraName("Keep");
specialType[CAM_TYPE_RODEO] = GetCameraTypeFromCameraName("Rodeo");
specialType[CAM_TYPE_MAGNE_BOOTS] = GetCameraTypeFromCameraName("MagneBoots");
specialType[CAM_TYPE_MAGNE_ROOF] = GetCameraTypeFromCameraName("MagneRoof");
specialType[CAM_TYPE_MAGNE_WALL] = GetCameraTypeFromCameraName("MagneWall");
specialType[CAM_TYPE_COCCO_JUMP] = GetCameraTypeFromCameraName("CoccoJump");
specialType[CAM_TYPE_BOAR] = GetCameraTypeFromCameraName("Boar");
specialType[CAM_TYPE_GOAT_BATTLE] = GetCameraTypeFromCameraName("GoatBattle");
specialType[CAM_TYPE_GORON_JUMP] = GetCameraTypeFromCameraName("GoronJump");
specialType[CAM_TYPE_SPINNER] = GetCameraTypeFromCameraName("Spinner");
specialType[CAM_TYPE_HOOK_WALL] = GetCameraTypeFromCameraName("HookWall");
specialType[CAM_TYPE_HOOK_ROOF] = GetCameraTypeFromCameraName("HookRoof");
specialType[CAM_TYPE_HOOK_ACTOR] = GetCameraTypeFromCameraName("HookActor");
specialType[CAM_TYPE_ROOF_HUNG] = GetCameraTypeFromCameraName("RoofHung");
specialType[CAM_TYPE_ROTARY] = GetCameraTypeFromCameraName("Rotary");
specialType[CAM_TYPE_STREET] = GetCameraTypeFromCameraName("Street");
specialType[CAM_TYPE_STREET_N] = GetCameraTypeFromCameraName("StreetN");
specialType[CAM_TYPE_STREET_P] = GetCameraTypeFromCameraName("StreetP");
specialType[CAM_TYPE_RAMPART_2] = GetCameraTypeFromCameraName("Rampart2");
specialType[CAM_TYPE_ALLAY] = GetCameraTypeFromCameraName("Allay");
specialType[CAM_TYPE_ALLAY_R] = GetCameraTypeFromCameraName("AllayR");
specialType[CAM_TYPE_ALLAY_R2] = GetCameraTypeFromCameraName("AllayR2");
specialType[CAM_TYPE_ALLAY_S] = GetCameraTypeFromCameraName("AllayS");
specialType[CAM_TYPE_ALLAY_N] = GetCameraTypeFromCameraName("AllayN");
specialType[CAM_TYPE_ALLAY_R3] = GetCameraTypeFromCameraName("AllayR3");
specialType[CAM_TYPE_COPY_ROD_HALL] = GetCameraTypeFromCameraName("CopyRodHall");
specialType[CAM_TYPE_MIDNA_TAG] = GetCameraTypeFromCameraName("MidnaTag");
specialType[CAM_TYPE_WARP_OBJ] = GetCameraTypeFromCameraName("WarpObj");
specialType[CAM_TYPE_LV9_GZELDA_TRI] = GetCameraTypeFromCameraName("LV9GZeldaTri");
specialType[CAM_TYPE_LV4_BOSS_SPJP] = GetCameraTypeFromCameraName("LV4BOSSSPJP");
specialType[CAM_TYPE_LV7_BOSS] = GetCameraTypeFromCameraName("LV7BOSS");
specialType[CAM_TYPE_TEPPEI_HOOK] = GetCameraTypeFromCameraName("TeppeiHook");
mCurType = mMapToolType = specialType[CAM_TYPE_FIELD_S];
specialType[CAM_TYPE_PEEP] = GetCameraTypeFromCameraName("Peep");
field_0x698 = 0xFF;
field_0x69c = 0;
mIsWolf = daPy_py_c::checkNowWolf() != 0 ? TRUE : FALSE;
mCurMode = 0;
mEngineHoldState = 0;
mForcedMode = 11;
mSightFitRadius = 0.0f;
mEventFlags = 0;
mForwardTiltOffset = cSAngle::_0;
mFrameCounter = 0;
mTicks = cM_rndFX(0x7FFF);
field_0x84 = 1.0f;
mTrimHeight = field_0x91c = 0.0f;
mTrimSize = 0;
mTrimTypeForce = -1;
mGear = 0;
field_0x944 = 0;
field_0x950 = mGear;
#if DEBUG
dbg_field_0xd8 = 0;
#endif
mBG.field_0x0.field_0x0 = mBG.field_0x5c.field_0x0 = false;
mBG.field_0xc0.field_0x3c = 0xFF;
mBG.field_0x0.field_0x58 = mBG.field_0x5c.field_0x58 = -G_CM3D_F_INF;
mBG.field_0x0.field_0x4.OffNormalGrp();
mBG.field_0x0.field_0x4.OnWaterGrp();
mBG.field_0xc0.field_0x0 = mBG.field_0xc0.field_0x1 = 0;
mBG.field_0xc0.field_0x4 = mBG.field_0xc0.field_0x10 = cXyz::Zero;
mBG.field_0xc0.field_0x20 = 0;
mBG.field_0xc0.field_0x1c = mBG.field_0xc0.field_0x1e = cSAngle::_0;
mBG.field_0xc0.field_0x34 = 0;
mBG.field_0x108.field_0x0 = 0;
mBG.field_0x108.field_0x4 = 0.0f;
mBG.field_0xc0.field_0x38 = -G_CM3D_F_INF;
mBG.field_0xc0.field_0x40 = 0xFF;
mWallUpDist = mCamSetup.mBGChk.WallUpDistance();
mMapToolType = 0xFF;
mRoomMapTool.Clr();
mStageCamTool.Clr();
mDefRoomCamTool.Clr();
mTagCamTool.Clr();
field_0x89c.Clr();
field_0x8d8.Clr();
setStageMapToolData();
if (mStageCamTool.mCameraIndex != 0xFF) {
mMapToolType = GetCameraTypeFromToolData(&mStageCamTool.mCamData);
}
dStage_dt_c* stage_dt = dComIfGp_getStage();
stage_stag_info_class* stag_info;
stag_info = stage_dt != NULL ? stage_dt->getStagInfo() : NULL;
if (stag_info != NULL && mMapToolType == 0xFF) {
switch (dStage_stagInfo_GetSTType(stag_info)) {
case ST_DUNGEON:
mMapToolType = GetCameraTypeFromCameraName("DungeonS");
break;
case ST_ROOM:
mMapToolType = GetCameraTypeFromCameraName("Room");
break;
default:
mMapToolType = GetCameraTypeFromCameraName("FieldS");
break;
}
}
int sp108 = 0xFF;
s32 sp10C = dComIfGp_roomControl_getStayNo();
dStage_roomDt_c* room_dt = dComIfGp_roomControl_getStatusRoomDt(sp10C);
if (room_dt != NULL) {
dStage_FileList_dt_c* filelist = room_dt->getFileListInfo();
if (filelist != NULL) {
sp108 = dStage_FileList_dt_GetDefaultCamera(filelist);
}
}
setRoomMapToolData(&mDefRoomCamTool, sp108, sp10C);
checkGroundInfo();
setMapToolData();
if (mRoomMapTool.mCameraIndex != 0xFF) {
mCurType = GetCameraTypeFromToolData(&mRoomMapTool.mCamData);
} else {
if (check_owner_action(mPadID, 0x8000000)) {
mCurType = GetCameraTypeFromCameraName("Cave");
} else {
mCurType = mMapToolType;
}
}
mCamStyle = mCamTypeData[mCurType].field_0x18[mIsWolf][mCurMode];
mLockOnActorID = 0xFFFFFFFF;
mEventData.field_0x14 = -1;
mEventData.field_0x18 = -1;
mEventData.mStaffIdx = -1;
mEventData.field_0xc = -1;
mEventData.field_0x0 = 1;
OS_REPORT("camera: init: type %d mode %d style %d\n", mCurType, mCurMode, mCamStyle);
mCamParam.Change(mCamStyle);
if (daPy_py_c::checkPeepEndSceneChange() || dComIfGp_getStartStagePoint() == -2 ||
dComIfGp_getStartStagePoint() == -3)
{
mCenter = mViewCache.mCenter = dComIfGs_getTurnRestart().getCameraCtr();
mEye = mViewCache.mEye = dComIfGs_getTurnRestart().getCameraEye();
mViewCache.mDirection.Val(mEye - mCenter);
mDirection = mViewCache.mDirection;
mControlledYaw = mViewCache.mDirection.U().Inv();
mUp = dComIfGs_getTurnRestart().getCameraUp();
mViewCache.mBank = mBank = cSAngle::_0;
mViewCache.mFovy = mFovy = dComIfGs_getTurnRestart().getCameraFvy();
} else if (daAlink_getAlinkActorClass()->checkStartFall()) {
cXyz attn_pos = attentionPos(mpPlayerActor);
if (mCamParam.Algorythmn() == 1) {
attn_pos.y += -20.0f;
}
cSGlobe spE8(0.0f, cSAngle((s16)0), directionOf(mpPlayerActor));
mCenter = mViewCache.mCenter = attn_pos + spE8.Xyz();
cXyz center = dComIfGs_getTurnRestart().getCameraCtr();
cXyz eye = dComIfGs_getTurnRestart().getCameraEye();
mViewCache.mDirection.Val(eye - center);
mControlledYaw = mViewCache.mDirection.U().Inv();
mEye = mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mUp = dComIfGs_getTurnRestart().getCameraUp();
mViewCache.mBank = mBank = cSAngle::_0;
mViewCache.mFovy = mFovy = dComIfGs_getTurnRestart().getCameraFvy();
} else {
cXyz attn_pos = attentionPos(mpPlayerActor);
if (mCamParam.Algorythmn() == 1) {
attn_pos.y += -20.0f;
}
cSGlobe spE8(0.0f, cSAngle((s16)0), directionOf(mpPlayerActor));
mCenter = mViewCache.mCenter = attn_pos + spE8.Xyz();
mViewCache.mDirection.Val(300.0f, 0, directionOf(mpPlayerActor).Inv());
mEye = mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mDirection = mViewCache.mDirection;
mControlledYaw = mViewCache.mDirection.U().Inv();
mViewCache.mFovy = mFovy = 60.0f;
mUp.set(0.0f, 1.0f, 0.0f);
mViewCache.mBank = mBank = cSAngle::_0;
}
mFakeAngleSys.field_0x0 = 0;
field_0x670 = field_0x674 = 0xFF;
field_0x66c = field_0x668 = 0;
field_0x678 = 1;
mZoomRatio = 0.0f;
field_0x738 = 85.0f;
#if DEBUG
mCamSetup.SetTypeTable(mCamTypeData, mCamTypeNum);
#endif
mFastShotState = 0;
field_0x611 = 0;
clearInfo(&mSavedView, 0);
clearInfo(&mSavedViewStack[0], 0);
clearInfo(&mSavedViewStack[1], 0);
clearInfo(&mRecovery.field_0x8, 0);
mRecovery.field_0x4 = 0;
mRecovery.field_0x28 = cXyz::Zero;
mRecovery.field_0x0 = -1;
field_0x93c = 0;
mThrowTimer = 0;
mBankOverride = cSAngle::_0;
mUpOverride.field_0x18 = mUp;
mUpOverride.field_0xc = mEye;
mUpOverride.field_0x0 = mCenter;
setFlag(0x1000);
daAlink_c* player = daAlink_getAlinkActorClass();
daMidna_c* midna = daPy_py_c::getMidnaActor();
mMidnaRidingAndVisible = player->checkMidnaRide() && !midna->checkNoDraw();
mLastBumpCase = 0;
field_0x95c = cXyz::Zero;
f32 unusedFloat1 = 0.2f;
f32 unusedFloat2 = 0.0f;
}
void dCamera_c::Start() {
if (mCamSetup.CheckFlag(0x8000) && mCurState != 0 && mCurState != 2) {
OS_REPORT("camera: start\n");
}
if (mCurState != 0) {
mCurState = 2;
}
}
void dCamera_c::QuickStart() {
if (mCamSetup.CheckFlag(0x8000) && mCurState != 0) {
OS_REPORT("camera: quick start\n");
}
mCurState = 0;
}
void dCamera_c::Stop() {
clrFlag(0x200000);
if (mCamSetup.CheckFlag(0x8000) && mCurState != 3) {
OS_REPORT("%06d: camera: stop \n", mFrameCounter);
}
mCurState = 3;
}
void dCamera_c::Stay() {
mCurState = 1;
}
bool dCamera_c::ChangeModeOK(s32 param_0) {
if (dComIfGp_evmng_cameraPlay() || chkFlag(0x20000000)) {
return 0;
}
return !(mCamTypeData[mCurType].field_0x18[mIsWolf][param_0] < 0);
}
void dCamera_c::initPad() {
if (chkFlag(0x1000000)) {
mPadInfo.mMainStick.mLastPosX = 0.0f;
mPadInfo.mMainStick.mLastPosY = 0.0f;
mPadInfo.mMainStick.mLastValue = 0.0f;
} else {
mPadInfo.mMainStick.mLastPosX = mDoCPd_c::getStickX3D(mPadID);
mPadInfo.mMainStick.mLastPosY = mDoCPd_c::getStickY(mPadID);
mPadInfo.mMainStick.mLastValue = mDoCPd_c::getStickValue(mPadID);
}
mPadInfo.mMainStick.mPosXDelta = 0.0f;
mPadInfo.mMainStick.mPosYDelta = 0.0f;
mPadInfo.mMainStick.mValueDelta = 0.0f;
mPadInfo.mMainStick.mAngle = cSAngle::_0;
if (chkFlag(0x800000)) {
mPadInfo.mMainStick.mLastPosX = 0.0f;
mPadInfo.mMainStick.mLastPosY = 0.0f;
mPadInfo.mMainStick.mLastValue = 0.0f;
} else {
mPadInfo.mCStick.mLastPosX = mDoCPd_c::getSubStickX(mPadID);
mPadInfo.mCStick.mLastPosY = mDoCPd_c::getSubStickY(mPadID);
mPadInfo.mCStick.mLastValue = mDoCPd_c::getSubStickValue(mPadID);
}
mPadInfo.mCStick.mPosXDelta = 0.0f;
mPadInfo.mCStick.mPosYDelta = 0.0f;
mPadInfo.mCStick.mValueDelta = 0.0f;
mPadInfo.mCStick.mAngle = cSAngle::_0;
mCStickYState = mCStickYHoldCount = mCStickUpLatch = 0;
mTriggerLeftLast = mDoCPd_c::getAnalogL(mPadID);
mTriggerLeftDelta = 0.0f;
mHoldLockL = 0;
mTrigLockL = 0;
mLockLActive = 0;
mLockLJustActivated = 0;
mTriggerRightLast = mDoCPd_c::getAnalogR(mPadID);
mTriggerRightDelta = 0.0f;
mHoldLockR = 0;
mTrigLockR = 0;
mLockRActive = 0;
mLockRJustActivated = 0;
mHoldX = mDoCPd_c::getHoldX(mPadID) ? true : false;
mTrigX = mDoCPd_c::getTrigX(mPadID) ? true : false;
mHoldY = mDoCPd_c::getHoldY(mPadID) ? true : false;
mTrigY = mDoCPd_c::getTrigY(mPadID) ? true : false;
mHoldY = mDoCPd_c::getHoldY(mPadID) ? true : false;
mTrigY = mDoCPd_c::getTrigY(mPadID) ? true : false;
mHoldZ = mDoCPd_c::getHoldZ(mPadID) ? true : false;
mTrigZ = mDoCPd_c::getTrigZ(mPadID) ? true : false;
field_0x21f = 0;
mHoldB = mDoCPd_c::getHoldB(mPadID) ? true : false;
mTrigB = mDoCPd_c::getTrigB(mPadID) ? true : false;
field_0x223 = 0;
mCameraInputActive = 0;
}
void dCamera_c::updatePad() {
dAttention_c* attn = dComIfGp_getAttention();
int var_r30 = mCamParam.Algorythmn(mCamStyle);
f32 var_f31;
f32 var_f30;
f32 var_f29;
if (chkFlag(0x1000000)) {
var_f31 = 0.0f;
var_f30 = 0.0f;
var_f29 = 0.0f;
} else {
var_f31 = mDoCPd_c::getStickX3D(mPadID);
var_f30 = mDoCPd_c::getStickY(mPadID);
var_f29 = mDoCPd_c::getStickValue(mPadID);
}
mPadInfo.mMainStick.mPosXDelta = var_f31 - mPadInfo.mMainStick.mLastPosX;
mPadInfo.mMainStick.mPosYDelta = var_f30 - mPadInfo.mMainStick.mLastPosY;
mPadInfo.mMainStick.mValueDelta = var_f29 - mPadInfo.mMainStick.mLastValue;
mPadInfo.mMainStick.mLastPosX = var_f31;
mPadInfo.mMainStick.mLastPosY = var_f30;
mPadInfo.mMainStick.mLastValue = var_f29;
mPadInfo.mMainStick.mAngle.Val(mDoCPd_c::getStickAngle3D(mPadID));
if (chkFlag(0x800000)) {
var_f31 = 0.0f;
var_f30 = 0.0f;
var_f29 = 0.0f;
} else {
var_f31 = mDoCPd_c::getSubStickX3D(mPadID);
#if TARGET_PC
if (dusk::getSettings().game.invertCameraXAxis) {
var_f31 *= -1.0f;
}
#endif
var_f30 = mDoCPd_c::getSubStickY(mPadID);
var_f29 = mDoCPd_c::getSubStickValue(mPadID);
}
mPadInfo.mCStick.mPosXDelta = var_f31 - mPadInfo.mCStick.mLastPosX;
mPadInfo.mCStick.mPosYDelta = var_f30 - mPadInfo.mCStick.mLastPosY;
mPadInfo.mCStick.mValueDelta = var_f29 - mPadInfo.mCStick.mLastValue;
mPadInfo.mCStick.mLastPosX = var_f31;
mPadInfo.mCStick.mLastPosY = var_f30;
mPadInfo.mCStick.mLastValue = var_f29;
mPadInfo.mCStick.mAngle.Val(mDoCPd_c::getSubStickAngle(mPadID));
f32 analog_l = mDoCPd_c::getAnalogL(mPadID);
mTriggerLeftDelta = mTriggerLeftLast - analog_l;
mTriggerLeftLast = analog_l;
mHoldLockL = mDoCPd_c::getHoldLockL(mPadID) ? true : false;
mTrigLockL = mDoCPd_c::getTrigLockL(mPadID) ? true : false;
if (mTriggerLeftLast > mCamSetup.ManualEndVal()) {
if (mLockLActive == 0) {
mLockLJustActivated = 1;
} else {
mLockLJustActivated = 0;
}
mLockLActive = 1;
} else {
mLockLJustActivated = 0;
mLockLActive = 0;
}
f32 analog_r = mDoCPd_c::getAnalogR(mPadID);
mTriggerRightDelta = mTriggerRightLast - analog_r;
mTriggerRightLast = analog_r;
mHoldLockR = mDoCPd_c::getHoldLockR(mPadID) ? true : false;
mTrigLockR = mDoCPd_c::getTrigLockR(mPadID) ? true : false;
if (mTriggerRightLast > mCamSetup.ManualEndVal()) {
if (mLockRActive == 0) {
mLockRJustActivated = 1;
} else {
mLockRJustActivated = 0;
}
mLockRActive = 1;
} else {
mLockRJustActivated = 0;
mLockRActive = 0;
}
mHoldX = mDoCPd_c::getHoldX(mPadID) ? true : false;
mTrigX = mDoCPd_c::getTrigX(mPadID) ? true : false;
mHoldY = mDoCPd_c::getHoldY(mPadID) ? true : false;
mTrigY = mDoCPd_c::getTrigY(mPadID) ? true : false;
mHoldZ = mDoCPd_c::getHoldZ(mPadID) ? true : false;
mTrigZ = mDoCPd_c::getTrigZ(mPadID) ? true : false;
mHoldB = mDoCPd_c::getHoldB(mPadID) ? true : false;
mTrigB = mDoCPd_c::getTrigB(mPadID) ? true : false;
bool sp6B = true;
bool sp6C = true;
int temp1;
int sp68;
if (mCamTypeData[mCurType].field_0x18[mIsWolf][0] > 0) {
sp68 = mIsWolf;
} else {
sp68 = 0;
}
temp1 = sp68;
if (mCamTypeData[mCurType].field_0x18[temp1][4] < 0) {
sp6B = false;
if (mGear == -1) {
mGear = 0;
}
}
if ((var_r30 != 1 && var_r30 != 8 && var_r30 != 7) || mCamParam.Flag(mCamStyle, 0x80)) {
sp6C = false;
if (mGear == 1) {
mGear = 0;
}
}
if (mCurMode == 0 || mCurMode == 4) {
if (check_owner_action(mPadID, 0x12000)) {
mGear = -1;
} else if (mGear == -1) {
mGear = 0;
}
if (mPadInfo.mCStick.mLastPosY < -mCamSetup.mCStick.SwTHH()) {
if (mCStickYState != -1) {
if (mGear == -1 && mCurMode == 4) {
mGear = 0;
setComStat(0x2000);
} else if (mGear == 0 && sp6C) {
mGear = 1;
}
}
mCStickYState = -1;
} else if (mPadInfo.mCStick.mLastPosY > mCamSetup.mCStick.SwTHH()) {
if (mCStickYState != 1) {
if (mGear == 0 && sp6B) {
setComStat(0x1000);
} else if (mGear == 1) {
mGear = 0;
}
}
mCStickYState = 1;
} else {
mCStickYState = 0;
}
if (mCStickYState != 0) {
mCStickYHoldCount++;
} else {
mCStickYHoldCount = 0;
}
}
field_0x223 = 0;
mCameraInputActive = 0;
if (mDoCPd_c::getStickValue(mPadID) > 0.001f || mDoCPd_c::getSubStickValue(mPadID) > 0.001f ||
mDoCPd_c::getHold(mPadID) != 0)
{
mCameraInputActive = 1;
}
#if DEBUG
if (mCamSetup.CheckFlag(0x8000) && !dComIfGp_evmng_cameraPlay()) {
if (((mGear + 1) & ~0x3) == 0) {
dDbVw_Report(20, 235, "%c", "LMH?"[mGear + 1]);
}
}
#endif
}
void dCamera_c::initMonitor() {
if (mpPlayerActor != NULL) {
mMonitor.field_0x0 = positionOf(mpPlayerActor);
} else {
mMonitor.field_0x0 = cXyz::Zero;
}
mMonitor.field_0xc = mMonitor.field_0x10 = field_0x2c0 = 0.0f;
mIdleFrameCount = 0;
field_0x2c8 = 0.0f;
mMonitor.field_0x14.field_0x0 = cXyz::Zero;
}
void dCamera_c::updateMonitor() {
if (mpPlayerActor == NULL) {
return;
}
cXyz sp24 = positionOf(mpPlayerActor);
mMonitor.field_0x14.field_0x0 = sp24 - mMonitor.field_0x0;
if (mBG.field_0xc0.field_0x1) {
dComIfG_Bgsp().MoveBgMatrixCrrPos(mBG.field_0x5c.field_0x4, true, &mMonitor.field_0x0, NULL,
NULL);
}
f32 var_f31;
if (chkFlag(0x10000)) {
var_f31 = cXyz(sp24 - mMonitor.field_0x0).abs();
} else {
var_f31 = dCamMath::xyzHorizontalDistance(sp24, mMonitor.field_0x0);
}
field_0x2c0 = var_f31 - mMonitor.field_0xc;
mMonitor.field_0x10 += (var_f31 - mMonitor.field_0x10) * 0.01f;
mMonitor.field_0xc = var_f31;
mMonitor.field_0x0 = sp24;
if (!push_any_key()) {
mIdleFrameCount++;
} else {
mIdleFrameCount = 0;
}
field_0x2c8 = mDirection.R() - field_0x2c8;
}
bool dCamera_c::checkForceLockTarget() {
bool ret = true;
if (mLockOnActorID != -1) {
mpLockOnActor = GetForceLockOnActor();
if (mpLockOnActor != NULL) {
if (dComIfGp_getAttention()->Lockon() || mForceLockTimer > mCamSetup.ForceLockOffTimer()
|| cXyz(positionOf(mpLockOnActor) - positionOf(mpPlayerActor)).abs() > mCamSetup.ForceLockOffDist())
{
ret = false;
}
} else {
ret = false;
}
} else {
ret = false;
}
return ret;
}
void dCamera_c::infoReport() {
#if DEBUG
int x = 20;
int y = 190;
const char* c1;
if (mBG.field_0xc0.field_0x44 != 0) {
c1 = " ";
} else {
c1 = "j";
}
const char* c2;
if (mStyleSettle.mFinished != 0) {
c2 = "O";
} else {
c2 = "x";
}
dDbVw_Report(x, y, "%s%s", c2, c1);
dDbVw_Report(x, y + 15, "TY%03d MD%03d", mCurType, mCurMode);
dDbVw_Report(x, y + 30, "ST%03d AL%03d", mCamStyle, mCamParam.Algorythmn());
#endif
}
namespace {
inline bool isPlayerFlying(daAlink_c* link) {
bool ret = false;
if (link->checkPlayerFly() && !link->checkBootsOrArmorHeavy()) {
ret = true;
}
return ret;
}
inline bool chkCornerCos(f32 param_0) {
return param_0 >= -0.5f && param_0 <= 0.5f;
}
} // namespace
void dCamera_c::debugDrawInit() {
#if DEBUG
dbg_field_0xd4 = 0;
#endif
}
bool dCamera_c::Run() {
#if TARGET_PC
ResetView();
#endif
daAlink_c* link = daAlink_getAlinkActorClass();
daMidna_c* midna = daPy_py_c::getMidnaActor();
mMidnaRidingAndVisible = link->checkMidnaRide() && !midna->checkNoDraw();
bool sp10 = false;
bool sp0F = false;
clrComStat(0x804);
#if DEBUG
debugDrawInit();
dDbgCamera.InitlChk();
#endif
int iVar8 = mIsWolf;
mIsWolf = daPy_py_c::checkNowWolf() ? 1 : 0;
mFocusLine.Off();
clrFlag(0x10168C21);
clrFlag(0x10);
mpAuxTargetActor1 = mpAuxTargetActor2 = NULL;
s32 stay_no = dComIfGp_roomControl_getStayNo();
if (stay_no != mRoomCtx.mRoomNo) {
onRoomChange(stay_no);
}
checkGroundInfo();
setMapToolData();
if (link->checkRollJump() || link->checkGoronRideWait()) {
setFlag(0x10000);
setFlag(0x100000);
} else {
if (mBG.field_0xc0.field_0x44 != 0) {
clrFlag(0x10000);
}
}
if (link->checkGrabThrow() || link->checkIronBallThrowMode()) {
mThrowTimer = mCamSetup.ThrowTimer();
} else {
if (mThrowTimer != 0) {
mThrowTimer--;
}
}
updateMonitor();
Att();
clrComStat(0xf400);
if (!dComIfGp_evmng_cameraPlay() && !chkFlag(0x20000000)) {
updatePad();
mCamSetup.mCStick.Shift(mPadID);
}
if (dComIfGp_getEvent()->runCheck()) {
mPadInfo.mMainStick.mLastPosX =
mPadInfo.mMainStick.mLastPosY =
mPadInfo.mMainStick.mLastValue = 0.0f;
mPadInfo.mCStick.mLastPosX =
mPadInfo.mCStick.mLastPosY =
mPadInfo.mCStick.mLastValue = 0.0f;
}
if (!checkForceLockTarget()) {
mLockOnActorID = -1;
} else {
mForceLockTimer++;
}
mNextType = nextType(mCurType);
if (mNextType != mCurType && onTypeChange(mCurType, mNextType)) {
if (mCamSetup.CheckFlag(0x8000)) {
OS_REPORT("%06d: camera: type change %d -> %d (%s)\n",
mFrameCounter, mCurType, mNextType, mCamTypeData[mNextType].name);
}
mCurType = mNextType;
}
clrComStat(0x40000);
if (mCurType == specialType[CAM_TYPE_PEEP]) {
setComStat(0x40000);
}
mNextMode = nextMode(mCurMode);
if ((iVar8 != mIsWolf || mNextMode != mCurMode)
&& mCamTypeData[mCurType].field_0x18[mIsWolf][mNextMode] >= 0
&& onModeChange(mCurMode, mNextMode))
{
if (mCamSetup.CheckFlag(0x8000)) {
OS_REPORT("%06d: camera: mode change %d -> %d\n",
mFrameCounter, mCurMode, mNextMode);
}
mCurMode = mNextMode;
mCurCamStyleTimer = 0;
}
if (!ChangeModeOK(mCurMode)) {
mCurMode = 0;
}
int style = mCamTypeData[mCurType].field_0x18[mIsWolf][mCurMode];
if (style >= 0 && mCamStyle != style && onStyleChange(mCamStyle, style)) {
u32 id = mCamParam.Id(style);
if (mCamSetup.CheckFlag(0x8000)) {
OS_REPORT("%06d: camera: style change %d -> %d (%c%c%c%c)\n",
mFrameCounter, mCamStyle, style,
(id >> 24) & 0xff, (id >> 16) & 0xff, (id >> 8) & 0xff, id & 0xff);
}
mCamStyle = style;
mCamParam.Change(mCamStyle);
setFlag(0x200);
}
clrFlag(0);
clrComStat(0x80);
if (mGear == -1) {
setComStat(0x80);
}
if (getComStat(0x2000)) {
setComStat(0x80);
}
if (mCamParam.CheckFlag(0x4000) && !check_owner_action(mPadID, 0x4000000)
&& !link->checkMagneBootsOn() && !isPlayerFlying(link))
{
mForwardTiltOffset += (forwardCheckAngle() - mForwardTiltOffset) * mCamSetup.mBGChk.FwdCushion();
} else {
mForwardTiltOffset = cSAngle::_0;
}
mBumpCheckFlags = 0x4001;
clrFlag(8);
if (chkFlag(0x200000) && mCamParam.Algorythmn(mCamStyle) != 10) {
if (push_any_key() || mMonitor.field_0xc > 10.0f || mBG.field_0xc0.field_0x44 == 0) {
clrFlag(0x200000);
}
} else {
sp0F = (this->*engine_tbl[mCamParam.Algorythmn(mCamStyle)])(mCamStyle);
field_0x170++;
field_0x160++;
mCurCamStyleTimer++;
}
mFrameCounter++;
mTicks++;
if (!sp0F) {
mEngineHoldState = 0;
}
defaultTriming();
if (!chkFlag(0x400)) {
mViewCache.mBank -= mViewCache.mBank * 0.05f;
}
shakeCamera();
blureCamera();
if (mCamParam.Algorythmn() != 10) {
clrFlag(0x80080);
if (mCamParam.CheckFlag(1)) {
if (mCurMode == 1 && mCamParam.CheckFlag(2)) {
mBumpCheckFlags = 0x4007;
} else if (chkFlag(0x20000)) {
mBumpCheckFlags = 0x4037;
} else {
mBumpCheckFlags = 0x4017;
}
} else if (mCamParam.CheckFlag(2)) {
mBumpCheckFlags = 0x4007;
}
if (mCamParam.CheckFlag(8)) {
mBumpCheckFlags |= 0x80;
}
if (mCamParam.CheckFlag(0x10)) {
mBumpCheckFlags &= ~0x4000;
}
mBumpCheckFlags &= ~0x8;
if (mCamParam.CheckFlag(0x4)) {
mBumpCheckFlags = 0x0;
}
#if PLATFORM_WII
if (mCurMode == 7 && !dComIfGp_checkPlayerStatus0(mPadID, 0x200000)) {
mBumpCheckFlags = 0x2000;
}
#endif
}
mFovy = mViewCache.mFovy;
mBank = mViewCache.mBank;
bumpCheck(mBumpCheckFlags);
cSAngle angle = mPadInfo.mMainStick.mAngle - mFakeAngleSys.field_0x4;
if (mPadInfo.mMainStick.mLastValue < mCamSetup.USOValue()
|| angle > cSAngle(mCamSetup.USOAngle()) || angle < cSAngle(-mCamSetup.USOAngle()))
{
mFakeAngleSys.field_0x0 = 0;
}
if (mFakeAngleSys.field_0x0 != 0) {
mControlledYaw = getUSOAngle(mPadInfo.mMainStick.mAngle);
#if DEBUG
if (mCamSetup.CheckFlag(0x8000) && dComIfGp_evmng_cameraPlay() == 0) {
int x = 90;
int y = 190;
dDbVw_Report(x, y, " F");
}
#endif
} else {
mControlledYaw = mDirection.U().Inv();
}
if (mCamSetup.CheckFlag(0x8000)) {
int x = 20;
int y = 235;
infoReport();
}
if (chkFlag(0x10)) {
mUp = mUpOverride.field_0x18.norm();
} else if (dComIfGp_getStageWorldRollAngleX() != 0) {
cSPolar polar;
polar.R(1.0f);
polar.V((s16)-dComIfGp_getStageWorldRollAngleX());
polar.U(dComIfGp_getStageWorldRollDirAngleY());
mUp = polar.Xyz();
} else if (mCenter.x == mEye.x && mCenter.z == mEye.z) {
mUp.set(0.01f, 1.0f, 0.0f);
} else {
mUp.set(0.0f, 1.0f, 0.0f);
}
if (!chkFlag(0x10)) {
mUpOverride.field_0x18.set(0.0f, 1.0f, 0.0f);
}
if (mBankOverride != cSAngle::_0) {
mBank = mBankOverride;
}
mBankOverride = cSAngle::_0;
f32 water_height = getWaterSurfaceHeight(&mEye);
if (water_height > mEye.y) {
dKy_camera_water_in_status_set(1);
Z2GetAudioMgr()->setCameraInWaterDepth(water_height - mEye.y);
} else {
dKy_camera_water_in_status_set(0);
Z2GetAudioMgr()->setCameraInWaterDepth(0.0f);
}
if (isModeOK()) {
setComStat(0x10);
} else {
clrComStat(0x10);
}
f32 hide_dist = mCamSetup.PlayerHideDist();
if (mDirection.R() < hide_dist) {
if (chkFlag(0x800) & 1) {
setComStat(2);
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " H");
}
#endif
} else if (chkFlag(0x10000000)) {
setComStat(0x20);
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " h");
}
#endif
} else {
#if DEBUG
if (mCurType != specialType[1] && false) {
mDirection.R(hide_dist + 0.1f);
mEye = mCenter + mDirection.Xyz();
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " <");
}
}
#endif
}
}
runEventRecoveryTrans();
#if DEBUG
if (mCamSetup.CheckFlag(0x200)) {
int x = 20;
int y = 320;
int yStep = 15;
cXyz aPos = attentionPos(mpPlayerActor);
cSAngle sp40 = directionOf(mpPlayerActor);
dDbVw_Report(x, y, "APOS %11.3f %11.3f %11.3f", aPos.x, aPos.y, aPos.z);
dDbVw_Report(x, y += yStep, "iCTR %11.3f %11.3f %11.3f",
mViewCache.mCenter.x, mViewCache.mCenter.y, mViewCache.mCenter.z);
dDbVw_Report(x, y += yStep, "iEYE %11.3f %11.3f %11.3f",
mViewCache.mEye.x, mViewCache.mEye.y, mViewCache.mEye.z);
dDbVw_Report(x, y += yStep, "iC2E %11.3f %11.3f %11.3f",
mViewCache.mDirection.R(), mViewCache.mDirection.V().Degree(),
mViewCache.mDirection.U().Degree());
dDbVw_Report(x, y += yStep, "CTR %11.3f %11.3f %11.3f",
mCenter.x, mCenter.y, mCenter.z);
dDbVw_Report(x, y += yStep, "EYE %11.3f %11.3f %11.3f",
mEye.x, mEye.y, mEye.z);
dDbVw_Report(x, y += yStep, "C2E %11.3f %11.3f %11.3f",
mDirection.R(), mDirection.V().Degree(), mDirection.U().Degree());
dDbVw_Report(x, y += yStep, "FVY %11.3f AANG %11.3f",
mFovy, sp40.Degree());
}
if (mCamSetup.CheckFlag(0x100)) {
if (mpPlayerActor != NULL) {
cXyz spCC = attentionPos(mpPlayerActor);
debugDrawPoint(spCC);
if (mpLockonTarget != NULL) {
cXyz spC0 = attentionPos(mpLockonTarget);
debugDrawPoint(spC0);
debugDrawLine(spCC, spC0);
}
}
debugDrawPoint(mCenter);
}
#endif
clrFlag(0x1000);
mTagCamTool.Clr();
field_0x89c.Clr();
return sp0F;
}
bool dCamera_c::NotRun() {
daAlink_c* link = daAlink_getAlinkActorClass();
daMidna_c* midna = daPy_py_c::getMidnaActor();
mMidnaRidingAndVisible = link->checkMidnaRide() && !midna->checkNoDraw();
clrComStat(0x804);
clrFlag(0x10168C21);
checkGroundInfo();
clrComStat(0x80);
if (dComIfGp_evmng_cameraPlay() || chkFlag(0x20000000)) {
if (mCurType != specialType[CAM_TYPE_EVENT]) {
pushInfo(&mSavedView, 1);
mEventData.field_0xc = mCurType;
mCurType = specialType[CAM_TYPE_EVENT];
mCamStyle = mCamParam.SearchStyle('EN01');
field_0x170 = 0;
field_0x160 = 0;
mCurCamStyleTimer = 0;
}
eventCamera(mCamTypeData[mCurType].field_0x18[mIsWolf][3]);
field_0x170++;
field_0x160++;
mCurCamStyleTimer++;
}
setComStat(0x14);
clrFlag(0x80080);
mFocusLine.Off();
shakeCamera();
blureCamera();
field_0x21 = 0;
#if DEBUG
if (mCamSetup.CheckFlag(0x200)) {
int x = 20;
int y = 320;
int yStep = 15;
dDbVw_Report(x, y, "iCTR %11.3f %11.3f %11.3f",
mViewCache.mCenter.x, mViewCache.mCenter.y, mViewCache.mCenter.z);
dDbVw_Report(x, y += yStep, "iEYE %11.3f %11.3f %11.3f",
mViewCache.mEye.x, mViewCache.mEye.y, mViewCache.mEye.z);
dDbVw_Report(x, y += yStep, "iC2E %11.3f %11.3f %11.3f",
mViewCache.mDirection.R(), mViewCache.mDirection.V().Degree(),
mViewCache.mDirection.U().Degree());
dDbVw_Report(x, y += yStep, "CTR %11.3f %11.3f %11.3f", mCenter.x, mCenter.y, mCenter.z);
dDbVw_Report(x, y += yStep, "EYE %11.3f %11.3f %11.3f", mEye.x, mEye.y, mEye.z);
dDbVw_Report(x, y += yStep, "FVY %11.3f ", mFovy);
}
#endif
if (mBankOverride != cSAngle::_0) {
mBank = mBankOverride;
}
mBankOverride = cSAngle::_0;
f32 water_height = getWaterSurfaceHeight(&mEye);
if (water_height > mEye.y) {
dKy_camera_water_in_status_set(1);
Z2GetAudioMgr()->setCameraInWaterDepth(water_height - mEye.y);
} else {
dKy_camera_water_in_status_set(0);
Z2GetAudioMgr()->setCameraInWaterDepth(0.0f);
}
mFrameCounter++;
mTicks++;
mTagCamTool.Clr();
field_0x89c.Clr();
return true;
}
s16 dCamera_c::V() {
if (chkFlag(0x10)) {
return mUpOverride.field_0x24.V();
} else {
return mDirection.V();
}
}
s16 dCamera_c::U() {
if (chkFlag(0x10)) {
return mUpOverride.field_0x24.U();
} else {
return mDirection.U().Inv();
}
}
bool dCamera_c::SetTrimSize(s32 size) {
bool rt = mTrimSize != size;
mTrimSize = size;
return rt;
}
bool dCamera_c::SetTrimTypeForce(s32 param_0) {
mTrimTypeForce = param_0;
return 1;
}
void dCamera_c::CalcTrimSize() {
if (mCurState != 2) {
switch (mTrimSize) {
case 0:
mTrimHeight += -mTrimHeight * 0.25f;
break;
case 2:
#if WIDESCREEN_SUPPORT
if (mDoGph_gInf_c::isWide() && mDoGph_gInf_c::isWideZoom()) {
mTrimHeight += (16.0f - mTrimHeight) * 0.25f;
break;
}
#endif
mTrimHeight += (mCamSetup.CinemaScopeTrimHeight() - mTrimHeight) * 0.25f;
break;
case 1:
mTrimHeight += (mCamSetup.VistaTrimHeight() - mTrimHeight) * 0.25f;
break;
case 3:
mTrimHeight += (mCamSetup.CinemaScopeTrimHeight() - mTrimHeight) * 0.25f;
break;
case 4:
mTrimHeight = 0.0f;
break;
}
} else {
OS_REPORT("%06d: camera: trim: keep\n", mFrameCounter);
}
if (mCurState == 1) {
mCurState = 0;
} else if (mCurState == 2) {
if (dComIfGp_getEvent()->isOrderOK()) {
mCurState = 0;
}
}
mForcedMode = 11;
}
int dCamera_c::Draw() {
#if DEBUG
debugDraw();
#endif
mFocusLine.Draw();
return 1;
}
void dCamera_c::debugDraw() {
#if DEBUG
GXColor color;
u32 i;
for (i = 0; i < dbg_field_0xd4; i++) {
color.r = (i & 0x1) != 0 ? 0xff : (i & 0x8) != 0 ? 0xc0 : 0x80;
color.g = (i & 0x2) != 0 ? 0xff : (i & 0x8) != 0 ? 0xc0 : 0x80;
color.b = (i & 0x4) != 0 ? 0xff : (i & 0x8) != 0 ? 0xc0 : 0x80;
color.a = 0x80;
if (dbg_field_0xc4[i] == 0) {
dDbVw_drawSphereXlu(dbg_field_0x04[i], 20.0f, color, 1);
} else if (dbg_field_0xc4[i] == 1) {
dDbVw_drawLineXlu(dbg_field_0x04[i], dbg_field_0x04[i + 1], color, 1, 12);
i++;
}
}
dbg_field_0xd4 = 0;
#endif
}
int dCamera_c::debugDrawPoint(cXyz& i_point) {
#if DEBUG
if (dbg_field_0xd4 >= 16) {
return 0;
}
dbg_field_0x04[dbg_field_0xd4] = i_point;
dbg_field_0xc4[dbg_field_0xd4] = 0;
dbg_field_0xd4++;
#endif
return 1;
}
int dCamera_c::debugDrawLine(cXyz& i_point_1, cXyz& i_point_2) {
#if DEBUG
if (dbg_field_0xd4 + 1 >= 16) {
return 0;
}
dbg_field_0x04[dbg_field_0xd4] = i_point_1;
dbg_field_0xc4[dbg_field_0xd4] = 1;
dbg_field_0xd4++;
dbg_field_0x04[dbg_field_0xd4] = i_point_2;
dbg_field_0xc4[dbg_field_0xd4] = 2;
dbg_field_0xd4++;
#endif
return 1;
}
void dCamera_c::setStageMapToolData() {
int cameraIndex = 0xFF;
int var_r27 = 0xFF;
mStageCamTool.Clr();
dStage_dt_c* stage_dt = (dStage_dt_c*)dComIfGp_getStage();
if (stage_dt != NULL) {
stage_camera_class* camera = stage_dt->getCamera();
stage_arrow_class* arrow = stage_dt->getArrow();
stage_stag_info_class* staginfo = stage_dt->getStagInfo();
if (staginfo != NULL) {
cameraIndex = dStage_stagInfo_DefaultCameraType(staginfo);
}
if (camera != NULL && cameraIndex >= 0 && cameraIndex < camera->num) {
mStageCamTool.mCameraIndex = cameraIndex;
mStageCamTool.mCamData = camera->m_entries[cameraIndex];
mStageCamTool.mFlags = (mStageCamTool.mCamData.field_0x14 >> 0xE) & 3;
if (mStageCamTool.mCamData.field_0x14 & 0x2000) {
mStageCamTool.mCamData.field_0x14 |= (u16) 0xC000;
} else {
mStageCamTool.mCamData.field_0x14 &= (u16) ~0xC000;
}
var_r27 = mStageCamTool.mCamData.m_arrow_idx;
if (arrow != NULL && var_r27 >= 0 && var_r27 < arrow->num) {
mStageCamTool.mArrowIndex = var_r27;
mStageCamTool.mArrowData = arrow->m_entries[var_r27];
}
}
}
}
void dCamera_c::setMapToolData() {
int room_no = dComIfGp_roomControl_getStayNo();
stage_camera_class* camera = dComIfGp_getRoomCamera(room_no);
stage_arrow_class* arrow = dComIfGp_getRoomArrow(room_no);
int var_r29 = 0xFF;
int var_r26 = 0xFF;
if (mBG.field_0xc0.field_0x40 == 0x1FF && mRoomMapTool.mpActor == NULL) {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 190, " k");
}
#endif
return;
}
if (mBG.field_0xc0.field_0x40 != 0xFF) {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 190, " p");
}
#endif
mRoomMapTool.Clr();
var_r29 = mBG.field_0xc0.field_0x40;
} else if (field_0x8d8.mCameraIndex != 0xFF) {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 190, " e");
}
#endif
mRoomMapTool.Clr();
var_r29 = field_0x8d8.mCameraIndex;
} else if (mDefRoomCamTool.mCameraIndex != 0xFF) {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 190, " r");
}
#endif
mRoomMapTool = mDefRoomCamTool;
return;
} else if (mStageCamTool.mCameraIndex != 0xFF) {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 190, " s");
}
#endif
mRoomMapTool = mStageCamTool;
return;
} else {
mRoomMapTool.Clr();
}
setRoomMapToolData(&mRoomMapTool, var_r29, room_no);
}
void dCamera_c::SetTagData(fopAc_ac_c* param_0, s32 param_1, u16 param_2, u8 param_3) {
int room_no = param_0 != NULL ? fopAcM_GetRoomNo(param_0) : dComIfGp_roomControl_getStayNo();
mTagCamTool.Set(param_1, room_no, param_0, param_2, param_3);
}
void dCamera_c::setRoomMapToolData(dCamMapToolData* i_toolData, s32 param_1, s32 i_roomNo) {
i_toolData->Set(param_1, i_roomNo, NULL, 0xFF, 0xFF);
}
s32 dCamera_c::nextMode(s32 i_curMode) {
dAttention_c* attn = dComIfGp_getAttention();
s32 next_mode = i_curMode;
cXyz player_pos = positionOf(mpPlayerActor);
daAlink_c* link = daAlink_getAlinkActorClass();
if (!dComIfGp_evmng_cameraPlay()) {
if (mBG.field_0x0.field_0x58 > player_pos.y) {
field_0x223 = 0;
}
switch (i_curMode) {
case 1:
case 2:
case 4:
case 7:
case 8:
default:
break;
}
if (!link->checkFastShotTime()) {
mFastShotState = 0;
}
if (mForcedMode != 11 && mCamTypeData[mCurType].field_0x18[mIsWolf][mForcedMode] >= 0) {
next_mode = mForcedMode;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 205, " MD---");
}
#endif
#if DEBUG
} else if (check_owner_action(mPadID, 0x200000) && attn->LockonTruth()) {
next_mode = 2;
} else if (check_owner_action(mPadID, 0x200000)) {
#else
} else if (check_owner_action(mPadID, 0x200000) && !attn->Lockon()) {
#endif
if (check_owner_action(mPadID, 0x25040)) {
next_mode = 7;
} else {
next_mode = 0;
}
} else if (link->checkGoatThrow() && dComIfGoat_GetThrow() != NULL) {
dComIfGp_getAttention()->LockSoundOff();
mpLockonTarget = dComIfGoat_GetThrow();
if (fopAcM_GetName(mpLockonTarget) == fpcNm_E_GOB_e) {
if (link->checkGoatThrowAfter()) {
next_mode = 2;
} else {
next_mode = 1;
}
} else if (fopAcM_GetName(mpLockonTarget) == fpcNm_OBJ_GRA_e) {
next_mode = 1;
} else {
next_mode = 2;
}
} else if (link->checkGoronSideMove() || link->getSumouCameraMode()) {
dComIfGp_getAttention()->LockSoundOff();
next_mode = 1;
} else if (link->checkFastShotTime()) {
mFastShotState = 1;
} else if (check_owner_action1(mPadID, 0x10)) {
next_mode = 9;
} else if ((check_owner_action1(mPadID, 0x400000)
|| check_owner_action1(mPadID, 0x200000)) && mpLockonTarget != NULL) {
next_mode = 6;
} else if (link->checkCutHeadProc()) {
next_mode = 6;
} else if (check_owner_action(mPadID, 6) && mpLockonTarget != NULL) {
next_mode = 5;
} else if (attn->LockonTruth() && mpLockonTarget != NULL
&& !check_owner_action(mPadID, 0xC000000)) {
next_mode = 2;
} else if (check_owner_action(mPadID, 0x12000)) {
next_mode = 4;
} else if (check_owner_action(mPadID, 0x25040) && !attn->Lockon()) {
next_mode = 7;
} else if ((check_owner_action(mPadID, 0x80480) && !attn->Lockon())
|| link->checkHawkWait()) {
next_mode = 8;
} else if (check_owner_action(mPadID, 0x4000000) || link->checkChainBlockPushPull()) {
next_mode = 10;
} else if (attn->Lockon()) {
next_mode = 1;
} else if ((check_owner_action(mPadID, 0x400000) || link->checkIronBallThrowMode()
|| link->checkBoomerangAtnKeep())
&& !check_owner_action(mPadID, 0x36A02311) && mFastShotState == 0
&& !check_owner_action1(mPadID, 0x11)) {
mpLockonTarget = get_boomerang_actor(mpPlayerActor);
next_mode = 2;
mLockOnActorID = -1;
mFastShotState = 1;
} else if ((link->checkCopyRodThrowAfter() || link->checkCopyRodAtnKeep())
&& link->getCopyRodCameraActor() == NULL) {
mpLockonTarget = link->getCopyRodActor();
next_mode = 2;
mLockOnActorID = -1;
mFastShotState = 1;
} else if (link->checkSpinnerRideWait()) {
next_mode = 1;
} else if (mLockOnActorID != -1) {
if (mpLockOnActor != NULL) {
next_mode = 2;
mpLockonTarget = mpLockOnActor;
} else {
next_mode = 0;
mLockOnActorID = -1;
}
} else {
next_mode = 0;
}
}
if (mCamTypeData[mCurType].field_0x18[mIsWolf][next_mode] >= 0) {
if (next_mode != 2) {
mLockOnActorID = -1;
}
if (next_mode == 1) {
setFlag(0x100000);
} else if (next_mode == 10) {
setFlag(0x100000);
}
} else {
next_mode = i_curMode;
}
switch (next_mode) {
case 4:
dComIfGp_getAttention()->LockSoundOff();
break;
}
return next_mode;
}
bool dCamera_c::onModeChange(s32 i_curMode, s32 i_nextMode) {
dAttention_c* unusedAttn = dComIfGp_getAttention();
field_0x160 = 0;
field_0x164 = 0;
field_0x168 = 1;
mSightFitRadius = 0.0f;
clrFlag(0x2306);
switch (i_curMode) {
case 3:
clrComStat(4);
break;
case 4:
case 7:
case 8:
if (i_nextMode == 0) {
setFlag(0x40000);
}
break;
}
switch (i_nextMode) {
case 7:
mGear = 0;
break;
case 1:
setFlag(0x100000);
// fallthrough
case 0:
if (mCamTypeData[mCurType].field_0x18[mIsWolf][i_curMode]
== mCamTypeData[mCurType].field_0x18[mIsWolf][i_nextMode])
{
field_0x168 = 0;
}
// fallthrough
case 2:
if (mCamSetup.CheckFlag(0x4000)) {
mGear = 0;
}
break;
case 10:
break;
}
return true;
}
int dCamera_c::ModeFix(s32 param_0) {
mForcedMode = param_0;
return 1;
}
static int l_debugMode;
s32 dCamera_c::nextType(s32 i_curType) {
s32 next_type = i_curType;
int sp30 = 0;
s8 var_r28 = 0x20;
#if DEBUG
if (l_debugMode == true) {
next_type = GetCameraTypeFromCameraName("Cheat");
} else if (mCamSetup.ForceType() != -1) {
next_type = mCamSetup.ForceType();
} else
#endif
{
#if DEBUG
if (mEngineHoldState == 0) {
#else
if (mEngineHoldState != 1) {
#endif
s32 iVar14 = 0xff;
if (mTagCamTool.mCameraIndex != 0xff) {
s32 type = GetCameraTypeFromToolData(&mTagCamTool.mCamData);
if (type != 0xff) {
iVar14 = type;
}
}
daAlink_c* link = daAlink_getAlinkActorClass();
daHorse_c* horse = dComIfGp_getHorseActor();
bool bVar2 = false;
bool bVar1 = false;
if (link->checkMagneBootsOn()) {
cXyz* top_vec = link->getMagneBootsTopVec();
if (cBgW_CheckBRoof(top_vec->y)) {
bVar2 = true;
} else if (cBgW_CheckBWall(top_vec->y)) {
bVar1 = true;
}
}
bool copy_rod = false;
fopAc_ac_c* copyRodCameraActor = link->getCopyRodCameraActor();
if (copyRodCameraActor != NULL) {
copy_rod = true;
}
if (check_owner_action(mPadID, 0x200000) && ChangeModeOK(4)
&& !dComIfGp_getAttention()->Lockon()) {
next_type = specialType[CAM_TYPE_SCOPE];
var_r28 = 0x6f;
} else if (iVar14 != 0xff && !(mTagCamTool.mFlags & 0x10)) {
next_type = iVar14;
mRoomMapTool = mTagCamTool;
var_r28 = 0x74;
} else if (link->checkMidnaLockJumpPoint() &&
(daPy_py_c::getMidnaActor()->checkFlyWaitAnime()
|| daPy_py_c::getMidnaActor()->checkNoInput())) {
next_type = specialType[CAM_TYPE_MIDNA_TAG];
var_r28 = 0x78;
} else if (daPy_py_c::getMidnaActor()->checkPortalObjCall()) {
next_type = specialType[CAM_TYPE_WARP_OBJ];
var_r28 = 0x58;
} else if (link->checkGoatStopGame()) {
next_type = specialType[CAM_TYPE_GOAT_BATTLE];
var_r28 = 0x62;
} else if (chkFlag(0x10000)) {
next_type = specialType[CAM_TYPE_GORON_JUMP];
var_r28 = 0x4a;
} else if (link->checkHorseRide()) {
next_type = specialType[CAM_TYPE_HORSE_T];
var_r28 = 0x48;
} else if (bVar1) {
next_type = specialType[CAM_TYPE_MAGNE_WALL];
var_r28 = 0x75;
} else if (bVar2) {
next_type = specialType[CAM_TYPE_MAGNE_ROOF];
var_r28 = 0x55;
} else if (copy_rod) {
next_type = specialType[CAM_TYPE_COPY_ROD_HALL];
var_r28 = 0x72;
} else if (link->checkBoarRide()) {
next_type = specialType[CAM_TYPE_BOAR];
var_r28 = 0x49;
} else if (link->checkCanoeRide()) {
next_type = specialType[CAM_TYPE_CANOE];
var_r28 = 0x43;
} else if (link->checkBoardRide()) {
next_type = specialType[CAM_TYPE_BOARD];
var_r28 = 0x42;
} else if (link->checkSpinnerRide()) {
next_type = specialType[CAM_TYPE_SPINNER];
var_r28 = 0x40;
} else if (check_owner_action1(mPadID, 0x2000000)) {
next_type = specialType[CAM_TYPE_HOOK_WALL];
var_r28 = 0x3e;
} else if (check_owner_action1(mPadID, 0x10000)) {
if (link->getHookshotRoofWaitActor() != NULL) {
next_type = specialType[CAM_TYPE_HOOK_ACTOR];
var_r28 = 0x5e;
} else {
next_type = specialType[CAM_TYPE_HOOK_ROOF];
var_r28 = 0x5e;
}
} else if (check_owner_action1(mPadID, 0x100000)) {
next_type = specialType[CAM_TYPE_ROOF_HUNG];
var_r28 = 0x7e;
} else if (link->checkCokkoGlide()) {
next_type = specialType[CAM_TYPE_COCCO_JUMP];
var_r28 = 0x66;
} else if (check_owner_action(mPadID, 0x100000)) {
if (getComStat(0x800)) {
next_type = specialType[CAM_TYPE_WATER_SURF];
var_r28 = 0x77;
} else if (mBG.field_0xc0.field_0x3c != 0xff) {
s32 stayNo = dComIfGp_roomControl_getStayNo();
setRoomMapToolData(&mRoomMapTool, mBG.field_0xc0.field_0x3c, stayNo);
s32 type = GetCameraTypeFromToolData(&mRoomMapTool.mCamData);
if (type != 0xff) {
next_type = type;
var_r28 = 0x6d;
} else {
next_type = specialType[CAM_TYPE_WATER];
var_r28 = 0x57;
}
} else {
next_type = specialType[CAM_TYPE_WATER];
var_r28 = 0x57;
}
} else if (iVar14 != 0xff) {
next_type = iVar14;
mRoomMapTool = mTagCamTool;
var_r28 = 0x54;
} else if (mRoomMapTool.mCameraIndex != 0xff) {
s32 type = GetCameraTypeFromToolData(&mRoomMapTool.mCamData);
if (type != 0xff) {
next_type = type;
var_r28 = 0x6d;
}
} else if (mRoomMapTool.mCameraIndex != 0x1ff) {
next_type = mMapToolType;
var_r28 = 0x44;
}
} else {
var_r28 = 0x3d;
}
}
field_0x698 = 0xff;
field_0x69c = 0;
if (mCamTypeData[mCurType].field_0x18[mIsWolf][0] < 0) {
next_type = mMapToolType;
var_r28 = 0x21;
if (mRoomMapTool.mCameraIndex != 0xff) {
s32 type = GetCameraTypeFromToolData(&mRoomMapTool.mCamData);
if (type != 0xff) {
next_type = type;
var_r28 = 0x5f;
}
}
}
if (!ChangeModeOK(2)) {
dComIfGp_getAttention()->LockSoundOff();
}
if (dComIfGp_evmng_cameraPlay() || chkFlag(0x20000000)) {
if (i_curType != specialType[CAM_TYPE_EVENT]) {
mEventData.field_0xc = next_type;
}
next_type = specialType[CAM_TYPE_EVENT];
dComIfGp_getAttention()->LockSoundOff();
} else {
clrFlag(0x40000000);
if (dComIfGp_getEvent()->runCheck()) {
setComStat(4);
dComIfGp_getAttention()->LockSoundOff();
}
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 190, " %c%02x", var_r28, mRoomMapTool.mCameraIndex);
}
#endif
}
return next_type;
}
bool dCamera_c::onTypeChange(s32 i_curType, s32 i_nextType) {
daAlink_c* unusedPlayer = daAlink_getAlinkActorClass();
if (i_curType == specialType[CAM_TYPE_EVENT]) {
if (mCamSetup.CheckFlag(0x4000)) {
mGear = 0;
}
if (mRecovery.field_0x4 != 0) {
cXyz vec = mRecovery.field_0x28 - positionOf(mpPlayerActor);
setEventRecoveryTrans(mRecovery.field_0x4);
popInfo(&mSavedView);
mViewCache.mCenter -= vec;
mViewCache.mEye -= vec;
}
mRecovery.field_0x4 = 0;
#if PLATFORM_GCN
field_0x668 = 0;
#endif
clearInfo(&mSavedView, 0);
clearInfo(&mSavedViewStack[0], 0);
clearInfo(&mSavedViewStack[1], 0);
if (chkFlag(0x400000)) {
mCamStyle = mCamTypeData[mEventData.field_0xc].field_0x18[mIsWolf][0];
mCamParam.Change(mCamStyle);
setFlag(0x200);
clrFlag(0x400000);
}
mEventData.field_0x14 = -1;
mEventData.field_0x18 = -1;
mEventData.mStaffIdx = -1;
mEventData.field_0xc = -1;
mEventData.field_0x0 = 1;
setFlag(0x20);
if (chkFlag(0x40000000)) {
cM3dGLin line(mViewCache.mCenter, mViewCache.mEye);
cXyz attn_pos = attentionPos(mpPlayerActor);
cXyz proj;
f32 dist;
if (cM3d_Len3dSqPntAndSegLine(&line, &attn_pos, &proj, &dist)) {
mViewCache.mCenter = proj;
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
}
clrFlag(0x40000000);
}
} else if (i_nextType == specialType[CAM_TYPE_EVENT]) {
clrFlag(0x200000);
pushInfo(&mSavedView, 1);
mSightFitRadius = 0.0f;
#if PLATFORM_GCN
field_0x668 = 0;
#endif
}
field_0x170 = 0;
field_0x16c = 0;
return true;
}
bool dCamera_c::onStyleChange(s32 param_0, s32 param_1) {
mCurCamStyleTimer = 0;
mStyleSettle.mFinished = false;
bool var_r30 = false;
switch (mCamParam.Algorythmn(param_0)) {
case 5:
case 6:
if (mFakeAngleSys.field_0x0 == 0) {
setUSOAngle();
}
var_r30 = true;
break;
case 4:
clrComStat(8);
setComZoomScale(1.0f);
break;
}
switch (mCamParam.Algorythmn(param_1)) {
case 0:
case 3:
default:
break;
case 8:
if (mCamParam.Algorythmn(param_0) == mCamParam.Algorythmn(param_1) && mCurMode == 0) {
setFlag(0x8000);
}
break;
case 1:
if (mCamParam.Algorythmn(param_0) == mCamParam.Algorythmn(param_1)) {
// empty block
}
break;
case 5:
case 6:
if (mFakeAngleSys.field_0x0 == 0 || var_r30) {
setUSOAngle();
}
break;
}
return true;
}
int dCamera_c::onRoomChange(s32 i_roomNo) {
mRoomCtx.mRoomNo = i_roomNo;
setFlag(0x1000);
int var_r29 = 0xFF;
dStage_roomDt_c* room_dt = dComIfGp_roomControl_getStatusRoomDt(i_roomNo);
if (room_dt != NULL) {
dStage_FileList_dt_c* filelist = room_dt->getFileListInfo();
if (filelist != NULL) {
var_r29 = dStage_FileList_dt_GetDefaultCamera(filelist);
}
}
if (var_r29 != 0xFF) {
setRoomMapToolData(&mDefRoomCamTool, var_r29, i_roomNo);
} else {
mDefRoomCamTool.Clr();
}
return 1;
}
fopAc_ac_c* dCamera_c::getParamTargetActor(s32 param_0) {
daAlink_c* player = daAlink_getAlinkActorClass();
fopAc_ac_c* result;
u32* name = (u32*)(mCamTypeData[param_0].name + 16);
//name += 16;
switch (*name) {
case '@LOC':
result = dComIfGp_getAttention()->LockonTarget(0);
break;
case '@ACT':
result = dComIfGp_getAttention()->ActionTarget(0);
break;
case '@CHK':
result = dComIfGp_getAttention()->CheckObjectTarget(0);
break;
case '@CPY':
result = player->getCopyRodCameraActor();
break;
default:
result = fopAcM_searchFromName4Event(mCamTypeData[param_0].name + 16, -1);
break;
}
return result;
}
int dCamera_c::GetCameraTypeFromMapToolID(s32 param_0, s32 i_roomNo) {
dStage_dt_c& stage_dt = g_dComIfG_gameInfo.play.getStage();
int i;
stage_camera_class* camera;
stage_arrow_class* arrow;
if (i_roomNo == -1) {
camera = stage_dt.getCamera();
arrow = stage_dt.getArrow();
} else {
camera = dComIfGp_getRoomCamera(i_roomNo);
arrow = dComIfGp_getRoomArrow(i_roomNo);
if (camera == NULL) {
if (!(mFrameCounter & 0xFFF)) {
OS_REPORT("camera: no room camera list. camera ID ignored\n");
}
return 0xFF;
}
}
if (param_0 < 0 || camera == NULL || (camera != NULL && param_0 >= camera->num)) {
OS_REPORT("camera: bad number %d for map data ID [%x:%d] room %d\n", param_0, camera,
camera != NULL ? camera->num : -99, i_roomNo);
return 0xFF;
}
i = 0;
while (i < mCamTypeNum) {
if (strcmp(camera->m_entries[param_0].m_cam_type, mCamTypeData[i].name) ==
0)
{
break;
}
i++;
}
if (i == mCamTypeNum) {
OS_REPORT("camera: type \'%s\' not found\n", camera->m_entries[param_0].m_cam_type);
return 0xFF;
}
mRoomMapTool.mCamData = camera->m_entries[param_0];
mRoomMapTool.mCameraIndex = param_0;
mRoomMapTool.mFlags = (mRoomMapTool.mCamData.field_0x14 >> 0xE) & 3;
if (mRoomMapTool.mCamData.field_0x14 & 0x2000) {
mRoomMapTool.mCamData.field_0x14 |= (u16)0xC000;
} else {
mRoomMapTool.mCamData.field_0x14 &= (u16)~0xC000;
}
mRoomMapTool.mArrowIndex = mRoomMapTool.mCamData.m_arrow_idx;
if (mRoomMapTool.mArrowIndex != -1 && mRoomMapTool.mArrowIndex < arrow->num) {
mRoomMapTool.mArrowData = arrow->m_entries[mRoomMapTool.mArrowIndex];
} else {
mRoomMapTool.mArrowIndex = 0xFF;
}
return i;
}
int dCamera_c::GetCameraTypeFromCameraName(char const* i_name) {
if (strcmp(i_name, mCamTypeData[mCurType].name) == 0) {
return mCurType;
}
int i = 0;
while (i < mCamTypeNum) {
if (strcmp(i_name, mCamTypeData[i].name) == 0) {
break;
}
i++;
}
if (i == mCamTypeNum) {
OS_REPORT("camera: type \'%s\' not found\n", i_name);
return 0xFF;
}
return i;
}
int dCamera_c::GetCameraTypeFromToolData(stage_camera2_data_class* i_data) {
if (i_data->field_0x16 != 0xFFFF) {
return i_data->field_0x16;
} else {
int type = GetCameraTypeFromCameraName(i_data->m_cam_type);
if (type < 0xFFFF) {
i_data->field_0x16 = type;
}
return type;
}
}
void dCamera_c::pushInfo(dCamera_c::dCamInfo_c* i_info, s16 param_1) {
i_info->mCenter = mCenter;
i_info->mEye = mEye;
i_info->mFovy = mFovy;
i_info->mBank = mBank;
i_info->field_0x1e = param_1;
}
void dCamera_c::popInfo(dCamera_c::dCamInfo_c* i_info) {
mCenter = mViewCache.mCenter = i_info->mCenter;
mEye = mViewCache.mEye = i_info->mEye;
mFovy = mViewCache.mFovy = i_info->mFovy;
mBank = mViewCache.mBank = i_info->mBank;
}
bool limited_range_addition(f32* o_result, f32 i_addend, f32 i_min, f32 i_max) {
f32 min = i_min;
f32 max = i_max;
if (i_min > i_max) {
i_addend = -i_addend;
min = i_max;
max = i_min;
}
*o_result += i_addend;
if (*o_result < min) {
*o_result = min;
return false;
}
if (*o_result > max) {
*o_result = max;
return false;
}
return true;
}
f32 dCamera_c::heightOf(fopAc_ac_c* i_actor) {
if (is_player(i_actor)) {
daPy_py_c* player = (daPy_py_c*)i_actor;
return player->getHeight();
} else {
return (i_actor->eyePos.y - i_actor->current.pos.y) * 1.1f;
}
}
cXyz dCamera_c::relationalPos(fopAc_ac_c* i_actor, cXyz* i_offset) {
if (i_actor == NULL) {
OS_REPORT("camera: error: actor NULL in relationalPos() \n");
return cXyz::Zero;
}
cXyz offset;
offset = dCamMath::xyzRotateY(*i_offset, cSAngle(i_actor->shape_angle.y));
return attentionPos(i_actor) + offset;
}
cXyz dCamera_c::relationalPos(fopAc_ac_c* i_actor1, fopAc_ac_c* i_actor2, cXyz* i_offset,
f32 param_3) {
if (i_actor1 == NULL) {
OS_REPORT("camera: error: actor NULL in relationalPos() \n");
return cXyz::Zero;
} else if (i_actor2 == NULL) {
return relationalPos(i_actor1, i_offset);
} else {
cXyz pos1 = attentionPos(i_actor1);
cXyz pos2 = attentionPos(i_actor2);
cXyz delta = pos2 - pos1;
cSGlobe delta_globe(delta);
delta.normalize();
pos1 -= delta * i_actor1->attention_info.field_0xa;
pos2 += delta * i_actor2->attention_info.field_0xa;
cXyz mid = pos1 + (pos2 - pos1) * 0.5f;
cXyz offset = *i_offset;
cSAngle angle = mViewCache.mDirection.U() - delta_globe.U();
if (angle < cSAngle::_0) {
offset.x = -offset.x;
}
cSGlobe offset_globe(offset);
offset_globe.U(delta_globe.U() + offset_globe.U());
delta_globe.R(0.5f * delta_globe.R() * angle.Cos() * param_3);
cXyz ret = mid + delta_globe.Xyz() + offset_globe.Xyz();
return ret;
}
}
void dCamera_c::setUSOAngle() {
mFakeAngleSys.field_0x0 = 1;
mFakeAngleSys.field_0x2 = mDirection.U().Inv();
mFakeAngleSys.field_0x4 = mPadInfo.mMainStick.mAngle;
}
cSAngle dCamera_c::getUSOAngle(cSAngle param_0) {
UNUSED(param_0);
return mFakeAngleSys.field_0x2;
}
bool dCamera_c::pointInSight(cXyz* i_point) {
cXyz proj;
scissor_class* scissor = get_window(field_0x0)->getScissor();
f32 scissor_width = scissor->width;
f32 scissor_height = scissor->height;
mDoLib_project(i_point, &proj);
#if DEBUG
if (mCamSetup.CheckFlag(0x80)) {
dDbVw_Report(100, 250, "VP %11.3f %11.3f %11.3f", proj.x, proj.y, proj.z);
OS_REPORT("VP %11.3f %11.3f %11.3f\n", proj.x, proj.y, proj.z);
OS_REPORT("VS %11.3f %11.3f\n", scissor_width, scissor_height);
}
#endif
return (proj.x > 0.0f && proj.x < scissor_width) && (proj.y > 0.0f && proj.y < scissor_height);
}
f32 dCamera_c::radiusActorInSight(fopAc_ac_c* i_actor1, fopAc_ac_c* i_actor2, cXyz* i_center,
cXyz* i_eye, f32 i_fovY, s16 i_bank, f32 param_6) {
dDlst_window_c* window = get_window(field_0x0);
scissor_class* scissor = window->getScissor();
f32 var_f29 = cAngle::d2r(i_fovY) * 0.5f;
#if TARGET_PC
view_port_class* viewport = window->getViewPort();
f32 var_f28 = (scissor->height - mTrimHeight * 2.0f) / viewport->height;
f32 sp34 = var_f29 * var_f28 * (mTrimHeight < 0.01f ? 0.95f : 1.0f);
var_f29 *= mWindowAspect;
var_f28 = scissor->width / viewport->width;
#else
f32 var_f28 = (scissor->height - mTrimHeight * 2.0f) / FB_HEIGHT;
f32 sp34 = var_f29 * var_f28 * (mTrimHeight < 0.01f ? 0.95f : 1.0f);
var_f29 *= mWindowAspect;
var_f28 = scissor->width / FB_WIDTH;
#endif
f32 sp30 = var_f29 * var_f28 * 0.85f;
cXyz pos1 = attentionPos(i_actor1);
pos1.y += (positionOf(i_actor1).y - attentionPos(i_actor1).y) * 0.5f;
cXyz pos2 = attentionPos(i_actor2);
pos2.y += (positionOf(i_actor2).y - attentionPos(i_actor2).y) * 0.5f;
cXyz delta = pos1 - pos2;
f32 dist = delta.abs();
f32 local_128 = 1.0f - (dist - 0.1f - 200.0f);
if (local_128 < 0.2f) {
local_128 = 0.2f;
}
if (local_128 > 1.0f) {
local_128 = 1.0f;
}
dist *= param_6 * local_128;
delta.normalize();
pos1 += delta * (i_actor1->attention_info.field_0xa + dist);
pos2 -= delta * (i_actor2->attention_info.field_0xa + dist);
Mtx look_mtx;
mDoMtx_lookAt(look_mtx, i_eye, i_center, &mUp, i_bank);
MTXMultVec(look_mtx, &pos1, &pos1);
MTXMultVec(look_mtx, &pos2, &pos2);
int bVar2 = 0;
var_f29 = fabsf(cM_atan2f(pos1.x, -pos1.z));
var_f28 = fabsf(cM_atan2f(pos1.y, -pos1.z));
if (var_f29 > sp30) {
bVar2 |= 1;
}
if (var_f28 > sp34) {
bVar2 |= 2;
}
var_f29 = fabsf(cM_atan2f(pos2.x, -pos2.z));
var_f28 = fabsf(cM_atan2f(pos2.y, -pos2.z));
if (var_f29 > sp30) {
bVar2 |= 4;
}
if (var_f28 > sp34) {
bVar2 |= 8;
}
if (bVar2 == 0) {
return 0.0f;
}
f32 ret = 0.0f;
f32 local_12c = 1.0f;
f32 local_130 = 1.0f;
if (bVar2 & 5) {
local_12c = tanf(sp30);
}
if (bVar2 & 0xA) {
local_130 = tanf(sp34);
}
f32 var_f31;
if (bVar2 & 1) {
var_f31 = pos1.z + fabsf(pos1.x) / local_12c;
if (var_f31 > ret) {
ret = var_f31;
}
}
if (bVar2 & 2) {
var_f31 = pos1.z + fabsf(pos1.y) / local_130;
if (var_f31 > ret) {
ret = var_f31;
}
}
if (bVar2 & 4) {
var_f31 = pos2.z + fabsf(pos2.x) / local_12c;
if (var_f31 > ret) {
ret = var_f31;
}
}
if (bVar2 & 8) {
var_f31 = pos2.z + fabsf(pos2.y) / local_130;
if (var_f31 > ret) {
ret = var_f31;
}
}
return ret;
}
f32 dCamera_c::groundHeight(cXyz* param_0) {
dBgS_GndChk gndchk;
gndchk.SetPos(param_0);
f32 gnd_y = dComIfG_Bgsp().GroundCross(&gndchk);
dBgS_CamGndChk_Wtr gndchk_wtr;
gndchk_wtr.SetPos(param_0);
f32 wtr_y = dComIfG_Bgsp().GroundCross(&gndchk_wtr);
//TODO: unsure if this is an actual version difference or a fakematch, the ternary matches
// for everything except GCN but the if-else matches for GCN and Wii but not ShieldD
#if PLATFORM_GCN
f32 height;
if (gnd_y >= wtr_y) {
height = gnd_y;
} else {
height = wtr_y;
}
#else
f32 height = gnd_y >= wtr_y ? gnd_y : wtr_y;
#endif
return height == -G_CM3D_F_INF ? param_0->y : height;
}
bool dCamera_c::lineBGCheck(cXyz* i_start, cXyz* i_end, dBgS_LinChk* i_linChk, u32 i_flags) {
if (i_flags & 0x8000) {
i_linChk->ClrCam();
i_linChk->SetObj();
} else {
i_linChk->ClrObj();
i_linChk->SetCam();
}
i_linChk->Set(i_start, i_end, NULL);
if (i_flags & 4) {
i_linChk->ClrSttsRoofOff();
} else {
i_linChk->SetSttsRoofOff();
}
if (i_flags & 2) {
i_linChk->ClrSttsWallOff();
} else {
i_linChk->SetSttsWallOff();
}
if (i_flags & 1) {
i_linChk->ClrSttsGroundOff();
} else {
i_linChk->SetSttsGroundOff();
}
if (i_flags & 8) {
i_linChk->OnWaterGrp();
} else {
i_linChk->OffWaterGrp();
}
if (dComIfG_Bgsp().LineCross(i_linChk)) {
return true;
} else {
return false;
}
}
bool dCamera_c::lineBGCheck(cXyz* i_start, cXyz* i_end, cXyz* o_cross, u32 i_flags) {
dBgS_CamLinChk lin_chk;
if (lineBGCheck(i_start, i_end, &lin_chk, i_flags)) {
cM3dGPla plane;
dComIfG_Bgsp().GetTriPla(lin_chk, &plane);
*o_cross = lin_chk.GetCross() + *plane.GetNP();
return true;
} else {
*o_cross = *i_end;
}
return false;
}
bool dCamera_c::lineBGCheck(cXyz* i_start, cXyz* i_end, u32 i_flags) {
dBgS_CamLinChk lin_chk;
return lineBGCheck(i_start, i_end, &lin_chk, i_flags);
}
u32 dCamera_c::lineCollisionCheckBush(cXyz* i_start, cXyz* i_end) {
u32 ret = 0;
u32 result = dComIfG_Ccsp()->GetMassResultCam();
if (result & 2) {
ret |= 2;
}
if (result & 4) {
ret |= 8;
}
if (result & 8) {
ret |= 4;
}
cM3dGCps cps;
cps.Set(*i_start, *i_end, 30.0f);
dComIfG_Ccsp()->SetMassCam(cps);
return ret;
}
static void sph_chk_callback(dBgS_SphChk* i_sphChk, cBgD_Vtx_t* i_vtxTbl, int i_vtxIdx0,
int i_vtxIdx1, int i_vtxIdx2, cM3dGPla* i_plane, void* i_data) {
camSphChkdata* sph_chk_data = (camSphChkdata*)i_data;
if (!sph_chk_data->field_0x1c) {
f32 len = cM3d_SignedLenPlaAndPos(i_plane, &sph_chk_data->field_0xc);
if (i_plane->getPlaneFunc(sph_chk_data->field_0x8) >= -0.0001f
&& len < sph_chk_data->field_0x4) {
cXyz normal = *i_plane->GetNP();
sph_chk_data->field_0xc += normal * (sph_chk_data->field_0x4 + 0.1f - len);
sph_chk_data->field_0x1c = true;
}
}
}
cXyz dCamera_c::compWallMargin(cXyz* i_center, cXyz* param_1, f32 i_radius) {
dBgS_CamSphChk sph_chk;
camSphChkdata sph_chk_data(i_center, param_1, i_radius);
sph_chk.SetCallback(&sph_chk_callback);
sph_chk.Set(*i_center, i_radius);
sph_chk_data.field_0x18 = i_radius;
for (int i = 0; i < 5; i++) {
cXyz vec = sph_chk_data.field_0xc;
sph_chk_data.Base(&vec);
sph_chk.Set(vec, i_radius);
sph_chk_data.field_0x1c = false;
if (!dComIfG_Bgsp().SphChk(&sph_chk, &sph_chk_data)) break;
}
return sph_chk_data.field_0xc;
}
int dCamera_c::defaultTriming() {
if (mTrimTypeForce >= 0) {
SetTrimSize(mTrimTypeForce);
mTrimTypeForce = -1;
} else {
switch (mCurMode) {
case 3:
SetTrimSize(2);
break;
case 1:
case 2:
case 5:
case 6:
SetTrimSize(1);
break;
case 4:
SetTrimSize(0);
break;
case 7:
case 8:
SetTrimSize(1);
break;
default:
SetTrimSize(0);
break;
}
}
return mTrimSize;
}
void dCamera_c::setView(f32 i_xOrig, f32 i_yOrig, f32 i_width, f32 i_height) {
dDlst_window_c* window = get_window(field_0x0);
view_port_class* view_port = window->getViewPort();
window->setViewPort(i_xOrig, i_yOrig, i_width, i_height, view_port->near_z, view_port->far_z);
window->setScissor(i_xOrig, i_yOrig, i_width, i_height);
}
#if TARGET_PC
void dCamera_c::ResetView() {
setView(0.0f, 0.0f, mDoGph_gInf_c::getWidth(), mDoGph_gInf_c::getHeight());
}
#endif
cSAngle dCamera_c::forwardCheckAngle() {
dBgS_CamLinChk lin_chk;
cSAngle ret = cSAngle::_0;
cSAngle local_1b8;
cSAngle local_1bc;
cXyz player_pos = positionOf(mpPlayerActor);
f32 player_height = heightOf(mpPlayerActor);
player_pos.y += player_height;
cXyz cross;
cSAngle local_1c0(mCamSetup.mBGChk.FwdChkAngle(0));
cSGlobe local_198(player_height * mCamSetup.mBGChk.FwdDistance(0),
local_1c0.Val(), mDirection.U().Inv());
cXyz local_f4 = player_pos + local_198.Xyz();
if (lineBGCheck(&player_pos, &local_f4, &cross, 0x40b7)) {
cXyz local_100 = local_f4 - player_pos;
if (local_100.abs() < 1.0f) {
local_f4 = cross;
} else {
local_f4 = cross - local_100.norm() * mCamSetup.mBGChk.FwdBackMargin();
}
}
cross = local_f4;
cross.y = player_height + groundHeight(&local_f4);
cSGlobe local_1a0(cross - player_pos);
if (local_1a0.V() >= cSAngle::_0) {
local_1b8 = local_1a0.V() * mCamSetup.mBGChk.FwdWeightH(0);
} else {
local_1b8 = local_1a0.V() * mCamSetup.mBGChk.FwdWeightL(0);
}
cSAngle local_1c4(mCamSetup.mBGChk.FwdChkAngle(1));
cSGlobe local_1a8(player_height * mCamSetup.mBGChk.FwdDistance(1),
local_1c4.Val(), mDirection.U().Inv());
cXyz local_10c = player_pos + local_1a8.Xyz();
if (lineBGCheck(&player_pos, &local_10c, &cross, 0x40b7)) {
cXyz local_100 = local_10c - player_pos;
if (local_100.abs() < 1.0f) {
local_10c = cross;
} else {
local_10c = cross - local_100.norm() * mCamSetup.mBGChk.FwdBackMargin();
}
}
cross = local_10c;
cross.y = player_height + groundHeight(&local_10c);
cSGlobe local_1b0(cross - player_pos);
if (local_1b0.V() >= cSAngle::_0) {
local_1bc = local_1b0.V() * mCamSetup.mBGChk.FwdWeightH(1);
} else {
local_1bc = local_1b0.V() * mCamSetup.mBGChk.FwdWeightL(1);
}
if (local_1b8 >= cSAngle::_0 && local_1bc >= cSAngle::_0) {
ret = local_1b8 >= local_1bc ? -local_1b8 : -local_1bc;
} else if (local_1b8 <= cSAngle::_0 && local_1bc <= cSAngle::_0) {
ret = local_1b8 <= local_1bc ? -local_1b8 : -local_1bc;
} else {
ret = -local_1b8;
}
if (ret <= cSAngle::_0) {
ret *= 0.75f;
}
return ret;
}
bool dCamera_c::bumpCheck(u32 i_flags) {
int var_r27 = 0;
#if PLATFORM_GCN
static int prev_plat1 = 0;
static int prev_plat2 = 0;
#endif
int var_r28 = 0;
f32 gaze_back_margin = mCamSetup.mBGChk.GazeBackMargin() + 0.5f;
f32 wall_cushion = mCamSetup.mBGChk.WallCushion();
f32 wall_back_cushion = mCamSetup.mBGChk.WallBackCushion();
f32 corner_cushion = mCamSetup.mBGChk.CornerCushion();
f32 corner_angle_max_cos = cDegree(mCamSetup.mBGChk.CornerAngleMax()).Cos();
f32 wall_up_distance = mCamSetup.mBGChk.WallUpDistance();
cXyz center = mViewCache.mCenter;
cXyz eye = mViewCache.mEye;
cSGlobe direction = mViewCache.mDirection;
if (mCamSetup.CheckFlag2(0x100) && dKy_TeachWind_existence_chk()) {
f32 wind_pow = dKyw_get_wind_pow();
if (wind_pow > 0.3f) {
cXyz* spD4 = dKyw_get_wind_vec();
cSGlobe wind_globe(*spD4);
wind_globe.R(mViewCache.mDirection.R() * cM_rndFX(mCamSetup.WindShakeGap4Ctr() * 0.0001f));
center += wind_globe.Xyz();
if (wind_pow > 1.0f) {
wind_pow = 1.0f;
}
wind_pow -= 0.3f;
cSAngle angle = wind_globe.U() - mViewCache.mDirection.U();
mFovy += mCamSetup.WindShakeGap4Fvy() * cM_rndFX(wind_pow / 0.7f) * (1.0f - fabsf(angle.Norm()));
#if DEBUG
dDbVw_Report(300, 180, "wind %f %f", wind_pow, angle.Norm());
#endif
}
}
if (is_player(mpPlayerActor)) {
fopAc_ac_c* spD0 = mpPlayerActor;
u32 grab_actor_id = static_cast<daPy_py_c*>(spD0)->getGrabActorID();
if (grab_actor_id != -1) {
fopAc_ac_c* grab_actor = fopAcM_SearchByID(grab_actor_id);
if (grab_actor != NULL && !fopAcM_CheckCarryType(grab_actor,
(fopAcM_CARRY)(fopAcM_CARRY_ITEM | fopAcM_CARRY_TYPE_8))) {
if (fopAcM_CheckCarryType(grab_actor, fopAcM_CARRY_SIDE)) {
wall_up_distance += 40.0f;
} else {
wall_up_distance += 100.0f;
}
}
}
}
f32 spC4 = mViewCache.mDirection.R() * mViewCache.mDirection.V().Sin();
if (i_flags & 0x10) {
if (spC4 > wall_up_distance) {
wall_up_distance = spC4;
}
} else {
clrFlag(0x4000);
}
bool sp0E = false;
if (chkFlag(0x2002)) {
if (mpAuxTargetActor1 != NULL && mpAuxTargetActor2 != NULL) {
f32 sight_radius = radiusActorInSight(mpPlayerActor, mpAuxTargetActor1, mpAuxTargetActor2);
if (sight_radius > 0.0f) {
f32 spBC = chkFlag(2) ? 0.33f : 0.08f;
mSightFitRadius += spBC * (sight_radius - mSightFitRadius);
var_r28 |= 0x40;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " *");
}
#endif
f32 spB8 = 1.0f;
if (field_0x160 < 10) {
spB8 = (f32)field_0x160 / 10.0f;
}
direction.R(mSightFitRadius * spB8 + direction.R());
eye = center + direction.Xyz();
}
} else if (mpAuxTargetActor1 != NULL) {
f32 sight_radius = radiusActorInSight(mpPlayerActor, mpAuxTargetActor1);
if (sight_radius > 0.0f) {
f32 spB0 = chkFlag(2) ? 0.33f : 0.08f;
mSightFitRadius += spB0 * (sight_radius - mSightFitRadius);
var_r28 |= 0x40;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " +");
}
#endif
f32 spAC = 1.0f;
if (field_0x160 < 10) {
spAC = (f32)field_0x160 / 10.0f;
}
direction.R(mSightFitRadius * spAC + direction.R());
eye = center + direction.Xyz();
}
}
}
if (mSightFitRadius > 0.1f && !(var_r28 & 0x40)) {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " >");
}
#endif
mSightFitRadius -= mSightFitRadius * 0.08f;
direction.R(mSightFitRadius + direction.R());
eye = center + direction.Xyz();
}
if ((i_flags & 0x80) && mBG.field_0x108.field_0x0 != 0) {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " B");
}
#endif
direction.V(mBG.field_0x108.field_0x4 + direction.V().Degree());
eye = center + direction.Xyz();
var_r28 |= 0x20;
}
dBgS_CamLinChk lin_chk1;
dBgS_CamLinChk lin_chk2;
cXyz norm_dir_vec = cXyz(eye - center).norm();
cXyz vec = eye + norm_dir_vec * gaze_back_margin;
bool var_r26 = false;
if (i_flags & 0xb7) {
if (lineBGCheck(&center, &vec, &lin_chk1, i_flags)) {
#if DEBUG
dDbgCamera.SetlChk(lin_chk1);
#endif
cXyz pos, mid;
cXyz sp3E0;
cSAngle sp44;
cSGlobe sp110, sp108;
cM3dGPla plane1;
dComIfG_Bgsp().GetTriPla(lin_chk1, &plane1);
cM3dGPla plane2;
bool sp0D = false;
cXyz* normal1 = plane1.GetNP();
if ((i_flags & 1) && normal1->y >= 0.75f) {
var_r27 = 4;
} else if ((i_flags & 4) && normal1->y < -0.5f) {
var_r27 = 3;
} else if (i_flags & 2) {
if (!(i_flags & 0x10)) {
var_r27 = 1;
} else if (!(i_flags & 0x20)) {
var_r27 = 2;
} else {
if (lineBGCheck(&vec, &center, &lin_chk2, i_flags)) {
#if DEBUG
dDbgCamera.SetlChk(lin_chk2);
#endif
f32 spA4 = cXyz(lin_chk1.GetCross() - lin_chk2.GetCross()).abs();
sp0D = dComIfG_Bgsp().GetTriPla(lin_chk2, &plane2);
cXyz* normal2 = plane2.GetNP();
cXyz cross;
f32 dot = VECDotProduct(normal1, normal2);
VECCrossProduct(normal1, normal2, &cross);
if (chkCornerCos(dot) && fabsf(cross.y) > 0.5f
&& cBgW_CheckBWall(normal2->y)) {
var_r27 = 5;
} else {
if (mLastBumpCase != 5 && mLastBumpCase != 6) {
var_r27 = 7;
} else {
var_r27 = 8;
}
}
} else {
if (mLastBumpCase == 5 || mLastBumpCase == 8) {
var_r27 = 8;
} else {
var_r27 = 2;
}
}
}
}
switch (var_r27) {
case 5:
case 6: {
var_r28 |= 2;
cXyz cross1 = lin_chk1.GetCross();
cXyz cross2 = lin_chk2.GetCross();
mid = (cross1 + cross2) * 0.5f;
if (cM3d_2PlaneLinePosNearPos(plane1, plane2, &mid, &pos)) {
mCornerNormalSum = *plane1.GetNP() + *plane2.GetNP();
mLastHitPos = pos;
cXyz vec3 = pos + mCornerNormalSum * 2.0f;
cross1 += *plane1.GetNP();
cross2 += *plane2.GetNP();
dBgS_CamLinChk lin_chk3;
if (!lineBGCheckBoth(&cross1, &vec3, &lin_chk3, i_flags)
&& !lineBGCheckBoth(&cross2, &vec3, &lin_chk3, i_flags))
{
vec = eye;
if (chkFlag(0x4000)) {
if (mWallRecoverStepCount == 0) {
f32 dist = cXyz(mEye - mViewCache.mEye).abs();
if (dist > 60.0f) {
mWallRecoverStepCount = 40;
} else if (dist < 6.0f) {
mWallRecoverStepCount = 4;
} else {
mWallRecoverStepCount = dist / 1.5f;
}
}
f32 sp94 = 1.0f / mWallRecoverStepCount;
direction.V(mDirection.V() + (direction.V() - mDirection.V()) * sp94);
vec = center + direction.Xyz();
if (--mWallRecoverStepCount == 0) {
clrFlag(0x4000);
}
}
if (lineBGCheck(&cross2, &eye, &lin_chk1, i_flags)) {
vec = lin_chk1.GetCross();
}
eye = compWallMargin(&vec, &center, gaze_back_margin);
var_r26 = true;
setFlag(0x80000);
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " C");
}
#endif
break;
}
}
// fallthrough
}
case 2:
case 7:
case 8: {
var_r28 |= 1;
vec = mLastHitPos = lin_chk1.GetCross();
if (i_flags & 0x10) {
bool sp0C;
switch (mLastBumpCase) {
case 2:
case 7:
case 8:
sp0C = false;
break;
default:
sp0C = true;
break;
}
f32 sp90 = vec.y - center.y;
f32 sp8C = wall_up_distance - sp90;
if (sp8C < 10.0f) {
sp8C = 10.0f;
}
cSGlobe globe(*plane1.GetNP());
globe.V(globe.V() + cSAngle::_90);
globe.R(sp8C * globe.V().Sin());
cXyz vec2 = vec + globe.Xyz();
cXyz vec3 = *plane1.GetNP();
vec3.y = 0.0f;
if (dComIfGp_evmng_cameraPlay() || CheckFlag(0x20000000)) {
field_0x968 = 1.0f;
field_0x96c = 0.0f;
}
if (sp0C) {
field_0x96c = 0.0f;
} else {
field_0x96c += (1.0f - field_0x96c) * 0.1f;
}
if (sp0C || !(mMonitor.field_0xc < 5.0f)
|| !(fabsf(mPadInfo.mCStick.mLastPosX) < 0.05f)) {
field_0x968 = 0.2f;
} else {
field_0x968 *= mMonitor.field_0xc / 5.0f;
}
f32 tmp = field_0x96c * (mIsWolf == 1 ? 30.0f : 30.0f);
center += vec3.norm() * (tmp * globe.V().Sin());
cSGlobe globe2(vec2 - center);
globe2.V(mDirection.V() + (globe2.V() - mDirection.V()) * field_0x968);
if (globe2.V() > cSAngle(80.0f)) {
globe2.V(cSAngle(80.0f));
}
globe2.R(gaze_back_margin + globe2.R());
vec = center + globe2.Xyz();
if (lineBGCheck(&center, &vec, &lin_chk1, i_flags)) {
vec = lin_chk1.GetCross();
}
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " U");
}
#endif
eye = compWallMargin(&vec, &center, gaze_back_margin);
tooNearEscape(&eye);
var_r26 = true;
setFlag(0x80);
setFlag(0x4000);
break;
}
// fallthrough
}
case 1:
case 3:
case 4: {
var_r28 |= 4;
setFlag(0x80);
vec = mLastHitPos = lin_chk1.GetCross();
eye = compWallMargin(&vec, &center, gaze_back_margin);
tooNearEscape(&eye);
var_r26 = true;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " L");
}
#endif
break;
}
default: {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " -");
}
#endif
}
}
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 190, " !");
}
#endif
} else {
var_r27 = 0;
if (chkFlag(0x4000)) {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " W+");
}
#endif
if (mWallRecoverStepCount == 0) {
f32 dist = cXyz(mEye - mViewCache.mEye).abs();
if (dist > 60.0f) {
mWallRecoverStepCount = 40;
} else if (dist < 6.0f) {
mWallRecoverStepCount = 4;
} else {
mWallRecoverStepCount = (int)(dist / 1.5f);
}
}
f32 rate = 1.0f / (f32)mWallRecoverStepCount;
direction.R(mDirection.R() + rate * (direction.R() - mDirection.R()));
direction.V(mDirection.V() + (direction.V() - mDirection.V()) * rate);
vec = center + direction.Xyz();
if (lineBGCheck(&center, &vec, &lin_chk1, i_flags)) {
vec = lin_chk1.GetCross();
}
if (--mWallRecoverStepCount == 0) {
clrFlag(0x4000);
}
} else {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " o");
}
#endif
vec = eye;
}
eye = compWallMargin(&vec, &center, gaze_back_margin);
var_r26 = true;
}
}
mLastBumpCase = var_r27;
int i;
if ((i_flags & 0x4000) && mCamSetup.CheckFlag2(0x400)) {
i = 0;
cCcD_ShapeAttr::Shape shape;
for (i = 0; i < 3; i++) {
if (!dComIfG_Ccsp()->chkCameraPoint(eye, &shape, mpPlayerActor, NULL)) {
break;
}
bool bVar9 = false;
cXyz vec;
f32 sp78, sp74;
switch (shape._0) {
case 0:
vec = shape._4;
vec.y -= shape._10;
sp78 = shape._10;
sp74 = shape._10 * 2.0f;
bVar9 = true;
break;
case 1:
vec = shape._4;
sp78 = shape._10;
sp74 = shape._14;
bVar9 = true;
break;
}
if (bVar9 && center.y >= vec.y && center.y <= vec.y + sp74) {
cXyz vec2;
vec2.x = vec.x - center.x;
vec2.y = 0.0f;
vec2.z = vec.z - center.z;
if (vec2.abs() <= sp78) {
bVar9 = false;
}
}
if (bVar9) {
cXyz vec2, vec3, vec4;
cM3dGCyl cyl(&vec, sp78, sp74);
cM3dGLin lin(center, eye);
int cylLine = cM3d_Cross_CylLin(&cyl, &lin, &vec2, &vec3);
if (cylLine) {
vec4.x = vec2.x - vec.x;
vec4.y = 0.0f;
vec4.z = vec2.z - vec.z;
vec4.normalize();
eye = vec2 + vec4 * 2.0f;
var_r26 = true;
}
}
}
#if DEBUG
if (i != 0 && mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " C%d", i);
}
#endif
}
if (i_flags & 0x80) {
dBgS_GndChk gnd_chk;
gnd_chk.SetPos(&eye);
f32 sp6C = dComIfG_Bgsp().GroundCross(&gnd_chk);
f32 sp68 = mBG.field_0x5c.field_0x58;
cXyz vec1, vec2;
if (sp6C < sp68 + 40.0f) {
vec1 = eye;
vec2 = center;
vec2 += (vec1 - vec2) * 0.5f;
} else {
vec2 = eye;
vec1 = center;
vec1 += (vec2 - vec1) * 0.5f;
}
f32 sp64 = 0.0f;
if (mBG.field_0xc0.field_0x44) {
int sp60 = lineCollisionCheckBush(&vec1, &vec2) & 6;
if (sp60 != 0) {
cXyz mass_cam_top_pos;
dComIfG_Ccsp()->GetMassCamTopPos(&mass_cam_top_pos);
if (eye.y < mass_cam_top_pos.y) {
eye.y = mEye.y + (mass_cam_top_pos.y - mEye.y) * 0.2f;
var_r26 = true;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " B");
}
#endif
}
}
}
} else if (i_flags & 0xb7) {
f32 fVar1 = eye.y - mBG.field_0x0.field_0x58;
if (fVar1 >= 0.0f && fVar1 < 3.0f) {
eye.y = mBG.field_0x0.field_0x58 + 3.0f;
var_r26 = true;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " W");
}
#endif
} else if (fVar1 <= 0.0f && fVar1 > -3.0f) {
eye.y = mBG.field_0x0.field_0x58 - 3.0f;
var_r26 = true;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 235, " W");
}
#endif
}
}
mCenter = center;
mEye = eye;
if (var_r26) {
direction.Val(eye - center);
}
mDirection = direction;
return var_r28 != 0 ? true : false;
}
bool dCamera_c::lineBGCheckBoth(cXyz* i_start, cXyz* i_end, dBgS_LinChk* i_linchk,
u32 i_flags) {
i_linchk->OnBackFlag();
i_linchk->OnFrontFlag();
return lineBGCheck(i_start, i_end, i_linchk, i_flags);
}
f32 dCamera_c::radiusActorInSight(fopAc_ac_c* param_0, fopAc_ac_c* param_1,
fopAc_ac_c* param_2) {
f32 var_f31 = radiusActorInSight(param_0, param_1, &mViewCache.mCenter, &mViewCache.mEye, mFovy, mBank, 0.05f);
f32 var_f30 = radiusActorInSight(param_0, param_2, &mViewCache.mCenter, &mViewCache.mEye, mFovy, mBank, 0.05f);
f32 var_f29;
if (var_f31 > var_f30) {
var_f29 = var_f31;
} else {
var_f29 = var_f30;
}
return var_f29;
}
BOOL dCamera_c::jutOutCheck(cXyz* param_0, f32 param_1) {
cXyz spB4 = attentionPos(mpPlayerActor);
spB4 += (positionOf(mpPlayerActor) - spB4) * 0.5f;
dBgS_CamLinChk linchk;
if (lineBGCheck(&spB4, param_0, &linchk, 0x40B7)) {
cM3dGPla plane;
dComIfG_Bgsp().GetTriPla(linchk, &plane);
*param_0 = linchk.GetCross();
*param_0 += *plane.GetNP() * param_1;
return TRUE;
}
return FALSE;
}
void dCamera_c::tooNearEscape(cXyz* param_0) {
f32 maxDist = 40.0f;
cXyz sp2C = attentionPos(mpPlayerActor);
cSGlobe sp58(*param_0 - sp2C);
if (sp58.R() < maxDist) {
sp58.R(maxDist);
*param_0 = sp2C + sp58.Xyz();
}
}
f32 dCamera_c::getWaterSurfaceHeight(cXyz* param_0) {
f32 var_f31 = -G_CM3D_F_INF;
cXyz spF8(*param_0);
dBgS_RoofChk roofchk;
roofchk.SetUnderwaterRoof();
roofchk.SetPos(spF8);
f32 roof_y = dComIfG_Bgsp().RoofChk(&roofchk);
if (spF8.y < roof_y) {
spF8.y = roof_y;
}
dBgS_CamGndChk_Wtr gndchk;
gndchk.SetPos(&spF8);
f32 gnd_y = dComIfG_Bgsp().GroundCross(&gndchk);
if (gnd_y > param_0->y) {
var_f31 = gnd_y;
}
return var_f31;
}
void dCamera_c::checkGroundInfo() {
daAlink_c* player = (daAlink_c*)mpPlayerActor;
cXyz gnd_chk_pos = positionOf(mpPlayerActor);
if (check_owner_action(mPadID, 0x8000000)) {
gnd_chk_pos = eyePos(mpPlayerActor);
gnd_chk_pos.y = positionOf(mpPlayerActor).y;
}
cXyz roof_chk_pos = gnd_chk_pos;
int var_r24 = 0;
gnd_chk_pos.y += 20.0f;
dBgS_RoofChk roof_chk;
roof_chk.SetUnderwaterRoof();
roof_chk.SetPos(roof_chk_pos);
f32 roof_y = dComIfG_Bgsp().RoofChk(&roof_chk);
if (roof_chk_pos.y < roof_y) {
roof_chk_pos.y = roof_y;
}
dBgS_CamGndChk gnd_chk;
gnd_chk.ClrCam();
gnd_chk.SetObj();
gnd_chk.SetPos(&gnd_chk_pos);
f32 ground_y = dComIfG_Bgsp().GroundCross(&gnd_chk);
mBG.field_0x5c.field_0x4.SetCam();
mBG.field_0x5c.field_0x4.ClrObj();
mBG.field_0x5c.field_0x4.SetPos(&gnd_chk_pos);
mBG.field_0x5c.field_0x58 = dComIfG_Bgsp().GroundCross(&mBG.field_0x5c.field_0x4);
if (mBG.field_0x5c.field_0x58 < ground_y) {
mBG.field_0x5c.field_0x58 = ground_y;
mBG.field_0x5c.field_0x4 = gnd_chk;
}
mBG.field_0x5c.field_0x0 = mBG.field_0x5c.field_0x58 != -1.0e9f;
mBG.field_0x0.field_0x4.SetPos(&roof_chk_pos);
mBG.field_0x0.field_0x58 = dComIfG_Bgsp().GroundCross(&mBG.field_0x0.field_0x4);
mBG.field_0x0.field_0x0 = mBG.field_0x0.field_0x58 != -1.0e9f;
if (check_owner_action(mPadID, 0x100000)
&& mBG.field_0x0.field_0x58 < attentionPos(mpPlayerActor).y + 40.0f)
{
setComStat(0x800);
mBG.field_0xc0.field_0x44 = 1;
} else if (player->checkRide() || player->checkRoofSwitchHang() || player->checkWolfRope()) {
mBG.field_0xc0.field_0x44 = 1;
} else if (check_owner_action1(mPadID, 0x2110000)) {
mBG.field_0xc0.field_0x44 = 1;
} else if (player->checkSpinnerRide()) {
mBG.field_0xc0.field_0x44 = 1;
} else if (player->checkMagneBootsOn()) {
Vec* bootsTopVec = player->getMagneBootsTopVec();
if (!cBgW_CheckBWall(bootsTopVec->y)) {
mBG.field_0xc0.field_0x44 = 1;
}
} else if (footHeightOf(mpPlayerActor) - mBG.field_0x5c.field_0x58 > mCamSetup.mBGChk.FloorMargin()) {
mBG.field_0xc0.field_0x44 = 0;
} else {
mBG.field_0xc0.field_0x44 = 1;
}
mBG.field_0xc0.field_0x1 = 0;
mBG.field_0xc0.field_0x20 = NULL;
if (dComIfG_Bgsp().ChkMoveBG(mBG.field_0x5c.field_0x4)) {
mBG.field_0xc0.field_0x20 = dComIfG_Bgsp().GetActorPointer(mBG.field_0x5c.field_0x4);
if (mBG.field_0xc0.field_0x20 != NULL) {
cXyz pos = positionOf(mBG.field_0xc0.field_0x20);
cSAngle angle = directionOf(mBG.field_0xc0.field_0x20);
if (mBG.field_0xc0.field_0x0 != 0) {
mBG.field_0xc0.field_0x4 = mBG.field_0xc0.field_0x10 - pos;
mBG.field_0xc0.field_0x1c = mBG.field_0xc0.field_0x1e - angle;
}
mBG.field_0xc0.field_0x0 = 1;
if (!dComIfGp_evmng_cameraPlay() && !chkFlag(0x20000000) && mBG.field_0xc0.field_0x44 != 0) {
mBG.field_0xc0.field_0x1 = 1;
}
if (mBG.field_0xc0.field_0x1 != 0) {
dComIfG_Bgsp().MoveBgMatrixCrrPos(mBG.field_0x5c.field_0x4, true,
&mViewCache.mCenter, NULL, NULL);
dComIfG_Bgsp().MoveBgMatrixCrrPos(mBG.field_0x5c.field_0x4, true,
&mViewCache.mEye, NULL, NULL);
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
}
mBG.field_0xc0.field_0x10 = pos;
mBG.field_0xc0.field_0x1e = angle;
}
} else {
mBG.field_0xc0.field_0x0 = 0;
}
if (mBG.field_0x5c.field_0x0) {
mBG.field_0xc0.field_0x34 = dComIfG_Bgsp().GetCamMoveBG(mBG.field_0x5c.field_0x4);
} else {
mBG.field_0xc0.field_0x34 = 0;
}
if (mBG.field_0x0.field_0x0 && check_owner_action(mPadID, 0x100000)) {
mBG.field_0xc0.field_0x3c = dComIfG_Bgsp().GetRoomCamId(mBG.field_0x0.field_0x4);
} else {
mBG.field_0xc0.field_0x3c = 0xff;
}
if (mBG.field_0xc0.field_0x44 == 0 && mFrameCounter != 0 && !check_owner_action(mPadID, 0x100000)) {
mBG.field_0xc0.field_0x40 = 0x1ff;
} else if (mBG.field_0x5c.field_0x0) {
mBG.field_0xc0.field_0x40 = dComIfG_Bgsp().GetRoomCamId(mBG.field_0x5c.field_0x4);
} else {
mBG.field_0xc0.field_0x40 = 0xff;
}
}
bool dCamera_c::chaseCamera(s32 param_0) {
static f32 JumpCushion = 0.9f;
f32 charge_latitude = mCamSetup.ChargeLatitude();
int charge_timer = mCamSetup.ChargeTimer();
f32 charge_b_ratio = mCamSetup.ChargeBRatio();
static cSAngle LatitudeLimitMax = 80.0f;
daAlink_c* player = (daAlink_c*)mpPlayerActor;
daMidna_c* midna = daPy_py_c::getMidnaActor();
if (dComIfGp_getAttention()->GetCheckObjectCount() != 0) {
mpAuxTargetActor1 = dComIfGp_getAttention()->CheckObjectTarget(0);
setFlag(2);
}
f32 val0 = mCamParam.Val(param_0, 0);
f32 val2 = mCamParam.Val(param_0, 2);
f32 val1 = mCamParam.Val(param_0, 1);
f32 val3 = mCamParam.Val(param_0, 3);
f32 val4 = mCamParam.Val(param_0, 4);
f32 val5 = mCamParam.Val(param_0, 5);
f32 val6 = mCamParam.Val(param_0, 6);
f32 val7 = mCamParam.Val(param_0, 7);
f32 val8 = mCamParam.Val(param_0, 8);
f32 val9 = mCamParam.Val(param_0, 9);
f32 val10 = mCamParam.Val(param_0, 10);
f32 val11 = mCamParam.Val(param_0, 11);
f32 val12 = mCamParam.Val(param_0, 12);
f32 val13 = mCamParam.Val(param_0, 13);
f32 val14 = mCamParam.Val(param_0, 14);
f32 val16 = mCamParam.Val(param_0, 16);
f32 val15 = mCamParam.Val(param_0, 15);
f32 val17 = mCamParam.Val(param_0, 17);
f32 val19 = mCamParam.Val(param_0, 19);
f32 val18 = mCamParam.Val(param_0, 18);
f32 val21 = mCamParam.Val(param_0, 21);
f32 val22 = mCamParam.Val(param_0, 22);
f32 val23 = mCamParam.Val(param_0, 23);
f32 val24 = mCamParam.Val(param_0, 24);
#if WIDESCREEN_SUPPORT
if (mDoGph_gInf_c::isWide()) {
val22 *= WideTurnSaving;
}
#endif
cSAngle ang1 = -75.0f;
cSAngle ang2 = 75.0f;
f32 dVar52 = 0.25f;
ChaseData* chase = (ChaseData*)mWork;
if (mCamParam.CheckFlag(1)) {
setFlag(0x20000);
}
if (player->checkSpinnerPathMove() || mCurType == specialType[CAM_TYPE_LV4_BOSS_SPJP]) {
mPadInfo.mMainStick.mLastPosX = 0.0f;
mPadInfo.mMainStick.mLastPosY = 0.0f;
mPadInfo.mMainStick.mLastValue = 0.0f;
}
if (mCurCamStyleTimer == 0) {
cXyz player_attention = attentionPos(mpPlayerActor) - positionOf(mpPlayerActor);
if (chkFlag(0x200) && mRecovery.field_0x8.field_0x1e <= 0) {
mViewCache.mCenter = mCenter;
mViewCache.mEye = mEye;
mViewCache.mDirection = mDirection;
mViewCache.mFovy = mFovy;
}
chase->field_0x40 = 0.0f;
chase->field_0x71 = false;
chase->field_0x96 = directionOf(mpPlayerActor).Inv();
chase->field_0x93 = false;
chase->field_0x73 = false;
chase->field_0x9c = 0xfe;
chase->field_0x18 = 0;
chase->field_0xa0 = mGear;
chase->field_0x94 = false;
chase->field_0xa4 = 0.0f;
chase->field_0x24 = 0.0f;
chase->field_0x98 = directionOf(mpPlayerActor);
if (chkFlag(0x100000)) {
setUSOAngle();
}
if (mCamParam.Flag(param_0, 0x200)) {
switch (mRoomMapTool.mFlags & 3) {
case 1:
mGear = 0;
break;
case 2:
mGear = 1;
break;
}
}
}
bool bVar6 = false;
if (check_owner_action(mPadID, 0x100000) && mBG.field_0xc0.field_0x44 == 0) {
bVar6 = true;
}
cSAngle player_direction = directionOf(mpPlayerActor);
bool bVar12 = false;
bool bVar2 = false;
bool bVar7 = false;
if (check_owner_action(mPadID, 0x300)) {
bVar12 = true;
}
if (check_owner_action(mPadID, 0x2000008)) {
bVar2 = true;
}
if (player->checkMagneBootsOn()) {
bVar7 = true;
Vec* bootsTopVec = player->getMagneBootsTopVec();
if (cBgW_CheckBWall(bootsTopVec->y)) {
bVar2 = true;
}
}
cSAngle player_angle_delta = player_direction - mViewCache.mDirection.U();
field_0x944 = 1;
if (mRoomMapTool.mCameraIndex != 0xff && mCamParam.Flag(param_0, 0x200) &&
#if DEBUG
mCamSetup.ForceType() == -1
#else
true
#endif
) {
if (mRoomMapTool.mCameraIndex != chase->field_0x9c) {
mCamParam.Fovy(mRoomMapTool.mCamData.field_0x11);
mCamParam.Arg0(mRoomMapTool.mCamData.field_0x12);
mCamParam.Arg1(mRoomMapTool.mCamData.field_0x13);
mCamParam.Arg2(mRoomMapTool.mCamData.field_0x14);
if (param_0 == mCamTypeData[mCurType].field_0x18[mIsWolf][mCurMode]) {
mCamParam.Change(param_0);
}
chase->field_0x9c = mRoomMapTool.mCameraIndex;
}
if (mCamParam.Fovy() != 0xff) {
val19 = (s8)mCamParam.Fovy();
}
if (mCamParam.Arg0() != 0xff) {
val9 = (s8)mCamParam.Arg0() * 100.0f;
}
if (mCamParam.Arg1() != 0xff) {
val14 = (s8)mCamParam.Arg1();
}
if (mCamParam.Arg2() != -1) {
val4 = mCamParam.Arg2();
}
} else if (mRoomMapTool.mCameraIndex == 0xff && chase->field_0x9c != 0xff) {
mCamParam.Fovy(0xff);
mCamParam.Arg0(0xff);
mCamParam.Arg1(0xff);
mCamParam.Arg2(-1);
if (param_0 == mCamTypeData[mCurType].field_0x18[mIsWolf][mCurMode]) {
mCamParam.Change(param_0);
}
chase->field_0x9c = 0xff;
}
if (mGear == 1) {
val7 = val9;
val8 = val9 - val9 * 0.2f;
val2 = val3 = val4;
val12= val13 = val14;
val17 = val18 = val19;
}
bool sp1E = true;
bool sp1D = false;
bool sp1C = false;
bool sp1B = false;
if (mIsWolf == 0) {
if (isPlayerCharging(mPadID)) {
sp1B = true;
}
if (check_owner_action(mPadID, 0x8000000)) {
sp1C = true;
}
f32 sp1E0;
if (check_owner_action1(mPadID, 0x2000000)) {
clrFlag(0x80);
cXyz* left_foot_pos = player->getLeftFootPosP();
cXyz* right_foot_pos = player->getRightFootPosP();
if (left_foot_pos->y < right_foot_pos->y) {
val0 = -val0;
}
} else if (mThrowTimer != 0 && !chkFlag(0x100000)) {
sp1E0 = mCamSetup.ThrowCtrAdjust();
val2 += sp1E0;
val3 += sp1E0;
sp1E0 = mCamSetup.ThrowVAngle();
if (val12 < sp1E0) {
val12 = sp1E0;
}
if (val13 < sp1E0) {
val13 = sp1E0;
}
sp1E0 = mCamSetup.ThrowCushion();
val16 = sp1E0;
val5 = sp1E0;
mForwardTiltOffset = cSAngle::_0;
chase->field_0x94 = true;
} else if ((player->getGrabActorID() != fpcM_ERROR_PROCESS_ID_e || mThrowTimer != 0)
&& chkFlag(0x100000)) {
sp1E0 = mCamSetup.ThrowCtrAdjust();
if (mThrowTimer != 0) {
sp1E0 *= (f32)mThrowTimer / mCamSetup.ThrowTimer();
}
val2 += sp1E0;
val3 += sp1E0;
} else if (player->checkCanoeRideTandem()) {
val1 -= 100.0f;
} else if (check_owner_action(mPadID, 0x100000)) {
sp1E0 = mMonitor.field_0x10 / 22.0f;
if (sp1E0 > 1.0f) {
sp1E0 = 1.0f;
}
val1 *= sp1E0;
}
if (chase->field_0x94) {
if (push_any_key()) {
chase->field_0x94 = false;
}
if (mThrowTimer == 0) {
sp1D = true;
}
} else if (chase->field_0x92 && chase->field_0x1a > 14) {
sp1E0 = 550.0f;
if (val8 < sp1E0) {
val8 = sp1E0;
}
sp1E0 *= 1.1f;
if (val7 < sp1E0) {
val7 = sp1E0;
}
}
} else {
if (isPlayerCharging(mPadID)) {
sp1B = true;
}
if (mMidnaRidingAndVisible != 0) {
val2 += 20.0f;
val3 += 20.0f;
}
if (check_owner_action1(mPadID, 0x1000000)) {
chase->field_0x73 = true;
chase->field_0x18 = 20;
} else if (chase->field_0x18 != 0) {
chase->field_0x73 = true;
chase->field_0x18--;
} else {
chase->field_0x73 = false;
}
if ((check_owner_action1(mPadID, 0x800000) || chase->field_0x73) && !chkFlag(0x100000)) {
val1 = -70.0f;
val2 = val3 = -70.0f;
sp1B = true;
f32 search_ball_scale = player->getSearchBallScale();
search_ball_scale *= 1.5f;
if (val8 < search_ball_scale) {
val8 = search_ball_scale;
}
search_ball_scale *= 1.1f;
if (val7 < search_ball_scale) {
val7 = search_ball_scale;
}
if (check_owner_action1(mPadID, 0x800000) && !chase->field_0x73) {
val10 = 1.0f;
val12 = val13 = 40.0f;
} else {
val8 = val7 * 0.75f;
val12 = 30.0f;
val16 = val13 = 1.0f;
}
val17 = val18 = 90.0f / mWindowAspect;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, " W");
}
#endif
}
if (chase->field_0x73) {
val22 = 0.0001f;
val16 = 0.0001f;
val10 = 0.0001f;
val21 = 0.0001f;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, " A");
}
#endif
}
if (mCurMode == 1 && val8 < 300.0f && val7 > 300.0f) {
val8 = 300.0f;
}
}
dAttention_c* attention = dComIfGp_getAttention();
if (mGear == 1 && !mCamParam.Flag(param_0, 0x20)) {
mForwardTiltOffset = cSAngle::_0;
}
if (mCurMode == 1) {
val16 = 0.25f;
}
bool sp1A = false;
if (check_owner_action1(mPadID, 0x10000)) {
cXyz hs_sub_chain_top_pos = daAlink_getAlinkActorClass()->getHsSubChainTopPos();
if (hs_sub_chain_top_pos.y - attentionPos(mpPlayerActor).y > 100.0f) {
sp1A = true;
}
}
if (check_owner_action(mPadID, 0x100)) {
#if DEBUG
val6 = 0.25f;
#endif
val7 -= 50.0f;
val8 -= 50.0f;
if (mIsWolf == 1) {
val1 = 1.0f;
} else {
val1 = -30.0f;
}
ang1.Val(-80.0f);
ang2.Val(80.0f);
val2 = 40.0f;
val3 = 30.0f;
if (player_angle_delta > cSAngle::_270 && player_angle_delta < cSAngle::_90) {
val12 = 30.0f;
val13 = 30.0f;
} else {
if (val12 < 10.0f) {
val12 = 10.0f;
}
if (val13 < 10.0f) {
val13 = 10.0f;
}
}
val6 = 0.05f;
val16 = 0.15f;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, " H");
}
#endif
} else if (check_owner_action(mPadID, 0x2000208)) {
val1 -= 50.0f;
val6 = 0.25f;
val7 -= 50.0f;
val8 -= 50.0f;
ang1.Val(-60.0f);
ang2.Val(60.0f);
if (val2 > 30.0f) {
val2 = 30.0f;
}
if (val3 > 30.0f) {
val3 = 30.0f;
}
mForwardTiltOffset = cSAngle::_0;
val16 = 0.15f;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, " L");
}
#endif
} else if (sp1A) {
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, " R");
}
#endif
mForwardTiltOffset = cSAngle::_0;
mBG.field_0xc0.field_0x44 = 0;
}
if (mIsWolf == 1 || check_owner_action(mPadID, 0x8000000)) {
if (val2 < -30.0f) {
val2 = -30.0f;
}
if (val3 < -30.0f) {
val3 = -30.0f;
}
if (val4 < -30.0f) {
val4 = -30.0f;
}
}
cXyz player_attention_pos = attentionPos(mpPlayerActor);
f32 sp1CC;
if (lineBGCheck(&player_attention_pos, &mViewCache.mEye, 0x40b7)) {
if (val4 > 20.0f) {
val4 = 20.0f;
} else if (val4 < -40.0f) {
val4 = -40.0f;
}
}
sp1CC = 0.05f;
if (mCurCamStyleTimer == 0) {
chase->field_0x38 = val0;
} else if (chkFlag(0x100000) && !check_owner_action1(mPadID, 0x2000000)
&& check_owner_action(mPadID, 0xa50c0)) {
if (mPadInfo.mMainStick.mLastPosX < -0.2f) {
chase->field_0x71 = true;
}
if (mPadInfo.mMainStick.mLastPosX > 0.2f) {
chase->field_0x71 = false;
}
chase->field_0x38 += ((chase->field_0x71 ? -45.0f : 45.0f) - chase->field_0x38) * 0.04f;
} else {
chase->field_0x38 += (val0 - chase->field_0x38) * 0.06f;
}
f32 sp1C8;
if (mGear == 1 || val7 <= val8) {
chase->field_0xa4 = 0.0f;
} else if (!mCamParam.Flag(param_0, 0x400)) {
sp1C8 = mViewCache.mDirection.R();
if (sp1C8 < val8) {
sp1C8 = val8;
} else if (sp1C8 > val7) {
sp1C8 = val7;
}
f32 tmp = (val7 - sp1C8) / (val7 - val8);
if (mCurCamStyleTimer == 0) {
chase->field_0xa4 = tmp;
} else {
chase->field_0xa4 += (tmp - chase->field_0xa4) * 0.75f;
}
}
f32 tmp = val2 + chase->field_0xa4 * (val3 - val2);
if (mCurCamStyleTimer == 0) {
chase->field_0x3c = tmp;
} else {
chase->field_0x3c += (tmp - chase->field_0x3c) * 0.08f;
}
cXyz vec(chase->field_0x38, chase->field_0x3c, val1);
if (mCurCamStyleTimer == 0) {
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
chase->field_0x0 = 'CHAS';
if (mBG.field_0xc0.field_0x44 != 0 && !check_owner_action(mPadID, 0x200)) {
chase->field_0x20 = 0.0f;
} else {
chase->field_0x20 = 1.0f;
}
chase->field_0x10 = 30;
chase->field_0x28 = val8;
chase->field_0x2c = val7;
chase->field_0x14 = chase->field_0x1a = chase->field_0x18 = 0;
chase->field_0x54 = 0.01f;
chase->field_0x78 = chase->field_0x7c = 0.01f;
chase->field_0x80 = 0.01f;
chase->field_0x74 = 0.01f;
chase->field_0x84 = val6;
chase->field_0x88 = val5;
chase->field_0x44 = 0;
chase->field_0x70 = true;
chase->field_0x34 = mViewCache.mFovy;
chase->field_0x48 = 0.0f;
chase->field_0x72 = false;
chase->field_0x91 = false;
chase->field_0x92 = false;
chase->field_0x30 = positionOf(mpPlayerActor).y;
chase->field_0x95 = false;
chase->field_0x4c = 1.0f;
chase->field_0xa8 = 0;
f32 sp1BC = 0.0f;
int timer;
if (dComIfGp_evmng_cameraPlay()) {
getEvIntData(&timer, "Timer", 20);
chase->field_0x4 = timer != 0 ? timer : 1;
chase->field_0x95 = true;
} else {
cXyz pos = relationalPos(mpPlayerActor, &vec);
cSGlobe globe = mDirection.Invert();
globe.R(100000.0f);
cXyz pos2 = mEye + globe.Xyz();
cM3dGLin lin(pos2, mEye);
f32 dist;
if (cM3d_Len3dSqPntAndSegLine(&lin, &pos, &pos2, &dist)) {
if (mRecovery.field_0x8.field_0x1e <= 0) {
mCenter = pos2;
mDirection.Val(mEye - mCenter);
}
mViewCache.mCenter = pos2;
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
}
cSAngle ang;
if ((chkFlag(0x100000) || sp1C || bVar6) && fabsf(mPadInfo.mCStick.mLastPosX) < 0.05f) {
ang.Val(directionOf(mpPlayerActor).Inv());
} else {
ang.Val(mViewCache.mDirection.U());
}
cSGlobe globe2((val8 + val7) * 0.5f, cSAngle((val12 + val13) * 0.5f), ang);
cXyz pos3 = pos + globe2.Xyz();
f32 dist1 = cXyz(mEye - pos3).abs() * 2.5f;
f32 sp1AC;
dist = val3 + (val2 - val3) * chase->field_0xa4;
pos3 = pos;
pos.y += dist;
sp1AC = cXyz(mCenter - pos3).abs() * 8.0f;
sp1BC = fabsf(dist1 > sp1AC ? dist1 : sp1AC);
dist1 = val18 + (val17 - val18) * chase->field_0xa4;
sp1AC = fabsf(mFovy - dist1);
f32 sin = cSAngle(mFovy > dist1 ? mFovy : dist1).Sin();
sp1AC = 100.0f * (sin * sin) * sp1AC;
sp1BC = fabsf(sp1BC > sp1AC ? sp1BC : sp1AC);
sp1BC *= 1.2f;
sp1BC *= 0.00625f;
chase->field_0x4 = (int)(JMAFastSqrt(sp1BC) * 2.2f) + 1;
if (chase->field_0x4 < 5) {
chase->field_0x4 = 5;
}
}
if (player->checkGoronSideMove()) {
chase->field_0x4 = 20;
} else if (mCurType == specialType[CAM_TYPE_LV9_GZELDA_TRI]) {
chase->field_0x4 = 45;
} else if (chkFlag(0x20)) {
int sp1A4 = chase->field_0x4 / 6;
sp1A4 = sp1A4 > 15 ? 15 : sp1A4 < 5 ? 5 : sp1A4;
chase->field_0x4 = chase->field_0x4 + sp1A4;
} else if (player->checkMagneBootsOn()) {
cXyz* magne_boots_top_vec = player->getMagneBootsTopVec();
cXyz vec2 = mDirection.Xyz().norm();
f32 sp19C = VECDotProduct(magne_boots_top_vec, &vec2);
if (sp19C < -0.1f) {
vec2 = (vec2 + *magne_boots_top_vec) * 0.5f;
mViewCache.mDirection.Val(vec2);
mViewCache.mDirection.R(val8);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
chase->field_0x4 = 1;
mStyleSettle.mFinished = true;
}
} else if (Stage == 0x6a && player->checkCameraLargeDamage()) {
mViewCache.mCenter = relationalPos(mpPlayerActor, &vec);
mViewCache.mDirection.Val(val8, cSAngle(val13), mDirection.U());
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = val18;
mStyleSettle.mFinished = true;
chase->field_0x4 = 1;
} else if (mCurMode == 0 && !chase->field_0x95 && chase->field_0x4 < 10 && !chkFlag(0x50000)
&& (chkFlag(0x8000) || field_0x168 == 0)) {
mStyleSettle.mFinished = true;
chase->field_0x4 = 1;
}
chase->field_0x50 = mViewCache.mDirection.V().Degree();
chase->field_0x58 = mViewCache.mCenter;
chase->field_0x64 = mViewCache.mEye;
chase->field_0x34 = mViewCache.mFovy;
if (chkFlag(0x200)) {
chase->field_0x28 = chase->field_0x2c = mViewCache.mDirection.R();
}
chase->field_0x8 = chase->field_0x4 * (chase->field_0x4 + 1) >> 1;
chase->field_0xc = 0.0f;
chase->field_0x1c = 0;
chase->field_0x8c = 0;
chase->field_0x90 = false;
}
cXyz pos = relationalPos(mpPlayerActor, &vec);
fopAc_ac_c* copy_rod_camera = player->getCopyRodCameraActor();
bool sp19 = false;
if (copy_rod_camera != NULL) {
cXyz attention_pos = attentionPos(mpPlayerActor);
if (!lineBGCheck(&attention_pos, &mViewCache.mEye, 0x40b7)) {
sp19 = true;
mpAuxTargetActor1 = copy_rod_camera;
setFlag(0x2000);
}
}
if (player->checkHorseRide()) {
pos.y -= 100.0f;
}
if (!DEBUG || sp1E) {
jutOutCheck(&pos, 5.0f);
}
bool sp18 = false;
cXyz vec2(0.0f, 0.0f, mMonitor.field_0xc * 10.0f);
cXyz vec3 = attentionPos(mpPlayerActor) + dCamMath::xyzRotateY(vec2, player_direction);
dBgS_CamLinChk lin_chk;
if (lineBGCheck(&mViewCache.mEye, &vec3, &lin_chk, 0x40b7)) {
cM3dGPla plane;
dComIfG_Bgsp().GetTriPla(lin_chk, &plane);
vec3 = lin_chk.GetCross();
vec3 += *plane.GetNP();
val22 *= 3.0f;
}
if (mStyleSettle.mFinished == 0) {
chase->field_0x96 = player_direction.Inv();
if (mBG.field_0xc0.field_0x1 != 0) {
dComIfG_Bgsp().MoveBgMatrixCrrPos(mBG.field_0x5c.field_0x4, true,
&chase->field_0x58, NULL, NULL);
}
chase->field_0xc = chase->field_0x4 - (int)mCurCamStyleTimer;
f32 sp194;
f32 rate = chase->field_0xc / chase->field_0x8;
chase->field_0x58 = pos;
if (chase->field_0x95) {
rate = 0.75f;
if (push_any_key() && mMonitor.field_0xc < 0.1f && mCurCamStyleTimer > 20) {
mStyleSettle.mFinished = true;
}
}
mViewCache.mCenter += (pos - mViewCache.mCenter) * rate;
f32 dist = dCamMath::xyzHorizontalDistance(pos, chase->field_0x58);
if (dist < fabsf(vec.x > vec.z ? vec.x : vec.z) + 20.0f) {
cXyz attention_pos = attentionPos(mpPlayerActor);
attention_pos.y -= 15.0f;
dBgS_CamLinChk lin_chk;
if (lineBGCheck(&attention_pos, &mViewCache.mCenter, &lin_chk, 0x40b7)) {
cM3dGPla plane;
dComIfG_Bgsp().GetTriPla(lin_chk, &plane);
mViewCache.mCenter = lin_chk.GetCross();
mViewCache.mCenter += *plane.GetNP();
}
}
sp194 = limitf(mViewCache.mDirection.R(), val8, val7);
cSAngle ang = val12 + chase->field_0xa4 * (val13 - val12);
if (!chase->field_0x95) {
ang += mForwardTiltOffset;
}
chase->field_0x50 = ang.Degree();
cSGlobe globe(sp194, ang, cSAngle(mControlledYaw.Inv()));
mViewCache.mDirection.R(mViewCache.mDirection.R() + (globe.R() - mViewCache.mDirection.R()) * rate);
mViewCache.mDirection.V(mViewCache.mDirection.V() + (globe.V() - mViewCache.mDirection.V()) * rate);
if (chkFlag(0x100000) || sp1C || bVar6) {
mViewCache.mDirection.U(mViewCache.mDirection.U() + (chase->field_0x96 - mViewCache.mDirection.U()) * rate);
}
chase->field_0x64 = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mEye = chase->field_0x64;
if (mCurCamStyleTimer >= chase->field_0x4 - 1) {
mStyleSettle.mFinished = true;
}
chase->field_0x28 = chase->field_0x2c = mViewCache.mDirection.R();
f32 sp188 = val17 + chase->field_0xa4 * (val18 - val17);
mViewCache.mFovy += (sp188 - mViewCache.mFovy) * rate;
chase->field_0x8 -= chase->field_0xc;
chase->field_0x8c = 0;
chase->field_0x90 = false;
return true;
}
chase->field_0x95 = false;
if (mCStickYHoldCount == 1 && chase->field_0xa0 != mGear) {
chase->field_0x1c = 20;
chase->field_0xa0 = mGear;
}
if (chase->field_0x1c != 0) {
f32 sp184 = 1.0f - (chase->field_0x1c - 1) / 20.0f;
dVar52 = dCamMath::rationalBezierRatio(sp184, 0.5f);
}
if (player->checkThrowDamage()) {
chase->field_0x91 = true;
fopAc_ac_c* target = dComIfGp_getAttention()->LockonTarget(0);
if (target != NULL && fopAcM_GetName(target) == fpcNm_E_HZ_e) {
setFlag(0x2000);
mpAuxTargetActor1 = target;
}
} else {
chase->field_0x91 = false;
}
bool sp17 = false;
bool sp16 = false;
bool sp15 = false;
cXyz player_pos = positionOf(mpPlayerActor);
player_pos.y += 10.0f;
f32 sp17C = footHeightOf(mpPlayerActor) - groundHeight(&player_pos);
if (mBG.field_0xc0.field_0x44 != 0 && !check_owner_action(mPadID, 0x200)) {
chase->field_0x20 = 0.0f;
chase->field_0x10 = 0;
} else if (chase->field_0x10 < 30) {
sp17 = true;
chase->field_0x10++;
chase->field_0x20 += (JumpCushion - chase->field_0x20) * dCamMath::rationalBezierRatio(chase->field_0x10 / 30.0f, 1.25f);
} else if (!bVar2) {
sp16 = true;
if (mBG.field_0x5c.field_0x0 && dComIfG_Bgsp().GetGroundCode(mBG.field_0x5c.field_0x4) == 4) {
sp15 = true;
} else if (player->checkCokkoGlide()) {
sp17 = true;
sp16 = false;
}
val10 = 0.01f;
chase->field_0x20 += (1.0f - chase->field_0x20) * 0.1f;
}
if (check_owner_action(mPadID, 0x2800008)) {
if (mFakeAngleSys.field_0x0 == 0) {
setUSOAngle();
chase->field_0x98 = directionOf(mpPlayerActor);
} else {
cSAngle ang = chase->field_0x98 - directionOf(mpPlayerActor);
if (ang.Abs() > cSAngle(50.0f)) {
mFakeAngleSys.field_0x0 = 0;
}
}
}
if (chase->field_0x91) {
chase->field_0x84 = 0.35f;
} else if (check_owner_action(mPadID, 0x2000108)
&& !(player_angle_delta > cSAngle::_270 && player_angle_delta < cSAngle::_90))
{
chase->field_0x84 = 0.1f;
} else {
chase->field_0x84 += (val6 - chase->field_0x84) * 0.4f;
}
if (chase->field_0x91) {
if (val2 < -10.0f) {
val2 = -10.0f;
}
if (val3 < -10.0f) {
val3 = -10.0f;
}
chase->field_0x88 = 0.25f;
} else if (sp17 || sp16) {
f32 sp178 = val5 * 0.1f;
chase->field_0x88 = sp178 + (0.9f - sp178) * chase->field_0x20;
if (chkFlag(0x100000) && chase->field_0x84 > 0.25f) {
chase->field_0x84 = chase->field_0x20 * 0.75f + 0.25f;
}
} else if (chase->field_0x1c != 0) {
chase->field_0x88 = dVar52;
} else if (bVar6 && mDoCPd_c::getTrigA(mPadID)) {
chase->field_0x88 = 0.01f;
} else if (bVar6) {
chase->field_0x88 += (val5 - chase->field_0x88) * 0.1f;
} else {
chase->field_0x88 += (val5 - chase->field_0x88) * 0.4f;
}
cXyz vec4(chase->field_0x84, chase->field_0x88, chase->field_0x84);
bool sp14 = false;
bool sp13 = true;
bool sp12 = chkFlag(0x80) && mDirection.R() < val8;
if (chkFlag(0x100000) ||
check_owner_action(mPadID, 0x2800108) ||
isPlayerCharging(mPadID) ||
sp17) {
sp13 = false;
}
if (sp12 && mMonitor.field_0xc < 0.1f && !chkFlag(0x100000)
&& !check_owner_action(mPadID, 0x2800108) && !check_owner_action1(mPadID, 0x2110000))
{
sp14 = true;
}
if (mCamParam.Flag(param_0, 0x1000)) {
f32 sp174 = 0.0f;
if (push_any_key()) {
chase->field_0x8c = 0;
chase->field_0x90 = false;
} else if (chase->field_0x8c < mCamSetup.WaitRollTimer()) {
chase->field_0x8c++;
} else {
fopAc_ac_c* target = attention->LockonTarget(0);
if (target != NULL) {
cXyz delta = positionOf(target) - positionOf(mpPlayerActor);
cSAngle ang = -mViewCache.mDirection.U();
delta = dCamMath::xyzRotateY(delta, ang);
cXyz vec5 = delta;
if (fabsf(vec5.y) < 200.0f) {
vec5.y = 0.0f;
vec5.x *= 0.5f;
f32 sp16C = vec5.abs();
if (sp16C < 500.0f) {
sp174 = -delta.x * 0.55f * (1.0f - sp16C / 500.0f);
}
}
}
}
chase->field_0x40 += (sp174 - chase->field_0x40) * 0.01f;
cSGlobe globe(chase->field_0x40, mViewCache.mDirection.V(), mViewCache.mDirection.U() + cSAngle::_270);
pos += globe.Xyz();
}
mViewCache.mCenter += (pos - mViewCache.mCenter) * vec4;
cSGlobe globe = mViewCache.mEye - mViewCache.mCenter;
f32 sp168;
if (chase->field_0x1a > 0 && chase->field_0x1a <= 14) {
sp168 = chase->field_0x1a / 14.0f;
if (sp168 > 1.0f) {
sp168 = 1.0f;
}
f32 rate = dCamMath::rationalBezierRatio(sp168, charge_b_ratio);
chase->field_0x70 = true;
chase->field_0x48 = (1.0f - chase->field_0x48) * rate;
} else if (bVar6) {
f32 sp160 = 0.2f;
f32 target = 1.0f;
sp168 = dCamMath::rationalBezierRatio(mPadInfo.mMainStick.mLastPosX, val23);
if (!mDoCPd_c::getHoldA(mPadID)) {
target = 1.0f - ((1.0f - val24) + val24 * cSAngle(sp168 * 180.0f).Cos());
target *= mPadInfo.mMainStick.mLastValue;
}
chase->field_0x24 += (target - chase->field_0x24) * 0.4f;
if (chase->field_0x70) {
chase->field_0x48 = 0.05f;
}
chase->field_0x70 = false;
chase->field_0x48 += (val24 * chase->field_0x24 - chase->field_0x48) * sp160;
} else if (chkFlag(0x100000) || sp1C) {
f32 sp158 = 0.2f;
if (chase->field_0x70) {
chase->field_0x48 = 0.05f;
}
chase->field_0x70 = false;
chase->field_0x48 += (1.0f - chase->field_0x48) * sp158;
} else {
chase->field_0x70 = true;
if (mFakeAngleSys.field_0x0 != 0) {
chase->field_0x48 = 0.0f;
} else if (mPadInfo.mMainStick.mLastPosY >= 0.0f) {
sp168 = dCamMath::rationalBezierRatio(mPadInfo.mMainStick.mLastPosX, val23);
chase->field_0x48 = 1.0f - (1.0f - val24 + val24 * cSAngle(sp168 * 180.0f).Cos());
} else {
sp168 = dCamMath::rationalBezierRatio(mPadInfo.mMainStick.mLastPosX, val23 * 2.0f);
chase->field_0x48 = 1.0f - (1.0f - val24 + val24 * cSAngle(sp168 * 180.0f).Cos());
}
chase->field_0x48 *= mPadInfo.mMainStick.mLastValue;
chase->field_0x48 *= val22;
if (check_owner_action(mPadID, 0x2000008)) {
if (chase->field_0x14 == 0) {
if (check_owner_action(mPadID, 8)) {
chase->field_0x14 = 1;
} else if (player_angle_delta > cSAngle::_270 && player_angle_delta < cSAngle::_90) {
chase->field_0x14 = 1;
} else {
chase->field_0x14 = -1;
}
} else {
int sp154 = 32;
int sp150 = 30;
f32 sp14C = 0.5f;
if (chase->field_0x14 < 0) {
chase->field_0x14--;
} else if (chase->field_0x14 < sp150) {
chase->field_0x48 = chase->field_0x14 / (f32)sp150 * sp14C;
chase->field_0x14++;
} else {
chase->field_0x48 = sp14C;
}
}
} else {
chase->field_0x14 = 0;
}
}
cSAngle ang3;
f32 sp148 = chase->field_0x48 * globe.V().Cos();
if (chkFlag(0x80000)) {
cXyz vec5 = mLastHitPos;
cSGlobe globe = vec5 - mViewCache.mCenter;
ang3 = globe.U();
sp148 = sAngleX(mCornerNormalSum).Cos() * 0.3f + 0.35f;
} else if (chase->field_0x90) {
ang3 = player_direction.Inv();
sp148 = mCamSetup.WaitRollSpeed();
} else if (sp14) {
ang3 = mViewCache.mDirection.U();
} else if (sp1C) {
ang3 = player_direction.Inv();
} else if (chkFlag(0x100000) || bVar6) {
if (player->checkChainBlockPushPull()) {
fopAc_ac_c* sp144 = player->getChainGrabActor();
cSGlobe globe = mViewCache.mCenter - attentionPos(sp144);
ang3 = globe.U();
} else if ((mIsWolf != 1 || mCurMode != 1) && !mCamParam.Flag(param_0, 0x100)) {
ang3 = player_direction.Inv();
} else {
ang3 = chase->field_0x96;
}
} else {
ang3 = player_direction.Inv();
}
bool sp11 = false;
f32 sp140 = 0.05f;
f32 last_pos_x = mPadInfo.mCStick.mLastPosX;
f32 sp138 = fabsf(last_pos_x);
f32 sp134 = mPadInfo.mCStick.mLastPosY;
f32 sp130 = fabsf(sp134);
f32 sp12C = 8.0f;
f32 sp128 = 12.0f;
chase->field_0x93 = false;
if (sp11 || (!mCamParam.Flag(param_0, 0x40) && fabsf(last_pos_x) > sp140)) {
chase->field_0xac += (dCamMath::rationalBezierRatio(last_pos_x, 0.5f) * sp12C - chase->field_0xac) * chase->field_0x4c;
ang3 = globe.U() + cSAngle(chase->field_0xac);
sp148 = fabsf(last_pos_x) - 0.05f;
if (mCamSetup.CheckFlag(0x1000) && mFakeAngleSys.field_0x0 == 0) {
setUSOAngle();
}
if (mCamSetup.CheckFlag2(0x40)) {
chase->field_0x93 = true;
chase->field_0x9a = ang3;
} else if (chkFlag(0x100000)) {
chase->field_0x93 = true;
chase->field_0x9a = ang3;
}
clrFlag(0x20000);
} else if (check_owner_action1(mPadID, 0x2010000) && mCurMode == 0) {
chase->field_0x9a = mDirection.U().Val();
chase->field_0x93 = true;
} else if (mIsWolf == 1 && isPlayerCharging(mPadID)) {
chase->field_0x9a = mDirection.U().Val();
chase->field_0x93 = true;
} else {
chase->field_0xac = 0.0f;
}
if (check_owner_action1(mPadID, 0x1000000) || chase->field_0x91) {
chase->field_0x9a = mDirection.U().Val();
chase->field_0x93 = true;
}
if (sp18) {
sp148 *= 0.6f;
}
if (chase->field_0x93) {
mViewCache.mDirection.U(chase->field_0x9a);
} else {
mViewCache.mDirection.U(globe.U() + (ang3 - globe.U()) * sp148);
}
cSAngle ang4;
f32 sp124 = chase->field_0x78;
if (sp1B && !bVar7) {
chase->field_0x50 = charge_latitude;
if (chase->field_0x1a < 14) {
f32 sp120 = chase->field_0x1a / 14.0f;
chase->field_0x78 = dCamMath::rationalBezierRatio(sp120, charge_b_ratio);
setFlag(0x4000000);
chase->field_0x1a++;
} else {
if (player->checkCutLargeTurnState()) {
chase->field_0x92 = true;
}
chase->field_0x78 = 1.0f;
}
} else if (chase->field_0x1a >= 14 && chase->field_0x1a < 34) {
chase->field_0x50 = charge_latitude;
chase->field_0x1a++;
chase->field_0x78 = 1.0f;
} else {
if (chase->field_0x1a != 0) {
chase->field_0x78 = 0.0f;
}
chase->field_0x1a = 0;
if (mCurMode == 1) {
f32 sp11C = val12 + (val13 - val12) * chase->field_0xa4;
chase->field_0x78 = 0.5f;
chase->field_0x50 += (sp11C - chase->field_0x50) * chase->field_0x48;
} else {
if (check_owner_action1(mPadID, 0x800000) && false) {
chase->field_0x78 = 0.25f;
chase->field_0x50 = val12;
} else if (check_owner_action1(mPadID, 0x1000000) || chase->field_0x73) {
chase->field_0x78 = 0.75f;
chase->field_0x50 = val12;
} else if (chkFlag(0x10000)) {
chase->field_0x50 += (val12 - chase->field_0x50) * chase->field_0x20;
chase->field_0x78 = val16;
} else if (chkFlag(0x80000) || sp14 || sp1D) {
chase->field_0x78 = 0.0f;
chase->field_0x50 = mViewCache.mDirection.V().Degree();
} else if ((!sp17 && !sp16 && (!bVar2 || mCurMode != 0 || mGear != 0)) || bVar12) {
f32 sp118 = val12 + (val13 - val12) * chase->field_0xa4;
sp118 += mForwardTiltOffset.Degree();
chase->field_0x50 += (sp118 - chase->field_0x50) * val16;
chase->field_0x78 += (JumpCushion - chase->field_0x78) * sp1CC;
} else if (bVar2) {
chase->field_0x50 = globe.V().Degree();
chase->field_0x78 = 0.95f;
} else if (isPlayerFlying(player)) {
if (chase->field_0x30 < positionOf(mpPlayerActor).y) {
chase->field_0x78 = dCamMath::rationalBezierRatio(chase->field_0x20, val15);
} else {
chase->field_0x78 += (0.75f - chase->field_0x78) * 0.15f;
}
chase->field_0x50 = globe.V().Degree();
} else {
chase->field_0x50 = globe.V().Degree();
chase->field_0x78 = dCamMath::rationalBezierRatio(chase->field_0x20, val15);
if (chase->field_0x91) {
ang1.Val(-50.0f);
chase->field_0x78 = 0.75f;
}
}
}
}
if (chase->field_0x1a == 0) {
chase->field_0x92 = false;
}
chase->field_0x30 = positionOf(mpPlayerActor).y;
ang4.Val(chase->field_0x50);
if (ang4 < ang1) {
ang4.Val(ang1);
} else if (ang4 > ang2) {
ang4.Val(ang2);
}
if (chase->field_0x1c != 0) {
chase->field_0x78 = dVar52;
}
mViewCache.mDirection.V(mViewCache.mDirection.V() + (ang4 - mViewCache.mDirection.V()) * chase->field_0x78);
f32 fVar55 = globe.R();
if (chase->field_0x1c != 0) {
val11 = 1.0f;
}
f32 sp110 = chase->field_0x2c;
chase->field_0x28 += (val8 - chase->field_0x28) * val11;
chase->field_0x2c += (val7 - chase->field_0x2c) * val11;
bool bVar6a = false;
bool bVar2a = false;
if (sp16 && !check_owner_action(mPadID, 0x100000)) {
fVar55 = mViewCache.mDirection.R() + (fVar55 - mViewCache.mDirection.R()) * 0.4f;
if (!sp15 && fVar55 > val7 * 1.5f) {
fVar55 = val7 * 1.5f;
}
} else if (fVar55 < chase->field_0x28) {
fVar55 = chase->field_0x28;
bVar6a = true;
} else if (fVar55 > chase->field_0x2c) {
fVar55 = chase->field_0x2c;
bVar2a = true;
}
if (sp17) {
chase->field_0x74 += (chase->field_0x20 - chase->field_0x74) * 0.01f;
} else if (sp16) {
chase->field_0x74 += (chase->field_0x20 - chase->field_0x74) * 0.01f;
} else if (chase->field_0x1c != 0) {
chase->field_0x74 = dVar52;
} else if (bVar6a) {
chase->field_0x74 += (val10 - chase->field_0x74) * 0.01f;
} else if (bVar2a) {
chase->field_0x74 += (val10 - chase->field_0x74) * 0.01f;
} else {
chase->field_0x74 = 1.0f;
}
sp110 = mViewCache.mDirection.R();
mViewCache.mDirection.R(mViewCache.mDirection.R() + (fVar55 - mViewCache.mDirection.R()) * chase->field_0x74);
chase->field_0x64 = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mEye = chase->field_0x64;
if (chase->field_0x1c != 0) {
chase->field_0x80 = dVar52;
} else {
chase->field_0x80 += (val21 - chase->field_0x80) * 0.01f;
}
f32 sp10C = val17 + (val18 - val17) * chase->field_0xa4;
mViewCache.mFovy += (sp10C - mViewCache.mFovy) * chase->field_0x80;
if (chase->field_0x1c != 0) {
chase->field_0x1c--;
}
return true;
}
bool dCamera_c::lockonCamera(s32 param_0) {
f32 lockon_change_cushion = mCamSetup.LockonChangeCushion();
cSAngle charge_latitude = cSAngle(mCamSetup.ChargeLatitude());
f32 charge_b_ratio = mCamSetup.ChargeBRatio();
int lockon_change_timer = mCamSetup.LockonChangeTimer();
f32 sp200 = 0.15f;
f32 val1 = mCamParam.Val(param_0, 1);
f32 val5 = mCamParam.Val(param_0, 5);
f32 val6 = mCamParam.Val(param_0, 6);
f32 val25 = mCamParam.Val(param_0, 25);
f32 val26 = mCamParam.Val(param_0, 26);
f32 val4 = mCamParam.Val(param_0, 4);
f32 val13 = mCamParam.Val(param_0, 13);
f32 val15 = mCamParam.Val(param_0, 15);
f32 val16 = mCamParam.Val(param_0, 16);
f32 val27 = mCamParam.Val(param_0, 27);
f32 val22 = mCamParam.Val(param_0, 22);
f32 val23 = mCamParam.Val(param_0, 23);
f32 val24 = mCamParam.Val(param_0, 24);
f32 val10 = mCamParam.Val(param_0, 10);
f32 val11 = mCamParam.Val(param_0, 11);
f32 val20 = mCamParam.Val(param_0, 20);
f32 val21 = mCamParam.Val(param_0, 21);
LockOnData* lockon = (LockOnData*)mWork;
dAttention_c* attention = dComIfGp_getAttention();
daAlink_c* player = (daAlink_c*)mpPlayerActor;
if (dComIfGp_evmng_cameraPlay()) {
fopAc_ac_c* target = getEvActor("Target");
if (target != NULL) {
mpLockonTarget = target;
}
}
if (mCurCamStyleTimer == 0) {
if (mRecovery.field_0x8.field_0x1e <= 0) {
mViewCache.mDirection = mDirection;
mViewCache.mCenter = mCenter;
mViewCache.mEye = mEye;
}
lockon->field_0x0 = 'LOCK';
lockon->field_0xc = 0;
lockon->field_0x10 = 1.0f;
lockon->field_0x18 = false;
lockon->field_0x28 = false;
lockon->field_0x1c = mViewCache.mCenter;
cXyz attention_pos = attentionPos(mpPlayerActor);
lockon->field_0x34.Val(mViewCache.mCenter - attention_pos);
if (mViewCache.mCenter.x == attention_pos.x && mViewCache.mCenter.z == attention_pos.z) {
lockon->field_0x34.U(directionOf(mpPlayerActor));
}
lockon->field_0x54 = lockon->field_0x58 = 0.0f;
lockon->field_0x5c = mCamSetup.Cushion4Base();
lockon->field_0x60 = 1.0f;
lockon->field_0x14 = 0;
lockon->field_0x29 = false;
lockon->field_0x2c = 0;
lockon->field_0x30 = 0;
lockon->field_0x40 = false;
lockon->field_0x44 = 0;
lockon->field_0x48 = mViewCache.mDirection.R();
lockon->field_0x50 = mViewCache.mDirection.V();
lockon->field_0x4c = 1.0f;
lockon->field_0x2a = false;
lockon->field_0x3c = fpcM_ERROR_PROCESS_ID_e;
if (player->checkCutHeadProc() && mpLockonTarget != NULL) {
lockon->field_0x3c = fopAcM_GetID(mpLockonTarget);
}
if (mpLockonTarget != NULL) {
if (fopAcM_GetName(mpLockonTarget) == fpcNm_Obj_Bemos_e
|| fopAcM_GetName(mpLockonTarget) == fpcNm_Obj_Lv6bemos2_e)
{
setUSOAngle();
}
} else if (mCamParam.Flag(param_0, 0x2000)) {
fopAc_ac_c* target = getParamTargetActor(mCurType);
if (target != NULL) {
lockon->field_0x3c = fopAcM_GetID(target);
}
}
if (mCurType == specialType[CAM_TYPE_LV7_BOSS]) {
cSAngle ang = -10.0f;
if (mViewCache.mDirection.V() < ang) {
mViewCache.mDirection.V(cSAngle(-10.0f));
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
}
}
} else {
mStyleSettle.mFinished = true;
}
if (player->checkCutHeadProc() && lockon->field_0x3c != fpcM_ERROR_PROCESS_ID_e) {
mpLockonTarget = fopAcM_SearchByID(lockon->field_0x3c);
if (mpLockonTarget != NULL) {
dComIfGp_getAttention()->keepLock(30);
} else {
dComIfGp_getAttention()->keepLock(0);
}
}
if (mpLockonTarget == NULL && lockon->field_0x3c != fpcM_ERROR_PROCESS_ID_e) {
mpLockonTarget = fopAcM_SearchByID(lockon->field_0x3c);
}
bool bVar1 = false;
if (check_owner_action(mPadID, 6)) {
lockon_change_timer = 5;
} else if (mCurType == specialType[CAM_TYPE_LV9_GZELDA_TRI]) {
lockon_change_timer = 60;
} else if (mCurType == specialType[CAM_TYPE_TEPPEI_HOOK]) {
lockon_change_timer = 40;
}
if (mBG.field_0xc0.field_0x1) {
dComIfG_Bgsp().MoveBgMatrixCrrPos(mBG.field_0x5c.field_0x4, true,
&lockon->field_0x1c, NULL, NULL);
}
if (player->checkCopyRodThrowAfter()) {
lockon->field_0x28 = true;
} else if (!attention->LockonTruth() && check_owner_action(mPadID, 0x400000)) {
lockon->field_0x28 = true;
} else {
lockon->field_0x28 = false;
}
if (lockon->field_0x28) {
if (chkFlag(0x80080)) {
lockon->field_0x48 = cXyz(mLastHitPos - mViewCache.mCenter).abs();
val11 = lockon->field_0x48;
}
val10 = lockon->field_0x48;
if (val23 < 40.0f) {
val23 = 20.0f;
}
if (val24 < 20.0f) {
val24 = 20.0f;
}
val13 = 0.75f;
val15 = lockon->field_0x50.Degree();
val16 = 20.0f;
val27 = 0.1f;
val22 = 0.4f;
}
if (mpLockonTarget != NULL && mLockOnActorID != fpcM_ERROR_PROCESS_ID_e
&& fopAcM_GetName(mpLockonTarget) != fpcNm_E_HZ_e)
{
val15 = 60.0f;
val16 = 20.0f;
val26 = -20.0f;
}
if (mpLockonTarget != NULL) {
if (fopAcM_GetName(mpLockonTarget) == fpcNm_COW_e) {
val27 = 0.8f;
val22 = 0.8f;
val23 = 5.0f;
val24 = 10.0f;
} else if (fopAcM_GetName(mpLockonTarget) == fpcNm_Obj_Cdoor_e) {
val23 = 15.0f;
val24 = 5.0f;
}
}
if (player->checkThrowDamage()) {
bVar1 = true;
val15 = -10.0f;
val16 = 0.0f;
val10 = 300.0f;
val11 = 250.0f;
val5 = 0.05f;
val6 = 0.1f;
}
if (!check_owner_action(mPadID, 0) && !check_owner_action1(mPadID, 0x1200000)) {
bVar1 = true;
}
if (dComIfGp_getAttention()->LockEdge()) {
field_0x160 = mCurCamStyleTimer = 0;
lockon->field_0x2a = false;
}
cSGlobe globe;
f32 curveWeight = mCamSetup.CurveWeight();
f32 lockon_release_distance = attention->LockonReleaseDistanse();
f32 sp1A0;
f32 sp19C = 10000.0f;
if (mpLockonTarget != NULL) {
cXyz target_attention_pos = attentionPos(mpLockonTarget);
cXyz player_attention_pos = attentionPos(mpPlayerActor);
if (mCurMode == 6) {
target_attention_pos.x = positionOf(mpLockonTarget).x;
target_attention_pos.z = positionOf(mpLockonTarget).z;
}
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
char name[16];
fopAcM_getNameString(mpLockonTarget, name);
dDbVw_Report(0x1e0, 0x109, "%s", name);
}
#endif
if (check_owner_action(mPadID, 0x2000008)) {
cXyz vec(0.0f, 0.0f, -90.0f);
player_attention_pos += dCamMath::xyzRotateY(vec, directionOf(mpPlayerActor));
}
globe.Val(target_attention_pos - player_attention_pos);
globe.R(globe.R() + mpLockonTarget->attention_info.field_0xa);
sp1A0 = globe.R() / lockon_release_distance;
if (sp1A0 > 1.0f) {
sp1A0 = 1.0f;
}
sp19C = dCamMath::xyzHorizontalDistance(target_attention_pos, player_attention_pos);
} else {
OS_REPORT("NULL TARGET&&&&&&&&&&&&& \n");
globe.Val(mCamSetup.ParallelDist(), cSAngle::_0, directionOf(mpPlayerActor));
sp1A0 = 1.0f;
}
cSAngle ang1 = globe.U();
cSAngle ang2 = rangef(val23, val24, sp1A0);
if (player->checkHorseRide()) {
ang1.Val(directionOf(mpPlayerActor));
}
bool sp0F = false;
bool sp0E = false;
bool sp0D = false;
if (check_owner_action(mPadID, 0x100)) {
sp0F = true;
}
if (check_owner_action(mPadID, 0x2000008)) {
sp0E = true;
}
if (player->checkMagneBootsOn()) {
sp0D = true;
Vec* magneBootsTopVec = player->getMagneBootsTopVec();
if ((u8)cBgW_CheckBWall(magneBootsTopVec->y)) {
sp0E = true;
}
}
#if TARGET_PC
f32 sp194 = 1.0f;
if (mCurCamStyleTimer < lockon_change_timer && !lockon->field_0x2a) {
sp194 = dCamMath::rationalBezierRatio((f32)mCurCamStyleTimer / lockon_change_timer, 0.5f);
ang2 *= sp194;
} else if (mCurCamStyleTimer >= lockon_change_timer) {
lockon->field_0x2a = true;
}
#else
f32 sp194;
if (mCurCamStyleTimer < lockon_change_timer && !lockon->field_0x2a) {
sp194 = dCamMath::rationalBezierRatio((f32)mCurCamStyleTimer / lockon_change_timer, 0.5f);
ang2 *= sp194;
} else if (mCurCamStyleTimer >= lockon_change_timer) {
lockon->field_0x2a = true;
sp194 = 1.0f;
}
#endif
cSAngle ang3(mViewCache.mDirection.U().Inv() - ang1);
if (mCurCamStyleTimer != 0 && mCurCamStyleTimer < lockon_change_timer) {
if (lockon->field_0x2c == 0) {
ang1 -= ang2;
ang3 = -ang3;
} else {
ang1 += ang2;
}
} else if (ang3 < cSAngle::_0) {
lockon->field_0x2c = 0;
ang1 -= ang2;
ang3 = -ang3;
} else {
lockon->field_0x2c = 1;
ang1 += ang2;
}
cXyz attention_pos = attentionPos(mpPlayerActor);
if (mIsWolf == 1 && false) {
attention_pos.x = positionOf(mpPlayerActor).x;
attention_pos.z = positionOf(mpPlayerActor).z;
}
bool sp0C = false;
if (chkFlag(0x80080)) {
cXyz attention_pos = attentionPos(mpPlayerActor);
if (!pointInSight(&attention_pos)) {
if (lockon->field_0x14 == 0) {
lockon->field_0x30 = lockon->field_0x2c == 1 ? 0 : 1;
}
sp0C = true;
lockon->field_0x14 = 30;
}
}
if (lockon->field_0x14 != 0) {
lockon->field_0x14--;
if (lockon->field_0x14 == 0 && mPadInfo.mMainStick.mLastValue <= 0.1f) {
lockon->field_0x14 = 1;
}
sp0C = true;
}
f32 fVar43 = 1.0f - fabsf(mPadInfo.mCStick.mLastPosY);
f32 fVar44;
if (bVar1) {
if (mCurCamStyleTimer == 0) {
lockon->field_0x5c = 0.01f;
}
fVar44 = 0.25f;
} else if (mBG.field_0xc0.field_0x44 == 0) {
fVar44 = mCamSetup.Cushion4Jump();
} else {
fVar44 = sp194 * mCamSetup.Cushion4Base();
}
lockon->field_0x5c += (fVar44 - lockon->field_0x5c) * mCamSetup.CusCus();
lockon->field_0x1c.x = attention_pos.x;
lockon->field_0x1c.z = attention_pos.z;
f32 dVar37;
if (sp0C) {
dVar37 = rangef(val25, val26, sp1A0) + 25.0f;
} else {
dVar37 = rangef(val25, val26, sp1A0);
}
lockon->field_0x1c.y +=
((attention_pos.y + dVar37) - lockon->field_0x1c.y) * lockon->field_0x5c;
if (mCurCamStyleTimer == 0) {
cXyz vec = lockon->field_0x1c;
lockon->field_0x34.Val(mViewCache.mCenter - vec);
if (mViewCache.mCenter.x == vec.x && mViewCache.mCenter.z == vec.z) {
lockon->field_0x34.U(directionOf(mpPlayerActor));
}
}
f32 sp184;
f32 sp180 = globe.R() * 0.05f;
f32 r;
if (mpLockonTarget != NULL) {
f32 sp178 = ang3.Cos();
f32 sp174 = cSAngle(globe.V()).Cos();
if (sp178 < 0.0f) {
sp174 = -sp174;
}
f32 sp170 = std::fabs(sp178) < std::fabs(sp174) ? sp178 : sp174;
r = sp170 * (val4 < 0.5f ? val4 : 1.0f - val4);
sp184 = val4 * globe.R() - r * globe.R() * val1;
} else {
f32 sp16C = globe.R() * 0.5f;
sp184 = sp16C + sp16C * ang3.Cos();
}
cSAngle ang4 = globe.U();
lockon->field_0x58 += (val6 - lockon->field_0x58) * mCamSetup.CusCus();
lockon->field_0x54 += (val5 - lockon->field_0x54) * mCamSetup.CusCus();
cSAngle u, v;
cSAngle ang5 = globe.V() - lockon->field_0x34.V();
if (sp0C) {
r = lockon->field_0x34.R() * 0.75f * fabsf(ang5.Cos());
u.Val(lockon->field_0x34.U() + (ang4 - lockon->field_0x34.U()) * lockon->field_0x58);
v.Val(lockon->field_0x34.V() + ang5 * 0.05f);
} else {
r = lockon->field_0x34.R() + (sp184 - lockon->field_0x34.R()) *
lockon->field_0x54 * fabsf(ang5.Cos());
u.Val(lockon->field_0x34.U() + (ang4 - lockon->field_0x34.U()) * lockon->field_0x58);
v.Val(lockon->field_0x34.V() + ang5 * lockon->field_0x58);
}
lockon->field_0x34.Val(r, v, u);
mViewCache.mCenter = lockon->field_0x1c + lockon->field_0x34.Xyz();
dBgS_CamLinChk lin_chk;
if (mpLockonTarget != NULL && lineBGCheck(&attention_pos, &mViewCache.mCenter, &lin_chk, 0x40b7)) {
cXyz target_attention_pos = attentionPos(mpLockonTarget);
dBgS_CamLinChk lin_chk2;
int iVar5 = 0;
if (lineBGCheckBoth(&attention_pos, &mViewCache.mEye, &lin_chk2, 0x40b7)) {
iVar5 |= 1;
} else if (lineBGCheckBoth(&target_attention_pos, &mViewCache.mEye, &lin_chk2, 0x40b7)) {
iVar5 |= 2;
}
if (iVar5 != 0) {
cM3dGPla plane;
dComIfG_Bgsp().GetTriPla(lin_chk, &plane);
mViewCache.mCenter = lin_chk.GetCross();
mViewCache.mCenter += *plane.GetNP() * 5.0f;
if (fopAcM_GetName(mpLockonTarget) != fpcNm_E_HZ_e) {
ForceLockOff(mLockOnActorID);
}
}
}
cSGlobe globe2 = mViewCache.mEye - mViewCache.mCenter;
cSAngle u2 = mViewCache.mDirection.U();
cSAngle v2 = mViewCache.mDirection.V();
f32 r2 = mViewCache.mDirection.R();
f32 sp160;
cSAngle ang6 = ang3 - ang2;
curveWeight = mCamSetup.CurveWeight();
#if AVOID_UB
f32 sp15C = 0.0f;
#else
f32 sp15C;
#endif
f32 sp158 = mPadInfo.mCStick.mLastPosX;
if (mCamParam.Flag(param_0, 0x40)) {
sp158 = 0.0f;
}
if (mPadInfo.mCStick.mLastPosY > mCamSetup.mCStick.SwTHH()) {
if (mCStickUpLatch != 1) {
lockon->field_0x40 = false;
lockon->field_0x4c = 0.0f;
}
mCStickUpLatch = 1;
} else {
mCStickUpLatch = 0;
}
bool bVar3 = false;
if (fabsf(sp158) > 0.05f) {
cSAngle ang = globe2.U() + cSAngle(dCamMath::rationalBezierRatio(sp158, 0.5f) * 7.5f);
sp15C = fabsf(sp158) - 0.05f;
lockon->field_0x42 = ang;
lockon->field_0x4c = 0.0f;
bVar3 = true;
} else if (mCamParam.Flag(param_0, 0x100)) {
if (mCurMode == 0) {
lockon->field_0x40 = true;
cSAngle ang = globe2.U() - directionOf(mpPlayerActor);
lockon->field_0x42 = mViewCache.mDirection.U() +
(globe2.U() - mViewCache.mDirection.U()) * val22 * ang.Sin();
}
if (mCurMode != 2) {
ang1.Val(directionOf(mpPlayerActor));
}
} else if (lockon->field_0x40) {
sp15C = 1.0f;
lockon->field_0x4c = 1.0f;
} else {
lockon->field_0x40 = false;
lockon->field_0x4c += (1.0f - lockon->field_0x4c) * 0.01f;
}
if (lockon->field_0x40 || bVar3) {
u2 = globe2.U() + (lockon->field_0x42 - globe2.U()) * sp15C;
} else if (sp0C) {
cSAngle ang;
if (lockon->field_0x30 == 1) {
ang.Val(15.0f);
} else {
ang.Val(-15.0f);
}
u2 += ((globe.U().Inv() + ang) - u2) * 0.05f;
} else if (check_owner_action1(mPadID, 0x1200000)) {
u2 = globe2.U();
} else {
f32 sp154;
if (mpLockonTarget == NULL) {
sp15C = sp200 * sp194;
} else if (ang3 < ang2) {
sp154 = (f32)ang6.Val() / ang2.Val();
sp15C = val27 * dCamMath::rationalBezierRatio(-sp154, curveWeight);
} else {
cSAngle ang = ang2 + (cSAngle::_180 - ang2) * 0.5f;
if (ang6 > ang) {
ang6 = cSAngle::_180 - ang6;
ang = cSAngle::_180 - ang;
}
sp154 = (f32)ang6.Val() / ang.Val();
sp15C = val27 + (val22 - val27) * dCamMath::rationalBezierRatio(sp154, curveWeight);
}
if (!lockon->field_0x2a) {
f32 sp150;
int sp14C = lockon_change_timer >> 1;
if (mCurCamStyleTimer < sp14C) {
sp150 = (f32)mCurCamStyleTimer / sp14C;
sp15C = lockon_change_cushion * sp150;
} else {
sp150 = (f32)(mCurCamStyleTimer - sp14C) / sp14C;
sp15C = sp15C * sp150 + lockon_change_cushion * (1.0f - sp150);
}
}
ang6 = ang1.Inv() - mViewCache.mDirection.U();
if (fabsf(ang6.Degree()) < 2.0f && false) {
lockon->field_0x2a = true;
}
u2 += ang6 * sp15C * lockon->field_0x4c;
}
if (sp0E) {
cSAngle ang7 = ang1.Inv();
cSAngle ang8 = ang7 - u2;
if (ang8 < cSAngle::_270) {
u2 = ang7 - cSAngle::_270;
} else if (ang8 > cSAngle::_90) {
u2 = ang7 - cSAngle::_90;
}
}
if (isPlayerCharging(mPadID)) {
if (lockon->field_0xc <= 20) {
f32 tmp = lockon->field_0xc / 20.0f;
v2 += (charge_latitude - v2) * dCamMath::rationalBezierRatio(tmp, charge_b_ratio);
setFlag(0x4000000);
lockon->field_0xc++;
} else {
v2 = charge_latitude;
}
} else {
lockon->field_0xc = 0;
if (!mBG.field_0xc0.field_0x44 && !bVar1) {
v2 += (globe2.V() - v2) * fVar43 * fabsf(mViewCache.mDirection.V().Cos());
} else {
cSAngle ang7 = lockon->field_0x34.V();
ang7 *= cSAngle(lockon->field_0x34.U() - mViewCache.mDirection.U()).Cos();
ang7 *= val13;
cSAngle ang8 = rangef(val15, val16, sp1A0);
ang8 *= 1.0f - val13;
v2 += ((ang7 + ang8) - v2) * sp200 * sp194;
}
s16 val = v2.Val();
if (!mCamSetup.CheckLatitudeRange(&val)) {
v2.Val(val);
}
}
if (sp0C) {
r2 += (280.0f - r2) * 0.05f;
} else {
sp160 = globe2.R();
if (defaultRadius(val10, val11, &sp160)) {
r2 = sp160 + (rangef(val10, val11, sp1A0) - sp160) * 0.02f;
} else {
r2 += (sp160 - r2) * 0.4f * sp194;
}
}
mViewCache.mDirection.Val(r2, v2, u2);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy += (rangef(val20, val21, sp1A0) - mViewCache.mFovy) * 0.15f * sp194;
if (mpLockonTarget != NULL) {
setFlag(0x2000);
mpAuxTargetActor1 = mpLockonTarget;
if (attention->GetLockonCount() >= 2 && mCamParam.Flag(param_0, 0x1000)) {
mpAuxTargetActor2 = attention->LockonTarget(1);
}
}
if (player->checkHorseRide()) {
daHorse_c* horse = dComIfGp_getHorseActor();
if (horse != NULL && horse->getLashDashStart()) {
onHorseDush();
lockon->field_0x44 = 16;
} else if (lockon->field_0x44 != 0) {
lockon->field_0x44--;
}
}
return true;
}
fopAc_ac_c* dCamera_c::getMsgCmdSpeaker() {
dComIfG_MesgCamInfo_c* info = dComIfGp_getMesgCameraInfo();
fopAc_ac_c* actor = NULL;
int idx = 0;
char var_r28 = '\0';
int sp10 = 0;
if (info->mBasicID >= 1 && info->mBasicID <= 10) {
idx = info->mBasicID - 1;
actor = info->mActor[idx];
var_r28 = 'A';
}
if (info->mID >= 1 && info->mID <= 10) {
idx = info->mID - 1;
actor = info->mActor[idx];
var_r28 = 'T';
}
#if DEBUG
int sp0C;
if (mCamSetup.CheckFlag(0x8000)) {
if (actor != NULL) {
dDbVw_Report(20, 280, "ACT %c%02d", var_r28, var_r28 == 'a' ? idx + 1 : idx + 1);
}
}
#endif
return actor;
}
s32 dCamera_c::getMsgCmdCut(s32 param_0) {
dComIfG_MesgCamInfo_c* info = dComIfGp_getMesgCameraInfo();
s32 retval = param_0;
if (!(info->mBasicID >= 1 && info->mBasicID <= 10) && info->mBasicID > 0) {
retval = info->mBasicID;
}
if (!(info->mID >= 1 && info->mID <= 10) && info->mID > 0) {
retval = info->mID;
}
return retval;
}
bool dCamera_c::talktoCamera(s32 param_0) {
f32 val0 = mCamParam.Val(param_0, 0);
f32 val2 = mCamParam.Val(param_0, 2);
f32 val1 = mCamParam.Val(param_0, 1);
f32 val3 = mCamParam.Val(param_0, 3);
f32 val7 = mCamParam.Val(param_0, 7);
f32 val8 = mCamParam.Val(param_0, 8);
f32 val16 = mCamParam.Val(param_0, 16);
f32 val15 = mCamParam.Val(param_0, 15);
f32 val12 = mCamParam.Val(param_0, 12);
f32 val6 = mCamParam.Val(param_0, 6);
f32 val23 = mCamParam.Val(param_0, 23);
f32 val24 = mCamParam.Val(param_0, 24);
f32 val17 = mCamParam.Val(param_0, 17);
f32 val18 = mCamParam.Val(param_0, 18);
f32 sp480 = 300.0f;
s32 zero = 0;
fopAc_ac_c* listener;
fopAc_ac_c* speaker;
TalkData* talk = (TalkData*)mWork;
fopAc_ac_c* ride_actor = NULL;
bool sp5D = true;
daAlink_c* player = (daAlink_c*)mpPlayerActor;
int val;
if (mCurCamStyleTimer == 0) {
talk->field_0x0 = 'TALK';
talk->field_0x44 = 0;
talk->field_0x38 = -1;
talk->field_0x48 = 20;
talk->field_0x3c = zero;
talk->field_0x40 = -1;
talk->field_0x5c = 999.9f;
talk->field_0x60 = 999.9f;
talk->field_0x7c = 1.0f;
talk->field_0xb4 = cXyz::Zero;
talk->field_0x89 = false;
talk->field_0x88 = false;
talk->field_0x8c = mBumpCheckFlags;
mBumpCheckFlags &= ~0x8;
if (!dComIfGp_evmng_cameraPlay()) {
talk->field_0x84 = 0;
talk->field_0x86 = 0;
talk->field_0x54 = val7;
talk->field_0x64 = val8;
talk->field_0x58 = talk->field_0x68 = val17;
talk->field_0x6c = val18;
talk->field_0x70 = mpPlayerActor;
talk->field_0x74 = mpLockonTarget;
} else {
getEvIntData(&val, "Smoothless", 0);
talk->field_0x84 = val;
getEvIntData(&val, "Mode", 0);
talk->field_0x86 = val;
if (getEvFloatData(&talk->field_0x54, "Radius", val7)) {
getEvFloatData(&talk->field_0x64, "RadiusNear", talk->field_0x54);
} else {
getEvFloatData(&talk->field_0x64, "RadiusNear", val8);
}
getEvFloatData(&talk->field_0x5c, "Longitude", 999.9f);
if (getEvFloatData(&talk->field_0x68, "Fovy", val17)) {
getEvFloatData(&talk->field_0x6c, "FovyNear", talk->field_0x68);
} else {
getEvFloatData(&talk->field_0x6c, "FovyNear", val18);
}
talk->field_0x58 = talk->field_0x68;
getEvFloatData(&talk->field_0x60, "Latitude", 999.9f);
talk->field_0x70 = getEvActor("Listener", "@STARTER");
talk->field_0x74 = getEvActor("Speaker", "@TALKPARTNER");
}
talk->field_0x78 = talk->field_0x74;
talk->field_0x80 = val2;
}
fopAc_ac_c* msg_speaker_sp464 = getMsgCmdSpeaker();
if (msg_speaker_sp464 != NULL) {
listener = talk->field_0x70;
speaker = msg_speaker_sp464;
} else if (dComIfGp_evmng_cameraPlay()) {
listener = talk->field_0x70;
speaker = talk->field_0x74;
} else {
listener = mpPlayerActor;
speaker = mpLockonTarget;
}
#if DEBUG
JUT_ASSERT(7287, listener != speaker);
#else
if (listener == speaker) {
speaker = NULL;
}
#endif
if (listener == NULL || speaker == NULL) {
mStyleSettle.mFinished = true;
return false;
}
if (talk->field_0x78 != speaker) {
mCurCamStyleTimer = 0;
mStyleSettle.mFinished = false;
#if DEBUG
char name1[16];
char name2[16];
fopAcM_getNameString(talk->field_0x78, name1);
fopAcM_getNameString(speaker, name2);
OS_REPORT("camera: speaker change %s -> %s\n", name1, name2);
#endif
talk->field_0x44 = 0;
talk->field_0x78 = speaker;
}
bool sp5C = false;
if (fopAcM_GetName(speaker) == fpcNm_NI_e || fopAcM_GetName(speaker) == fpcNm_BD_e
|| fopAcM_GetName(speaker) == fpcNm_SQ_e || fopAcM_GetName(speaker) == fpcNm_FR_e
|| fopAcM_GetName(speaker) == fpcNm_DO_e || fopAcM_GetName(speaker) == fpcNm_NPC_NE_e)
{
sp5C = true;
talk->field_0x54 = 260.0f;
talk->field_0x64 = 210.0f;
talk->field_0x58 = talk->field_0x68 = 45.0f;
talk->field_0x6c = 48.0f;
val24 = 80.0f;
val23 = 40.0f;
}
if (fopAcM_GetName(speaker) == fpcNm_Tag_Mwait_e) {
daTagMwait_c* tagMwait = (daTagMwait_c*)speaker;
if (tagMwait->checkEndMessage()) {
talk->field_0x3c = 35;
speaker = daPy_py_c::getMidnaActor();
}
}
if (talk->field_0x86 != 0) {
talk->field_0x3c = talk->field_0x86;
}
talk->field_0x3c = getMsgCmdCut(talk->field_0x3c);
#if DEBUG
if (mCamSetup.ModeSwitchType() > 0) {
talk->field_0x3c = mCamSetup.ModeSwitchType();
}
if (mCamSetup.CheckFlag(0x8000)) {
char name[16];
int x = 20;
int y = 190;
fopAcM_getNameString(speaker, name);
dDbVw_Report(x, y + 75, "%s", name);
dDbVw_Report(x + 70, y, "CUT%02d", talk->field_0x3c);
}
if (mCamSetup.CheckFlag(0x100)) {
cXyz speakerAttnPos = attentionPos(speaker);
cXyz listenerAttnPos = attentionPos(listener);
debugDrawPoint(speakerAttnPos);
debugDrawPoint(listenerAttnPos);
debugDrawLine(speakerAttnPos, listenerAttnPos);
}
#endif
if (talk->field_0x3c != talk->field_0x40) {
OS_REPORT("%06d: talk cut change %d \n", mFrameCounter, talk->field_0x3c);
talk->field_0x44 = 0;
talk->field_0x40 = talk->field_0x3c;
}
cSAngle sp298 = val16;
cSAngle sp294 = val15;
cSAngle sp290 = val24;
cSAngle sp28C = val23;
if (mCurCamStyleTimer == 0) {
cSAngle sp288;
cXyz sp15BC;
cSGlobe sp540 = positionOf(speaker) - positionOf(listener);
cXyz sp15B0;
cXyz sp15A4;
if (mCamParam.Flag(param_0, 0x400) || player->checkCanoeRide()
|| player->checkHorseRide() || check_owner_action(mPadID, 0x100000))
{
sp15B0 = attentionPos(listener);
sp15A4 = attentionPos(speaker);
if (player->checkCanoeRide() && listener == mpPlayerActor) {
sp15B0.y += 40.0f;
}
} else {
sp15BC = attentionPos(listener) - positionOf(listener);
sp288.Val(sp540.U() - directionOf(listener));
sp15B0 = positionOf(listener) + dCamMath::xyzRotateY(sp15BC, sp288);
sp15BC = attentionPos(speaker) - positionOf(speaker);
sp288.Val(sp540.U().Inv() - directionOf(speaker));
sp15A4 = positionOf(speaker) + dCamMath::xyzRotateY(sp15BC, sp288);
}
if (mIsWolf == 1) {
if (listener == mpPlayerActor) {
sp15B0.y += 80.0f;
}
if (speaker == mpPlayerActor) {
sp15A4.y += 80.0f;
}
}
talk->field_0x28 = mViewCache.mDirection;
talk->field_0xb4 = sp15B0 - sp15A4;
talk->field_0x30.Val(talk->field_0xb4);
talk->field_0xb4.normalize();
sp15B0 += talk->field_0xb4 * listener->attention_info.field_0xa;
sp15A4 -= talk->field_0xb4 * speaker->attention_info.field_0xa;
if (talk->field_0x30.R() < 88.0f) {
talk->field_0x30.R(88.0f);
}
f32 sp454 = dCamMath::xyzHorizontalDistance(sp15B0, sp15A4);
f32 sp450 = sp454 - 88.0f;
sp480 -= 88.0f;
talk->field_0x7c = sp450 > sp480 ? 1.0f : sp450 / sp480;
talk->field_0x80 = val3 + (val2 - val3) * talk->field_0x7c;
cXyz stack_160(val0, talk->field_0x80, val1);
f32 sp44C = talk->field_0x64 + (talk->field_0x54 - talk->field_0x64) * talk->field_0x7c;
if (sp44C < sp454) {
sp44C = sp454;
}
talk->field_0x28.R(sp44C);
if (talk->field_0x84 != 0) {
talk->field_0x48 = 1;
} else {
talk->field_0x48 = (int)(JMAFastSqrt(fabsf(mViewCache.mDirection.R() - talk->field_0x28.R())) / 2.0f);
if (talk->field_0x48 < 2) {
talk->field_0x48 = 2;
}
if (talk->field_0x48 > 22) {
talk->field_0x48 = 22;
}
talk->field_0x48 += 8;
}
cSAngle sp284;
cSAngle sp280;
if (talk->field_0x5c >= -180.0f && talk->field_0x5c <= 360.0f) {
sp284.Val(talk->field_0x5c);
sp280 = sp284 - talk->field_0x30.U();
talk->field_0x28.U(sp284);
} else if (fopAcM_GetName(speaker) == fpcNm_OBJ_KANBAN2_e
|| fopAcM_GetName(speaker) == fpcNm_TAG_KMSG_e
|| fopAcM_GetName(speaker) == fpcNm_KNOB20_e
|| fopAcM_GetName(speaker) == fpcNm_Obj_NamePlate_e) {
sp284.Val(directionOf(speaker));
sp280 = sp284 - talk->field_0x30.U();
talk->field_0x28.U(sp284);
} else {
sp284.Val(mViewCache.mDirection.U());
sp280 = sp284 - talk->field_0x30.U();
if (sp280 > cSAngle::_90) {
sp280 = cSAngle::_90 - (sp280 - cSAngle::_90);
}
if (sp280 < cSAngle::_270) {
sp280 = cSAngle::_270 - (sp280 - cSAngle::_270);
}
if (sp280 > sp290) {
sp280 = sp290;
}
if (sp280 > cSAngle::_0 && sp280 < sp28C) {
sp280 = sp28C;
}
if (sp280 < -sp290) {
sp280 = -sp290;
}
if (sp280 < cSAngle::_0 && sp280 > -sp28C) {
sp280 = -sp28C;
}
talk->field_0x28.U(talk->field_0x30.U() + sp280);
}
fopAc_ac_c* sp448 = listener;
fopAc_ac_c* sp444 = speaker;
f32 sp440 = 0.25f;
{
cSAngle sp27C = talk->field_0x28.U();
cXyz sp158C = sp15B0;
cXyz sp1580 = sp15A4;
cXyz sp1574 = sp1580 - sp158C;
cSGlobe sp538 = sp1574;
sp1574.normalize();
sp158C -= sp1574 * listener->attention_info.field_0xa;
sp1580 += sp1574 * sp444->attention_info.field_0xa;
cXyz sp1568;
cXyz sp15CC = sp1580 - sp158C;
if (lineBGCheck(&sp158C, &sp1580, &sp1568, 0x40b7)) {
sp1580 = sp1568 - sp15CC.norm() * 10.0f;
sp15CC = sp1580 - sp158C;
}
cXyz sp1550 = sp158C + sp15CC * 0.5f;
cXyz sp1544 = stack_160;
cSAngle sp278 = sp27C - sp538.U();
if (sp278 < cSAngle::_0) {
sp1544.x = -sp1544.x;
}
cSGlobe sp530 = sp1544;
sp530.U(sp538.U() + sp530.U());
sp538.R(sp538.R() * 0.5f * sp278.Cos() * sp440);
talk->field_0x4 = sp1550 + sp538.Xyz() + sp530.Xyz();
talk->field_0xc0 = sp1580;
}
cSAngle sp274;
if (talk->field_0x60 != 999.9f) {
sp274.Val(talk->field_0x60);
} else {
sp274 = talk->field_0x30.V() * (sp280.Cos() + 0.1f) * val6 + cSAngle(val12);
if (sp274 > sp298) {
sp274 = sp298;
}
if (sp274 < sp294) {
sp274 = sp294;
}
}
talk->field_0x28.V(sp274);
cSAngle sp270;
if (player->checkRide()) {
ride_actor = player->getRideActor();
}
if (talk->field_0x30.U() - talk->field_0x28.U() > cSAngle::_0) {
sp270 = cSAngle(10.0f);
} else {
sp270 = cSAngle(-10.0f);
}
talk->field_0x10 = talk->field_0x4 + talk->field_0x28.Xyz();
talk->field_0x58 = talk->field_0x6c + (talk->field_0x68 - talk->field_0x6c) * talk->field_0x7c;
bool sp5B = false;
int i = 0;
if (fopAcM_GetName(speaker) == fpcNm_MIDNA_e && mMidnaRidingAndVisible) {
talk->field_0x4 = attentionPos(speaker);
talk->field_0x4.y -= 35.0f;
f32 fVar36 = talk->field_0x30.U() - talk->field_0x28.U() > cSAngle::_0 ? -40.0f : 40.0f;
talk->field_0x28.U(cSAngle(fVar36) + directionOf(listener));
talk->field_0x28.V(cSAngle(10.0f));
talk->field_0x28.R(200.0f);
talk->field_0x10 = talk->field_0x4 + talk->field_0x28.Xyz();
talk->field_0x48 = 16;
talk->field_0x58 = 55.0f;
talk->field_0x88 = true;
sp5B = true;
}
if (sp5C) {
talk->field_0x4.y = attentionPos(speaker).y - 10.0f;
}
if (mCamParam.Flag(param_0, 0x100)) {
talk->field_0x28.U(mViewCache.mDirection.U());
}
cSAngle sp26C;
bool sp5A = false;
cXyz sp1538 = cXyz::Zero;
for (i = 0; i < 36; i++) {
sp26C = talk->field_0x28.U() - talk->field_0x30.U();
if (fabsf(sp26C.Degree()) < 10.0f) {
talk->field_0x28.U(talk->field_0x28.U() + sp270);
} else {
if (!sp5B) {
f32 radius = radiusActorInSight(listener, speaker, &talk->field_0x4,
&talk->field_0x10, talk->field_0x58,
0, 0.1f);
if (radius > 0.0f) {
talk->field_0x28.R(talk->field_0x28.R() + radius);
talk->field_0x10 = talk->field_0x4 + talk->field_0x28.Xyz();
}
}
if (!lineBGCheck(&sp15B0, &talk->field_0x10, talk->field_0x8c)
&& !lineBGCheck(&talk->field_0x4, &talk->field_0x10, talk->field_0x8c)
&& !lineCollisionCheck(sp15B0, talk->field_0x10, listener, speaker, ride_actor))
{
if (!lineBGCheck(&sp15A4, &talk->field_0x10, talk->field_0x8c)
&& !lineCollisionCheck(sp15A4, talk->field_0x10, listener, speaker, ride_actor))
{
sp5A = true;
break;
}
sp1538 = talk->field_0x10;
}
talk->field_0x28.U(talk->field_0x28.U() + sp270);
if (talk->field_0x60 != 999.9f) {
sp274.Val(talk->field_0x60);
} else {
sp274 = talk->field_0x30.V()
* (cSAngle(talk->field_0x30.U() - talk->field_0x28.U()).Cos() + 0.1f)
* val6 + cSAngle(val12);
if (sp274 > sp298) {
sp274 = sp298;
}
if (sp274 < sp294) {
sp274 = sp294;
}
}
talk->field_0x28.V(sp274);
if (!talk->field_0x88) {
talk->field_0x4 = relationalPos2(listener, speaker, &stack_160, 0.25f,
talk->field_0x28.U());
}
talk->field_0x10 = talk->field_0x4 + talk->field_0x28.Xyz();
}
}
if (!sp5A) {
sp1538.set(0.0f, 15.0f, -20.0f);
talk->field_0x4 = relationalPos(mpPlayerActor, &sp1538);
sp1538.set(60.0f, 70.0f, -200.0f);
talk->field_0x10 = relationalPos(mpPlayerActor, &sp1538);
talk->field_0x28.Val(talk->field_0x10 - talk->field_0x4);
}
talk->field_0xcc = sp15B0;
talk->field_0xd8 = sp15A4;
talk->field_0x4c = talk->field_0x48 * (talk->field_0x48 + 1) >> 1;
if (talk->field_0x38 == -1) {
if (talk->field_0x30.U() - talk->field_0x28.U() > cSAngle::_0) {
talk->field_0x38 = 0;
} else {
talk->field_0x38 = 1;
}
}
}
if ((fopAcM_GetName(speaker) == fpcNm_Tag_Mhint_e && ((daTagMhint_c*)speaker)->checkNoAttention())
|| (fopAcM_GetName(speaker) == fpcNm_Tag_Mstop_e && ((daTagMstop_c*)speaker)->checkNoAttention()))
{
bool sp59 = false;
if (mIsWolf == 1 && check_owner_action(mPadID, 0x100000)) {
sp59 = true;
}
if (mCurCamStyleTimer == 0) {
if (!sp59) {
talk->field_0x28.U(cSAngle(15.0f) + directionOf(listener));
talk->field_0x28.V(cSAngle(5.0f));
talk->field_0x28.R(140.0f);
} else {
talk->field_0x28.U(cSAngle(30.0f) + directionOf(listener));
talk->field_0x28.V(cSAngle(25.0f));
talk->field_0x28.R(180.0f);
}
talk->field_0x10 = talk->field_0x4 + talk->field_0x28.Xyz();
talk->field_0x48 = 16;
talk->field_0x58 = 55.0f;
}
talk->field_0x4 = positionOf(listener);
if (!sp59) {
talk->field_0x4.y += 110.0f;
} else {
talk->field_0x4.y += 10.0f;
}
}
cXyz sp152C = cXyz::Zero;
bool sp58 = false;
if (is_player(listener) && mIsWolf == 1) {
cXyz sp1520(0.0f, 0.0f, 45.0f);
sp152C = dCamMath::xyzRotateY(sp1520, directionOf(listener));
sp58 = true;
}
cXyz sp1514;
cXyz sp1508;
cXyz sp14FC;
cXyz sp14F0;
int sp430 = talk->field_0x3c;
switch (sp430) {
case 0:
break;
case 50:
talk->field_0x48 = 1;
talk->field_0x4c = 1.0f;
sp430 = 0;
break;
case 20:
case 21:
case 62: {
fopAc_ac_c* actor1_sp42C;
fopAc_ac_c* actor2_sp428;
if (sp430 != 20) {
actor1_sp42C = speaker;
actor2_sp428 = listener;
sp1514 = talkEyePos(actor2_sp428);
sp1508 = talkEyePos(actor1_sp42C);
sp14FC = talkBasePos(actor2_sp428);
sp14F0 = talkBasePos(actor1_sp42C);
if (sp5C) {
sp1508.y = attentionPos(speaker).y;
}
if (fopAcM_GetName(speaker) == fpcNm_NPC_KKRI_e) {
sp1508.y = attentionPos(speaker).y - 40.0f;
}
if (sp58) {
sp14FC += sp152C;
}
} else {
actor1_sp42C = listener;
actor2_sp428 = speaker;
sp1514 = talkEyePos(actor2_sp428);
sp1508 = talkEyePos(actor1_sp42C);
sp14FC = talkBasePos(actor2_sp428);
sp14F0 = talkBasePos(actor1_sp42C);
if (sp5C) {
sp1514.y = attentionPos(speaker).y;
}
if (sp58) {
sp14F0 += sp152C;
}
}
mViewCache.mCenter = sp14F0;
if (talk->field_0x44 == 0) {
cXyz sp14E4 = sp14FC;
sp14E4.y = sp1514.y;
cXyz sp14D8 = sp14F0;
sp14D8.y = sp1508.y;
mViewCache.mDirection.Val(sp14E4 - sp14D8);
if (sp430 == 62) {
mViewCache.mDirection.U(directionOf(speaker));
}
mViewCache.mDirection.R(125.0f);
talk->field_0x1c.y = sp1508.y - 25.0f - sp14F0.y;
mStyleSettle.mFinished = true;
}
mViewCache.mCenter.y = sp14F0.y + talk->field_0x1c.y;
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = 60.0f;
hideActor(actor2_sp428);
break;
}
case 39:
case 40:
case 64: {
fopAc_ac_c* actor1_sp424;
fopAc_ac_c* actor2_sp420;
if (sp430 != 39) {
actor1_sp424 = speaker;
actor2_sp420 = listener;
} else {
actor1_sp424 = listener;
actor2_sp420 = speaker;
}
if (talk->field_0x44 == 0) {
if (sp430 != 39) {
sp1514 = talkEyePos(actor2_sp420);
sp1508 = talkEyePos(actor1_sp424);
sp14FC = talkBasePos(actor2_sp420);
sp14F0 = talkBasePos(actor1_sp424);
if (sp5C) {
sp1508.y = attentionPos(speaker).y;
}
if (sp58) {
sp14FC += sp152C;
}
} else {
sp1514 = talkEyePos(actor2_sp420);
sp1508 = talkEyePos(actor1_sp424);
sp14FC = talkBasePos(actor2_sp420);
sp14F0 = talkBasePos(actor1_sp424);
if (sp5C) {
sp1514.y = attentionPos(speaker).y;
}
if (sp58) {
sp14F0 += sp152C;
}
}
mViewCache.mCenter = sp14F0;
cXyz sp14CC = sp14FC;
sp14CC.y = sp1514.y;
cXyz sp14C0 = sp14F0;
sp14C0.y = sp1508.y;
mViewCache.mDirection.Val(sp14CC - sp14C0);
if (sp430 == 64) {
mViewCache.mDirection.U(directionOf(speaker));
}
mViewCache.mDirection.R(125.0f);
mViewCache.mDirection.V(cSAngle(35.0f));
talk->field_0x1c.y = sp1508.y - 25.0f - sp14F0.y;
mStyleSettle.mFinished = true;
mViewCache.mCenter.y = sp14F0.y + talk->field_0x1c.y;
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = 60.0f;
}
hideActor(actor2_sp420);
break;
}
case 16:
case 17:
case 61: {
fopAc_ac_c* actor1_sp41C;
fopAc_ac_c* actor2_sp418;
if (sp430 != 16) {
actor1_sp41C = speaker;
actor2_sp418 = listener;
sp1514 = talkEyePos(actor2_sp418);
sp1508 = talkEyePos(actor1_sp41C);
sp14FC = talkBasePos(actor2_sp418);
sp14F0 = talkBasePos(actor1_sp41C);
if (sp5C) {
sp1508.y = attentionPos(speaker).y;
}
if (sp58) {
sp14FC += sp152C;
}
} else {
actor1_sp41C = listener;
actor2_sp418 = speaker;
sp1514 = talkEyePos(actor2_sp418);
sp1508 = talkEyePos(actor1_sp41C);
sp14FC = talkBasePos(actor2_sp418);
sp14F0 = talkBasePos(actor1_sp41C);
if (sp5C) {
sp1514.y = attentionPos(speaker).y;
}
if (sp58) {
sp14F0 += sp152C;
}
}
mViewCache.mCenter = sp14F0;
if (talk->field_0x44 == 0) {
cXyz sp14B4 = sp14FC;
sp14B4.y = sp1514.y;
cXyz sp14A8 = sp14F0;
sp14A8.y = sp1508.y;
mViewCache.mDirection.Val(sp14B4 - sp14A8);
if (sp430 == 61) {
mViewCache.mDirection.U(directionOf(speaker));
}
mViewCache.mDirection.R(76.0f);
talk->field_0x1c.y = sp1508.y - 10.0f - sp14F0.y;
mStyleSettle.mFinished = true;
}
mViewCache.mCenter.y = sp14F0.y + talk->field_0x1c.y;
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = 50.0f;
hideActor(actor2_sp418);
break;
}
case 22:
case 23:
case 63: {
fopAc_ac_c* actor1_sp414;
fopAc_ac_c* actor2_sp410;
if (sp430 != 22) {
actor1_sp414 = speaker;
actor2_sp410 = listener;
sp1514 = talkEyePos(actor2_sp410);
sp1508 = talkEyePos(actor1_sp414);
sp14FC = talkBasePos(actor2_sp410);
sp14F0 = talkBasePos(actor1_sp414);
if (sp5C) {
sp1508.y = attentionPos(speaker).y;
}
if (sp58) {
sp14FC += sp152C;
}
} else {
actor1_sp414 = listener;
actor2_sp410 = speaker;
sp1514 = talkEyePos(actor2_sp410);
sp1508 = talkEyePos(actor1_sp414);
sp14FC = talkBasePos(actor2_sp410);
sp14F0 = talkBasePos(actor1_sp414);
if (sp5C) {
sp1514.y = attentionPos(speaker).y;
}
if (sp58) {
sp14F0 += sp152C;
}
}
mViewCache.mCenter = sp14F0;
if (talk->field_0x44 == 0) {
cXyz sp149C = sp14FC;
sp149C.y = sp1514.y;
cXyz sp1490 = sp1508;
sp1490.y = sp1508.y;
mViewCache.mDirection.Val(sp149C - sp1490);
if (sp430 == 63) {
mViewCache.mDirection.U(directionOf(speaker));
}
mViewCache.mDirection.R(125.0f);
talk->field_0x1c.y = sp1508.y - 15.0f - sp14F0.y;
mStyleSettle.mFinished = true;
}
mViewCache.mCenter.y = sp14F0.y + talk->field_0x1c.y;
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = 45.0f;
hideActor(actor2_sp410);
break;
}
case 41:
case 42:
case 65: {
fopAc_ac_c* actor1_sp40C;
fopAc_ac_c* actor2_sp408;
if (sp430 != 41) {
actor1_sp40C = speaker;
actor2_sp408 = listener;
sp1514 = talkEyePos(actor2_sp408);
sp1508 = talkEyePos(actor1_sp40C);
sp14FC = talkBasePos(actor2_sp408);
sp14F0 = talkBasePos(actor1_sp40C);
if (sp5C) {
sp1508.y = attentionPos(speaker).y;
}
if (sp58) {
sp14FC += sp152C;
}
} else {
actor1_sp40C = listener;
actor2_sp408 = speaker;
sp1514 = talkEyePos(actor2_sp408);
sp1508 = talkEyePos(actor1_sp40C);
sp14FC = talkBasePos(actor2_sp408);
sp14F0 = talkBasePos(actor1_sp40C);
if (sp5C) {
sp1514.y = attentionPos(speaker).y;
}
if (sp58) {
sp14F0 += sp152C;
}
}
talk->field_0x90 = sp14F0;
if (talk->field_0x44 == 0) {
cXyz sp1484 = sp14FC;
sp1484.y = sp1514.y;
cXyz sp1478 = sp1508;
sp1478.y = sp1508.y;
talk->field_0xa8.Val(sp1484 - sp1478);
talk->field_0xa8.R(190.0f);
if (sp430 == 0x41) {
talk->field_0xa8.U(directionOf(speaker));
}
talk->field_0x1c.y = sp1508.y - 40.0f - sp14F0.y;
mStyleSettle.mFinished = true;
}
talk->field_0x90.y = sp14F0.y + talk->field_0x1c.y;
talk->field_0x9c = talk->field_0x90 + talk->field_0xa8.Xyz();
talk->field_0xb0 = 45.0f;
cXyz sp146C = attentionPos(actor1_sp40C);
if (lineBGCheck(&sp146C, &talk->field_0x9c, talk->field_0x8c)
|| lineCollisionCheck(sp146C, talk->field_0x9c, listener, speaker, NULL))
{
sp430 = 0;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, "-----");
}
#endif
} else {
mViewCache.mCenter = talk->field_0x90;
mViewCache.mEye = talk->field_0x9c;
mViewCache.mDirection = talk->field_0xa8;
mViewCache.mFovy = talk->field_0xb0;
hideActor(actor2_sp408);
}
break;
}
case 14:
case 15: {
fopAc_ac_c* actor1_sp404;
fopAc_ac_c* actor2_sp400;
if (sp430 == 14) {
actor1_sp404 = speaker;
actor2_sp400 = listener;
sp1514 = talkEyePos(actor2_sp400);
sp1508 = talkEyePos(actor1_sp404);
cSGlobe sp528 = talk->field_0x30;
sp14FC = talkBasePos(actor2_sp400);
sp14F0 = talkBasePos(actor1_sp404);
if (sp5C) {
sp1508.y = attentionPos(speaker).y;
}
if (sp58) {
sp14FC += sp152C;
}
} else {
actor1_sp404 = listener;
actor2_sp400 = speaker;
sp1514 = talkEyePos(actor2_sp400);
sp1508 = talkEyePos(actor1_sp404);
sp14FC = talkBasePos(actor2_sp400);
sp14F0 = talkBasePos(actor1_sp404);
if (sp5C) {
sp1514.y = attentionPos(speaker).y;
}
if (sp58) {
sp14F0 += sp152C;
}
}
mViewCache.mCenter = sp14F0;
mViewCache.mCenter.y = sp1508.y - 10.0f - talk->field_0x7c * 10.0f;
if (talk->field_0x44 == 0) {
mViewCache.mDirection.Val(sp1514 - sp1508);
mViewCache.mDirection.R(mViewCache.mDirection.R() - 5.0f);
mStyleSettle.mFinished = true;
}
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
f32 sp3FC = 85.0f;
f32 sp3F8 = 35.0f;
mViewCache.mFovy = sp3FC + (sp3F8 - sp3FC) * talk->field_0x7c;
cXyz sp404 = attentionPos(actor1_sp404);
hideActor(actor2_sp400);
break;
}
case 18:
case 19: {
fopAc_ac_c* actor1_sp3F4;
fopAc_ac_c* actor2_sp3F0;
int sp3EC;
if (sp430 == 18) {
actor1_sp3F4 = listener;
actor2_sp3F0 = speaker;
sp3EC = talk->field_0x38;
sp1514 = talkEyePos(actor2_sp3F0);
sp1508 = talkEyePos(actor1_sp3F4);
sp14FC = talkBasePos(actor2_sp3F0);
sp14F0 = talkBasePos(actor1_sp3F4);
if (sp5C) {
sp1514.y = attentionPos(speaker).y;
}
if (sp58) {
sp14F0 += sp152C;
}
} else {
actor1_sp3F4 = speaker;
actor2_sp3F0 = listener;
sp3EC = talk->field_0x38 ? 0 : 1;
sp1514 = talkEyePos(actor2_sp3F0);
sp1508 = talkEyePos(actor1_sp3F4);
sp14FC = talkBasePos(actor2_sp3F0);
sp14F0 = talkBasePos(actor1_sp3F4);
if (sp5C) {
sp1508.y = attentionPos(speaker).y;
}
if (sp58) {
sp14FC += sp152C;
}
}
if (talk->field_0x44 == 0) {
mStyleSettle.mFinished = true;
cXyz sp1454(0.0f, -15.0f, 15.0f);
cSGlobe sp520 = sp1514 - attentionPos(actor1_sp3F4);
cSGlobe sp518 = sp1454;
sp518.U(sp518.U() + sp520.U());
talk->field_0x1c = sp14F0 + sp518.Xyz();
talk->field_0x1c.y += sp1508.y - sp14F0.y;
cSAngle sp268 = sp3EC ? -80.0f : 75.0f;
talk->field_0x90 = talk->field_0x1c;
talk->field_0xa8.Val(120.0f, cSAngle::_0, sp268 + directionOf(actor1_sp3F4));
}
talk->field_0x9c = talk->field_0x90 + talk->field_0xa8.Xyz();
talk->field_0xb0 = 50.0f;
cXyz sp1448 = attentionPos(actor1_sp3F4);
if (lineBGCheck(&sp1448, &talk->field_0x9c, talk->field_0x8c)
|| lineCollisionCheck(sp1448, talk->field_0x9c, listener, speaker, NULL))
{
sp430 = 0;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, "-----");
}
#endif
} else {
mViewCache.mCenter = talk->field_0x90;
mViewCache.mEye = talk->field_0x9c;
mViewCache.mDirection = talk->field_0xa8;
mViewCache.mFovy = talk->field_0xb0;
}
break;
}
case 24:
case 25: {
fopAc_ac_c* actor1_sp3E8;
fopAc_ac_c* actor2_sp3E4;
int sp3E0;
if (sp430 == 24) {
actor1_sp3E8 = listener;
actor2_sp3E4 = speaker;
sp3E0 = talk->field_0x38;
sp1514 = talkEyePos(actor2_sp3E4);
sp1508 = talkEyePos(actor1_sp3E8);
sp14FC = talkBasePos(actor2_sp3E4);
sp14F0 = talkBasePos(actor1_sp3E8);
if (sp5C) {
sp1514.y = attentionPos(speaker).y;
}
if (sp58) {
sp14F0 += sp152C;
}
} else {
actor1_sp3E8 = speaker;
actor2_sp3E4 = listener;
sp3E0 = talk->field_0x38 ? 0 : 1;
sp1514 = talkEyePos(actor2_sp3E4);
sp1508 = talkEyePos(actor1_sp3E8);
sp14FC = talkBasePos(actor2_sp3E4);
sp14F0 = talkBasePos(actor1_sp3E8);
if (sp5C) {
sp1508.y = attentionPos(speaker).y;
}
if (sp58) {
sp14FC += sp152C;
}
}
if (talk->field_0x44 == 0) {
mStyleSettle.mFinished = true;
cXyz sp143C(0.0f, -10.0f, 20.0f);
cSGlobe sp510 = sp1514 - attentionPos(actor1_sp3E8);
cSGlobe sp508 = sp143C;
sp508.U(sp508.U() + sp510.U());
talk->field_0x1c = sp1508 + sp508.Xyz();
cSAngle sp264 = sp3E0 ? -45.0f : 45.0f;
talk->field_0x90 = talk->field_0x1c;
talk->field_0xa8.Val(120.0f, cSAngle(25.0f), sp264 + directionOf(actor1_sp3E8));
}
talk->field_0x9c = talk->field_0x90 + talk->field_0xa8.Xyz();
talk->field_0xb0 = 45.0f;
cXyz sp3E8 = attentionPos(actor1_sp3E8);
if (lineBGCheck(&sp3E8, &talk->field_0x9c, talk->field_0x8c)
|| lineCollisionCheck(sp3E8, talk->field_0x9c, listener, speaker, NULL))
{
sp430 = 0;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, "-----");
}
#endif
} else {
mViewCache.mCenter = talk->field_0x90;
mViewCache.mEye = talk->field_0x9c;
mViewCache.mDirection = talk->field_0xa8;
mViewCache.mFovy = talk->field_0xb0;
}
break;
}
case 26:
case 27: {
fopAc_ac_c* actor1_sp3DC;
fopAc_ac_c* actor2_sp3D8;
int sp3D4;
if (sp430 != 26) {
actor1_sp3DC = listener;
actor2_sp3D8 = speaker;
sp3D4 = talk->field_0x38;
sp1514 = talkEyePos(actor2_sp3D8);
sp1508 = talkEyePos(actor1_sp3DC);
sp14FC = talkBasePos(actor2_sp3D8);
sp14F0 = talkBasePos(actor1_sp3DC);
if (sp5C) {
sp1514.y = attentionPos(speaker).y;
}
if (sp58) {
sp14F0 += sp152C;
}
} else {
actor1_sp3DC = speaker;
actor2_sp3D8 = listener;
sp3D4 = talk->field_0x38 ? 0 : 1;
sp1514 = talkEyePos(actor2_sp3D8);
sp1508 = talkEyePos(actor1_sp3DC);
sp14FC = talkBasePos(actor2_sp3D8);
sp14F0 = talkBasePos(actor1_sp3DC);
if (sp5C) {
sp1508.y = attentionPos(speaker).y;
}
if (sp58) {
sp14FC += sp152C;
}
}
if (talk->field_0x44 == 0) {
mStyleSettle.mFinished = true;
cXyz sp1424(0.0f, -30.0f, 20.0f);
if (sp5C && sp430 == 27) {
sp1424.y = -5.0f;
}
cSGlobe sp500 = attentionPos(actor2_sp3D8) - attentionPos(actor1_sp3DC);
cSGlobe sp4F8 = sp1424;
sp4F8.U(sp4F8.U() + sp500.U());
talk->field_0x1c = sp1508 + sp4F8.Xyz();
cSAngle sp260 = sp3D4 ? -30.0f : 35.0f;
cSAngle sp25C = sp5C ? 0.0f : -35.0f;
talk->field_0x90 = talk->field_0x1c;
talk->field_0xa8.Val(90.0f, cSAngle(-35.0f), sp260 + directionOf(actor1_sp3DC));
}
talk->field_0x9c = talk->field_0x90 + talk->field_0xa8.Xyz();
talk->field_0xb0 = 55.0f;
cXyz sp1418 = attentionPos(actor1_sp3DC);
if (lineBGCheck(&sp1418, &talk->field_0x9c, talk->field_0x8c)
|| lineCollisionCheck(sp1418, talk->field_0x9c, listener, speaker, NULL))
{
sp430 = 0;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, "-----");
}
#endif
} else {
mViewCache.mCenter = talk->field_0x90;
mViewCache.mEye = talk->field_0x9c;
mViewCache.mDirection = talk->field_0xa8;
mViewCache.mFovy = talk->field_0xb0;
}
break;
}
case 11:
case 12:
case 30:
case 31: {
fopAc_ac_c* actor1_sp3D0;
fopAc_ac_c* actor2_sp3CC;
int sp3C8;
if (sp430 != 11 && sp430 != 30) {
actor1_sp3D0 = speaker;
actor2_sp3CC = listener;
sp3C8 = talk->field_0x38;
sp1514 = talkEyePos(actor2_sp3CC);
sp1508 = talkEyePos(actor1_sp3D0);
sp14FC = talkBasePos(actor2_sp3CC);
sp14F0 = talkBasePos(actor1_sp3D0);
if (sp5C) {
sp1508.y = attentionPos(speaker).y;
}
if (sp58) {
sp14FC += sp152C;
}
} else {
actor1_sp3D0 = listener;
actor2_sp3CC = speaker;
sp3C8 = talk->field_0x38 ? 0 : 1;
sp1514 = talkEyePos(actor2_sp3CC);
sp1508 = talkEyePos(actor1_sp3D0);
sp14FC = talkBasePos(actor2_sp3CC);
sp14F0 = talkBasePos(actor1_sp3D0);
if (sp5C) {
sp1514.y = attentionPos(speaker).y;
}
if (sp58) {
sp14F0 += sp152C;
}
}
if (talk->field_0x44 == 0) {
f32 sp3C4 = 0.45f;
f32 sp3C0 = (sp1508.y - talkBasePos(actor1_sp3D0).y) * 1.2f;
f32 sp3BC = (sp1514.y - sp1508.y) * sp3C4;
f32 sp3B8 = sp3C0 * 0.7f + sp3BC;
cXyz sp140C(25.0f, 10.0f, talk->field_0x30.R() * sp3C4);
cXyz sp1400(75.0f, sp3BC, -75.0f);
if (sp3C8) {
sp140C.x = -sp140C.x;
sp1400.x = -sp1400.x;
}
cSGlobe sp4F0 = sp1514 - sp1508;
cSGlobe sp4E8 = sp140C;
sp4E8.U(sp4E8.U() + sp4F0.U());
talk->field_0x90 = attentionPos(actor1_sp3D0) + sp4E8.Xyz();
talk->field_0x90.y = sp14F0.y + sp3B8;
sp4E8.Val(sp1400);
sp4E8.U(sp4E8.U() + sp4F0.U().Inv());
sp4E8.V(sp4E8.V() * 0.25f + sp4F0.V() * 0.75f);
talk->field_0x9c = sp1514 + sp4E8.Xyz();
talk->field_0xa8.Val(talk->field_0x9c - talk->field_0x90);
mStyleSettle.mFinished = true;
if (sp430 == 11 || sp430 == 12) {
talk->field_0xb0 = 55.0f;
} else {
talk->field_0xb0 = 65.0f;
}
}
cXyz sp13F4 = attentionPos(actor1_sp3D0);
if (lineBGCheck(&sp13F4, &talk->field_0x9c, talk->field_0x8c)
|| lineCollisionCheck(sp13F4, talk->field_0x9c, listener, speaker, NULL))
{
sp430 = 0;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, "-----");
}
#endif
} else {
mViewCache.mCenter = talk->field_0x90;
mViewCache.mEye = talk->field_0x9c;
mViewCache.mDirection = talk->field_0xa8;
mViewCache.mFovy = talk->field_0xb0;
}
break;
}
case 13: {
if (talk->field_0x44 == 0) {
mStyleSettle.mFinished = true;
}
mViewCache.mCenter = talk->field_0x4;
mViewCache.mDirection.Val(400.0f, cSAngle(35.0f), talk->field_0x28.U());
if (mViewCache.mDirection.V() > sp298) {
mViewCache.mDirection.V(sp298);
}
if (mViewCache.mDirection.V() < sp294) {
mViewCache.mDirection.V(sp294);
}
cXyz sp13E8 = attentionPos(listener);
cXyz sp13DC = attentionPos(speaker);
cSAngle sp258;
if (talk->field_0x38) {
sp258 = 20.0f;
} else {
sp258 = -20.0f;
}
int i = 0;
for (i = 0; i < 18; i++) {
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
if (!lineBGCheck(&sp13E8, &mViewCache.mEye, talk->field_0x8c)
&& !lineBGCheck(&sp13DC, &mViewCache.mEye, talk->field_0x8c)
&& !lineCollisionCheck(sp13E8, mViewCache.mEye, listener, speaker, NULL)
&& !lineCollisionCheck(sp13DC, mViewCache.mEye, listener, speaker, NULL))
{
break;
}
mViewCache.mDirection.U(mViewCache.mDirection.U() + sp258);
}
mViewCache.mFovy = 60.0f;
break;
}
case 32:
if (talk->field_0x44 == 0) {
mStyleSettle.mFinished = true;
mViewCache.mCenter = talk->field_0x4;
cSAngle sp254;
if (talk->field_0x38) {
sp254 = talk->field_0x30.U() + cSAngle::_90;
} else {
sp254 = talk->field_0x30.U() + cSAngle::_270;
}
mViewCache.mDirection.Val(400.0f, cSAngle(15.0f), sp254);
if (mViewCache.mDirection.V() > sp298) {
mViewCache.mDirection.V(sp298);
}
if (mViewCache.mDirection.V() < sp294) {
mViewCache.mDirection.V(sp294);
}
cXyz sp13D0 = attentionPos(listener);
cXyz sp13C4 = attentionPos(speaker);
cSAngle sp250 = cSAngle::_0;
int i = 0;
for (i = 0; i < 18; i++) {
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
if (!lineBGCheck(&sp13D0, &mViewCache.mEye, talk->field_0x8c)
&& !lineBGCheck(&sp13C4, &mViewCache.mEye, talk->field_0x8c)
&& !lineCollisionCheck(sp13D0, mViewCache.mEye, listener, speaker, NULL)
&& !lineCollisionCheck(sp13C4, mViewCache.mEye, listener, speaker, NULL))
{
break;
}
if ((i & 1) == 0) {
sp250 += cSAngle(20.0f);
mViewCache.mDirection.U(sp254 + sp250);
} else {
mViewCache.mDirection.U(sp254 - sp250);
}
}
mViewCache.mFovy = 60.0f;
}
break;
case 28: {
if (talk->field_0x44 == 0) {
mStyleSettle.mFinished = true;
}
cXyz sp13B8 = talkBasePos(speaker);
cXyz sp13AC = talkBasePos(listener);
cXyz sp13A0 = sp13B8 - sp13AC;
cSGlobe sp4E0 = sp13A0;
cSAngle sp24C;
f32 sp3AC = dCamMath::xyzHorizontalDistance(sp13B8, sp13AC) * 2.0f * 0.5f;
cDegree sp3A8 = mWindowAspect * 60.0f * 0.5f;
f32 sp3A4 = sp3AC / sp3A8.Tan();
if (talk->field_0x38) {
sp24C = cSAngle::_270;
} else {
sp24C = cSAngle::_90;
}
talk->field_0x90 = talkBasePos(listener) + sp13A0 * 0.5f;
talk->field_0x90.y = (talkEyePos(speaker).y + talkEyePos(listener).y) * 0.5f - 30.0f;
talk->field_0xa8.Val(sp3A4, cSAngle::_0, sp4E0.U() + sp24C);
talk->field_0x9c = talk->field_0x90 + talk->field_0xa8.Xyz();
talk->field_0xb0 = 60.0f;
if (lineBGCheck(&sp13B8, &talk->field_0x9c, talk->field_0x8c)
|| lineBGCheck(&sp13AC, &talk->field_0x9c, talk->field_0x8c)
|| lineCollisionCheck(sp13B8, talk->field_0x9c, listener, speaker, NULL)
|| lineCollisionCheck(sp13AC, talk->field_0x9c, listener, speaker, NULL))
{
sp430 = 0;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, "-----");
}
#endif
} else {
mViewCache.mCenter = talk->field_0x90;
mViewCache.mEye = talk->field_0x9c;
mViewCache.mDirection = talk->field_0xa8;
mViewCache.mFovy = talk->field_0xb0;
}
break;
}
case 29: {
fopAc_ac_c* actor1_sp3A0 = speaker;
fopAc_ac_c* actor2_sp39C = listener;
talk->field_0x90 = talkBasePos(actor1_sp3A0);
if (talk->field_0x44 == 0) {
cXyz sp1394 = talkBasePos(actor2_sp39C);
sp1394.y = talkEyePos(actor2_sp39C).y;
cXyz sp1388 = talkBasePos(actor1_sp3A0);
if (sp5C) {
sp1388.y = attentionPos(actor1_sp3A0).y;
}
sp1388.y = talkEyePos(actor1_sp3A0).y;
talk->field_0xa8.Val(sp1394 - sp1388);
talk->field_0xa8.R(200.0f);
talk->field_0x1c.y = attentionPos(actor1_sp3A0).y - 68.0f - talkBasePos(actor1_sp3A0).y;
mStyleSettle.mFinished = true;
}
talk->field_0x90.y = talk->field_0x1c.y + talkBasePos(actor1_sp3A0).y;
talk->field_0x9c = talk->field_0x90 + talk->field_0xa8.Xyz();
talk->field_0xb0 = 55.0f;
cXyz sp137C = attentionPos(actor1_sp3A0);
if (lineBGCheck(&sp137C, &talk->field_0x9c, talk->field_0x8c)
|| lineCollisionCheck(sp137C, talk->field_0x9c, listener, actor1_sp3A0, NULL))
{
sp430 = 0;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, "-----");
}
#endif
} else {
mViewCache.mCenter = talk->field_0x90;
mViewCache.mEye = talk->field_0x9c;
mViewCache.mDirection = talk->field_0xa8;
mViewCache.mFovy = talk->field_0xb0;
hideActor(listener);
}
break;
}
case 37:
if (talk->field_0x44 == 0) {
fopAc_ac_c* actor1_sp398 = speaker;
fopAc_ac_c* actor2_sp394 = listener;
sp1514 = talkEyePos(actor2_sp394);
sp1508 = talkEyePos(actor1_sp398);
sp14FC = talkBasePos(actor2_sp394);
sp14F0 = talkBasePos(actor1_sp398);
if (sp5C) {
sp1508.y = attentionPos(actor1_sp398).y;
}
if (sp58) {
sp14FC += sp152C;
}
mViewCache.mCenter = sp14F0;
cXyz sp1370 = sp14FC;
sp1370.y = sp1514.y;
cXyz sp1364 = sp14F0;
sp1364.y = sp1508.y;
mViewCache.mDirection.Val(sp1370 - sp1364);
mViewCache.mDirection.V(mViewCache.mDirection.V() + cSAngle(5.0f));
mViewCache.mDirection.R(750.0f);
talk->field_0x1c.y = sp1508.y - sp14F0.y;
mStyleSettle.mFinished = true;
mViewCache.mCenter.y = sp14F0.y + talk->field_0x1c.y;
cXyz sp1358 = attentionPos(actor2_sp394);
cXyz sp134C = attentionPos(actor1_sp398);
cSAngle sp248;
if (talk->field_0x38) {
mViewCache.mDirection.U(mViewCache.mDirection.U() + cSAngle(10.0f));
sp248 = 20.0f;
} else {
mViewCache.mDirection.U(mViewCache.mDirection.U() - cSAngle(10.0f));
sp248 = -20.0f;
}
int i = 0;
fopAc_ac_c* midna = daPy_py_c::getMidnaActor();
for (i = 0; i < 18; i++) {
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
if (!lineBGCheck(&sp1358, &mViewCache.mEye, talk->field_0x8c)
&& !lineBGCheck(&sp134C, &mViewCache.mEye, talk->field_0x8c)
&& !lineCollisionCheck(sp1358, mViewCache.mEye, actor2_sp394, midna, NULL)
&& !lineCollisionCheck(sp134C, mViewCache.mEye, actor2_sp394, midna, NULL))
{
break;
}
mViewCache.mDirection.U(mViewCache.mDirection.U() + sp248);
}
mViewCache.mFovy = 60.0f;
}
break;
case 38: {
fopAc_ac_c* actor1_sp388 = speaker;
fopAc_ac_c* actor2_sp384 = listener;
sp1514 = talkEyePos(actor2_sp384);
sp1508 = talkEyePos(actor1_sp388);
cSGlobe sp4D8 = sp1514 - sp1508;
if (talk->field_0x44 == 0) {
mStyleSettle.mFinished = true;
cSGlobe sp4D0 = sp4D8;
sp4D0.R(sp4D8.R() * 0.5f);
mViewCache.mCenter = sp1508 + sp4D0.Xyz();
mViewCache.mCenter.y = sp1508.y - 20.0f - talk->field_0x7c * 10.0f;
f32 sp380 = 1.0f - talk->field_0x7c;
if (talk->field_0x38) {
sp4D0.Val(cXyz(-45.0f + talk->field_0x7c * 20.0f, 5.0f, -80.0f - talk->field_0x7c * 40.0f));
} else {
sp4D0.Val(cXyz(65.0f - talk->field_0x7c * 20.0f, 5.0f, -80.0f - talk->field_0x7c * 40.0f));
}
sp4D0.U(sp4D0.U() + directionOf(actor2_sp384));
sp4D0.V(sp4D0.V() + sp4D8.V());
mViewCache.mEye = sp1514 + sp4D0.Xyz();
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
f32 sp37C = 25.0f;
f32 sp378 = 40.0f;
mViewCache.mFovy = sp378 + (sp37C - sp378) * talk->field_0x7c;
}
break;
}
case 33: {
fopAc_ac_c* actor1_sp374 = listener;
fopAc_ac_c* actor2_sp370 = speaker;
cXyz sp1340(0.0f, 25.0f, -70.0f);
cSGlobe sp4C8 = sp1340;
sp4C8.U(sp4C8.U() + directionOf(actor1_sp374));
mViewCache.mCenter = attentionPos(actor1_sp374) + sp4C8.Xyz();
mViewCache.mDirection.Val(140.0f, cSAngle(-20.0f), cSAngle(-40.0f) + directionOf(actor1_sp374));
mStyleSettle.mFinished = true;
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = 58.0f;
break;
}
case 34: {
fopAc_ac_c* actor1_sp36C = listener;
fopAc_ac_c* actor2_sp368 = speaker;
mViewCache.mCenter = talkBasePos(actor1_sp36C);
if (talk->field_0x44 == 0) {
mViewCache.mDirection.V(cSAngle(20.0f));
mViewCache.mDirection.R(160.0f);
mViewCache.mDirection.U(directionOf(actor1_sp36C).Inv());
talk->field_0x1c.y = 95.0f;
mStyleSettle.mFinished = true;
}
mViewCache.mCenter.y += talk->field_0x1c.y;
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = 58.0f;
break;
}
case 35:
case 36: {
fopAc_ac_c* actor1_sp364 = listener;
fopAc_ac_c* actor2_sp360 = speaker;
int sp35C = talk->field_0x38;
sp1514 = attentionPos(actor2_sp360);
sp1508 = attentionPos(actor1_sp364);
sp14FC = talkBasePos(actor2_sp360);
sp14F0 = talkBasePos(actor1_sp364);
// first condition might not be correct as it's not actually present in assembly
if (sp35C && false) {
sp14F0 += sp152C;
}
if (talk->field_0x44 == 0) {
mStyleSettle.mFinished = true;
}
cXyz sp1334(0.0f, 10.0f, -60.0f);
cSGlobe sp4C0 = sp1334;
sp4C0.U(sp4C0.U() + directionOf(actor1_sp364));
talk->field_0x90 = sp1508 + sp4C0.Xyz();
cSAngle sp98;
if (sp430 == 36) {
sp98.Val(-150.0f);
talk->field_0xa8.Val(200.0f, cSAngle::_0, sp98 + directionOf(actor1_sp364));
} else {
sp98.Val(-35.0f);
talk->field_0xa8.Val(160.0f, cSAngle::_0, sp98 + directionOf(actor1_sp364));
}
talk->field_0xb0 = 60.0f;
talk->field_0x9c = talk->field_0x90 + talk->field_0xa8.Xyz();
cXyz sp1328 = attentionPos(actor1_sp364);
if (lineBGCheck(&sp1328, &talk->field_0x9c, talk->field_0x8c)
|| lineCollisionCheck(sp1328, talk->field_0x9c, listener, speaker, NULL))
{
talk->field_0x90.y -= 20.0f;
talk->field_0xa8.Val(180.0f, cSAngle(35.0f), sp98 + directionOf(actor1_sp364));
talk->field_0x9c = talk->field_0x90 + talk->field_0xa8.Xyz();
if (lineBGCheck(&sp1328, &talk->field_0x9c, talk->field_0x8c)
|| lineCollisionCheck(sp1328, talk->field_0x9c, listener, speaker, NULL))
{
sp430 = 0;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(90, 190, "-----");
}
#endif
} else {
mViewCache.mCenter = talk->field_0x90;
mViewCache.mEye = talk->field_0x9c;
mViewCache.mDirection = talk->field_0xa8;
mViewCache.mFovy = talk->field_0xb0;
}
} else {
mViewCache.mCenter = talk->field_0x90;
mViewCache.mEye = talk->field_0x9c;
mViewCache.mDirection = talk->field_0xa8;
mViewCache.mFovy = talk->field_0xb0;
}
break;
}
default: {
OS_REPORT("camera: WARNING: talk: unknown cut(%d)!\n", sp430);
sp430 = 0;
break;
}
}
if (talk->field_0x84 != 0) {
mStyleSettle.mFinished = true;
}
if (sp430 == 0) {
if (mStyleSettle.mFinished) {
mViewCache.mCenter = talk->field_0x4;
mViewCache.mDirection = talk->field_0x28;
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = talk->field_0x58;
} else {
talk->field_0x50 = (f32)(talk->field_0x44 + 1) / talk->field_0x48;
f32 sp358 = dCamMath::rationalBezierRatio(talk->field_0x50, 0.28f);
mViewCache.mCenter += (talk->field_0x4 - mViewCache.mCenter) * sp358;
mViewCache.mDirection.R(mViewCache.mDirection.R()
+ (talk->field_0x28.R() - mViewCache.mDirection.R()) * sp358);
mViewCache.mDirection.V(mViewCache.mDirection.V()
+ (talk->field_0x28.V() - mViewCache.mDirection.V()) * sp358);
mViewCache.mDirection.U(mViewCache.mDirection.U()
+ (talk->field_0x28.U() - mViewCache.mDirection.U()) * sp358);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy += (talk->field_0x58 - mViewCache.mFovy) * sp358;
talk->field_0x4c -= talk->field_0x50;
if (talk->field_0x44 >= talk->field_0x48 - 1) {
mStyleSettle.mFinished = true;
}
sp5D = false;
}
}
talk->field_0x44++;
return sp5D;
}
bool dCamera_c::CalcSubjectAngle(s16* param_0, s16* param_1) {
return false;
}
bool dCamera_c::SaveZoomRatio() {
if (mCamParam.Algorythmn() != 4) {
return false;
}
SubjectData* subject = (SubjectData*)mWork;
mZoomRatio = subject->mZoomRatio;
return true;
}
bool dCamera_c::subjectCamera(s32 param_0) {
f32 val0 = mCamParam.Val(param_0, 0);
f32 val2 = mCamParam.Val(param_0, 2);
f32 val1 = mCamParam.Val(param_0, 1);
f32 val25 = mCamParam.Val(param_0, 25);
f32 val4 = mCamParam.Val(param_0, 4);
f32 val26 = mCamParam.Val(param_0, 26);
f32 val20 = mCamParam.Val(param_0, 20);
f32 val19 = mCamParam.Val(param_0, 19);
f32 val21 = mCamParam.Val(param_0, 21);
f32 val7 = mCamParam.Val(param_0, 7);
f32 val10 = mCamParam.Val(param_0, 10);
f32 val17 = mCamParam.Val(param_0, 17);
f32 val27 = mCamParam.Val(param_0, 27);
f32 val22 = mCamParam.Val(param_0, 22);
f32 val16 = mCamParam.Val(param_0, 16);
f32 val24 = mCamParam.Val(param_0, 24);
f32 val18 = mCamParam.Val(param_0, 18);
daAlink_c* player = (daAlink_c*)mpPlayerActor;
SubjectData* subject = (SubjectData*)mWork;
bool sp14 = check_owner_action(mPadID, 0x1040) != 0;
bool sp13 = check_owner_action(mPadID, 0x4000) != 0;
bool sp12 = check_owner_action(mPadID, 0x400) != 0;
bool magne_boots_on = player->checkMagneBootsOn() != 0;
bool sp10 = check_owner_action(mPadID, 0x80080) != 0;
bool sp0F = check_owner_action(mPadID, 0x40) != 0;
if (mCurCamStyleTimer == 0) {
subject->field_0x0 = 'SUBN';
subject->field_0x2a.Val(mViewCache.mDirection.U().Inv());
subject->field_0x28.Val(mViewCache.mDirection.V());
subject->field_0x14 = 7;
if (check_owner_action1(mPadID, 0x2000000)) {
subject->field_0x14 = 2;
}
subject->field_0x10 = 0;
subject->mZoomRatio = mZoomRatio;
mZoomRatio = 0.0f;
subject->field_0x18 = param_0;
subject->field_0x1c = false;
subject->field_0x20 = 0.0f;
subject->field_0x1d = false;
if (sp14 || sp12) {
subject->field_0x1d = directionOf(mpPlayerActor) - mViewCache.mDirection.U() > cSAngle::_0;
} else if (sp13) {
subject->field_0x1d = player->getHookshotLeft() != 0;
}
}
if (subject->field_0x1d) {
val0 = -val0;
}
cXyz stack_1bc;
cSAngle stack_448;
MtxP mtx, inv_mtx;
if (magne_boots_on) {
stack_1bc = *player->getMagneBootsTopVec();
mtx = player->getMagneBootsMtx();
inv_mtx = player->getMagneBootsInvMtx();
stack_448 = cSAngle(player->getMagneBootsModelShapeAngle());
} else {
stack_1bc = cXyz::BaseY;
mtx = mDoMtx_getIdentity();
inv_mtx = mDoMtx_getIdentity();
stack_448 = directionOf(mpPlayerActor);
}
cXyz sp2D0, sp1D4, sp2B8;
s16 bow_angle_x, bow_angle_y;
cSAngle angle_x = player->getCameraAngleX();
cSAngle angle_y = player->getCameraAngleY();
cXyz* bow_pos = player->checkBowCameraArrowPosP(&bow_angle_x, &bow_angle_y);
bool sp0E = false;
if (check_owner_action(mPadID, 0x200000) && bow_pos != NULL) {
sp2D0 = *bow_pos;
angle_x.Val(bow_angle_x);
angle_y.Val(bow_angle_y);
} else if (sp13) {
if (player->getHookshotLeft()) {
sp2D0 = player->getLeftHandPos();
} else {
sp2D0 = player->getRightHandPos();
}
} else if (player->checkIronBallThrowReturnMode()) {
sp2D0 = attentionPos(mpPlayerActor);
cXyz* iron_ball_pos = player->getIronBallCenterPos();
cSGlobe globe = sp2D0 - *iron_ball_pos;
f32 tmp = cXyz(*iron_ball_pos - sp2D0).abs();
if (tmp > 200.0f) {
angle_x = globe.V();
angle_y = globe.U().Inv();
} else {
angle_x = subject->field_0x28;
angle_y = subject->field_0x2a;
}
angle_x += cSAngle(5.0f);
} else if (sp12) {
sp2D0 = attentionPos(mpPlayerActor);
subject->field_0x28 = angle_x;
subject->field_0x2a = angle_y;
angle_x += cSAngle(5.0f);
} else {
sp2D0 = *player->getSubjectEyePos();
}
if (!sp0E) {
subject->field_0x2e = angle_x;
subject->field_0x2c = angle_y;
}
bool sp0D = false;
if (magne_boots_on) {
cXyz player_pos = positionOf(mpPlayerActor);
subject->field_0x4 = mViewCache.mCenter - player_pos;
subject->field_0x30 = mViewCache.mEye - player_pos;
mDoMtx_multVecSR(inv_mtx, &subject->field_0x4, &subject->field_0x4);
mDoMtx_multVecSR(inv_mtx, &subject->field_0x30, &subject->field_0x30);
subject->field_0x4 += player_pos;
subject->field_0x30 += player_pos;
subject->field_0x48.Val(subject->field_0x30 - subject->field_0x4);
}
if (mCurCamStyleTimer == 0) {
subject->field_0x4 = mViewCache.mCenter;
subject->field_0x30 = mViewCache.mEye;
subject->field_0x48 = mViewCache.mDirection;
subject->field_0x3c = mUp;
field_0x738 = val16;
}
bool sp0C = false;
bool sp0B = false;
bool sp0A;
f32 spA4 = 1.0f;
if (mGear == -1) {
sp0B = true;
sp0C = true;
} else {
sp0A = false;
}
if (mCurType == specialType[CAM_TYPE_SCOPE]) {
mGear = 0;
mCamParam.SetFlag(0x10);
mCamParam.SetFlag(4);
} else if (mCurMode == 4) {
mGear = -1;
if (mPadInfo.mCStick.mLastPosY < -mCamSetup.mCStick.SwTHH()) {
if (mCStickYState != -1 && mGear == -1) {
mGear = 0;
setComStat(0x2000);
}
mCStickYState = -1;
} else {
mCStickYState = 0;
}
} else if (sp12 || player->checkIronBallThrowReturnMode()) {
val0 = 0.0f;
val2 = 40.0f;
val1 = 50.0f;
val7 = 270.0f;
val17 = 70.0f;
} else if (sp13 || sp14) {
f32 spA0 = mCamSetup.mCStick.SwTHH();
f32 sp9C = mPadInfo.mCStick.mLastPosX;
if (mGear == -1) {
sp0C = true;
}
if (sp0C) {
subject->field_0x20 += (1.0f - subject->field_0x20) * 0.3f;
} else {
subject->field_0x20 += (0.0f - subject->field_0x20) * 0.3f;
}
subject->field_0x20 = 1.0f;
mCamParam.SetFlag(0x10);
mCamParam.SetFlag(4);
if (sp13) {
val0 += ((player->getHookshotLeft() ? val20 : -val20) - val0) * subject->field_0x20;
val2 += (val19 - val2) * subject->field_0x20;
val1 += (val21 - val1) * subject->field_0x20;
val7 += (val10 - val7) * subject->field_0x20;
} else if (sp0F) {
val0 += (19.0f - val0) * subject->field_0x20;
val2 += (0.0f - val2) * subject->field_0x20;
val1 += (val26 - val1) * subject->field_0x20;
val7 += (val10 - val7) * subject->field_0x20;
} else if (sp14) {
val0 += (val25 - val0) * subject->field_0x20;
val2 += (val4 - val2) * subject->field_0x20;
val1 += (val26 - val1) * subject->field_0x20;
val7 += (val10 - val7) * subject->field_0x20;
} else {
val0 += (0.0f - val0) * subject->field_0x20;
val2 += (0.0f - val2) * subject->field_0x20;
val1 += (0.0f - val1) * subject->field_0x20;
val7 += (20.0f - val7) * subject->field_0x20;
}
}
if (mCurMode == 4 && getComStat(0x800)) {
val2 = 50.0f;
} else if (player->checkHawkWait()) {
val7 = 150.0f;
val2 = 20.0f;
}
if (mCamParam.Flag(param_0, 0x4000)) {
setFlag(0x800);
}
if (mCamParam.Flag(param_0, 0x20)) {
setFlag(0x10000000);
}
cXyz sp1E0(val0, val2, val1);
sp1D4 = dCamMath::xyzRotateX(sp1E0, angle_x);
sp1E0 = dCamMath::xyzRotateY(sp1D4, angle_y);
f32 sp6C = sp12 ? 40.0f : 0.0f;
cXyz sp294(0.0f, sp6C, -val7);
sp1D4 = dCamMath::xyzRotateX(sp294, angle_x);
sp294 = dCamMath::xyzRotateY(sp1D4, angle_y);
if (magne_boots_on) {
mDoMtx_multVecSR(mtx, &sp1E0, &sp1E0);
mDoMtx_multVecSR(mtx, &sp294, &sp294);
}
f32 sp94 = 1.0f;
f32 sp90 = 1.0f;
if (player->checkIronBallThrowReturnMode()) {
sp94 = sp90 = 0.1f;
} else if (player->checkHorseRide() || player->checkCanoeRide()) {
sp94 = sp90 = 1.0f;
}
cXyz sp288 = sp2D0 + sp1E0;
dBgS_CamLinChk lin_chk;
if (mIsWolf == 1) {
cXyz sp27C = positionOf(mpPlayerActor);
sp27C.y = sp2D0.y;
if (lineBGCheck(&sp27C, &sp288, &lin_chk, 0x40b7)) {
cM3dGPla plane;
dComIfG_Bgsp().GetTriPla(lin_chk, &plane);
sp288 = lin_chk.GetCross();
sp288 += *plane.GetNP() * 5.0f;
}
} else if (mCurMode == 7) {
// empty block
}
sp288 = mViewCache.mCenter + (sp288 - mViewCache.mCenter) * sp94;
cXyz sp270 = sp288 + sp294;
sp270 = mViewCache.mEye + (sp270 - mViewCache.mEye) * sp90;
if (magne_boots_on) {
setFlag(0x10);
sp2B8 = stack_1bc;
} else {
sp2B8 = cXyz::BaseY;
}
#if PLATFORM_GCN
cXyz stack_234 = sp270 - sp288;
cXyz stack_240, stack_24c;
stack_234.normalize();
stack_240 = sp288 + stack_234 * 40.0f;
if (lineBGCheck(&stack_240, &sp288, &stack_24c, 0x40b7)) {
sp270 = stack_24c + stack_234 * 10.0f;
}
#endif
if (mStyleSettle.mFinished) {
mViewCache.mCenter = sp288;
mViewCache.mEye = sp270;
} else {
cSGlobe stack_43c = sp270 - sp288;
f32 tmp = 1.0f / (subject->field_0x14 - subject->field_0x10);
mViewCache.mCenter += (sp288 - mViewCache.mCenter) * tmp;
mViewCache.mDirection.R(mViewCache.mDirection.R() + (stack_43c.R() - mViewCache.mDirection.R()) * tmp);
mViewCache.mDirection.V(mViewCache.mDirection.V() + (stack_43c.V() - mViewCache.mDirection.V()) * tmp);
mViewCache.mDirection.U(mViewCache.mDirection.U() + (stack_43c.U() - mViewCache.mDirection.U()) * tmp);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy += (val17 - mViewCache.mFovy) * tmp;
subject->field_0x3c += (sp2B8 - subject->field_0x3c) * tmp;
sp2B8 = subject->field_0x3c.norm();
if (subject->field_0x10 == subject->field_0x14 - 1) {
mStyleSettle.mFinished = true;
}
subject->field_0x10++;
if (magne_boots_on) {
mUpOverride.field_0x0 = mViewCache.mCenter;
mUpOverride.field_0xc = mViewCache.mEye;
mUpOverride.field_0x24 = mViewCache.mDirection;
mUpOverride.field_0x18 = sp2B8;
}
return true;
}
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
mUpOverride.field_0x0 = mViewCache.mCenter;
mUpOverride.field_0xc = mViewCache.mEye;
mUpOverride.field_0x24 = mViewCache.mDirection;
mUpOverride.field_0x18 = sp2B8;
if (mCamParam.Flag(param_0, 0x400)) {
f32 sp88 = 0.0f;
f32 sp84 = 0.0f;
int sp80 = 0;
if (mPadInfo.mCStick.mLastPosY > 0.01f) {
sp88 = dCamMath::rationalBezierRatio(mPadInfo.mCStick.mLastPosY, mCamSetup.CurveWeight());
sp80 = -1;
} else if (mPadInfo.mCStick.mLastPosY < -0.01f) {
sp84 = dCamMath::rationalBezierRatio(-mPadInfo.mCStick.mLastPosY, mCamSetup.CurveWeight());
sp80 = 1;
}
f32 sp7C = subject->mZoomRatio + val18 * (sp88 - sp84) * 0.1f;
if (sp7C < 0.0f) {
subject->mZoomRatio = 0.0f;
} else if (sp7C > 1.0f) {
subject->mZoomRatio = 1.0f;
} else {
subject->mZoomRatio = sp7C;
if (sp80 == -1) {
mDoAud_seStartLevel(Z2SE_AL_HAWK_EYE_ZOOMIN, NULL, 0, 0);
} else if (sp80 == 1) {
mDoAud_seStartLevel(Z2SE_AL_HAWK_EYE_ZOOMOUT, NULL, 0, 0);
}
}
if (subject->mZoomRatio == 0.0f || subject->mZoomRatio == 0.5f || subject->mZoomRatio == 1.0f) {
sp84 = sp88 = 0.0f;
}
f32 tmp2 = subject->mZoomRatio * 8.0f + 1.0f;
f32 zoom_fovy = dCamMath::zoomFovy(val17 * 0.5f, tmp2) * 2.0f;
mViewCache.mFovy += (zoom_fovy - mViewCache.mFovy) * val22;
setComZoomScale(tmp2);
setComZoomForcus(1.0f - fabsf(sp88 - sp84) * -511.0f);
if (check_owner_action(mPadID, 0x200000)) {
setComStat(8);
}
} else {
mViewCache.mFovy = val17;
}
return true;
}
bool dCamera_c::magneCamera(s32 param_0) {
f32 val5 = mCamParam.Val(param_0, 5);
f32 val0 = mCamParam.Val(param_0, 0);
f32 val1 = mCamParam.Val(param_0, 1);
f32 val2 = mCamParam.Val(param_0, 2);
f32 val3 = mCamParam.Val(param_0, 3);
f32 val7 = mCamParam.Val(param_0, 7);
f32 val8 = mCamParam.Val(param_0, 8);
f32 val11 = mCamParam.Val(param_0, 11);
f32 val12 = mCamParam.Val(param_0, 12);
f32 val13 = mCamParam.Val(param_0, 13);
f32 val16 = mCamParam.Val(param_0, 16);
f32 val24 = mCamParam.Val(param_0, 24);
f32 val17 = mCamParam.Val(param_0, 17);
f32 val18 = mCamParam.Val(param_0, 18);
f32 val21 = mCamParam.Val(param_0, 21);
MagneData* magne = (MagneData*)mWork;
daAlink_c* player = (daAlink_c*)mpPlayerActor;
mStyleSettle.mFinished = mCurCamStyleTimer != 0;
bool sp08 = false;
cSAngle sp54;
MtxP mtx, inv_mtx;
if (player->checkMagneBootsOn()) {
mtx = player->getMagneBootsMtx();
inv_mtx = player->getMagneBootsInvMtx();
sp54 = player->getMagneBootsModelShapeAngle();
} else {
mtx = mDoMtx_getIdentity();
inv_mtx = mDoMtx_getIdentity();
sp54 = directionOf(mpPlayerActor);
}
cXyz player_pos = positionOf(mpPlayerActor);
magne->field_0x4 = mViewCache.mCenter - player_pos;
magne->field_0x10 = mViewCache.mEye - player_pos;
mDoMtx_multVecSR(inv_mtx, &magne->field_0x4, &magne->field_0x4);
mDoMtx_multVecSR(inv_mtx, &magne->field_0x10, &magne->field_0x10);
magne->field_0x4 += player_pos;
magne->field_0x10 += player_pos;
if (mCurCamStyleTimer == 0) {
magne->field_0x0 = 'MAG_';
magne->field_0x1c.Val(magne->field_0x10 - magne->field_0x4);
}
f32 var_f31 = (magne->field_0x1c.R() - val8) / (val7 - val8);
if (var_f31 > 1.0f) {
var_f31 = 1.0f;
} else if (var_f31 < 0.0f) {
var_f31 = 0.0f;
}
f32 sp74 = val3 + (val2 - val3) * var_f31;
cXyz sp18C(val0, sp74, val1);
sp18C = dCamMath::xyzRotateY(sp18C, sp54);
cXyz sp180 = attentionPos(mpPlayerActor) - player_pos;
mDoMtx_multVecSR(inv_mtx, &sp180, &sp180);
sp180 += player_pos;
magne->field_0x4 += ((sp180 + sp18C) - magne->field_0x4) * val5;
cSGlobe stack_230 = magne->field_0x10 - magne->field_0x4;
f32 fVar2 = stack_230.R();
if (fVar2 > val7) {
fVar2 = val7;
} else if (fVar2 < val8) {
fVar2 = val8;
}
f32 cstick_x = mPadInfo.mCStick.mLastPosX;
if (mCamParam.Flag(param_0, 0x40)) {
cstick_x = 0.0f;
}
cSAngle stack_238;
if (mCurMode == 1) {
stack_238 = sp54.Inv();
} else if (fabsf(cstick_x) > 0.05f) {
stack_238 = magne->field_0x1c.U() + cSAngle(dCamMath::rationalBezierRatio(cstick_x, 0.5f) * 10.0f);
} else {
cSAngle stack_23c = sp54.Inv() - stack_230.U();
f32 sin = stack_23c.Sin();
f32 tmp = fabsf(sin * mPadInfo.mMainStick.mLastValue);
f32 tmp2 = stack_23c.Cos() > 0.0f ? 8.0f : 4.0f;
stack_238 = stack_230.U() + cSAngle(sin * tmp2 * dCamMath::rationalBezierRatio(tmp, 1.0f));
}
cSAngle stack_240 = val13 + (val12 - val13) * var_f31;
magne->field_0x1c.Val(fVar2, stack_240, stack_238);
magne->field_0x10 = magne->field_0x4 + magne->field_0x1c.Xyz();
cXyz stack_144 = magne->field_0x4 - player_pos;
cXyz stack_150 = magne->field_0x10 - player_pos;
mDoMtx_multVecSR(mtx, &stack_144, &stack_144);
mDoMtx_multVecSR(mtx, &stack_150, &stack_150);
stack_144 += player_pos;
stack_150 += player_pos;
stack_230.Val(stack_150 - stack_144);
mViewCache.mCenter = stack_144;
mViewCache.mDirection.R(mViewCache.mDirection.R()
+ (stack_230.R() - mViewCache.mDirection.R()) * val11);
mViewCache.mDirection.V(mViewCache.mDirection.V()
+ (stack_230.V() - mViewCache.mDirection.V()) * val16);
mViewCache.mDirection.U(mViewCache.mDirection.U()
+ (stack_230.U() - mViewCache.mDirection.U()) * val24 * stack_230.V().Cos());
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
f32 sp5C = val18 + (val17 - val18) * var_f31;
mViewCache.mFovy += (sp5C - mViewCache.mFovy) * val21;
return true;
}
bool dCamera_c::colosseumCamera(s32 param_0) {
f32 val0 = mCamParam.Val(param_0, 0);
f32 val2 = mCamParam.Val(param_0, 2);
f32 val1 = mCamParam.Val(param_0, 1);
f32 val3 = mCamParam.Val(param_0, 3);
f32 unusedFloat1 = 0.0f;
f32 unusedFloat2 = 0.0f;
f32 unusedFloat3 = 0.0f;
f32 val7 = mCamParam.Val(param_0, 7);
f32 val8 = mCamParam.Val(param_0, 8);
f32 unusedFloat4 = 0.0f;
f32 val11 = mCamParam.Val(param_0, 11);
f32 val10 = mCamParam.Val(param_0, 10);
f32 val12 = mCamParam.Val(param_0, 12);
f32 val13 = mCamParam.Val(param_0, 13);
f32 unusedFloat5 = 0.0f;
f32 unusedFloat6 = 0.0f;
f32 val17 = mCamParam.Val(param_0, 17);
f32 val18 = mCamParam.Val(param_0, 18);
f32 unusedFloat7 = 0.0f;
f32 unusedFloat8 = 0.0f;
ColosseumData* colosseum = (ColosseumData*)mWork;
if (Stage == 0x6b && positionOf(mpPlayerActor).y < -1.0f) {
param_0 = mCamTypeData[specialType[CAM_TYPE_FIELD_S]].field_0x18[mIsWolf][0];
return chaseCamera(param_0);
}
if (mCurCamStyleTimer == 0) {
colosseum->field_0x14 = 0.0f;
colosseum->field_0x18 = 40;
if (mRoomMapTool.mCameraIndex != 0xff && mCamParam.Flag(param_0, 0x200)) {
colosseum->field_0x8.x = mRoomMapTool.mArrowData.posX;
colosseum->field_0x8.y = mRoomMapTool.mArrowData.posY;
colosseum->field_0x8.z = mRoomMapTool.mArrowData.posZ;
} else if (mCamParam.Flag(param_0, 0x2000)) {
fopAc_ac_c* target = getParamTargetActor(mCurType);
colosseum->field_0x8.x = positionOf(target).x;
colosseum->field_0x8.y = attentionPos(mpPlayerActor).y;
colosseum->field_0x8.z = positionOf(target).z;
}
mEventData.field_0xf0.Init(5, 100);
}
if (colosseum->field_0x14 < 0.999f) {
colosseum->field_0x14 += 1.0f / colosseum->field_0x18;
} else {
mStyleSettle.mFinished = true;
colosseum->field_0x14 = 1.0f;
}
cXyz stack_e8 = colosseum->field_0x8;
if (!mCamParam.Flag(param_0, 0x1000)) {
stack_e8.y = attentionPos(mpPlayerActor).y;
}
cXyz stack_f4(val0, 0.0f, val1);
cXyz stack_100;
stack_100 = dCamMath::xyzRotateY(stack_f4, mViewCache.mDirection.U().Inv());
stack_100 += attentionPos(mpPlayerActor);
cSGlobe stack_1bc = stack_100 - stack_e8;
f32 var_f31;
if (stack_1bc.R() < val10) {
var_f31 = 0.0f;
stack_1bc.R(val10);
} else if (stack_1bc.R() > val11) {
var_f31 = 1.0f;
stack_1bc.R(val11);
} else {
var_f31 = (stack_1bc.R() - val10) / (val11 - val10);
stack_1bc.R(val10 + (val11 - val10) * var_f31);
}
static f32 Dsp[5] = {0.0f, 0.0f, 0.25f, 1.0f, 1.0f};
f32 sp3C = mEventData.field_0xf0.Spot(Dsp, var_f31);
#if DEBUG
dDbVw_Report(180, 320, "D %6.3f (%6.3f)", sp3C, var_f31);
#endif
var_f31 = sp3C;
cXyz stack_10c;
stack_10c = stack_e8 + stack_1bc.Xyz();
if (!mCamParam.Flag(param_0, 0x800)) {
stack_10c.y = 0.0f;
}
stack_10c.y += val3 + (val2 - val3) * var_f31;
f32 fVar8 = val8 + (val7 - val8) * var_f31;
cSAngle stack_1c0 = val13 + (val12 - val13) * var_f31;
if (mCamParam.Flag(param_0, 0x1000)) {
stack_1c0 += stack_1bc.V();
}
cSAngle stack_1c4 = stack_1bc.U();
if (!mStyleSettle.mFinished) {
mViewCache.mCenter += (stack_10c - mViewCache.mCenter) * colosseum->field_0x14;
mViewCache.mDirection.R(mViewCache.mDirection.R()
+ (fVar8 - mViewCache.mDirection.R()) * colosseum->field_0x14);
mViewCache.mDirection.V(mViewCache.mDirection.V()
+ (stack_1c0 - mViewCache.mDirection.V()) * colosseum->field_0x14);
mViewCache.mDirection.U(mViewCache.mDirection.U()
+ (stack_1c4 - mViewCache.mDirection.U()) * colosseum->field_0x14);
} else {
mViewCache.mCenter = stack_10c;
mViewCache.mDirection.Val(fVar8, stack_1c0, stack_1c4);
}
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
f32 fVar9 = val18 + (val17 - val18) * var_f31;
mViewCache.mFovy += (fVar9 - mViewCache.mFovy) * colosseum->field_0x14;
return true;
}
bool dCamera_c::test1Camera(s32 param_0) {
return false;
}
bool dCamera_c::test2Camera(s32 param_0) {
return false;
}
bool dCamera_c::towerCamera(s32 param_0) {
cSAngle stack_444 = cSAngle(mCamSetup.ChargeLatitude());
f32 sp224 = mCamSetup.ChargeBRatio();
cSAngle stack_448 = 80.0f;
cSAngle stack_44c = -60.0f;
cSAngle stack_450 = 60.0f;
f32 sp220 = 8.0f;
f32 unkFloatConst1 = 0.9f;
f32 val0 = mCamParam.Val(param_0, 0);
f32 val2 = mCamParam.Val(param_0, 2);
f32 val1 = mCamParam.Val(param_0, 1);
f32 val5 = mCamParam.Val(param_0, 5);
f32 val6 = mCamParam.Val(param_0, 6);
f32 val3 = mCamParam.Val(param_0, 3);
f32 val26 = mCamParam.Val(param_0, 26);
f32 val7 = mCamParam.Val(param_0, 7);
f32 val8 = mCamParam.Val(param_0, 8);
f32 val10 = mCamParam.Val(param_0, 10);
f32 val11 = mCamParam.Val(param_0, 11);
f32 val12 = mCamParam.Val(param_0, 12);
f32 val13 = mCamParam.Val(param_0, 13);
f32 val16 = mCamParam.Val(param_0, 16);
f32 val17 = mCamParam.Val(param_0, 17);
f32 val18 = mCamParam.Val(param_0, 18);
f32 val20 = mCamParam.Val(param_0, 20);
f32 val21 = mCamParam.Val(param_0, 21);
cSAngle stack_454 = mCamParam.Val(param_0, 23);
cSAngle stack_458 = mCamParam.Val(param_0, 24);
f32 val22 = mCamParam.Val(param_0, 22);
f32 val27 = mCamParam.Val(param_0, 27);
f32 val4 = mCamParam.Val(param_0, 4);
f32 val9 = mCamParam.Val(param_0, 9);
f32 val14 = mCamParam.Val(param_0, 14);
f32 val19 = mCamParam.Val(param_0, 19);
if (mGear == 1) {
val7 = val9;
val8 = val9 * 0.9f;
val2 = val3 = val4;
val12 = val13 = val14;
val17 = val18 = val19;
}
TowerData* tower = (TowerData*)mWork;
daAlink_c* player = (daAlink_c*)mpPlayerActor;
dAttention_c* sp1B4 = dComIfGp_getAttention();
if (mCurCamStyleTimer == 0) {
tower->field_0x54.x = mRoomMapTool.mArrowData.posX;
tower->field_0x54.y = mRoomMapTool.mArrowData.posY;
tower->field_0x54.z = mRoomMapTool.mArrowData.posZ;
tower->field_0x60 = (s16)mRoomMapTool.mArrowData.angleY;
tower->field_0x64 = stack_454 <= cSAngle::_90 ? 1 : 0;
}
if (mRoomMapTool.mArrowIndex == 0xff) {
if (mCurCamStyleTimer == 0) {
OS_REPORT("%s: %d: no mapdata use towerCamera() engine !!\n", __FILE__, 0x25ff);
}
param_0 = mCamTypeData[specialType[CAM_TYPE_FIELD_S]].field_0x18[mIsWolf][mCurMode];
return chaseCamera(param_0);
}
if (check_owner_action(mPadID, 0x8100000)) {
if (stack_44c < cSAngle(4.0f)) {
stack_44c.Val(4.0f);
}
if (val2 < -10.0f) {
val2 = -10.0f;
}
}
cSGlobe stack_41c = attentionPos(mpPlayerActor) - tower->field_0x54;
cSAngle sp11C = directionOf(mpPlayerActor);
bool uVar2 = stack_41c.U() - mViewCache.mDirection.U() > cSAngle::_0;
bool uVar1 = stack_41c.U() - sp11C > cSAngle::_0;
if (mCurCamStyleTimer == 0) {
tower->field_0x0 = 'TOWR';
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
tower->field_0x18 = 0.0f;
tower->field_0x1c = tower->field_0x20 = mDirection.R();
tower->field_0x10 = tower->field_0x14 = 0;
tower->field_0x24 = tower->field_0x40 = mDirection.V().Degree();
tower->field_0x48 = mViewCache.mCenter;
tower->field_0x74 = tower->field_0x78 = 0.01f;
tower->field_0x7c = 0.01f;
tower->field_0x70 = 0.75f;
tower->field_0x80 = val6;
tower->field_0x84 = val5;
tower->field_0x38 = 0;
tower->field_0x6b = true;
tower->field_0x2c = mFovy;
tower->field_0x3c = 0.0f;
tower->field_0x44 = 0.0f;
tower->field_0x6a = false;
cSAngle stack_460;
if (mCamParam.Flag(param_0, 0x100)) {
stack_460.Val(stack_41c.U() - mViewCache.mDirection.U().Inv());
} else {
stack_460.Val(stack_41c.U() - directionOf(mpPlayerActor));
}
if (stack_460 > cSAngle::_0) {
tower->field_0x44 = 1.0f;
} else {
tower->field_0x44 = -1.0f;
}
tower->field_0x68 = false;
tower->field_0x28 = mViewCache.mDirection.U();
tower->field_0x30 = 0.0f;
tower->field_0x34 = 0.0f;
tower->field_0x6c = false;
}
f32 fVar4 = limitf((mViewCache.mDirection.R() - val8) / (val7 - val8), 0.0f, 1.0f);
cXyz stack_210;
if (mCamParam.Flag(param_0, 0x400)) {
cSAngle stack_464 = tower->field_0x60 - stack_41c.U();
tower->field_0x30 = val0 * stack_464.Sin();
} else if (chkFlag(0x100000) && check_owner_action(mPadID, 0xa50c0)) {
if (mPadInfo.mMainStick.mLastPosX < -0.2f) {
tower->field_0x6c = true;
}
if (mPadInfo.mMainStick.mLastPosX > 0.2f) {
tower->field_0x6c = false;
}
tower->field_0x30 += ((tower->field_0x6c ? -45.0f : 45.0f) - tower->field_0x30) * 0.04f;
} else {
tower->field_0x30 += (val0 - tower->field_0x30) * 0.06f;
}
stack_210.x = tower->field_0x30;
if (!tower->field_0x68) {
stack_210.y = val3 + (val2 - val3) * fVar4;
stack_210.z = val1 * fVar4;
} else {
stack_210.y = 20.0f;
stack_210.z = 1.0f;
}
bool bVar4 = Stage == 0x69 && player->checkSpinnerRide();
bool bVar3 = Stage == 0x65 && dComIfGp_evmng_cameraPlay();
bool bVar5 = Stage == 0x6b && check_owner_action1(mPadID, 0x10000);
if (mCurCamStyleTimer == 0) {
if (bVar3) {
tower->field_0x4 = 25;
} else if (bVar4) {
tower->field_0x4 = 5;
} else if (dComIfGp_evmng_cameraPlay()) {
int timer;
getEvIntData(&timer, "Timer", 20);
tower->field_0x4 = timer != 0 ? timer : 1;
} else if (chkFlag(0x8000) || mCurMode == 1) {
mStyleSettle.mFinished = true;
tower->field_0x4 = 1;
} else {
cXyz stack_21c = relationalPos(mpPlayerActor, &stack_210);
f32 sp1A8 = cXyz(mEye - stack_21c).abs() - val7;
f32 sp1A4 = cXyz(mCenter - stack_21c).abs() - val7;
f32 sp1A0 = fabsf(sp1A8 > sp1A4 ? sp1A8 : sp1A4);
sp1A8 = heightOf(mpPlayerActor);
sp1A0 /= (sp1A8 < 10.0f ? 10.0f : sp1A8);
tower->field_0x4 = (int)(JMAFastSqrt(sp1A0) * sp220) + 1;
}
tower->field_0x8 = tower->field_0x4 * (tower->field_0x4 + 1) >> 1;
tower->field_0xc = 0.0f;
}
cXyz stack_228;
cSGlobe stack_424 = stack_210;
if (mCamParam.Flag(param_0, 0x1000)) {
stack_424.U(stack_424.U() + directionOf(mpPlayerActor));
} else {
stack_424.U(stack_424.U() + stack_41c.U());
}
if (mCamParam.Flag(param_0, 0x800) && mpLockonTarget != NULL) {
stack_228 = attentionPos(mpPlayerActor) + stack_424.Xyz()
+ (attentionPos(mpLockonTarget) - attentionPos(mpPlayerActor)) * val26;
mpAuxTargetActor1 = mpLockonTarget;
setFlag(0x2000);
} else {
stack_228 = attentionPos(mpPlayerActor) + stack_424.Xyz();
}
cXyz sp40C;
if (!mStyleSettle.mFinished) {
if (mBG.field_0xc0.field_0x1) {
dComIfG_Bgsp().MoveBgMatrixCrrPos(mBG.field_0x5c.field_0x4, true,
&tower->field_0x48, NULL, NULL);
}
tower->field_0xc = tower->field_0x4 - (int)mCurCamStyleTimer;
f32 sp19C;
f32 ratio = tower->field_0xc / tower->field_0x8;
tower->field_0x48 += (stack_228 - tower->field_0x48) * ratio;
mViewCache.mCenter += (tower->field_0x48 - mViewCache.mCenter) * val6;
sp40C = attentionPos(mpPlayerActor);
sp40C.y -= 15.0f;
dBgS_CamLinChk lin_chk;
if (lineBGCheck(&sp40C, &mViewCache.mCenter, &lin_chk, 0x40b7)) {
cM3dGPla plane;
dComIfG_Bgsp().GetTriPla(lin_chk, &plane);
mViewCache.mCenter = lin_chk.GetCross();
mViewCache.mCenter += *plane.GetNP();
}
sp19C = limitf(mViewCache.mDirection.R(), val8, val7);
cSAngle sp110;
sp110 = mViewCache.mDirection.V();
if (bVar5) {
sp110 = cSAngle(val12);
}
if (sp110 < stack_44c) {
sp110 = stack_44c;
}
if (sp110 > stack_450) {
sp110 = stack_450;
}
cSGlobe stack_42c(sp19C, sp110, cSAngle(mControlledYaw.Inv()));
mViewCache.mDirection.R(mViewCache.mDirection.R()
+ (stack_42c.R() - mViewCache.mDirection.R()) * ratio);
mViewCache.mDirection.V(mViewCache.mDirection.V()
+ (stack_42c.V() - mViewCache.mDirection.V()) * ratio);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
if (mCurCamStyleTimer >= tower->field_0x4 - 1) {
mStyleSettle.mFinished = true;
}
tower->field_0x24 = mViewCache.mDirection.V().Degree();
tower->field_0x1c = tower->field_0x20 = mViewCache.mDirection.R();
mViewCache.mFovy += (val17 - mViewCache.mFovy) * ratio;
tower->field_0x8 -= tower->field_0xc;
return true;
}
cXyz sp408 = positionOf(mpPlayerActor);
sp408.y += 10.0f;
f32 heightOffGround = footHeightOf(mpPlayerActor) - groundHeight(&sp408);
if (mBG.field_0xc0.field_0x44) {
tower->field_0x18 = 0.0f;
tower->field_0x10 = 0;
} else if (tower->field_0x10 < 80) {
tower->field_0x10++;
tower->field_0x18 += (unkFloatConst1 - tower->field_0x18)
* dCamMath::rationalBezierRatio(tower->field_0x10 / 80.0f, 1.25f);
}
cSAngle sp10C = sp11C - mViewCache.mDirection.U();
cXyz sp3F4(tower->field_0x80, tower->field_0x84, tower->field_0x80);
mViewCache.mCenter += (stack_228 - mViewCache.mCenter) * sp3F4;
sp40C = attentionPos(mpPlayerActor);
sp40C.y -= 15.0f;
cSGlobe sp238 = mViewCache.mEye - mViewCache.mCenter;
f32 fVar18 = 1.0f;
if (val7 > val8) {
fVar18 = (mViewCache.mDirection.R() - val8) / (val7 - val8);
if (fVar18 < 0.0f) {
fVar18 = 0.0f;
}
if (fVar18 > 1.0f) {
fVar18 = 1.0f;
}
}
bool spinner_path_move_temp = player->checkSpinnerPathMove();
bool spinner_path_move = spinner_path_move_temp;
f32 sp18C = mPadInfo.mCStick.mLastPosX;
f32 sp188 = spinner_path_move ? 1.0f : mPadInfo.mMainStick.mLastValue;
f32 sp184 = 0.05f;
f32 sp180 = 8.0f;
cSAngle sp108;
cSAngle sp104 = stack_454 + (stack_454 - stack_458) * sp188;
if (!mCamParam.Flag(param_0, 0x40) && fabsf(sp18C) > sp184) {
cSAngle sp100 = mViewCache.mDirection.U() + cSAngle(dCamMath::rationalBezierRatio(sp18C, 0.5f) * sp180);
f32 sp17C = fabsf(sp18C) - sp184;
sp108.Val(mViewCache.mDirection.U() + (sp100 - mViewCache.mDirection.U()) * sp17C);
tower->field_0x6a = true;
tower->field_0x78 += (0.8f - tower->field_0x78) * 0.05f;
tower->field_0x28 = sp108;
} else {
if (tower->field_0x6a) {
tower->field_0x78 = 0.0f;
tower->field_0x6a = false;
}
if (mCamParam.Flag(param_0, 0x800)) {
cSAngle stack_47c;
stack_47c.Val(stack_41c.U() - directionOf(mpPlayerActor));
f32 fVar19 = mMonitor.field_0x10 / playerMaxSpeed();
if (fVar19 > 1.0f) {
fVar19 = 1.0f;
}
if (stack_47c > cSAngle::_0) {
if (tower->field_0x44 < 1.0f) {
tower->field_0x44 += fVar19 * 0.025f;
}
} else {
if (tower->field_0x44 > -1.0f) {
tower->field_0x44 -= fVar19 * 0.025f;
}
}
tower->field_0x78 += (0.5f - tower->field_0x78) * 0.05f;
if (tower->field_0x64 == 0) {
cSAngle stack_480 = cSAngle::_180 - sp104;
tower->field_0x28 = stack_41c.U().Inv() - stack_480 * tower->field_0x44;
} else {
cSAngle stack_484 = sp104;
tower->field_0x28 = stack_41c.U() - stack_484 * tower->field_0x44;
}
} else if (mCamParam.Flag(param_0, 0x100)) {
if (!uVar2) {
cSAngle stack_488 = sp238.U() - stack_41c.U();
f32 tmp = dCamMath::rationalBezierRatio(fVar18, val20);
if (stack_488 > sp104) {
tmp = 1.0f;
}
sp108.Val(sp238.U() + ((stack_41c.U() + sp104) - sp238.U()) * tmp);
} else {
cSAngle stack_48c = stack_41c.U() - sp238.U();
f32 tmp = dCamMath::rationalBezierRatio(fVar18, val20);
if (stack_48c > sp104) {
tmp = 1.0f;
}
sp108.Val(sp238.U() + ((stack_41c.U() - sp104) - sp238.U()) * tmp);
}
tower->field_0x28 += (sp108 - tower->field_0x28) * 0.33f;
f32 var_f15 = sp188;
if (check_owner_action(mPadID, 0x2000108)) {
var_f15 = 0.0f;
}
tower->field_0x78 = val27 + val22 * var_f15;
} else {
if (uVar1) {
f32 sp168 = 1.0f;
sp108.Val(sp238.U() + ((stack_41c.U() + sp104) - sp238.U()) * sp168);
} else {
f32 sp164 = 1.0f;
sp108.Val(sp238.U() + ((stack_41c.U() - sp104) - sp238.U()) * sp164);
}
tower->field_0x28 += (sp108 - tower->field_0x28) * 0.33f;
f32 sp160 = sp188;
if (check_owner_action(mPadID, 0x2000108) || tower->field_0x69 != uVar1) {
tower->field_0x78 = 0.0f;
} else {
f32 sp15C = val27 + val22 * sp160;
tower->field_0x78 += (sp15C - tower->field_0x78) * 0.05f;
}
}
}
tower->field_0x69 = uVar1;
mViewCache.mDirection.U(mViewCache.mDirection.U()
+ (tower->field_0x28 - mViewCache.mDirection.U()) * tower->field_0x78);
f32 temp = (val13 + (val12 - val13) * fVar18);
tower->field_0x24 += (temp - tower->field_0x24) * val11;
if (!mCamParam.Flag(param_0, 0x4000)) {
mForwardTiltOffset = cSAngle::_0;
}
cSAngle stack_490;
if (tower->field_0x10 == 0) {
stack_490.Val(tower->field_0x24 + mForwardTiltOffset.Degree());
tower->field_0x74 += (val16 - tower->field_0x74) * 0.01f;
} else {
stack_490 = sp238.V();
tower->field_0x24 = stack_490.Degree();
tower->field_0x74 = dCamMath::rationalBezierRatio(tower->field_0x18, 0.7f);
}
if (stack_490 < stack_44c) {
stack_490.Val(stack_44c);
} else if (stack_490 > stack_450) {
stack_490.Val(stack_450);
}
mViewCache.mDirection.V(mViewCache.mDirection.V()
+ (stack_490 - mViewCache.mDirection.V()) * tower->field_0x74);
f32 dVar20 = sp238.R();
tower->field_0x1c += (val8 - tower->field_0x1c) * val11;
tower->field_0x20 += (val7 - tower->field_0x20) * val11;
if (dVar20 < tower->field_0x1c) {
tower->field_0x70 += (val10 - tower->field_0x70) * 0.01f;
dVar20 = tower->field_0x1c;
} else if (dVar20 > tower->field_0x20) {
tower->field_0x70 += (val10 - tower->field_0x70) * 0.01f;
dVar20 = tower->field_0x20;
} else {
tower->field_0x70 = 1.0f;
}
if (mCamParam.Flag(param_0, 0x400)) {
cSGlobe stack_43c(dVar20, mViewCache.mDirection.V(), mViewCache.mDirection.U());
cXyz stack_258;
cXyz stack_264 = mViewCache.mCenter + stack_43c.Xyz();
tower->field_0x68 = false;
if (lineBGCheck(&stack_264, &mViewCache.mCenter, &stack_258, 0x40b7)) {
tower->field_0x68 = true;
}
}
mViewCache.mDirection.R(mViewCache.mDirection.R()
+ (dVar20 - mViewCache.mDirection.R()) * tower->field_0x70);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
if (mBG.field_0x0.field_0x0 && mViewCache.mEye.y < mBG.field_0x0.field_0x58 + 5.0f) {
mViewCache.mEye.y = mBG.field_0x0.field_0x58 + 5.0f;
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
}
tower->field_0x7c += (val21 - tower->field_0x7c) * 0.01f;
f32 tmp = val18 + (val17 - val18) * fVar18;
mViewCache.mFovy += (tmp - mViewCache.mFovy) * tower->field_0x7c;
return true;
}
bool dCamera_c::hookshotCamera(s32 param_0) {
f32 val0 = mCamParam.Val(param_0, 0);
f32 val2 = mCamParam.Val(param_0, 2);
f32 val1 = mCamParam.Val(param_0, 1);
f32 val5 = mCamParam.Val(param_0, 5);
f32 val6 = mCamParam.Val(param_0, 6);
f32 val7 = mCamParam.Val(param_0, 7);
f32 val8 = mCamParam.Val(param_0, 8);
f32 val11 = mCamParam.Val(param_0, 11);
f32 val23 = mCamParam.Val(param_0, 23);
f32 val17 = mCamParam.Val(param_0, 17);
cXyz stack_9c[4] = {
cXyz(180.0f, 20.0f, -160.0f),
cXyz(160.0f, 60.0f, -200.0f),
cXyz(170.0f, -80.0f, -150.0f),
cXyz(100.0f, -120.0f, -240.0f),
};
cXyz stack_cc[4] = {
cXyz(40.0f, -150.0f, 340.0f),
cXyz(10.0f, -100.0f, 280.0f),
cXyz(80.0f, -50.0f, 200.0f),
cXyz(40.0f, -80.0f, -160.0f),
};
int var_r23 = 8;
HookshotData* hookshot = (HookshotData*)mWork;
cXyz stack_d8;
cXyz stack_e4(val0, val2, val1);
if (mCurCamStyleTimer == 0) {
hookshot->field_0x0 = 'HOOK';
hookshot->field_0x8 = mCenter;
cXyz stack_f0 = positionOf(mpPlayerActor);
cXyz stack_fc = daAlink_getAlinkActorClass()->getHsChainTopPos();
csXyz stack_20c = daAlink_getAlinkActorClass()->getHsAngle();
cXyz stack_108 = stack_fc - stack_f0;
bool iVar2 = stack_20c.x < -0x3333;
cXyz* array;
if (iVar2) {
cSGlobe stack_214 = stack_108;
stack_20c.x = stack_214.V();
stack_20c.y = stack_214.U();
stack_20c.z = 0;
array = stack_cc;
} else {
array = stack_9c;
}
if (stack_108.abs() > val11 && mCamParam.Flag(param_0, 0x800)) {
cXyz stack_114;
cSGlobe stack_21c;
bool uVar6 = (mFrameCounter & 0x10) != 0;
for (int i = 0; i < 8; i++) {
stack_114 = array[i >> 1];
if (uVar6) {
stack_114.x = -stack_114.x;
}
stack_21c.Val(stack_114);
stack_21c.U(stack_21c.U() + stack_20c.y);
if (!iVar2) {
stack_21c.V(stack_21c.V() + stack_20c.x);
}
hookshot->field_0x14 = stack_fc + stack_21c.Xyz();
if (!lineBGCheck(&stack_f0, &hookshot->field_0x14, 7)) {
hookshot->field_0x20 = true;
break;
}
uVar6 = !uVar6;
}
}
mStyleSettle.mFinished = true;
return true;
}
f32 fovy;
if (hookshot->field_0x20 && mCurCamStyleTimer > var_r23 && mCamParam.Flag(param_0, 0x800)) {
stack_d8 = hookshot->field_0x14;
fovy = val17;
val23 = 1.0f;
} else {
stack_d8 = mEye;
fovy = val17;
}
cXyz stack_120(val6, val5, val6);
cXyz stack_12c = relationalPos(mpPlayerActor, &stack_e4);
if (mBG.field_0xc0.field_0x1) {
dComIfG_Bgsp().MoveBgMatrixCrrPos(mBG.field_0x5c.field_0x4, true,
&hookshot->field_0x8, NULL, NULL);
dComIfG_Bgsp().MoveBgMatrixCrrPos(mBG.field_0x5c.field_0x4, true,
&hookshot->field_0x14, NULL, NULL);
}
mViewCache.mCenter += (stack_12c - mViewCache.mCenter) * stack_120;
cSGlobe stack_224 = stack_d8 - mViewCache.mCenter;
if (stack_224.R() < val8) {
stack_224.R(val8);
}
if (stack_224.R() > val7) {
stack_224.R(val7);
}
mViewCache.mDirection.R(mViewCache.mDirection.R()
+ (stack_224.R() - mViewCache.mDirection.R()) * val23);
mViewCache.mDirection.V(mViewCache.mDirection.V()
+ (stack_224.V() - mViewCache.mDirection.V()) * val23);
mViewCache.mDirection.U(mViewCache.mDirection.U()
+ (stack_224.U() - mViewCache.mDirection.U()) * val23);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy += (fovy - mViewCache.mFovy) * val23;
return true;
}
bool dCamera_c::railCamera(s32 param_0) {
f32 proximityEaseBias = mCamParam.Val(param_0, 15);
f32 targetRadiusFar = mCamParam.Val(param_0, 7);
f32 targetRadiusNear = mCamParam.Val(param_0, 10);
f32 searchRadius = mCamParam.Val(param_0, 11);
f32 influenceDistMax = mCamParam.Val(param_0, 9);
#if DEBUG
f32 val12 = mCamParam.Val(param_0, 12);
#endif
f32 val27 = mCamParam.Val(param_0, 27);
f32 fovFar = mCamParam.Val(param_0, 17);
f32 fovNear = mCamParam.Val(param_0, 20);
f32 responseGain = mCamParam.Val(param_0, 21);
f32 responseLerpRate = mCamParam.Val(param_0, 14);
f32 centerLerpGainY = mCamParam.Val(param_0, 5);
f32 centerLerpGainXZ = mCamParam.Val(param_0, 6);
f32 playerOffsetX = mCamParam.Val(param_0, 0);
f32 playerOffsetY = mCamParam.Val(param_0, 2);
f32 playerOffsetZ = mCamParam.Val(param_0, 1);
RailData* rail = (RailData*)mWork;
if (mCurCamStyleTimer == 0) {
if (chkFlag(0x1000)) {
responseGain = 1.0f;
val27 = 1.0f;
rail->field_0x10 = 1.0f;
} else {
rail->field_0x10 = 0.0f;
}
rail->field_0x0d = 0xff;
}
rail->field_0x10 += responseLerpRate * (responseGain - rail->field_0x10);
if (mRoomMapTool.mCameraIndex == 0xff || mRoomMapTool.mPathId == 0xff) {
OS_REPORT("camera: rail data not found!\n");
return false;
}
s8 roomNo = fopAcM_GetRoomNo(this->mpPlayerActor);
dPath* roomPath = dPath_GetRoomPath(mRoomMapTool.mPathId, roomNo);
if (roomPath == NULL) {
OS_REPORT("camera: rail data not found!\n");
return false;
}
mCamParam.Arg0(mRoomMapTool.mCamData.field_0x12);
if (mCamParam.Arg0() != 0xff) {
searchRadius = (f32)(s8)mCamParam.Arg0() * 100.0f;
}
s32 roomPathLen = roomPath->m_num;
f32 bestHorDist = 0.0f;
if (mCurCamStyleTimer == 0) {
rail->field_0x00 = 'RAIL';
mStyleSettle.mFinished = true;
rail->field_0x0c = 0xff;
rail->field_0x14 = attentionPos(this->mpPlayerActor);
if (mCamParam.Flag(param_0, 0x800)) {
rail->field_0x08 = getParamTargetActor(mCurType);
if (rail->field_0x08 == NULL) {
OS_REPORT("camera: target %s actor not found!\n", &mCamTypeData[mCurType].name[16]);
}
}
rail->field_0x0d = 0xfe;
}
if (rail->field_0x0d != mRoomMapTool.mPathId) {
rail->field_0x0d = mRoomMapTool.mPathId;
rail->field_0x20.x = mRoomMapTool.mArrowData.posX;
rail->field_0x20.y = mRoomMapTool.mArrowData.posY;
rail->field_0x20.z = mRoomMapTool.mArrowData.posZ;
if (mCamParam.Flag(param_0, 0x800)) {
cXyz attnPos = attentionPos(mpPlayerActor);
cXyz curPointPos = (Vec)roomPath->m_points->m_position;
cXyz prevPointPos = (Vec)roomPath->m_points[roomPathLen - 1].m_position;
f32 horDist1 = dCamMath::xyzHorizontalDistance(curPointPos, attnPos);
f32 horDist2 = dCamMath::xyzHorizontalDistance(prevPointPos, attnPos);
if (horDist1 < horDist2) {
rail->field_0x14 = prevPointPos;
} else {
rail->field_0x14 = curPointPos;
}
}
}
cXyz focusPos;
cXyz eyeRefPos;
if (mCamParam.Flag(param_0, 0x800) && rail->field_0x08 != NULL) {
eyeRefPos = positionOf(rail->field_0x08);
eyeRefPos.y += 300.0f;
if (mpLockonTarget != NULL) {
mpAuxTargetActor1 = rail->field_0x04 = mpLockonTarget;
setFlag(0x2000);
focusPos = attentionPos(rail->field_0x04);
} else {
mpAuxTargetActor1 = rail->field_0x04 = rail->field_0x08;
setFlag(0x2000);
focusPos = eyeRefPos;
}
} else if (mCamParam.Flag(param_0, 0x100)) {
rail->field_0x08 = rail->field_0x04 = NULL;
focusPos = attentionPos(mpPlayerActor);
eyeRefPos = rail->field_0x20;
} else if (mpLockonTarget != NULL) {
mpAuxTargetActor1 = rail->field_0x08 = rail->field_0x04 = mpLockonTarget;
focusPos = attentionPos(rail->field_0x04);
setFlag(0x2000);
eyeRefPos = attentionPos(rail->field_0x08);
} else {
rail->field_0x08 = rail->field_0x04 = NULL;
focusPos = attentionPos(mpPlayerActor);
eyeRefPos = mEye;
}
cSGlobe focusFromPlayer = focusPos - attentionPos(mpPlayerActor);
f32 proximityRatio = 1.0f - focusFromPlayer.R() / influenceDistMax;
if (focusFromPlayer.R() > searchRadius * 2.0f) {
rail->field_0x08 = rail->field_0x04 = 0;
cSGlobe dirGlobe = mViewCache.mDirection;
dirGlobe.R(-searchRadius);
focusPos = eyeRefPos = attentionPos(mpPlayerActor) + dirGlobe.Xyz();
proximityRatio = 0.0f;
} else {
if (proximityRatio < 0.0f) {
proximityRatio = 0.0f;
} else if (proximityRatio > 1.0f) {
proximityRatio = 1.0f;
}
}
cXyz desiredCenter;
cXyz centerLerpGainVec(centerLerpGainXZ, centerLerpGainY, centerLerpGainXZ);
cXyz playerOffset(playerOffsetX, playerOffsetY, playerOffsetZ);
focusFromPlayer.R(proximityRatio * focusFromPlayer.R() * 0.75f);
int i;
if (mCamParam.Flag(param_0, 0x400)) {
cXyz unkXyz5;
bool unkFlag1 = false;
cM3dGLin unkLine1;
for (i = 0; i < roomPathLen - 1; i++) {
unkLine1.set(roomPath->m_points[i].m_position,
roomPath->m_points[i + 1].m_position);
f32 unusedFloat1;
if (cM3d_Len3dSqPntAndSegLine(&unkLine1, &eyeRefPos, &unkXyz5, &unusedFloat1) != 0) {
unkXyz5 += (eyeRefPos - unkXyz5) * 0.1f;
unkFlag1 = true;
break;
}
}
if (!unkFlag1) {
unkXyz5 = attentionPos(mpPlayerActor) + focusFromPlayer.Xyz();
}
desiredCenter = mViewCache.mCenter + (unkXyz5 - mViewCache.mCenter) * 0.1f;
} else {
desiredCenter = relationalPos(mpPlayerActor, &playerOffset) + focusFromPlayer.Xyz();
}
mViewCache.mCenter += (desiredCenter - mViewCache.mCenter) * centerLerpGainVec;
proximityRatio = dCamMath::rationalBezierRatio(proximityRatio, proximityEaseBias);
cM3dGSph searchSphere;
searchSphere.Set(mViewCache.mCenter, searchRadius);
bestHorDist = 0.0f;
cXyz bestEyePos = mViewCache.mEye;
s32 intersectCount = 0;
if (mCamParam.Flag(param_0, 0x800)) {
eyeRefPos = rail->field_0x14;
}
cXyz segStart;
cXyz segEnd;
cXyz crossPosA;
cXyz crossPosB;
cM3dGLin segLine;
f32 horDist;
for (i = 0; i < roomPathLen - 1; i++) {
segStart.set(roomPath->m_points[i].m_position);
segEnd.set(roomPath->m_points[i + 1].m_position);
segLine.set(segStart, segEnd);
switch (cM3d_Cross_LinSph_CrossPos(searchSphere, segLine, &crossPosA, &crossPosB)) {
case 2:
if (posInLine2D(&segStart, &segEnd, &crossPosB) != 0) {
horDist = dCamMath::xyzHorizontalDistance(crossPosB, eyeRefPos);
if (horDist > bestHorDist) {
bestHorDist = horDist;
bestEyePos = crossPosB;
}
intersectCount++;
}
case 1:
if (posInLine2D(&segStart, &segEnd, &crossPosA) != 0) {
horDist = dCamMath::xyzHorizontalDistance(crossPosA, eyeRefPos);
if (horDist > bestHorDist) {
bestHorDist = horDist;
bestEyePos = crossPosA;
}
intersectCount++;
}
break;
}
}
if (dPath_ChkClose(roomPath)) {
segStart.set(roomPath->m_points[i].m_position);
segEnd.set(roomPath->m_points->m_position);
segLine.set(segStart, segEnd);
switch (cM3d_Cross_LinSph_CrossPos(searchSphere, segLine, &crossPosA, &crossPosB)) {
case 2:
if (posInLine2D(&segStart, &segEnd, &crossPosB) != 0) {
horDist = dCamMath::xyzHorizontalDistance(crossPosB, eyeRefPos);
if (horDist > bestHorDist) {
bestHorDist = horDist;
bestEyePos = crossPosB;
}
intersectCount++;
}
case 1:
if (posInLine2D(&segStart, &segEnd, &crossPosA) != 0) {
horDist = dCamMath::xyzHorizontalDistance(crossPosA, eyeRefPos);
if (horDist > bestHorDist) {
bestHorDist = horDist;
bestEyePos = crossPosA;
}
intersectCount++;
}
break;
}
roomPathLen++;
}
if (intersectCount == 0) {
// empty block
}
cSGlobe eyeFromCenter = bestEyePos - mViewCache.mCenter;
cSAngle unkAngle1 = eyeFromCenter.U() - mViewCache.mDirection.U();
static cSAngle _120 = 120.0f;
if (unkAngle1.Abs() > _120) {
setUSOAngle();
}
f32 desiredRadius;
if (mCamParam.Flag(param_0, 0x1000)) {
desiredRadius = eyeFromCenter.R();
} else {
desiredRadius = targetRadiusFar - proximityRatio * (targetRadiusFar - targetRadiusNear);
}
mViewCache.mDirection.R(mViewCache.mDirection.R() +
rail->field_0x10 * (desiredRadius - mViewCache.mDirection.R()));
mViewCache.mDirection.U(mViewCache.mDirection.U() +
(eyeFromCenter.U() - mViewCache.mDirection.U()) * rail->field_0x10);
mViewCache.mDirection.V(mViewCache.mDirection.V() +
(eyeFromCenter.V() - mViewCache.mDirection.V()) * rail->field_0x10);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
f32 sp28 = fovFar - proximityRatio * (fovFar - fovNear);
mViewCache.mFovy += responseGain * (sp28 - mViewCache.mFovy);
return true;
}
bool dCamera_c::paraRailCamera(s32 param_0) {
int i;
f32 val7 = mCamParam.Val(param_0, 7);
f32 val10 = mCamParam.Val(param_0, 10);
f32 val11 = mCamParam.Val(param_0, 11);
f32 val9 = mCamParam.Val(param_0, 9);
f32 val15 = mCamParam.Val(param_0, 15);
f32 val14 = mCamParam.Val(param_0, 14);
f32 val17 = mCamParam.Val(param_0, 17);
f32 val20 = mCamParam.Val(param_0, 20);
f32 val21 = mCamParam.Val(param_0, 21);
f32 val5 = mCamParam.Val(param_0, 5);
f32 val6 = mCamParam.Val(param_0, 6);
f32 val0 = mCamParam.Val(param_0, 0);
f32 val2 = mCamParam.Val(param_0, 2);
f32 val1 = mCamParam.Val(param_0, 1);
ParaRailData* paraRail = (ParaRailData*)mWork;
mBumpCheckFlags = 0;
if (mTagCamTool.mCameraIndex == 0xff || mTagCamTool.mPathId == 0xff) {
OS_REPORT("camera: rail data not found!\n");
return false;
}
if (mCurCamStyleTimer == 0) {
if (chkFlag(0x1000)) {
val21 = 1.0f;
val6 = val5 = 1.0f;
paraRail->field_0x1c = 1.0f;
} else {
paraRail->field_0x1c = 0.0f;
}
paraRail->field_0x0d = 0xff;
}
paraRail->field_0x1c += val14 * (val21 - paraRail->field_0x1c);
s8 roomNo = fopAcM_GetRoomNo(mpPlayerActor);
dPath* path = dPath_GetRoomPath(mTagCamTool.mPathId, roomNo);
if (path == NULL) {
OS_REPORT("camera: rail data not found!\n");
return false;
}
mCamParam.Arg0(mRoomMapTool.mCamData.field_0x12);
if (mCamParam.Arg0() != 0xff) {
val11 = (f32)(s32)(s8)mCamParam.Arg0() * 100.0f;
}
cXyz sp260;
cXyz sp254;
cXyz sp248;
cM3dGLin sp288;
f32 sp50;
f32 sp4C;
u32 pathLen = path->m_num;
sp50 = 0.0f;
bool unkFlag1 = false;
if (mCurCamStyleTimer == 0) {
paraRail->field_0x00 = 'RARA';
mStyleSettle.mFinished = true;
paraRail->field_0x0c = 0xff;
unkFlag1 = true;
}
if (paraRail->field_0x0d != mRoomMapTool.mPathId) {
paraRail->field_0x0d = mRoomMapTool.mPathId;
}
cXyz sp23C;
cXyz sp230;
if (mpLockonTarget != NULL) {
mpAuxTargetActor1 = paraRail->field_0x08 = paraRail->field_0x04 = mpLockonTarget;
sp23C = attentionPos(paraRail->field_0x04);
setFlag(0x2000);
sp230 = attentionPos(paraRail->field_0x08);
} else {
paraRail->field_0x08 = paraRail->field_0x04 = NULL;
cSGlobe spA8 = mViewCache.mDirection;
spA8.R(100.0f);
sp23C = sp230 = attentionPos(mpPlayerActor) + spA8.Xyz();
}
cSGlobe sp17C = sp23C - attentionPos(mpPlayerActor);
f32 var_f31 = 1.0f - sp17C.R() / val9;
if (sp17C.R() > val11 * 2.0f) {
paraRail->field_0x08 = paraRail->field_0x04 = NULL;
cSGlobe sp98 = mViewCache.mDirection;
sp98.R(-val11);
sp23C = sp230 = attentionPos(mpPlayerActor) + sp98.Xyz();
var_f31 = 0.0f;
} else {
if (var_f31 < 0.0f) {
var_f31 = 0.0f;
} else if (var_f31 > 1.0f) {
var_f31 = 1.0f;
}
}
cXyz sp224;
cXyz sp218(val6, val5, val6);
cXyz sp20C(val0, val2, val1);
sp17C.R(var_f31 * sp17C.R() * 0.75f);
if (mCamParam.Flag(param_0, 0x400)) {
cXyz sp200;
bool unkFlag2 = false;
cM3dGLin sp26C;
for (i = 0; i < (int)(pathLen - 1); i++) {
sp26C.set(path->m_points[i].m_position,
path->m_points[i + 1].m_position);
f32 sp44;
if (cM3d_Len3dSqPntAndSegLine(&sp26C, &sp230, &sp200, &sp44) != 0) {
sp200 += (sp230 - sp200) * 0.1f;
unkFlag2 = true;
break;
}
}
if (!unkFlag2) {
cXyz sp1F4 = attentionPos(mpPlayerActor);
cXyz sp1E8 = (Vec)path->m_points->m_position;
cXyz sp1DC = (Vec)path->m_points[pathLen - 1].m_position;
f32 horDist1 = dCamMath::xyzHorizontalDistance(sp1E8, sp1F4);
f32 horDist2 = dCamMath::xyzHorizontalDistance(sp1DC, sp1F4);
if (horDist1 < horDist2) {
sp200 = sp1E8;
} else {
sp200 = sp1DC;
}
sp200 += (sp230 - sp200) * 0.1f;
}
sp224 = sp200;
} else {
sp224 = relationalPos(mpPlayerActor, &sp20C) + sp17C.Xyz();
}
mViewCache.mCenter += (sp224 - mViewCache.mCenter) * sp218;
var_f31 = dCamMath::rationalBezierRatio(var_f31, val15);
sp50 = val11 * val11;
cXyz cStack_120 = mViewCache.mEye;
int sp38 = 0;
for (i = 0; i < (int)(pathLen - 1); i++) {
sp254.set(path->m_points[i].m_position);
sp248.set(path->m_points[i + 1].m_position);
sp288.set(sp254, sp248);
if (cM3d_Len3dSqPntAndSegLine(&sp288, &mViewCache.mCenter, &sp260,
&sp4C)) {
if (sp4C < sp50) {
sp50 = sp4C;
cStack_120 = sp260;
}
sp38++;
}
}
if (dPath_ChkClose(path)) {
sp254.set(path->m_points[i].m_position);
sp248.set(path->m_points->m_position);
sp288.set(sp254, sp248);
if (cM3d_Len3dSqPntAndSegLine(&sp288, &mViewCache.mCenter, &sp260,
&sp4C) != 0) {
if (sp4C < sp50) {
sp50 = sp4C;
cStack_120 = sp260;
}
sp38++;
}
pathLen++;
}
if (sp38 == 0) {
if (mCamParam.Flag(param_0, 0x1000)) {
sp254.set(path->m_points->m_position);
sp248.set(path->m_points[path->m_num - 1].m_position);
f32 horDist1 = dCamMath::xyzHorizontalDistance(sp254, sp230);
f32 horDist2 = dCamMath::xyzHorizontalDistance(sp248, sp230);
if (horDist1 < horDist2) {
cStack_120 = sp254;
sp50 = horDist1;
} else {
cStack_120 = sp248;
sp50 = horDist2;
}
} else {
#if DEBUG
dDbVw_Report(0xb4, 0xf0, "camera: point not found!!");
#endif
}
}
if (unkFlag1) {
paraRail->field_0x10 = cStack_120;
} else {
paraRail->field_0x10 += (cStack_120 - paraRail->field_0x10) * 0.1f;
}
cSGlobe cStack_260 = paraRail->field_0x10 - mViewCache.mCenter;
cSAngle acStack_2cc = cStack_260.U() - mViewCache.mDirection.U();
static cSAngle _120 = 120.0f;
if (acStack_2cc.Abs() > _120) {
setUSOAngle();
}
f32 local_2c4;
if (mCamParam.Flag(param_0, 0x1000)) {
local_2c4 = cStack_260.R();
} else {
local_2c4 = val7 - var_f31 * (val7 - val10);
}
mViewCache.mDirection.R(mViewCache.mDirection.R() + paraRail->field_0x1c * (local_2c4 - mViewCache.mDirection.R()));
mViewCache.mDirection.U(mViewCache.mDirection.U() +
(cStack_260.U() - mViewCache.mDirection.U()) * paraRail->field_0x1c);
mViewCache.mDirection.V(mViewCache.mDirection.V() +
(cStack_260.V() - mViewCache.mDirection.V()) * paraRail->field_0x1c);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
f32 sp28 = val17 - var_f31 * (val17 - val20);
mViewCache.mFovy += paraRail->field_0x1c * (sp28 - mViewCache.mFovy);
return true;
}
bool dCamera_c::rideCamera(s32 param_0) {
static cSAngle LatMin = -80.0f;
static cSAngle LatMax = 80.0f;
f32 val2 = mCamParam.Val(param_0, 2);
f32 val1 = mCamParam.Val(param_0, 1);
f32 val0 = mCamParam.Val(param_0, 0);
f32 val25 = mCamParam.Val(param_0, 25);
f32 val6 = mCamParam.Val(param_0, 6);
f32 val5 = mCamParam.Val(param_0, 5);
f32 val7 = mCamParam.Val(param_0, 7);
f32 val10 = mCamParam.Val(param_0, 10);
f32 val11 = mCamParam.Val(param_0, 11);
f32 val12 = mCamParam.Val(param_0, 12);
f32 val15 = mCamParam.Val(param_0, 15);
f32 val22 = mCamParam.Val(param_0, 22);
f32 val27 = mCamParam.Val(param_0, 27);
cSAngle val23 = mCamParam.Val(param_0, 23);
f32 val17 = mCamParam.Val(param_0, 17);
f32 val20 = mCamParam.Val(param_0, 20);
f32 val21 = mCamParam.Val(param_0, 21);
f32 val4 = mCamParam.Val(param_0, 4);
f32 val9 = mCamParam.Val(param_0, 9);
f32 val14 = mCamParam.Val(param_0, 14);
f32 val19 = mCamParam.Val(param_0, 19);
f32 val24 = mCamParam.Val(param_0, 24);
f32 val26 = mCamParam.Val(param_0, 26);
if (!(val26 >= 0.0f && val26 <= 1.0f)) {
val26 = 0.5f;
}
cSAngle sp148 = -15.0f;
f32 sp1F8 = 0.1f;
int sp1F4 = 13;
int sp1F0 = 2;
f32 sp1EC = 1.0500001f;
f32 sp1E8 = 1.1500001f;
cSAngle sp144 = cSAngle::_0;
#if WIDESCREEN_SUPPORT
if (mDoGph_gInf_c::isWide()) {
val22 *= WideTurnSaving;
}
#endif
RideData* wk = (RideData*)mWork;
int sp1E4 = 20;
f32 var_f31 = 1.0f;
daAlink_c* player = (daAlink_c*)daAlink_getAlinkActorClass();
dAttention_c* attn = dComIfGp_getAttention();
if (mCurCamStyleTimer == 0) {
if (mRecovery.field_0x8.field_0x1e <= 0) {
mViewCache.mCenter = mCenter;
mViewCache.mEye = mEye;
mViewCache.mDirection = mDirection;
}
wk->field_0x98 = 0;
wk->field_0x9c = mpPlayerActor;
wk->field_0xa0 = 0;
if (player->checkHorseRide()) {
wk->field_0xa0 = dComIfGp_getHorseActor();
wk->field_0x98 = (daHorse_c*)wk->field_0xa0;
wk->field_0x00 = 0;
} else if (player->checkCargoCarry()) {
fopAc_ac_c* spA0 = fopAcM_SearchByName(fpcNm_KAGO_e);
if (spA0 != NULL) {
wk->field_0x9c = spA0;
wk->field_0xa0 = spA0;
if (mCurCamStyleTimer != 0) {
f32 sp1D4 = cXyz(positionOf(wk->field_0x9c) - wk->field_0x84).abs();
mMonitor.field_0x10 = sp1D4;
}
}
setFlag(0x8000);
wk->field_0x00 = 3;
}
wk->field_0x1c = 0;
wk->field_0x68.x = 0.0f;
wk->field_0x68.y = 0.0f;
wk->field_0x68.z = 0.0f;
}
field_0x944 = 1;
wk->field_0x48.Val(directionOf(wk->field_0x9c));
wk->field_0x08 = 0;
wk->field_0x84 = positionOf(wk->field_0x9c);
if (mCurCamStyleTimer == 0) {
wk->prove = 'RIDE';
wk->field_0x30 = cXyz::Zero;
wk->field_0x20 = 0;
wk->field_0x0c = mFrameCounter;
wk->field_0x1d = 1;
wk->field_0x5c.x = 0.0f;
wk->field_0x4c = mViewCache.mDirection.R();
wk->field_0x50 = 0.0f;
wk->field_0x54 = mViewCache.mDirection.V().Degree();
wk->field_0x58 = 0.0f;
wk->field_0x5c.y = 1.0f;
wk->field_0x08 = 0;
wk->field_0x3c = mViewCache.mCenter;
wk->field_0x24 = mViewCache.mCenter;
wk->field_0x90 = 0;
wk->field_0x18 = -1;
wk->field_0x10 = 0;
wk->field_0x14 = 0;
wk->field_0x78 = 0.0f;
wk->field_0x91 = 0;
wk->field_0x5c.z = sp1F8;
wk->field_0x7c = val27;
wk->field_0x94 = 0;
wk->field_0x92 = 0;
wk->field_0x93 = strncmp(&mCamTypeData[mCurType].name[16], "E_RD", 4) == 0;
if (mCamParam.Flag(param_0, 0x2000)) {
wk->field_0x94 = getParamTargetActor(mCurType);
}
if (mCamParam.Flag(param_0, 0x1000) && player->checkGoatThrow())
{
wk->field_0x94 = dComIfGoat_GetThrow();
wk->field_0x92 = 1;
}
if (player->checkBoardRide()) {
wk->field_0x94 = 0;
if (dComIfGs_isTmpBit((u16)dSv_event_tmp_flag_c::tempBitLabels[0x54])) {
wk->field_0x94 = fopAcM_SearchByName(fpcNm_NPC_YKM_e);
} else if (dComIfGs_isTmpBit((u16)dSv_event_tmp_flag_c::tempBitLabels[0x55])) {
wk->field_0x94 = fopAcM_SearchByName(fpcNm_NPC_YKW_e);
}
}
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
if (chkFlag(0x8000)) {
if (wk->field_0x98 == 0 && !player->checkCanoeRide()) {
wk->field_0x20 = 2;
mStyleSettle.mFinished = true;
}
} else {
if (chkFlag(32) && mCurType == specialType[9]) {
wk->field_0x20 = 3;
} else if (chkFlag(0x10000) || player->checkOctaIealHang()) {
wk->field_0x20 = 4;
} else {
if (mCamParam.Flag(param_0, 0x400)) {
wk->field_0x20 = 5;
}
}
}
}
JUT_ASSERT(0x2c12, wk->prove == 'RIDE');
f32 sp1D0 = mMonitor.field_0x10 / val11;
if (wk->field_0x98 != NULL) {
if (wk->field_0x98->getLashDashStart()) {
onHorseDush();
wk->field_0x10 = wk->field_0x18 = sp1F4;
wk->field_0x7c = 0.0f;
} else {
if (wk->field_0x10 != 0) {
wk->field_0x10--;
} else {
wk->field_0x7c = wk->field_0x7c + (val27 - wk->field_0x7c) * 0.1f;
wk->field_0x18 = -1;
}
}
} else {
wk->field_0x10 = 0;
wk->field_0x18 = -1;
wk->field_0x7c = wk->field_0x7c + (val27 - wk->field_0x7c) * 0.1f;
}
if (sp1D0 < -1.0f) {
sp1D0 = -1.0f;
} else {
if (sp1D0 > 1.0f) {
sp1D0 = 1.0f;
}
}
bool sp0F;
bool sp0E;
if (mGear == 1) {
val2 = val4;
val12 = val14;
val7 = val9;
val17 = val19;
sp0F = false;
sp0E = false;
}
f32 sp1CC = 0.0f;
f32 sp1C8 = 0.0f;
if (wk->field_0x92 != 0 && wk->field_0x94 != 0) {
fopAc_ac_c* sp1C4 = wk->field_0x94;
f32 sp1C0 = 400.0f;
f32 sp1BC = 1200.0f;
cXyz sp4F0 = positionOf(sp1C4) - positionOf(wk->field_0x9c);
f32 sp1B8 = sp4F0.abs();
cSAngle sp140 = -mViewCache.mDirection.U();
sp4F0 = dCamMath::xyzRotateY(sp4F0, sp140);
f32 sp1B4;
cXyz sp4E4 = sp4F0;
if (fabsf(sp4E4.y) < 200.0f) {
sp4E4.y = 0.0f;
sp4E4.x *= 0.5f;
f32 sp1B0 = sp4E4.abs();
if (sp1B0 < sp1BC) {
sp1B4 = 1.0f - sp1B0 / sp1BC;
sp1CC = -sp4F0.x * 0.6f * sp1B4;
}
}
if (mGear != 1) {
if (sp1B8 < sp1C0) {
sp1B4 = 1.0f;
} else if (sp1B8 > sp1BC) {
sp1B4 = 0.0f;
} else {
sp1B4 = 1.0f - (sp1B8 - sp1C0) / (sp1BC - sp1C0);
}
val2 += (-80.0f - val2) * sp1B4;
val12 += (28.0f - val12) * sp1B4;
val7 += (320.0f - val7) * sp1B4;
val22 += (0.3f - val22) * sp1B4;
sp140 = mViewCache.mDirection.U() - directionOf(wk->field_0x9c);
sp1F8 = 0.25f;
}
} else {
if (wk->field_0x98 != 0) {
fopAc_ac_c* sp1AC = attn->LockonTarget(0);
fopAc_ac_c* sp1A8 = attn->LockonTarget(1);
fopAc_ac_c* sp1A4 = attn->CheckObjectTarget(0);
if (wk->field_0x94 != 0) {
cXyz sp4D8 = attentionPos(wk->field_0x9c);
cXyz sp4CC = attentionPos(wk->field_0x94);
f32 sp1A0 = dCamMath::xyzHorizontalDistance(sp4D8, sp4CC);
if (sp1A0 < 6000.0f) {
sp1AC = wk->field_0x94;
sp1A8 = NULL;
}
}
if (sp1AC != NULL &&
(fopAcM_GetName(sp1AC) == fpcNm_E_RD_e || fopAcM_GetName(sp1AC) == fpcNm_E_FK_e ||
fopAcM_GetName(sp1AC) == fpcNm_B_GND_e || fopAcM_GetName(sp1AC) == fpcNm_E_KR_e))
{
cXyz sp4C0 = positionOf(sp1AC) - positionOf(wk->field_0x9c);
cSAngle spF8 = -mViewCache.mDirection.U();
sp4C0 = dCamMath::xyzRotateY(sp4C0, spF8);
cXyz sp4B4 = sp4C0;
if (fabsf(sp4B4.y) < 200.0f) {
sp4B4.y = 0.0f;
sp4B4.x *= 0.5f;
f32 sp19C = sp4B4.abs();
if (sp19C < 1000.0f) {
sp1CC = -sp4C0.x * 0.6f * (1.0f - sp19C / 1000.0f);
sp1CC = sp1CC * sp1D0;
}
}
}
if (sp1A4 != NULL) {
cXyz sp4A8 = positionOf(sp1A4) - positionOf(wk->field_0x9c);
cSAngle spF4 = -mViewCache.mDirection.U();
sp4A8 = dCamMath::xyzRotateY(sp4A8, spF4);
cXyz sp49C = sp4A8;
if (fabsf(sp49C.y) < 200.0f) {
sp49C.y = 0.0f;
sp49C.x *= 0.5f;
f32 sp198 = sp49C.abs();
if (sp198 < 800.0f) {
sp1CC = -sp4A8.x * 0.8f * (1.0f - sp198 / 800.0f);
sp1CC = sp1CC * sp1D0;
}
}
}
if (sp1AC != NULL && fopAcM_GetName(sp1AC) == fpcNm_E_KR_e) {
val12 = -5.0f;
val15 = 10.0f;
val7 = 800.0f;
val10 = -100.0f;
val2 = -20.0f;
} else {
if (sp1AC != NULL &&
(fopAcM_GetName(sp1AC) == fpcNm_E_RD_e &&
(fopAcM_GetParam(sp1AC) & 4) != 0 ||
fopAcM_GetName(sp1AC) == fpcNm_B_GND_e) &&
sp1A8 == NULL)
{
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 0xeb, " RB");
}
#endif
if (wk->field_0x93 != 0) {
val7 = 550.0f;
val2 = -120.0f;
val12 = 23.0f;
val17 = 60.0f;
} else {
val7 = 780.0f;
val10 = -150.0f;
val12 = 25.0f;
val15 = -10.0f;
val17 = 55.0f;
val20 = 15.0f;
}
} else {
if (sp1AC != NULL && (fopAcM_GetName(sp1AC) == fpcNm_E_RD_e ||
fopAcM_GetName(sp1AC) == fpcNm_E_FK_e) ||
sp1A8 != NULL && (fopAcM_GetName(sp1A8) == fpcNm_E_RD_e ||
fopAcM_GetName(sp1A8) == fpcNm_E_FK_e) ||
sp1A4 != NULL)
{
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 0xeb, " RD");
}
#endif
if (mGear == 1) {
val7 -= 1000.0f;
val12 += 5.0f;
} else {
val2 = -80.0f;
val25 = -100.0f;
val1 = 300.0f;
val12 = 20.0f;
val15 = 5.0f;
val7 = 1250.0f;
val10 = -200.0f;
val20 = 10.0f;
}
}
}
}
if (wk->field_0x98->checkJump()) {
if (wk->field_0x91 == 0) {
wk->field_0x74 = 0.01f;
wk->field_0x91 = 1;
}
val5 = 0.5f;
val6 = 0.4f;
if (mViewCache.mDirection.V() < (cSAngle)10.0f) {
val25 = -20.0f;
val12 += 10.0f;
} else {
val25 = -100.0f;
val12 -= 15.0f;
}
val7 = val7 * 0.75f;
val17 += 5.0f;
sp1F8 = 0.75f;
if (wk->field_0x93 != 0) {
val2 = 0.0f;
}
sp1CC = 0.0f;
} else {
wk->field_0x91 = 0;
}
} else {
if (player->checkCanoeRideTandem()) {
wk->field_0x91 = 0;
sp1C8 = -100.0f;
} else {
wk->field_0x91 = 0;
if (player->checkBoardRide()) {
wk->field_0x91 = 0;
daAlink_c* sp194 = (daAlink_c*)wk->field_0x94;
if (sp194 != NULL) {
cXyz sp490 = positionOf(sp194) - positionOf(wk->field_0x9c);
if (sp490.abs() < 1200.0f) {
val2 = -30.0f;
val25 = 10.0f;
val1 = 50.0f;
val12 = 34.0f;
val15 = 2.0f;
val7 = 900.0f;
val10 = -50.0f;
val20 = 10.0f;
cSAngle sp134 = -mViewCache.mDirection.U();
sp490 = dCamMath::xyzRotateY(sp490, sp134);
cXyz sp484 = sp490;
cSAngle sp130 = sAngleY(sp490);
f32 var_f30 = sp130.Cos();
val7 += var_f30 * 300.0f;
val12 += var_f30 * 4.0f;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
dDbVw_Report(20, 0xeb, " YK %f", (f32)var_f30);
}
#endif
if (fabsf(sp484.y) < 200.0f) {
sp484.y = 0.0f;
sp484.x *= 0.5f;
f32 sp18C = sp484.abs();
if (sp18C < 1000.0f) {
sp1CC = -sp490.x * 0.6f * (1.0f - sp18C / 1200.0f);
sp1CC *= sp1D0;
}
}
}
}
}
if (!isPlayerFlying(player) || !player->checkSpinnerRide() && !player->checkBoardRide()) {
wk->field_0x78 = 0.0f;
wk->field_0x14 = 0;
} else if (wk->field_0x14 < 40) {
wk->field_0x91 = 1;
wk->field_0x78 += (0.5f - wk->field_0x78) * dCamMath::rationalBezierRatio(wk->field_0x14 / 40.0f, 1.25f);
wk->field_0x14++;
} else {
sp0E = true;
wk->field_0x91 = 1;
wk->field_0x78 += (1.0f - wk->field_0x78) * 0.1f;
}
}
}
}
wk->field_0x74 += (val5 - wk->field_0x74) * 0.05f;
wk->field_0x74 += (1.0f - wk->field_0x74) * wk->field_0x78;
if (mCamSetup.CheckFlag(0x8000)) {
dComIfGp_evmng_cameraPlay();
}
wk->field_0x5c.z += (sp1F8 - wk->field_0x5c.z) * 0.25f;
wk->field_0x4c += wk->field_0x5c.z * (val7 - wk->field_0x4c);
wk->field_0x50 += wk->field_0x5c.z * (val10 - wk->field_0x50);
wk->field_0x54 += wk->field_0x5c.z * (val12 - wk->field_0x54);
wk->field_0x58 += wk->field_0x5c.z * (val15 - wk->field_0x58);
f32 sp188 = 0.0f;
if (check_owner_action1(mPadID, 0x2000000)) {
if (player->getHookshotLeft()) {
sp1CC = -15.0f;
} else {
sp1CC = 15.0f;
}
} else {
if (sp1D0 > val21 && mGear != 1) {
f32 sp184 = 1.0f / (1.0f - val21);
sp188 = dCamMath::rationalBezierRatio(sp184 * (sp1D0 - val21), 0.1f);
}
}
f32 sp180 = wk->field_0x4c + wk->field_0x50 * sp188;
f32 sp17C = wk->field_0x54 + wk->field_0x58 * sp188;
f32 sp178 = val17 + val20 * sp188;
cSGlobe sp260;
cSAngle sp12C;
wk->field_0x68.y = val2 + val25 * sp188;
wk->field_0x68.z += (sp1C8 + val1 * sp188 - wk->field_0x68.z) * 0.1f;
wk->field_0x68.x += (sp1CC - wk->field_0x68.x) * 0.05f;
cXyz sp478(wk->field_0x68.x, wk->field_0x68.y, wk->field_0x68.z);
sp260.Val(sp180, cAngle::d2s(sp17C), wk->field_0x48.Inv());
if (player->checkOctaIealHang() && mGear != 1) {
sp260.U(cSAngle(sp148) + directionOf(wk->field_0x9c).Inv());
}
if (mCurCamStyleTimer == 0) {
wk->field_0x74 = val5;
wk->field_0x80 = 1.0f;
} else {
wk->field_0x80 += (1.0f - wk->field_0x80) * 0.025f;
}
dBgS_CamLinChk sp510;
cXyz sp46C = attentionPos(wk->field_0x9c);
cXyz sp460 = relationalPos(wk->field_0x9c, &sp478);
if (lineBGCheck(&sp46C, &sp460, &sp510, 0x40b7)) {
cM3dGPla sp4FC;
dComIfG_Bgsp().GetTriPla(sp510, &sp4FC);
sp460 = sp510.GetCross();
sp460 += *sp4FC.GetNP();
}
cXyz sp454(val6, wk->field_0x74, val6);
wk->field_0x5c.y += (1.0f - wk->field_0x5c.y) * 0.2f;
wk->field_0x3c += (sp460 - wk->field_0x3c) * wk->field_0x5c.y;
jutOutCheck(&wk->field_0x3c, 5.0f);
cSAngle sp128;
if (!mStyleSettle.mFinished) {
switch (wk->field_0x20) {
case 1:
sp1E4 = 40;
var_f31 = 1.0f / (f32)(s32)(sp1E4 - mCurCamStyleTimer);
mViewCache.mCenter += (wk->field_0x3c - mViewCache.mCenter) * var_f31;
mViewCache.mEye = wk->field_0x24;
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
break;
case 2:
sp1E4 = 1;
break;
case 3:
sp1E4 = 1;
mViewCache.mCenter = wk->field_0x3c;
var_f31 = 1.0f;
mViewCache.mDirection.R(sp260.R());
mViewCache.mDirection.V(sp260.V());
mViewCache.mDirection.U(sp260.U());
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
break;
case 4:
sp1E4 = 8;
var_f31 = 1.0f / (f32)(s32)(sp1E4 - mCurCamStyleTimer);
mViewCache.mCenter += (wk->field_0x3c - mViewCache.mCenter) * sp454;
mViewCache.mDirection.R(mViewCache.mDirection.R() +
(sp260.R() - mViewCache.mDirection.R()) * var_f31);
mViewCache.mDirection.V(mViewCache.mDirection.V() +
(sp260.V() - mViewCache.mDirection.V()) * var_f31);
mViewCache.mDirection.U(mViewCache.mDirection.U() +
(sp260.U() - mViewCache.mDirection.U()) * var_f31);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
break;
case 5:
sp1E4 = 8;
var_f31 = 1.0f / (f32)(s32)(sp1E4 - mCurCamStyleTimer);
mViewCache.mCenter += mMonitor.field_0x14.field_0x0;
mViewCache.mCenter += (wk->field_0x3c - mViewCache.mCenter) * var_f31;
sp128 = sp260.V();
if (wk->field_0x9c != NULL && mCamParam.Flag(param_0, 0x100) && mGear != 1) {
sp128 += wk->field_0x9c->shape_angle.x;
}
mViewCache.mDirection.R(mViewCache.mDirection.R() +
(sp260.R() - mViewCache.mDirection.R()) * var_f31);
mViewCache.mDirection.V(mViewCache.mDirection.V() +
(sp128 - mViewCache.mDirection.V()) * var_f31);
mViewCache.mDirection.U(mViewCache.mDirection.U() +
(sp260.U() - mViewCache.mDirection.U()) * var_f31);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
break;
default:
sp1E4 = mCurMode == 1 ? 8 : 20;
var_f31 = 1.0f / (f32)(s32)(sp1E4 - mCurCamStyleTimer);
mViewCache.mCenter += (wk->field_0x3c - mViewCache.mCenter) * var_f31;
sp128 = sp260.V();
if (wk->field_0x9c != 0 && mCamParam.Flag(param_0, 0x100) != 0 && mGear != 1) {
sp128 += wk->field_0x9c->shape_angle.x;
}
mViewCache.mDirection.R(mViewCache.mDirection.R() +
(sp260.R() - mViewCache.mDirection.R()) * var_f31);
mViewCache.mDirection.V(mViewCache.mDirection.V() +
(sp128 - mViewCache.mDirection.V()) * var_f31);
mViewCache.mDirection.U(mViewCache.mDirection.U() +
(sp260.U() - mViewCache.mDirection.U()) * var_f31);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
break;
}
mViewCache.mFovy += var_f31 * (sp178 - mViewCache.mFovy);
if (mCurCamStyleTimer == sp1E4 - 1) {
OS_REPORT("ready ok (%d)\n", wk->field_0x20);
mStyleSettle.mFinished = true;
}
return true;
}
bool sp0D = true;
if (mGear == 1 && !player->checkCanoeRide()) {
sp0D = false;
}
mViewCache.mCenter += (wk->field_0x3c - mViewCache.mCenter) * sp454;
f32 sp174 = mPadInfo.mCStick.mLastPosX;
f32 sp170;
if (wk->field_0x10 != 0 && wk->field_0x18 - wk->field_0x10 > (s32)sp1F0 && mGear == 0) {
f32 var_f1_0 = 1.0f / wk->field_0x10;
sp170 = mViewCache.mDirection.R() + var_f1_0 * (sp1EC * sp260.R() - mViewCache.mDirection.R());
} else {
sp170 = mViewCache.mDirection.R() + wk->field_0x7c * (sp260.R() - mViewCache.mDirection.R());
}
if (sp0D) {
var_f31 = val22 * val26;
var_f31 += val22 * (1.0f - val26) * sp1D0;
} else if (wk->field_0x93 != 0) {
cSAngle acStack_4ac = directionOf(wk->field_0x9c).Inv() - mViewCache.mDirection.U();
var_f31 = val24 * fabsf(acStack_4ac.Sin());
} else if (mCamParam.Flag(param_0, 0x1000) != 0) {
var_f31 = val22;
} else {
cSAngle acStack_4b0 = directionOf(wk->field_0x9c).Inv() - mViewCache.mDirection.U();
f32 sp168 = sp1D0 * fabsf(acStack_4b0.Sin());
var_f31 = val24 * sp168;
}
cSAngle sp11C;
cSAngle sp118;
if (push_any_key()) {
wk->field_0x90 = 0;
}
bool sp0C = false;
bool sp0B = false;
f32 sp164 = 8.0f;
var_f31 *= wk->field_0x80;
f32 sp160 = 0.05f;
if (!mCamParam.Flag(param_0, 0x40) && (fabsf(sp174) > sp160 || wk->field_0x90 != 0)) {
cSAngle sp8C = mViewCache.mDirection.U() + (cSAngle)(sp164 * dCamMath::rationalBezierRatio(sp174, 0.5f));
var_f31 = fabsf(sp174) - sp160;
sp11C.Val(mViewCache.mDirection.U() +
(sp8C - mViewCache.mDirection.U()) * var_f31);
wk->field_0x90 = 1;
wk->field_0x80 = 0.0f;
sp0B = true;
} else {
if (mCamParam.Flag(param_0, 0x1000)) {
cSAngle sp110 = sp144 + directionOf(wk->field_0x9c).Inv();
sp11C.Val(mViewCache.mDirection.U() + (sp110 - mViewCache.mDirection.U()) * var_f31);
} else if (wk->field_0x98 != 0) {
if (wk->field_0x98->checkTurnStandCamera()) {
sp11C.Val(mViewCache.mDirection.U());
} else {
sp11C.Val(mViewCache.mDirection.U() +
(sp260.U() - mViewCache.mDirection.U()) * var_f31);
}
} else {
sp11C.Val(mViewCache.mDirection.U() + (sp260.U() - mViewCache.mDirection.U()) * var_f31);
}
}
if (!sp0B) {
wk->field_0x80 = wk->field_0x80 + (1.0f - wk->field_0x80) * 0.01f;
}
cSGlobe sp258 = mViewCache.mEye - mViewCache.mCenter;
f32 sp15C = 0.25f;
if (wk->field_0x9c != 0 && mCamParam.Flag(param_0, 0x100) != 0) {
if (player->checkBoardRide()) {
sp258.V(sp260.V() + wk->field_0x9c->shape_angle.x);
} else {
sp258.V(wk->field_0x9c->shape_angle.x);
}
sp15C = 0.4f;
} else {
if (player->checkOctaIealHang() && mGear != 1) {
f32 sp158 = cSAngle(sp260.U() - sp11C).Cos();
sp118.Val(wk->field_0x9c->shape_angle.x);
sp260.V(sp260.V() + sp118 * sp158);
sp15C = 0.0f;
}
}
if (wk->field_0x98 != 0 && wk->field_0x91 != 0 && mMonitor.field_0x14.field_0x0.y < -1.0f) {
sp15C = 0.9f;
} else {
if (wk->field_0x91 != 0) {
sp15C = (sp15C + (1.0f - sp15C) * wk->field_0x78);
sp258.V(sp258.V() + cSAngle(10.0f));
}
}
sp260.V(sp260.V() + (sp258.V() - sp260.V()) * sp15C);
cSAngle sp10C = mViewCache.mDirection.V() + (sp260.V() - mViewCache.mDirection.V()) * wk->field_0x7c;
if (sp10C < LatMin) {
sp10C.Val(LatMin);
} else {
if (sp10C > LatMax) {
sp10C.Val(LatMax);
}
}
mViewCache.mDirection.Val(sp170, sp10C, sp11C);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
if (wk->field_0x10 != 0 && wk->field_0x18 - wk->field_0x10 > (s32)sp1F0 && mGear == 0) {
f32 sp154 = 1.0f / (f32)wk->field_0x10;
mViewCache.mFovy =
mViewCache.mFovy + sp154 * (sp178 * sp1E8 - mViewCache.mFovy);
} else {
mViewCache.mFovy = mViewCache.mFovy + wk->field_0x7c * (sp178 - mViewCache.mFovy);
}
if (sp0D) {
mViewCache.mBank +=
(val23 * mPadInfo.mMainStick.mLastPosX - mViewCache.mBank) * (fabsf(sp1D0) * 0.01f);
setFlag(0x400);
} else {
mViewCache.mBank += (cSAngle::_0 - mViewCache.mBank) * 0.05f;
setFlag(0x400);
}
return true;
}
bool dCamera_c::manualCamera(s32 param_0) {
#if DEBUG
f32 val0 = mCamParam.Val(param_0, 0);
f32 val1 = mCamParam.Val(param_0, 1);
f32 val6 = mCamParam.Val(param_0, 6);
f32 val5 = mCamParam.Val(param_0, 5);
f32 val27 = mCamParam.Val(param_0, 27);
f32 val22 = mCamParam.Val(param_0, 22);
f32 val26 = mCamParam.Val(param_0, 26);
f32 val3 = mCamParam.Val(param_0, 3);
f32 val4 = mCamParam.Val(param_0, 4);
f32 val11 = mCamParam.Val(param_0, 11);
f32 val8 = mCamParam.Val(param_0, 8);
f32 val9 = mCamParam.Val(param_0, 9);
f32 val24 = mCamParam.Val(param_0, 24);
f32 val16 = mCamParam.Val(param_0, 16);
f32 val13 = mCamParam.Val(param_0, 13);
f32 val14 = mCamParam.Val(param_0, 14);
f32 val21 = mCamParam.Val(param_0, 21);
f32 val18 = mCamParam.Val(param_0, 18);
f32 val19 = mCamParam.Val(param_0, 19);
ManualData* manual = (ManualData*)mWork;
bool sp09 = dComIfGp_getAttention()->LockonTruth() != 0;
if (mCurCamStyleTimer == 0) {
manual->field_0x00 = 'MAN_';
mStyleSettle.mFinished = true;
if (sp09 && mpLockonTarget != NULL) {
manual->field_0x1c = 1.0f;
} else {
manual->field_0x1c = 0.0f;
}
cXyz attnPos = attentionPos(mpPlayerActor);
manual->field_0x20 = mViewCache.mCenter.y - attnPos.y;
manual->field_0x2c = val8;
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
if (isPlayerCharging(mPadID)) {
manual->field_0x28 = 1;
} else {
manual->field_0x28 = 0;
}
manual->field_0x30 = mViewCache.mDirection;
manual->field_0x04 = cXyz::Zero;
manual->field_0x40 = 0;
manual->field_0x44 = mViewCache.mDirection.U();
manual->field_0x48 = mPadInfo.mCStick.mLastPosX;
if (mCamParam.Flag(param_0, 0x100)) {
s16 sp24 = ((s16)mViewCache.mDirection.U() >> 0xe) & 0x3;
if (manual->field_0x48 > 0.0f) {
manual->field_0x48 = -0.8f;
} else {
manual->field_0x48 = 0.8f;
}
}
}
if (check_owner_action(mPadID, 0x8000000)) {
if (val13 < 4.0f) {
val13 = 4.0f;
}
if (val3 < -10.0f) {
val3 = -10.0f;
}
} else if (check_owner_action(mPadID, 0x2800108)) {
if (check_owner_action(mPadID, 0x2000000)) {
val13 = -58.0f;
} else {
val13 = -70.0f;
}
val14 = 70.0f;
val16 = 4.0f;
val6 = 0.45f;
if (val9 > 500.0f) {
val9 = 500.0f;
}
}
f32 sp98[2];
if (mPadInfo.mCStick.mLastPosX >= 0.75f) {
sp98[0] = 1.0f;
} else if (mPadInfo.mCStick.mLastPosX <= -0.75f) {
sp98[0] = -1.0f;
} else {
sp98[0] = dCamMath::rationalBezierRatio(mPadInfo.mCStick.mLastPosX * 1.3333334f, 2.0f);
}
if (mPadInfo.mCStick.mLastPosY >= 0.75f) {
sp98[1] = 1.0f;
} else if (mPadInfo.mCStick.mLastPosY <= -0.75f) {
sp98[1] = -1.0f;
} else {
sp98[1] = dCamMath::rationalBezierRatio(mPadInfo.mCStick.mLastPosY * 1.3333334f, 2.0f);
}
UnkManualCameraParam sp188;
sp188.r = sp188.v = sp188.fov = sp188.u = val27;
if (check_owner_action(mPadID, 0x2800008) && mFakeAngleSys.field_0x0 == 0) {
setUSOAngle();
}
f32 sp48 = manual->field_0x20;
if (!limited_range_addition(&sp48, -sp98[1] * val26, val3, val4))
{
sp188.fov = val22;
}
manual->field_0x20 += sp188.fov * (sp48 - manual->field_0x20);
if (check_owner_action(mPadID, 0x100) != 0) {
if (val1 > -10.0f) {
val1 = -10.0f;
}
if (manual->field_0x20 < 30.0f) {
manual->field_0x20 = 30.0f;
}
}
cXyz sp94(val0, manual->field_0x20, val1);
bool sp08 = false;
if (sp09 && mpLockonTarget != NULL) {
manual->field_0x10 = relationalPos(mpPlayerActor, mpLockonTarget, &sp94, 0.5f);
cXyz sp178 = relationalPos(mpPlayerActor, &sp94);
dBgS_CamLinChk sp2B0;
dBgS_CamLinChk sp240;
if (lineBGCheck(&sp178, &manual->field_0x10, &sp2B0, 0x40b7) &&
lineBGCheckBoth(&mEye, &sp178, &sp240, 0x40b7) != 0) {
cM3dGPla cStack_198;
dComIfG_Bgsp().GetTriPla(sp240, &cStack_198);
} else {
manual->field_0x04 = manual->field_0x10 - sp178;
if (manual->field_0x1c < 1.0f) {
manual->field_0x1c += 0.05f;
manual->field_0x10 = sp178 + manual->field_0x04 * manual->field_0x1c;
} else if (manual->field_0x1c > 1.0f) {
manual->field_0x1c = 1.0f;
}
}
} else {
sp08 = true;
}
if (sp08) {
manual->field_0x10 = relationalPos(mpPlayerActor, &sp94);
if (manual->field_0x1c > 0.0f) {
manual->field_0x1c -= 0.05f;
manual->field_0x10 = manual->field_0x10 + manual->field_0x04 * manual->field_0x1c;
} else if (manual->field_0x1c < 0.0f) {
manual->field_0x1c = 0.0f;
}
}
f32 sp44;
f32 sp40;
if (mCurCamStyleTimer == 0) {
sp44 = cXyz(manual->field_0x10 - mViewCache.mCenter).abs();
sp40 = sp44 > 100.0f ? 0.0f : 1.0f - sp44 / 100.0f;
manual->field_0x38 = val6 * sp40;
manual->field_0x3c = val5 * sp40;
} else {
manual->field_0x38 += (val6 - manual->field_0x38) * 0.05f;
manual->field_0x3c += (val5 - manual->field_0x3c) * 0.05f;
}
cXyz sp160(manual->field_0x38, manual->field_0x3c, manual->field_0x38);
mViewCache.mCenter += (manual->field_0x10 - mViewCache.mCenter) * sp160;
if (mpLockonTarget == NULL) {
cXyz sp154 = attentionPos(mpPlayerActor);
if (check_owner_action(mPadID, 0x8100100)) {
sp154.y = eyePos(mpPlayerActor).y + 30.0f;
} else {
sp154.y -= 15.0f;
}
dBgS_CamLinChk sp158;
if (lineBGCheck(&sp154, &mViewCache.mCenter, &sp158, 0x40b7)) {
cM3dGPla sp1A4;
dComIfG_Bgsp().GetTriPla(sp158, &sp1A4);
mViewCache.mCenter = sp158.GetCross();
mViewCache.mCenter += *sp1A4.GetNP();
}
}
f32 sp3C = manual->field_0x30.R();
if (!limited_range_addition(&sp3C, (-sp98[1] * val11), val8, val9)) {
sp188.r = val22;
}
f32 sp38 = manual->field_0x30.V().Degree();
if (!limited_range_addition(&sp38, -sp98[1] * val16, val13, val14)) {
sp188.v = val22;
}
f32 sp34;
if (!mCamParam.Flag(param_0, 0x100)) {
sp34 = manual->field_0x30.U().Degree();
sp34 += sp98[0] * val24;
}
manual->field_0x30.Val(sp3C, cAngle::d2s(sp38), cAngle::d2s(sp34));
if (sp09 && mpLockonTarget != NULL) {
setFlag(0x2000);
mpAuxTargetActor1 = mpLockonTarget;
}
mViewCache.mDirection.R(mViewCache.mDirection.R() +
(manual->field_0x30.R() - mViewCache.mDirection.R()) * sp188.r);
mViewCache.mDirection.V(mViewCache.mDirection.V() +
(manual->field_0x30.V() - mViewCache.mDirection.V()) * sp188.v);
mViewCache.mDirection.U(mViewCache.mDirection.U() +
(manual->field_0x30.U() - mViewCache.mDirection.U()) * sp188.u);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
f32 sp30 = mViewCache.mFovy;
if (!limited_range_addition(&sp30, -sp98[1] * val21, val18, val19)) {
sp188.fov = mCamParam.Val(param_0, 22);
}
mViewCache.mFovy += sp188.fov * (sp30 - mViewCache.mFovy);
int sp2C = manual->field_0x40;
if (mPadInfo.mMainStick.mLastValue > 0.01f ||
dComIfGp_getAttention()->LockonTruth() ||
check_owner_action(mPadID, 0x100000)) {
sp2C = 0;
} else {
switch (manual->field_0x40) {
default:
sp2C = 0;
case 0:
if (sp3C < val8 * 1.0001f) {
setComStat(0x400);
if (sp98[1] < 0.3f) {
sp2C = 1;
}
}
break;
case 1:
if (sp98[1] < -0.01f) {
sp2C = 0;
} else if (sp98[1] > 0.9f) {
sp2C = 2;
setComStat(0x1000);
setComStat(0x400);
} else {
setComStat(0x400);
}
break;
case 2:
if (sp98[1] < 0.9f) {
sp2C = 0;
}
break;
}
}
manual->field_0x40 = sp2C;
#endif
return true;
}
bool dCamera_c::observeCamera(s32 param_0) {
f32 curveWeight = mCamSetup.CurveWeight();
f32 val0 = mCamParam.Val(param_0, 0);
f32 val17 = mCamParam.Val(param_0, 17);
cSAngle val16 = mCamParam.Val(param_0, 16);
cSAngle val24 = mCamParam.Val(param_0, 24);
ObserveData* observe = (ObserveData*)mWork;
if (mCurCamStyleTimer == 0) {
observe->field_0x00 = 'OBSV';
mStyleSettle.mFinished = true;
if (mRoomMapTool.mCameraIndex != 0xff && mCamParam.Flag(param_0, 0x200) != 0)
{
mCamParam.Fovy(mRoomMapTool.mCamData.field_0x11);
mCamParam.Arg0(mRoomMapTool.mCamData.field_0x12);
mCamParam.Arg1(mRoomMapTool.mCamData.field_0x13);
mCamParam.Arg2(mRoomMapTool.mCamData.field_0x14);
if (param_0 == mCamTypeData[mCurType].field_0x18[mIsWolf][mCurMode]) {
mCamParam.Change(param_0);
}
} else {
mCamParam.Fovy(0xff);
mCamParam.Arg0(0xff);
mCamParam.Arg1(0xff);
mCamParam.Arg2(-1);
if (param_0 == mCamTypeData[mCurType].field_0x18[mIsWolf][mCurMode]) {
mCamParam.Change(param_0);
}
}
if (mRoomMapTool.mArrowIndex != 0xff) {
observe->field_0x04 = cXyz(mRoomMapTool.mArrowData.posX, mRoomMapTool.mArrowData.posY,
mRoomMapTool.mArrowData.posZ);
cSGlobe sp60(50.0f, -mRoomMapTool.mArrowData.angleX,
mRoomMapTool.mArrowData.angleY);
observe->field_0x28 = observe->field_0x04 + sp60.Xyz();
} else {
observe->field_0x04 = mViewCache.mEye;
cSGlobe sp58(50.0f, mViewCache.mDirection.V().Inv(), mViewCache.mDirection.U().Inv());
observe->field_0x28 = observe->field_0x04 + sp58.Xyz();
}
observe->field_0x10.Val(observe->field_0x04 - observe->field_0x28);
mViewCache.mCenter = observe->field_0x28;
mViewCache.mEye = observe->field_0x04;
mViewCache.mDirection = observe->field_0x10;
}
if (mCamParam.Flag(param_0, 0x200)) {
if (mCamParam.Fovy() != 0xff) {
val17 = (s8)mCamParam.Fovy();
}
if (mCamParam.Arg0() != 0xff) {
val16 = (f32)(s8)mCamParam.Arg0();
}
if (mCamParam.Arg1() != 0xff) {
val24 = (f32)(s8)mCamParam.Arg1();
}
}
// not sure how else to get these on the stack instead of in registers, this seems plausible
// given they're used quite a bit and it makes sense for the compiler to not want to spill them
// otherwise
f32 sp50[2];
int zero = 0;
if (zero == 0) {
if (mPadInfo.mMainStick.mLastPosX >= 0.75f) {
sp50[0] = 1.0f;
} else if (mPadInfo.mMainStick.mLastPosX <= -0.75f) {
sp50[0] = -1.0f;
} else {
sp50[0] = dCamMath::rationalBezierRatio(mPadInfo.mMainStick.mLastPosX * (4.0f / 3.0f), curveWeight);
}
if (mPadInfo.mMainStick.mLastPosY >= 0.75f) {
sp50[1] = 1.0f;
} else if (mPadInfo.mMainStick.mLastPosY <= -0.75f) {
sp50[1] = -1.0f;
} else {
sp50[1] = dCamMath::rationalBezierRatio(mPadInfo.mMainStick.mLastPosY * (4.0f / 3.0f), curveWeight);
}
if (dComIfGs_getOptCameraControl() != 0) {
sp50[1] = -sp50[1];
}
}
cSAngle sp40;
cSAngle sp3C = mViewCache.mDirection.V() + (cSAngle)(val0 * sp50[1]);
sp40 = sp3C - observe->field_0x10.V();
if (sp40 > val16) {
sp3C = observe->field_0x10.V() + val16;
} else if (sp40 < -val16) {
sp3C = observe->field_0x10.V() - val16;
}
mViewCache.mDirection.V(sp3C);
cSAngle sp38 = mViewCache.mDirection.U() - (cSAngle)(val0 * sp50[0]);
sp40 = sp38 - observe->field_0x10.U();
if (sp40 > val24) {
sp38 = observe->field_0x10.U() + val24;
} else if (sp40 < -val24) {
sp38 = observe->field_0x10.U() - val24;
}
mViewCache.mDirection.U(sp38);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = val17;
return true;
}
bool dCamera_c::fixedFrameCamera(s32 param_0) {
f32 val24 = mCamParam.Val(param_0, 24);
f32 val17 = mCamParam.Val(param_0, 17);
FixedFrameData* fixedFrame = (FixedFrameData*)mWork;
if (mCurCamStyleTimer == 0) {
fixedFrame->mArrowIndex = 0xff;
mStyleSettle.mFinished = false;
}
if (mRoomMapTool.mArrowIndex == 0xff) {
return false;
}
if (fixedFrame->mArrowIndex != mRoomMapTool.mArrowIndex) {
mCurCamStyleTimer = 0;
fixedFrame->mArrowIndex = mRoomMapTool.mArrowIndex;
mStyleSettle.mFinished = false;
}
if (mCurCamStyleTimer == 0) {
fixedFrame->field_0x00 = 'FIXF';
fixedFrame->field_0x04 = cXyz(mRoomMapTool.mArrowData.posX, mRoomMapTool.mArrowData.posY,
mRoomMapTool.mArrowData.posZ);
cSGlobe spFC(100000.0f, -mRoomMapTool.mArrowData.angleX,
mRoomMapTool.mArrowData.angleY);
fixedFrame->field_0x2c = fixedFrame->field_0x38 = fixedFrame->field_0x04 + spFC.Xyz();
cM3dGLin sp14C(fixedFrame->field_0x2c, fixedFrame->field_0x04);
cXyz sp12C = attentionPos(this->mpPlayerActor);
cXyz sp120;
f32 sp30;
if (cM3d_Len3dSqPntAndSegLine(&sp14C, &sp12C, &sp120, &sp30) != 0) {
fixedFrame->field_0x2c = sp120;
} else {
f32 temp = cXyz(fixedFrame->field_0x04 - attentionPos(mpPlayerActor)).abs();
spFC.Val(temp, -mRoomMapTool.mArrowData.angleX,
mRoomMapTool.mArrowData.angleY);
fixedFrame->field_0x2c = fixedFrame->field_0x04 + spFC.Xyz();
}
dBgS_CamLinChk dStack_108;
if (lineBGCheck(&fixedFrame->field_0x04, &fixedFrame->field_0x2c, &dStack_108, 0x40b7)) {
cM3dGPla sp138;
dComIfG_Bgsp().GetTriPla(dStack_108, &sp138);
cXyz cross = dStack_108.GetCross();
fixedFrame->field_0x2c = cross - *sp138.GetNP() * 5.0f;
}
fixedFrame->field_0x10.Val(fixedFrame->field_0x04 - fixedFrame->field_0x2c);
fixedFrame->field_0x24 = mRoomMapTool.mCamData.field_0x11 == 0xff ? val17 : mRoomMapTool.mCamData.field_0x11;
s32 local_240 = mRoomMapTool.mCamData.field_0x13 == 0xff ? -1 : mRoomMapTool.mCamData.field_0x13;
if (local_240 == -1) {
f32 temp1 = cXyz(fixedFrame->field_0x04 - mEye).abs();
temp1 /= heightOf(mpPlayerActor);
fixedFrame->field_0x18 = (s32)(val24 * JMAFastSqrt(temp1)) + 1;
} else {
fixedFrame->field_0x18 = local_240;
}
fixedFrame->field_0x1c = (fixedFrame->field_0x18 * (fixedFrame->field_0x18 + 1)) >> 1;
}
if (!mStyleSettle.mFinished) {
fixedFrame->field_0x20 = (f32)(s32)(fixedFrame->field_0x18 - mCurCamStyleTimer);
f32 fVar11 = fixedFrame->field_0x20 / fixedFrame->field_0x1c;
fixedFrame->field_0x1c -= fixedFrame->field_0x20;
mViewCache.mCenter += (fixedFrame->field_0x2c - mViewCache.mCenter) * fVar11;
mViewCache.mDirection.R(mViewCache.mDirection.R() +
fVar11 * (fixedFrame->field_0x10.R() - mViewCache.mDirection.R()));
mViewCache.mDirection.V(mViewCache.mDirection.V() +
(fixedFrame->field_0x10.V() - mViewCache.mDirection.V()) * fVar11);
mViewCache.mDirection.U(mViewCache.mDirection.U() +
(fixedFrame->field_0x10.U() - mViewCache.mDirection.U()) * fVar11);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = mViewCache.mFovy + fVar11 * (fixedFrame->field_0x24 - mViewCache.mFovy);
if (mCurCamStyleTimer >= (u32)fixedFrame->field_0x18 - 1) {
mStyleSettle.mFinished = true;
}
}
return true;
}
bool dCamera_c::fixedPositionCamera(s32 param_0) {
f32 focusOffsetX = mCamParam.Val(param_0, 0);
f32 focusOffsetY = mCamParam.Val(param_0, 2);
f32 focusOffsetZ = mCamParam.Val(param_0, 1);
f32 centerLerpGainY = mCamParam.Val(param_0, 5);
f32 centerLerpGainXZ = mCamParam.Val(param_0, 6);
f32 targetRadiusMax = mCamParam.Val(param_0, 7);
f32 targetRadiusMin = mCamParam.Val(param_0, 8);
f32 val24 = mCamParam.Val(param_0, 24);
f32 val23 = mCamParam.Val(param_0, 23);
f32 targetFovY = mCamParam.Val(param_0, 17);
FixedPositionData* fixedPosition = (FixedPositionData*)mWork;
cXyz anchorPos;
if (mCurCamStyleTimer == 0) {
fixedPosition->field_0x00 = 'FIXP';
fixedPosition->field_0x1c = cXyz::Zero;
fixedPosition->field_0x2c = 0xff;
fixedPosition->field_0x30 = 0xfe;
}
if (mRoomMapTool.mArrowIndex != fixedPosition->field_0x2c) {
mCurCamStyleTimer = 0;
mStyleSettle.mFinished = false;
fixedPosition->field_0x2c = mRoomMapTool.mArrowIndex;
}
fixedPosition->field_0x28 = 0;
f32 desiredFovY;
u32 sp5C;
if (mCamParam.Flag(param_0, 0x200) && mRoomMapTool.mArrowIndex != 0xff) {
if (mRoomMapTool.mCameraIndex != fixedPosition->field_0x30) {
mCamParam.Fovy(mRoomMapTool.mCamData.field_0x11);
mCamParam.Arg0(mRoomMapTool.mCamData.field_0x12);
mCamParam.Arg1(mRoomMapTool.mCamData.field_0x13);
mCamParam.Arg2(mRoomMapTool.mCamData.field_0x14);
if (param_0 == mCamTypeData[mCurType].field_0x18[mIsWolf][mCurMode]) {
mCamParam.Change(param_0);
}
fixedPosition->field_0x30 = mRoomMapTool.mCameraIndex;
}
anchorPos.x = mRoomMapTool.mArrowData.posX;
anchorPos.y = mRoomMapTool.mArrowData.posY;
anchorPos.z = mRoomMapTool.mArrowData.posZ;
if (fixedPosition->field_0x1c != anchorPos) {
setUSOAngle();
}
fixedPosition->field_0x1c = anchorPos;
if (mCamParam.Fovy() != 0xff) {
f32 fovY = mCamParam.Fovy();
mCamParam.SetVal(param_0, 17, fovY);
}
if (mCamParam.Arg1() == 0xff) {
sp5C = -1;
} else {
sp5C = mCamParam.Arg1();
fixedPosition->field_0x28 = 1;
}
} else {
anchorPos = mEye;
sp5C = -1;
}
desiredFovY = targetFovY;
cXyz focusOffset(focusOffsetX, focusOffsetY, focusOffsetZ);
if (mCurCamStyleTimer == 0) {
if (mFrameCounter == 0) {
fixedPosition->field_0x04 = 1;
fixedPosition->field_0x08 = fixedPosition->field_0x04;
} else if (fixedPosition->field_0x28 == 0) {
cXyz sp1A8 = anchorPos;
cSGlobe sp184 = anchorPos - mViewCache.mCenter;
if (sp184.R() > targetRadiusMax) {
sp184.R(targetRadiusMax);
}
sp1A8 = mViewCache.mCenter + sp184.Xyz();
f32 sp54 = cXyz(sp1A8 - mEye).abs();
f32 sp50 = cXyz(mCenter - relationalPos(mpPlayerActor, &focusOffset)).abs();
f32 sp4C = sp54 > sp50 ? sp54 : sp50;
f32 sp48 = heightOf(mpPlayerActor);
sp4C /= sp48 < 10.0f ? 10.0f : sp48;
fixedPosition->field_0x04 = (s32)(val24 * JMAFastSqrt(sp4C)) + 1;
fixedPosition->field_0x08 = (fixedPosition->field_0x04 * (fixedPosition->field_0x04 + 1)) >> 1;
} else {
fixedPosition->field_0x04 = sp5C;
fixedPosition->field_0x08 = fixedPosition->field_0x04;
}
fixedPosition->field_0x10 = mViewCache.mCenter;
}
cXyz centerLerpGain(centerLerpGainXZ, centerLerpGainY, centerLerpGainXZ);
cXyz targetCenter = relationalPos(mpPlayerActor, &focusOffset);
if (mCamParam.Flag(param_0, 0x4000)) {
targetCenter.y = anchorPos.y;
}
if (!mStyleSettle.mFinished) {
if (mFrameCounter == 0) {
centerLerpGain.x = 1.0f;
centerLerpGain.y = 1.0f;
centerLerpGain.z = 1.0f;
}
f32 frameLerpRatio;
if (fixedPosition->field_0x28 == 0) {
fixedPosition->field_0x0c = (s32)(fixedPosition->field_0x04 - mCurCamStyleTimer);
frameLerpRatio = fixedPosition->field_0x0c / fixedPosition->field_0x08;
fixedPosition->field_0x08 -= fixedPosition->field_0x0c;
} else {
frameLerpRatio = 1.0f / fixedPosition->field_0x08;
fixedPosition->field_0x08 -= 1.0f;
}
fixedPosition->field_0x10 += (targetCenter - fixedPosition->field_0x10) * frameLerpRatio;
mViewCache.mCenter += (fixedPosition->field_0x10 - mViewCache.mCenter) * centerLerpGain;
cSGlobe targetDirection = anchorPos - mViewCache.mCenter;
if (mCamParam.Flag(param_0, 0x20)) {
targetDirection.V((s16)-mRoomMapTool.mArrowData.angleX);
}
if (targetDirection.R() < targetRadiusMin) {
targetDirection.R(targetRadiusMin);
}
if (targetDirection.R() > targetRadiusMax) {
targetDirection.R(targetRadiusMax);
}
mViewCache.mDirection.R((mViewCache.mDirection.R() + (targetDirection.R() - mViewCache.mDirection.R()) * frameLerpRatio));
mViewCache.mDirection.V(mViewCache.mDirection.V() +
(targetDirection.V() - mViewCache.mDirection.V()) * frameLerpRatio);
mViewCache.mDirection.U(mViewCache.mDirection.U() +
(targetDirection.U() - mViewCache.mDirection.U()) * frameLerpRatio);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy += (desiredFovY - mViewCache.mFovy) * frameLerpRatio;
if (mCurCamStyleTimer >= fixedPosition->field_0x04 - 1) {
mStyleSettle.mFinished = true;
}
return true;
}
mViewCache.mCenter += (targetCenter - mViewCache.mCenter) * centerLerpGain;
cSGlobe cStack_1a8 = anchorPos - mViewCache.mCenter;
if (mCamParam.Flag(param_0, 0x20)) {
cStack_1a8.V((s16)-mRoomMapTool.mArrowData.angleX);
}
if (cStack_1a8.R() < targetRadiusMin) {
cStack_1a8.R(targetRadiusMin);
}
if (cStack_1a8.R() > targetRadiusMax) {
cStack_1a8.R(targetRadiusMax);
}
mViewCache.mDirection.R(mViewCache.mDirection.R() +
(cStack_1a8.R() - mViewCache.mDirection.R()) * val23);
mViewCache.mDirection.V(mViewCache.mDirection.V() +
(cStack_1a8.V() - mViewCache.mDirection.V()) * val23);
mViewCache.mDirection.U(mViewCache.mDirection.U() +
(cStack_1a8.U() - mViewCache.mDirection.U()) * val23);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mViewCache.mFovy = mViewCache.mFovy + val23 * (desiredFovY - mViewCache.mFovy);
return true;
}
bool dCamera_c::oneSideCamera(s32 param_1) {
f32 focusOffsetX = mCamParam.Val(param_1, 0);
f32 focusOffsetY = mCamParam.Val(param_1, 2);
f32 focusOffsetZ = mCamParam.Val(param_1, 1);
f32 val5 = mCamParam.Val(param_1, 5);
f32 val6 = mCamParam.Val(param_1, 6);
f32 val7 = mCamParam.Val(param_1, 7);
f32 val8 = mCamParam.Val(param_1, 8);
f32 val24 = mCamParam.Val(param_1, 24);
f32 val23 = mCamParam.Val(param_1, 23);
f32 val17 = mCamParam.Val(param_1, 17);
f32 angle180 = 180.0f;
OneSideData* oneSide = (OneSideData*)mWork;
cXyz arrowPos;
if (mCurCamStyleTimer == 0) {
oneSide->field_0x00 = 'ONES';
oneSide->field_0x1c = cXyz::Zero;
oneSide->field_0x2c = 0xff;
oneSide->field_0x34 = 0xfe;
}
if (mRoomMapTool.mArrowIndex != oneSide->field_0x2c) {
mCurCamStyleTimer = 0;
mStyleSettle.mFinished = false;
oneSide->field_0x2c = mRoomMapTool.mArrowIndex;
}
oneSide->field_0x28 = 0;
cSAngle unkAngle1;
f32 fovY;
if (mCamParam.Flag(param_1, 0x200) && mRoomMapTool.mArrowIndex != 0xff) {
if (mRoomMapTool.mCameraIndex != oneSide->field_0x34) {
mCamParam.Fovy(mRoomMapTool.mCamData.field_0x11);
mCamParam.Arg0(mRoomMapTool.mCamData.field_0x12);
mCamParam.Arg1(mRoomMapTool.mCamData.field_0x13);
mCamParam.Arg2(mRoomMapTool.mCamData.field_0x14);
if (param_1 == mCamTypeData[mCurType].field_0x18[mIsWolf][mCurMode]) {
mCamParam.Change(param_1);
}
oneSide->field_0x34 = mRoomMapTool.mCameraIndex;
}
arrowPos.x = mRoomMapTool.mArrowData.posX;
arrowPos.y = mRoomMapTool.mArrowData.posY;
arrowPos.z = mRoomMapTool.mArrowData.posZ;
if (oneSide->field_0x1c != arrowPos) {
setUSOAngle();
}
oneSide->field_0x1c = arrowPos;
if (mCamParam.Fovy() != 0xff) {
f32 fovY = mCamParam.Fovy();
mCamParam.SetVal(param_1, 17, fovY);
}
if (mCamParam.Arg0() != 0xff) {
unkAngle1.Val((f32)mCamParam.Arg0());
} else {
unkAngle1.Val(90.0f);
}
if (mCamParam.Arg1() != 0xff) {
val24 = (f32)mCamParam.Arg1() / 100.0f;
}
} else {
arrowPos = mEye;
unkAngle1.Val(90.0f);
}
mStyleSettle.mFinished = true;
cXyz focusPosOffset(focusOffsetX, focusOffsetY, focusOffsetZ);
focusPosOffset = dCamMath::xyzRotateY(focusPosOffset, directionOf(mpPlayerActor));
cXyz focusPosWithOffset = attentionPos(mpPlayerActor) + focusPosOffset;
cSGlobe focusGlobe = focusPosWithOffset - arrowPos;
f32 unkRatio = focusGlobe.R() >= angle180 ? 1.0f : focusGlobe.R() / angle180;
if (!mCamParam.Flag(param_1, 0x800)) {
focusGlobe.V((s16)-mRoomMapTool.mArrowData.angleX);
}
cSAngle arrowAngle = (s16)(s32)mRoomMapTool.mArrowData.angleY;
cSAngle unkAngle2 = focusGlobe.U() - arrowAngle;
cSAngle unkAngle3;
cSAngle unkAngle4 = unkAngle2 * val24;
if ((unkAngle2 >= unkAngle1 || unkAngle2 <= -unkAngle1) && mCurCamStyleTimer != 0) {
unkAngle3 = oneSide->field_0x32;
} else if (unkAngle4 > unkAngle1) {
unkAngle3 = arrowAngle + unkAngle1;
} else if (unkAngle4 < -unkAngle1) {
unkAngle3 = arrowAngle - unkAngle1;
} else {
unkAngle3 = arrowAngle + unkAngle4;
}
if (mCurCamStyleTimer == 0) {
oneSide->field_0x32 = unkAngle3;
} else {
oneSide->field_0x32 += (unkAngle3 - oneSide->field_0x32) * val6 * unkRatio;
}
focusGlobe.U(oneSide->field_0x32);
cXyz center = arrowPos + focusGlobe.Xyz();
mViewCache.mCenter = center;
mViewCache.mEye = arrowPos;
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
fovY = val17;
mViewCache.mFovy = fovY;
return true;
}
bool dCamera_c::eventCamera(s32 param_0) {
char sp90[12];
UNUSED(param_0);
int var_r29 = -1;
typedef bool (dCamera_c::*func)();
func l_func[] = {
&dCamera_c::pauseEvCamera,
&dCamera_c::pauseEvCamera,
&dCamera_c::talktoEvCamera,
&dCamera_c::fixedPositionEvCamera,
&dCamera_c::fixedFrameEvCamera,
&dCamera_c::uniformTransEvCamera,
&dCamera_c::watchActorEvCamera,
&dCamera_c::restorePosEvCamera,
&dCamera_c::getItemEvCamera,
&dCamera_c::gameOverEvCamera,
&dCamera_c::turnToActorEvCamera,
&dCamera_c::rollingEvCamera,
&dCamera_c::tactEvCamera,
&dCamera_c::pauseEvCamera,
&dCamera_c::portalWarpEvCamera,
&dCamera_c::styleEvCamera,
&dCamera_c::saveEvCamera,
&dCamera_c::loadEvCamera,
&dCamera_c::useItem0EvCamera,
&dCamera_c::useItem1EvCamera,
&dCamera_c::fixedFramesEvCamera,
&dCamera_c::bSplineEvCamera,
&dCamera_c::possessedEvCamera,
&dCamera_c::twoActor0EvCamera,
&dCamera_c::stokerEvCamera,
&dCamera_c::uniformBrakeEvCamera,
&dCamera_c::uniformAcceleEvCamera,
&dCamera_c::stbWaitEvCamera,
&dCamera_c::currentEvCamera,
&dCamera_c::peepHoleEvCamera,
&dCamera_c::digHoleEvCamera,
&dCamera_c::hintTalkEvCamera,
&dCamera_c::bspTransEvCamera,
&dCamera_c::maptoolIdEvCamera,
};
static char* ActionNames[34] = {
"PAUSE",
"WAIT",
"TALK",
"FIXEDPOS",
"FIXEDFRM",
"UNITRANS",
"WATCHACTOR",
"RESTOREPOS",
"GETITEM",
"GAMEOVER",
"TURNTOACTOR",
"ROLLING",
"TACT",
"WINDDIR",
"PORTALWARP",
"STYLE",
"SAVE",
"LOAD",
"USEITEM0",
"USEITEM1",
"FIXEDFRMS",
"BSPLINE",
"POSSESSED",
"TWOACTOR0",
"STOKER",
"UNIBRAKE",
"UNIACCELE",
"STBWAIT",
"CURRENT",
"PEEPHOLE",
"DIGHOLE",
"HINTTALK",
"BSPTRANS",
"MAPTOOL",
};
int sp38 = 34;
if (field_0x170 == 0) {
clrFlag(0x200000);
mEventData.field_0x1c = 2;
}
if (!chkFlag(0x20000000)) {
int sp34 = dComIfGp_evmng_cameraPlay();
if (sp34 == 0) {
OS_REPORT("camera: event: %d: event not running\n", 0x3434);
return false;
}
if (sp34 == 2) {
SetTrimTypeForce(mEventData.field_0x1c);
return true;
}
int sp30 = dComIfGp_evmng_getMyStaffId("CAMERA", 0, 0);
if (sp30 < 0) {
OS_REPORT("camera: event: %d: camera not found\n", 0x343f);
return false;
}
if (mEventData.mStaffIdx != sp30) {
clrFlag(0x200000);
field_0x170 = field_0x160 = mCurCamStyleTimer = 0;
}
mEventData.mStaffIdx = sp30;
var_r29 = dComIfGp_evmng_getMyActIdx(mEventData.mStaffIdx, ActionNames, sp38, 0, 0);
if ((mEventData.field_0xc == specialType[15] || mEventData.field_0xc == specialType[16] ||
mEventData.field_0xc == specialType[17] || mEventData.field_0xc == specialType[19] ||
mEventData.field_0xc == specialType[20] || mEventData.field_0xc == specialType[21] ||
mEventData.field_0xc == specialType[22] || mEventData.field_0xc == specialType[23] ||
mEventData.field_0xc == specialType[24] || mEventData.field_0xc == specialType[18]) &&
*(int*)((intptr_t)&mEventData + 0xc) != -1) // fakematch to force additional load
{
var_r29 = 28;
} else if (mEventData.field_0xc == specialType[14] && var_r29 != 2) {
var_r29 = 28;
} else if (dComIfGp_evmng_getIsAddvance(mEventData.mStaffIdx)) {
OS_REPORT("camera: event: next cut \n");
mStyleSettle.mFinished = false;
mCurCamStyleTimer = 0;
}
} else {
mEventData.mStaffIdx = -1;
if (field_0x170 == 0) {
mStyleSettle.mFinished = false;
field_0x170 = field_0x160 = mCurCamStyleTimer = 0;
}
var_r29 = mEventData.field_0x18;
if (mEventData.field_0xc == specialType[15] || mEventData.field_0xc == specialType[16] ||
mEventData.field_0xc == specialType[17] || mEventData.field_0xc == specialType[19] ||
mEventData.field_0xc == specialType[20] || mEventData.field_0xc == specialType[21] ||
mEventData.field_0xc == specialType[22] || mEventData.field_0xc == specialType[23] ||
mEventData.field_0xc == specialType[24] || mEventData.field_0xc == specialType[18])
{
var_r29 = 28;
} else if (mEventData.field_0xc == specialType[14] && var_r29 != 2) {
var_r29 = 28;
}
}
if (field_0x170 == 0) {
pushInfo(mSavedViewStack, 1);
pushInfo(mSavedViewStack + 1, 0);
mEventData.field_0x0 = 0;
mEventData.field_0xec = NULL;
int sp2C = dComIfGp_getEvent()->getMapToolId();
if (sp2C != -1) {
mEventData.field_0xec = dEvt_control_c::searchMapEventData(sp2C);
}
if (mEventData.field_0xec != NULL) {
switch (mEventData.field_0xec->field_0x2) {
case 2:
setEventRecoveryTrans(mCamSetup.MapToolCameraLongTimer());
break;
case 1:
setEventRecoveryTrans(mCamSetup.MapToolCameraShortTimer());
break;
case 3:
setEventRecoveryTrans(1);
break;
default:
setEventRecoveryTrans(0);
break;
}
if (mEventData.field_0xec->type == dStage_MapEvent_dt_TYPE_MAPTOOLCAMERA && (mEventData.field_0xec->field_0xC & 0x80) != 0)
{
field_0x8d8.mCameraIndex = mEventData.field_0xec->data.maptool.field_0x16;
OS_REPORT("camera: event: change default type %d \n", field_0x8d8.mCameraIndex);
}
} else {
setEventRecoveryTrans(0);
}
OS_REPORT("%06d: camera: event: start (%d)\n", g_Counter.mCounter0, mEventData.mStaffIdx);
}
if (var_r29 < 0 || var_r29 >= sp38) {
OS_REPORT("camera: event: %d: engine not found\n", 0x34ad);
dComIfGp_evmng_cutEnd((this->mEventData).mStaffIdx);
return false;
}
f32 sp28;
int sp24;
int sp20;
int sp1C;
int sp18;
int sp14;
f32 sp10;
int sp0C;
if (mCurCamStyleTimer == 0) {
#if DEBUG
OS_REPORT("camera: event: cut [%s]\n",
ActionNames[var_r29]);
#endif
if (getEvFloatData(&sp28, "KeepDist") != 0 && mViewCache.mDirection.R() < sp28)
{
mViewCache.mDirection.R(sp28);
mViewCache.mEye = mViewCache.mCenter + mViewCache.mDirection.Xyz();
mDirection.R(sp28);
mEye = mCenter + mDirection.Xyz();
}
BE(int)* sp90_i;
if (getEvStringData(sp90, "Trim", "DEFAULT") != false) {
sp90_i = (BE(int)*)sp90;
if (*sp90_i == 'STAN') {
mEventData.field_0x1c = 0;
} else if (*sp90_i == 'VIST') {
mEventData.field_0x1c = 1;
} else if (*sp90_i == 'CINE') {
mEventData.field_0x1c = 2;
} else if (*sp90_i == 'DEMO') {
mEventData.field_0x1c = 3;
} else if (*sp90_i == 'NONE') {
mEventData.field_0x1c = 4;
} else if (*sp90_i == 'KEEP') {
mEventData.field_0x1c = 999;
}
} else if (mEventData.field_0xec != NULL) {
switch (mEventData.field_0xec->field_0x1) {
case 0:
mEventData.field_0x1c = 0;
break;
case 1:
mEventData.field_0x1c = 1;
break;
case 2:
mEventData.field_0x1c = 2;
break;
}
} else {
mEventData.field_0x1c = 2;
}
getEvIntData(&sp24, "Recover", 0);
mRecovery.field_0x4 = (s16)sp24;
getEvIntData(&sp24, "WaitAnyKey", 0);
if (sp24 != 0) {
setFlag(0x200000);
}
if (var_r29 == 27) {
sp0C = 3;
} else {
sp0C = 1;
}
sp20 = sp0C;
getEvIntData(&mEventData.field_0x20, "BGCheck", sp20);
if (getEvIntData(&sp24, "SavePos") != 0) {
if ((sp24 == 0) || (sp24 == 1)) {
pushInfo(&mSavedViewStack[sp24], 1);
}
if (sp24 == 2) {
pushInfo(&mSavedView, 1);
}
}
if (getEvIntData(&sp24, "LoadPos") != 0) {
if ((sp24 == 0) || (sp24 == 1)) {
popInfo(&mSavedViewStack[sp24]);
}
if (sp24 == 2) {
popInfo(&mSavedView);
}
}
}
SetTrimTypeForce(mEventData.field_0x1c);
getEvIntData(&sp1C, "PlayerHide", 0);
if (sp1C != 0) {
setComStat(2);
setComStat(0x10000);
}
getEvIntData(&sp1C, "WideMode", 0);
#if WIDESCREEN_SUPPORT
if (sp1C == 1) {
mDoGph_gInf_c::onWideZoom();
} else if (sp1C == 2) {
mDoGph_gInf_c::offWideZoom();
}
#endif
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
sp18 = 20;
sp14 = 190;
dDbVw_Report(sp18, sp14 + 60, "E %s", ActionNames[var_r29]);
}
#endif
if (isModeOK()) {
setComStat(4);
} else {
clrComStat(4);
}
clrFlag(0x400000);
switch (mEventData.field_0x20) {
case 1:
mBumpCheckFlags = 0x4007;
break;
case 2:
mBumpCheckFlags = 0x4017;
break;
case 3:
mBumpCheckFlags = 0x0;
break;
case 4:
mBumpCheckFlags = 0x4;
break;
case 5:
mBumpCheckFlags = 0xc007;
break;
default:
mBumpCheckFlags = 0x4001;
break;
}
mBumpCheckFlags &= 0x80b7;
if ((this->*l_func[var_r29])() != 0) {
mStyleSettle.mFinished = true;
dComIfGp_evmng_cutEnd(mEventData.mStaffIdx);
if (mEventData.field_0x0 == 0) {
OS_REPORT("camera: event: cut end (%d)\n", mEventData.mStaffIdx);
}
if (mEventData.field_0xec != NULL) {
switch (mEventData.field_0xec->field_0x3) {
case 2:
mRecovery.field_0x4 = mCamSetup.MapToolCameraLongTimer();
break;
case 1:
mRecovery.field_0x4 = mCamSetup.MapToolCameraShortTimer();
break;
case 3:
mRecovery.field_0x4 = 1;
break;
default:
mRecovery.field_0x4 = 0;
break;
}
}
mEventData.field_0x0 = 1;
}
if (chkFlag(0x40000000)) {
cM3dGLin sp9C(mViewCache.mCenter, mViewCache.mEye);
cXyz sp84 = attentionPos(mpPlayerActor);
cXyz sp78;
if (cM3d_Len3dSqPntAndSegLine(&sp9C, &sp84, &sp78, &sp10) != 0) {
mViewCache.mCenter = sp78;
mViewCache.mDirection.Val(mViewCache.mEye - mViewCache.mCenter);
}
clrFlag(0x40000000);
}
return true;
}
bool dCamera_c::currentEvCamera() {
int style = mCamTypeData[mEventData.field_0xc].field_0x18[mIsWolf][0];
if (style < 0) {
style = mCamParam.SearchStyle('CN01');
}
int i;
if (getEvIntData(&i, "Continue", 0)) {
setFlag(0x400000);
}
(this->*engine_tbl[mCamParam.Algorythmn(style)])(style);
setFlag(0x8);
mBumpCheckFlags = 0x4001;
clrFlag(0x80080);
if (mCamParam.Flag(style, 0x1)) {
if (mCurMode == 1 && mCamParam.Flag(style, 0x2) != 0) {
mBumpCheckFlags = 0x4007;
} else if (chkFlag(0x20000)) {
mBumpCheckFlags = 0x4037;
} else {
mBumpCheckFlags = 0x4017;
}
} else if (mCamParam.Flag(style, 0x2)) {
mBumpCheckFlags = 0x4007;
}
if (mCamParam.Flag(style, 0x8)) {
mBumpCheckFlags |= 0x80;
}
if (mCamParam.Flag(style, 0x10)) {
mBumpCheckFlags &= ~0x4000;
}
mBumpCheckFlags &= ~0x8;
if (mCamParam.Flag(style, 0x4)) {
mBumpCheckFlags = 0;
}
return true;
}
bool dCamera_c::letCamera(s32) {
return true;
}
void dCamera_c::setEventRecoveryTrans(s16 param_0) {
pushInfo(&mRecovery.field_0x8, param_0);
mRecovery.field_0x28 = positionOf(mpPlayerActor);
}
s16 dCamera_c::runEventRecoveryTrans() {
if (mRecovery.field_0x8.field_0x1e > 0) {
#if PLATFORM_GCN
field_0x668++;
#endif
#if PLATFORM_GCN
if (field_0x668 >= mRecovery.field_0x8.field_0x1e) {
#else
if ((int)field_0x170 >= mRecovery.field_0x8.field_0x1e) {
#endif
mRecovery.field_0x8.field_0x1e = 0;
} else {
#if PLATFORM_GCN
f32 var_f30 = (f32)field_0x668 / (f32)mRecovery.field_0x8.field_0x1e;
#else
f32 var_f30 = (f32)field_0x170 / (f32)mRecovery.field_0x8.field_0x1e;
#endif
f32 ratio = dCamMath::rationalBezierRatio(1.0f - var_f30, 1.0f);
mCenter = mViewCache.mCenter + (mRecovery.field_0x8.mCenter - mViewCache.mCenter) * ratio;
cXyz attPos = attentionPos(mpPlayerActor);
dBgS_CamLinChk lin_chk;
cM3dGPla plane;
if ((mBumpCheckFlags & 0xb7) && lineBGCheck(&attPos, &mCenter, &lin_chk, 0x40b7)) {
dComIfG_Bgsp().GetTriPla(lin_chk, &plane);
mCenter = lin_chk.GetCross();
mCenter += *plane.GetNP() * 5.0f;
}
mEye = mViewCache.mEye + (mRecovery.field_0x8.mEye - mViewCache.mEye) * ratio;
if ((mBumpCheckFlags & 0xb7) && lineBGCheck(&mCenter, &mEye, &lin_chk, 0x40b7)) {
dComIfG_Bgsp().GetTriPla(lin_chk, &plane);
mEye = lin_chk.GetCross();
mEye += *plane.GetNP() * mCamSetup.mBGChk.GazeBackMargin();
}
mDirection.Val(mEye - mCenter);
mFovy = mViewCache.mFovy + ratio * (mRecovery.field_0x8.mFovy - mViewCache.mFovy);
mBank = mViewCache.mBank + (mRecovery.field_0x8.mBank - mViewCache.mBank) * ratio;
}
} else {
clearInfo(&mRecovery.field_0x8, 0);
}
return mRecovery.field_0x8.field_0x1e;
}
void dCamera_c::EventRecoverNotime() {
mRecovery.field_0x4 = 1;
Reset(mRecovery.field_0x8.mCenter, mRecovery.field_0x8.mEye, mRecovery.field_0x8.mFovy, mRecovery.field_0x8.mBank);
}
int dCamera_c::Set(cXyz i_center, cXyz i_eye) {
mCenter = i_center;
mEye = i_eye;
return 1;
}
int dCamera_c::Set(cXyz i_center, cXyz i_eye, f32 i_fovy, s16 i_bank) {
mCenter = i_center;
mEye = i_eye;
mFovy = i_fovy;
mBank.Val(i_bank);
return 1;
}
int dCamera_c::Set(cXyz i_center, cXyz i_eye, s16 i_bank, f32 i_fovy) {
mCenter = i_center;
mEye = i_eye;
mFovy = i_fovy;
mBank.Val(i_bank);
return 1;
}
int dCamera_c::Reset(cXyz i_center, cXyz i_eye, f32 i_fovy, s16 i_bank) {
mCenter = i_center;
mEye = i_eye;
mFovy = i_fovy;
mBank = cSAngle(i_bank);
return Reset();
}
int dCamera_c::Reset(cXyz i_center, cXyz i_eye) {
mCenter = i_center;
mEye = i_eye;
return Reset();
}
int dCamera_c::Reset() {
mViewCache.mCenter = mCenter;
mViewCache.mEye = mEye;
mViewCache.mFovy = mFovy;
mViewCache.mBank = mBank;
mDirection.Val(mEye - mCenter);
mViewCache.mDirection = mDirection;
mControlledYaw = cSAngle(mDirection.U().Inv());
return 1;
}
f32 dCamera_c::shakeCamera() {
static f32 const wave[] = {0.4f, 0.9f, 2.1f, 3.2f};
f32 var_f31 = 0.0f;
if (mShake.field_0x10 < mShake.m_length) {
int var_r29 = mShake.field_0x10 >> 3;
int var_r27 = mShake.field_0x10 & 7;
int var_r26 = (mShake.field_0x4[var_r29] << 8) | mShake.field_0x4[var_r29 + 1];
int var_r28 = 1 << (15 - var_r27);
f32 var_f30 = 1.0f;
for (var_r29 = 0; var_r29 < 4; var_r29++) {
if (var_r28 & var_r26) {
var_f31 += var_f30 * wave[var_r29];
} else {
var_f30 *= 0.43f;
}
var_r28 >>= 1;
}
mShake.field_0x10++;
var_f31 *= cM_rndFX(0.05f) + 0.95f;
f32 var_f29 = var_f31;
if (mShake.field_0x10 & 1) {
var_f31 = -var_f31;
}
cXyz sp64(mShake.m_pos);
sp64.x += cM_rndFX(0.045f);
sp64.z += cM_rndFX(0.045f);
sp64 = sp64 * var_f31;
if (field_0x6fc & 2) {
mShake.field_0x24 = mShake.mEyeShake = sp64 * 1.0f;
}
if (field_0x6fc & 0x40) {
mShake.field_0x24 = mShake.mEyeShake = sp64 * 10.0f;
}
if (field_0x6fc & 4) {
mShake.field_0x3c = var_f31 * cM_rndFX(0.12f);
}
if (field_0x6fc & 8) {
mShake.field_0x40 = cSAngle(var_f31 * cM_rndFX(0.15f));
}
if (field_0x6fc & 0x10) {
mDoGph_gInf_c::setBlureRate((int)(var_f29 * 30.0f));
mDoGph_gInf_c::onBlure();
}
} else {
mShake.field_0x24 -= mShake.field_0x24 * 0.1f;
mShake.mEyeShake -= mShake.mEyeShake * 0.1f;
mShake.field_0x3c -= mShake.field_0x3c * 0.1f;
mShake.field_0x40 -= mShake.field_0x40 * 0.1f;
}
return var_f31;
}
int dCamera_c::StartShake(s32 i_length, u8* i_pattern, s32 i_flags, cXyz i_pos) {
// This function originally used a constant defined as a static data member in one of
// dCamera_c's anonymous classes, but this is illegal in C++ and is not accepted by
// MWCC for Wii. It seems this was resolved for the Shield release by hardcoding the constant
// (or possibly using a define).
#if defined(__MWERKS__) && __MWERKS__ < 0x4200
#define PATTERN_LENGTH_MAX mViewCache.PatternLengthMax
#else
#define PATTERN_LENGTH_MAX 4
#endif
#if TARGET_PC
*(u32*)i_pattern = BSWAP32(*(u32*)i_pattern);
#endif
if (i_length < 0 || i_length > PATTERN_LENGTH_MAX << 3) {
OS_REPORT("camera: shake: too long data\n");
i_length = PATTERN_LENGTH_MAX << 3;
}
mShake.m_length = i_length;
if (i_flags & 0x20) {
field_0x6fc &= ~0x20;
mBlure.field_0x4 = mBlure.field_0x14;
}
int i;
int var_r28 = i_length >> 3;
for (i = 0; i < PATTERN_LENGTH_MAX; i++) {
mShake.field_0x0[i] = mShake.field_0x4[i] = 0;
}
for (i = 0; i < var_r28; i++) {
mShake.field_0x0[i] = mShake.field_0x4[i] = i_pattern[i];
}
var_r28 = i_length & 7;
mShake.field_0x0[i] = (0xFF << (8 - var_r28)) & i_pattern[i];
if (i_length == PATTERN_LENGTH_MAX << 3) {
mShake.field_0x4[i] = mShake.field_0x0[i] | (i_pattern[0] >> var_r28);
} else {
mShake.field_0x4[i] = mShake.field_0x0[i];
}
mShake.m_pos = i_pos.norm();
mShake.field_0x10 = 0;
field_0x6fc = i_flags;
return 1;
}
int dCamera_c::StopShake() {
mShake.m_length = 0;
mShake.field_0x10 = 0;
field_0x6fc = 0;
return 1;
}
void dCamera_c::StartBlure(int param_0, fopAc_ac_c* i_actor, f32 i_alpha, f32 i_scale) {
mBlure.field_0x14 = param_0;
mBlure.mpActor = NULL;
mBlure.mAlpha = i_alpha;
mBlure.mScale.x = i_scale;
mBlure.mScale.y = i_scale;
mBlure.mScale.z = 0.0f;
mBlure.mpActor = i_actor;
mBlure.mPosition.x = 0.5f;
mBlure.mPosition.y = 0.5f;
mBlure.mPosition.z = 0.0f;
mBlure.field_0x8.x = 0;
mBlure.field_0x8.y = 0;
mBlure.field_0x8.z = 0;
mBlure.field_0x4 = param_0;
#if DEBUG
if (mCamSetup.CheckFlag(0x8000)) {
OS_REPORT("camera: start blure: timer %d, type %d\n", param_0, mCurType);
}
#endif
}
void dCamera_c::ResetBlure() {
mBlure.mpActor = NULL;
mBlure.mAlpha = 0.75f;
mBlure.mPosition.x = 0.5f;
mBlure.mPosition.y = 0.5f;
mBlure.mPosition.z = 0.0f;
mBlure.mScale.x = 1.0f;
mBlure.mScale.y = 1.0f;
mBlure.mScale.z = 0.0f;
mBlure.field_0x8.x = 0;
mBlure.field_0x8.y = 0;
mBlure.field_0x8.z = 0;
mBlure.field_0x4 = 0;
mBlure.field_0x14 = 1;
}
void dCamera_c::SetBlureAlpha(f32 i_alpha) {
mBlure.mAlpha = i_alpha;
}
void dCamera_c::SetBlureScale(f32 i_scalex, f32 i_scaley, f32 i_scalez) {
mBlure.mScale.x = i_scalex;
mBlure.mScale.y = i_scaley;
mBlure.mScale.z = i_scalez;
}
void dCamera_c::SetBlurePosition(f32 i_posx, f32 i_posy, f32 i_posz) {
SetBlureActor(NULL);
mBlure.mPosition.x = i_posx;
mBlure.mPosition.y = i_posy;
mBlure.mPosition.z = i_posz;
}
void dCamera_c::SetBlureActor(fopAc_ac_c* i_actor) {
mBlure.mpActor = i_actor;
}
int dCamera_c::blureCamera() {
if (mBlure.field_0x4 > 0) {
if (mBlure.mpActor != NULL) {
scissor_class* scissor = get_window(field_0x0)->getScissor();
cXyz eyePosition = eyePos(mBlure.mpActor);
cXyz res;
mDoLib_project(&eyePosition, &res);
mBlure.mPosition.x = res.x / scissor->width;
mBlure.mPosition.y = res.y / scissor->height;
mBlure.mPosition.z = 0.0f;
}
mBlure.field_0x4--;
f32 mult = (f32)mBlure.field_0x4 / (f32)mBlure.field_0x14;
cXyz xyz;
xyz.x = mBlure.mScale.x + (1.0f - mBlure.mScale.x) * mult;
xyz.y = mBlure.mScale.y + (1.0f - mBlure.mScale.y) * mult;
xyz.z = 0.0f;
mDoMtx_stack_c::transS(mBlure.mPosition.x, mBlure.mPosition.y, mBlure.mPosition.z);
mDoMtx_stack_c::scaleM(xyz);
mDoMtx_stack_c::XrotM(mBlure.field_0x8.x);
mDoMtx_stack_c::YrotM(mBlure.field_0x8.y);
mDoMtx_stack_c::ZrotM(mBlure.field_0x8.z);
mDoMtx_stack_c::transM(-mBlure.mPosition.x, -mBlure.mPosition.y, -mBlure.mPosition.z);
mDoGph_gInf_c::onBlure(mDoMtx_stack_c::get());
u8 blureRate = mBlure.mAlpha * 230.0f * mult;
mDoMtx_stack_c::scaleM(xyz);
mDoGph_gInf_c::setBlureRate(blureRate);
}
else {
mDoGph_gInf_c::offBlure();
mBlure.field_0x4 = 0;
}
return mBlure.field_0x4;
}
void dCamera_c::onHorseDush() {
dComIfGp_getVibration().StartShock(VIBMODE_S_POWER2, 1, cXyz(0.0f, 1.0f, 0.0f));
// debug indicates this function somehow has scoped declarations, so we add a useless block here
{
int var_r30 = 55;
f32 alpha = 0.75f;
f32 scale = 1.0f;
StartBlure(var_r30, mpPlayerActor, alpha, scale);
}
}
fopAc_ac_c* dCamera_c::GetForceLockOnActor() {
return fopAcM_SearchByID(mLockOnActorID);
}
int dCamera_c::ForceLockOn(fopAc_ac_c* i_actor) {
mForceLockTimer = 0;
mpLockOnActor = i_actor;
mLockOnActorID = fopAcM_GetID(i_actor);
return 1;
}
int dCamera_c::ForceLockOff(fpc_ProcID i_id) {
if (i_id == mLockOnActorID || i_id == fpcM_ERROR_PROCESS_ID_e) {
mLockOnActorID = fpcM_ERROR_PROCESS_ID_e;
mpLockOnActor = NULL;
mForceLockTimer = 0;
return 1;
}
return 0;
}
int dCamera_c::ForceLockOff(fopAc_ac_c* i_actor) {
if (i_actor == mpLockOnActor) {
mLockOnActorID = fpcM_ERROR_PROCESS_ID_e;
mpLockOnActor = NULL;
mForceLockTimer = 0;
return 1;
}
return 0;
}
s16 dCam_getAngleY(camera_class* i_cam) {
return ((camera_process_class*)i_cam)->mCamera.U();
}
s16 dCam_getAngleX(camera_class* i_cam) {
return ((camera_process_class*)i_cam)->mCamera.V();
}
s16 dCam_getControledAngleY(camera_class* i_cam) {
return ((camera_process_class*)i_cam)->mCamera.U2();
}
camera_class* dCam_getCamera() {
return dComIfGp_getCamera(0);
}
dCamera_c* dCam_getBody() {
camera_process_class* camera = (camera_process_class*)dCam_getCamera();
return &camera->mCamera;
}
static void preparation(camera_process_class* i_this) {
camera_process_class* process = i_this;
camera_class* a_this = (camera_class*)i_this;
dCamera_c* camera = &i_this->mCamera;
int camera_id = get_camera_id(a_this);
dDlst_window_c* window = get_window(camera_id);
view_port_class* viewport = window->getViewPort();
f32 aspect = mDoGph_gInf_c::getAspect();
camera->SetWindow(viewport->width, viewport->height);
fopCamM_SetAspect((camera_class*)i_this, aspect);
if (!daAlink_c::getE3Zhint()) {
dComIfGp_offCameraAttentionStatus(camera_id, 0x1002B);
}
}
static void view_setup(camera_process_class* i_this) {
camera_class* a_this = (camera_class*)i_this;
dDlst_window_c* window = get_window(a_this);
view_port_class* viewport = window->getViewPort();
view_class* view = (view_class*)i_this;
mDoMtx_lookAt(view->viewMtx, &view->lookat.eye, &view->lookat.center, &view->lookat.up, view->bank);
MTXCopy(view->viewMtx, view->viewMtxNoTrans);
view->viewMtxNoTrans[0][3] = 0.0f;
view->viewMtxNoTrans[1][3] = 0.0f;
view->viewMtxNoTrans[2][3] = 0.0f;
dComIfGd_setWindow(window);
dComIfGd_setViewport(viewport);
dComIfGd_setView(view);
f32 far_;
f32 var_f30;
if (getComStat(8)) {
far_ = view->far_;
} else {
#if DEBUG
if (g_envHIO.mOther.mAdjustCullFar != 0) {
var_f30 = g_envHIO.mOther.mCullFarValue;
} else
#endif
{
var_f30 = dStage_stagInfo_GetCullPoint(dComIfGp_getStageStagInfo());
}
far_ = var_f30;
}
mDoLib_clipper::setup(view->fovy, view->aspect, view->near_, far_);
}
static void store(camera_process_class* i_camera) {
camera_process_class* process = (camera_process_class*)i_camera;
camera_class* camera = (camera_class*)i_camera;
dCamera_c* dCamera = &i_camera->mCamera;
int camera_id = get_camera_id(camera);
dDlst_window_c* window = get_window(camera_id);
view_port_class* viewport = window->getViewPort();
bool error = false;
cXyz center(*fopCamM_GetCenter_p(camera));
cXyz eye(*fopCamM_GetEye_p(camera));
cXyz up(*fopCamM_GetUp_p(camera));
cSAngle angle(fopCamM_GetBank(camera));
f32 fovy = fopCamM_GetFovy(camera);
dDemo_camera_c* demoCamera = dDemo_c::getCamera();
if (demoCamera != NULL && !dComIfGp_getPEvtManager()->cameraPlay()) {
if (demoCamera->checkEnable(dDemo_camera_c::ENABLE_VIEW_TARG_POS_e)) {
center = demoCamera->getTarget();
}
if (demoCamera->checkEnable(dDemo_camera_c::ENABLE_VIEW_POS_e)) {
eye = demoCamera->getTrans();
}
if (demoCamera->checkEnable(dDemo_camera_c::ENABLE_VIEW_UP_VEC_e)) {
up = demoCamera->getUp();
}
if (demoCamera->checkEnable(dDemo_camera_c::ENABLE_VIEW_ROLL_e)) {
angle = cSAngle(cAngle::d2s(-demoCamera->getRoll()));
}
if (demoCamera->checkEnable(dDemo_camera_c::ENABLE_PROJ_FOVY_e)) {
fovy = demoCamera->getFovy();
}
#if DEBUG
} else if (dDebugPad.Enable(0) && dCamera->CameraID() == 0) {
if (dDbgCamera.Playing()) {
center = dCamera->Center();
eye = dCamera->Eye();
up = dCamera->Up();
angle = dCamera->Bank();
fovy = dCamera->Fovy();
} else {
center = dDbgCamera.Center();
eye = dDbgCamera.Eye();
up = dDbgCamera.Up();
angle = dDbgCamera.Bank();
fovy = dDbgCamera.Fovy();
}
#endif
} else if (!dCamera->CheckFlag(1)) {
center = dCamera->Center();
eye = dCamera->Eye();
up = dCamera->Up();
angle = dCamera->Bank();
fovy = dCamera->Fovy();
}
if (eye.x == center.x && eye.z == center.z) {
error = true;
OS_REPORT("camera: ERROR: bad direction !!\n");
}
if (fovy < 0.0f || std::isnan(fovy)) {
error = true;
OS_REPORT("camera: ERROR: bad fovy !!\n");
}
if (std::isnan(eye.x) || std::isnan(eye.y) || std::isnan(eye.z)) {
error = true;
OS_REPORT("camera: ERROR: bad eye !!\n");
}
if (std::isnan(center.x) || std::isnan(center.y) || std::isnan(center.z)) {
error = true;
OS_REPORT("camera: ERROR: bad eye !!\n");
}
if (!error) {
fopCamM_SetCenter(camera, center.x, center.y, center.z);
fopCamM_SetEye(camera, eye.x, eye.y, eye.z);
fopCamM_SetUp(camera, up.x, up.y, up.z);
fopCamM_SetBank(camera, angle);
fopCamM_SetFovy(camera, fovy);
}
dStage_dt_c* stage = (dStage_dt_c*)dComIfGp_getStage();
#if DEBUG
if (dCamera->mCamSetup.CheckFlag(0x400)) {
fopCamM_SetNear(camera, dCamera->Near4Debug());
fopCamM_SetFar(camera, dCamera->Far4Debug());
} else if (stage != NULL) {
if (dComIfGp_getCameraAttentionStatus(camera_id) & 0x8) {
fopCamM_SetNear(camera, 30.0f);
} else {
fopCamM_SetNear(camera, stage->getStagInfo()->mNear);
}
fopCamM_SetFar(camera, stage->getStagInfo()->mFar);
}
#else
if (dComIfGp_getCameraAttentionStatus(camera_id) & 0x8) {
fopCamM_SetNear(camera, 30.0f);
} else {
if (stage != NULL) {
fopCamM_SetNear(camera, stage->getStagInfo()->mNear);
}
}
if (stage != NULL) {
fopCamM_SetFar(camera, stage->getStagInfo()->mFar);
}
#endif
cSGlobe globe(eye - center);
fopCamM_SetAngleY(camera, globe.U().Inv());
fopCamM_SetAngleX(camera, globe.V());
}
cXyz dCamera_c::Up() {
if (chkFlag(0x10)) {
return mUpOverride.field_0x18;
} else {
return mUp;
}
}
cXyz dCamera_c::Eye() {
return mEye + mShake.mEyeShake;
}
cXyz dCamera_c::Center() {
return mCenter + mShake.field_0x24;
}
static int camera_execute(camera_process_class* i_this) {
preparation(i_this);
if (dDemo_c::getCamera() != NULL) {
i_this->mCamera.ResetView();
}
dComIfGp_offCameraAttentionStatus(0, 0x40);
if (i_this->mCamera.Active()) {
i_this->mCamera.Run();
} else {
i_this->mCamera.NotRun();
}
i_this->mCamera.CalcTrimSize();
store(i_this);
view_setup(i_this);
return 1;
}
static int camera_draw(camera_process_class* i_this) {
camera_class* a_this = (camera_class*)i_this;
dCamera_c* body = &i_this->mCamera;
dDlst_window_c* window = get_window(a_this);
view_port_class* viewport = window->getViewPort();
camera_process_class* process = i_this;
int camera_id = get_camera_id(a_this);
#if DEBUG
if (dDebugPad.Enable(0) && body->CameraID() == 0) {
if (dDebugPad.Trigger() != 0) {
dDbgCamera.Reset(body);
}
dDbgCamera.Run();
cXyz center;
cXyz eye;
cXyz up;
cSAngle bank;
f32 fovY;
if (dDebugPad.Trigger() == 0) {
if (dDbgCamera.Playing()) {
center = body->Center();
eye = body->Eye();
up = body->Up();
bank = body->Bank();
fovY = body->Fovy();
} else {
center = dDbgCamera.Center();
eye = dDbgCamera.Eye();
up = dDbgCamera.Up();
bank = dDbgCamera.Bank();
fovY = dDbgCamera.Fovy();
dDbgCamera.DrawShape();
}
body->U2(cSGlobe(eye - center).U().Inv());
fopCamM_SetCenter(a_this, center.x, center.y, center.z);
fopCamM_SetEye(a_this, eye.x, eye.y, eye.z);
fopCamM_SetUp(a_this, up.x, up.y, up.z);
fopCamM_SetBank(a_this, bank);
fopCamM_SetFovy(a_this, fovY);
fopCamM_SetAngleY(a_this, body->U());
fopCamM_SetAngleX(a_this, body->V());
}
}
#endif
int trim_height = body->TrimHeight();
#if TARGET_PC
trim_height *= viewport->height / FB_HEIGHT;
window->setScissor(0.0f, trim_height, viewport->width, viewport->height - trim_height * 2.0f);
#else
window->setScissor(0.0f, trim_height, FB_WIDTH, FB_HEIGHT - trim_height * 2.0f);
#endif
C_MTXPerspective(process->view.projMtx, process->view.fovy, process->view.aspect, process->view.near_, process->view.far_);
mDoMtx_lookAt(process->view.viewMtx, &process->view.lookat.eye, &process->view.lookat.center,
&process->view.lookat.up, process->view.bank);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(process->view.viewMtx),
process->view.viewMtx);
#endif
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomProjection(process->view.projMtx);
#endif
j3dSys.setViewMtx(process->view.viewMtx);
cMtx_inverse(process->view.viewMtx, process->view.invViewMtx);
Z2GetAudience()->setAudioCamera(process->view.viewMtx, process->view.lookat.eye, process->view.lookat.center,
process->view.fovy, process->view.aspect, getComStat(0x80), camera_id,
false);
dBgS_GndChk gndchk;
gndchk.OnWaterGrp();
gndchk.SetPos(&process->view.lookat.eye);
f32 cross = dComIfG_Bgsp().GroundCross(&gndchk);
if (cross != -G_CM3D_F_INF) {
if (dComIfG_Bgsp().ChkGrpInf(gndchk, 0x100)) {
mDoAud_getCameraMapInfo(6);
} else {
mDoAud_getCameraMapInfo(dComIfG_Bgsp().GetMtrlSndId(gndchk));
}
mDoAud_setCameraGroupInfo(dComIfG_Bgsp().GetGrpSoundId(gndchk));
Vec spDC;
spDC.x = process->view.lookat.eye.x;
spDC.y = cross;
spDC.z = process->view.lookat.eye.z;
Z2AudioMgr::getInterface()->setCameraPolygonPos(&spDC);
} else {
Z2AudioMgr::getInterface()->setCameraPolygonPos(NULL);
}
MTXCopy(process->view.viewMtx, process->view.viewMtxNoTrans);
process->view.viewMtxNoTrans[0][3] = 0.0f;
process->view.viewMtxNoTrans[1][3] = 0.0f;
process->view.viewMtxNoTrans[2][3] = 0.0f;
cMtx_concatProjView(process->view.projMtx, process->view.viewMtx, process->view.projViewMtx);
body->Draw();
return 1;
}
static int init_phase1(camera_class* i_this) {
camera_process_class* camera = (camera_process_class*)i_this;
int camera_id = get_camera_id(i_this);
dComIfGp_setCamera(camera_id, i_this);
fopCamM_SetPrm1(i_this, dComIfGp_getCameraWinID(camera_id));
fopCamM_SetPrm2(i_this, dComIfGp_getCameraPlayer1ID(camera_id));
fopCamM_SetPrm3(i_this, dComIfGp_getCameraPlayer2ID(camera_id));
dComIfGp_setWindowNum(0);
i_this->field_0x238 = 0;
i_this->field_0x22f = 71;
camera->mCamera.field_0xb0c = 0;
return cPhs_NEXT_e;
}
static int init_phase2(camera_class* i_this) {
camera_process_class* camera = (camera_process_class*)i_this;
dCamera_c* body = &camera->mCamera;
int camera_id = get_camera_id(i_this);
i_this->field_0x238++;
fopAc_ac_c* player = (fopAc_ac_c*)get_player_actor(i_this);
if (player == NULL) {
return cPhs_INIT_e;
}
dBgS_GndChk gndchk;
cXyz spA4(player->current.pos);
spA4.y += 50.0f;
gndchk.SetPos(&spA4);
if (dComIfG_Bgsp().GroundCross(&gndchk) == -G_CM3D_F_INF) {
#if DEBUG
if (i_this->field_0x238 < 100) {
if (i_this->field_0x238 % 100 == 0 && i_this->field_0x238 != 0) {
OS_REPORT("camera: can not found floor... %d\n", i_this->field_0x238);
}
return cPhs_INIT_e;
}
OS_REPORT("\ncamera: Warning: give up to get floor info !!\n\n");
#else
return cPhs_INIT_e;
#endif
}
fopAcM_setStageLayer(player);
dComIfGp_setWindowNum(1);
JKR_NEW_ARGS (body) dCamera_c(i_this);
f32 var_f31 = 0.0f;
f32 var_f30 = 160000.0f;
if (dComIfGp_getStage()->getStagInfo() != NULL) {
dStage_dt_c* stage_dt = dComIfGp_getStage();
var_f31 = stage_dt->getStagInfo()->mNear;
var_f30 = stage_dt->getStagInfo()->mFar;
}
dDlst_window_c* window = get_window(camera_id);
view_port_class* viewport = window->getViewPort();
var_f31 = 1.0f;
fopCamM_SetNear(i_this, var_f31);
fopCamM_SetFar(i_this, var_f30);
fopCamM_SetFovy(i_this, 30.0f);
fopCamM_SetAspect(i_this, mDoGph_gInf_c::getAspect());
fopCamM_SetCenter(i_this, player->current.pos.x, player->current.pos.y, player->current.pos.z);
fopCamM_SetBank(i_this, 0);
store(camera);
view_setup(camera);
camera->mCamera.field_0xb0c = 1;
if (body->CameraID() == 0) {
#if DEBUG
dDbgCamera.Init(body);
#endif
}
i_this->field_0x238 = 0;
dComIfGp_getAttention()->Init(player, PAD_1);
return cPhs_NEXT_e;
}
static void dummy() {
const char* s1 = "Create -> Camera\n";
const char* s2 = "Delete -> Camera\n";
}
static int camera_create(camera_class* i_this) {
static request_of_phase_process_fn l_method[3] = {
(request_of_phase_process_fn)init_phase1,
(request_of_phase_process_fn)init_phase2,
(request_of_phase_process_fn)NULL,
};
camera_process_class* camera = (camera_process_class*)i_this;
return dComLbG_PhaseHandler(&camera->phase_request, l_method, i_this);
}
static int camera_delete(camera_process_class* i_this) {
dCamera_c* camera = &i_this->mCamera;
if (camera->CameraID() == 0) {
#if DEBUG
dDbgCamera.Finish();
#endif
}
camera->~dCamera_c();
dComIfGp_setCamera(0, NULL);
return 1;
}
static int is_camera_delete(void* i_this) {
return 1;
}
void dCamForcusLine::Init() {
field_0x49 = 0;
field_0x48 = 1;
field_0x38 = cXyz(320.0f, 240.0f, 0.0f);
field_0x44.r = 0xFF;
field_0x44.g = 0xFF;
field_0x44.b = 0xFF;
field_0x44.a = 0x60;
field_0x4c = 100;
field_0x50 = 100;
field_0x54 = 100;
field_0x58 = 0x50;
field_0x5a = 0;
field_0x5c = 4;
field_0x5e = 4;
field_0x68 = 180.0f;
field_0x6c = 0.0f;
field_0x60 = 180.0f;
field_0x64 = 60.0f;
}
void dCamForcusLine::Draw() {
if (field_0x49) {
if (field_0x48 == 0) {
mEffectLine.initRnd(field_0x4c, field_0x50, field_0x54);
}
mEffectLine.update(field_0x38, field_0x44, field_0x58, field_0x5a, field_0x5c, field_0x5e, field_0x60, field_0x64, field_0x68, field_0x6c);
}
}
bool dCamForcusLine::Off() {
field_0x49 = false;
return field_0x49 == false;
}
static leafdraw_method_class method = {
(process_method_func)camera_create,
(process_method_func)camera_delete,
(process_method_func)camera_execute,
(process_method_func)is_camera_delete,
(process_method_func)camera_draw,
};
camera_process_profile_definition g_profile_CAMERA = {
/* Layer ID */ fpcLy_CURRENT_e,
/* List ID */ 11,
/* List Prio */ fpcPi_CURRENT_e,
/* Proc Name */ fpcNm_CAMERA_e,
/* Proc SubMtd */ &g_fpcLf_Method.base,
/* Size */ sizeof(camera_process_class),
/* Size Other */ 0,
/* Parameters */ 0,
/* View Leaf SubMtd */ &g_fopVw_Method,
/* Draw Prio */ fpcDwPi_CAMERA_e,
/* fopCam Leaf SubMtd */ &g_fopCam_Method,
0,
0,
0,
0,
0,
/* Camera SubMtd */ &method,
0,
};
camera_process_profile_definition g_profile_CAMERA2 = {
/* Layer ID */ fpcLy_CURRENT_e,
/* List ID */ 11,
/* List Prio */ fpcPi_CURRENT_e,
/* Proc Name */ fpcNm_CAMERA2_e,
/* Proc SubMtd */ &g_fpcLf_Method.base,
/* Size */ sizeof(camera_process_class),
/* Size Other */ 0,
/* Parameters */ 0,
/* View Leaf SubMtd */ &g_fopVw_Method,
/* Draw Prio */ fpcDwPi_CAMERA2_e,
/* fopCam Leaf SubMtd */ &g_fopCam_Method,
0,
0,
0,
0,
0,
/* Camera SubMtd */ &method,
0,
};