diff options
| author | krimtonz <33664508+krimtonz@users.noreply.github.com> | 2020-12-06 16:39:47 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-06 17:39:47 -0500 |
| commit | 321388673b4a3e763d23dec16e08e9c513869de4 (patch) | |
| tree | e43235b424e19e6f3563e73d484a7afe41365aa4 /src/code | |
| parent | dadee87f9423fd7b06ec088bf4bde5f768598d3c (diff) | |
decompile z_camera (#398)
* cleanup
* name camera action functions
* decompile a few small functions, name a few Camera struct members
* decompile camera data, decompile a few camera functions
* Split ASM for code_800BB0A0
* removing code_800BB0A0.s
* PR Requests, Camera WIP
* remove #define NON_MATCHING from db_camera
* rename code_8007BF90.c to z_olib.c, rename functions in z_olib.c
* camera wip
* rename some struct memebers, some decomp wip
* pr updates
* camera wip
* name some fields in Camera Struct, being making sense of Camera_Update
* Camera WIP
* wip
* wip
* add z64camera.h header, begin creating CameraSetting macros
* wip
* wip
* wip
* wip
* migrate camera bss to c
* match a couple functions in db_camera
* match some small db_camera functions
* wip
* migrate db_camera rodata, match a few functions
* remote db_camera.rodata.s
* match some of db_camera
* identify types of some unknown data pieces
* some small wip
* Match Camera_Init, some function changes, some struct name changes. Change unk_C0 and unk_CC to floats from Vec3fs
* add naming for a few more Camera struct members
* wip
* match func_80043F94
* Match Camera_Jump1
* document some of Camera_Jump1
* wip
* match Camera_Jump3
* Match Camera_Update, FeelsAmazing
* wip
* wip
* match Camera_SetParam
* minor cleanup
* wip
* wip
* match Camera_KeepOn0
* some documentation, modify some matching functions to match style of others.
* match Camera_Demo1
* match camera_demo9
* document Camera_Demo1 and Camera_Demo9
* wip
* Match camera_battle4
* match camera_unique2
* Match Camera_Unique3
* match camera_special6
* match Camera_Special5
* wip
* document camera_special6
* naming updates
* match camera_Unique1
* match Camera_Unique0
* wip
* Match Camera_CalcUpFromPitchYawRoll
* match func_80045508
* document Camera_Battle4
* document several camera functions, move camera data to separate file
* rename phi/theta to pitch/yaw
* wip
* uniq9 wip
* Camera_Unqiue9 OK
* document Camera_Unique9
* name unk_160 in camera struct
* wip
* wip
* minor updates
* fix conflicts
* wip
* wip
* Olib updates
* wip
* wip
* rename most Math3D functions, few matches, documentation
* wip
* document most of math3d
* wip
* wip
* wip
* pr updates
* Match Camera_Fixed4
* match func_80058E8C
* pr updates
* add missing comment block finalizer
* Merge math3dupdates
* match Camera_ChangeSetting
* Match Camera_ChangeMode
* match func_80058148
* Match Camera_Special9
* decompile the rest of camera data
* match Camera_Demo5
* name a few camera functions in z_play
* match func_80046CB4, some work on other fucntions
* wip
* impove some non matchings
* fix function rename
* match func_800588B4
* match Camera_Subj4
* wip
* Camera_Demo3 matching, Camera_Battle1 big progress
* Camera_Normal2 OK
* wip
* match Camera_Parallel1
* normalize some things across functions
* match Camera_Normal1
* Match Camera_Normal3
* some cleanup
* more cleanup
* more cleanup , match Camera_CalcDefaultPitch
* data formatting
* Match Camera_Jump2
* document Camera_Jump2
* Match Camera_KeepOn3
* document some of Camera_KeepOn3
* improve some non_matchings
* match func_80045C74 and func_800460A8
* code cleanup, documentation
* match Camera_KeepOn1
* Match Camera_Subj3
* Match Camera_Battle1
* remove non_matching from func_80044adc and func_80046e20
* name several members of Battle1
* more documentation on Battle1
* cleanup
* renaming Camera_Vec3fScaleXYZFactor to Camera_Vec3fTranslateByUnitVector
* reorganize update structs, remove final references to params, remove CameraParams union
* implement camera enums into player
* Renaming Camera_GetDir to Camera_GetInputDir, Camera_GetRealDir to Camera_GetCamDir, etc, implement camera enum's into player
* remove non-global camera variables from variables.h
* clean up some variable declarations
* finish pr comment updates
* fix some warnings
* data formatting
* finish commenting on data
* delete unused asm
* remove asm
Co-authored-by: fig <fig02srl@gmail.com>
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/db_camera.c | 266 | ||||
| -rw-r--r-- | src/code/z_actor.c | 24 | ||||
| -rw-r--r-- | src/code/z_bgcheck.c | 8 | ||||
| -rw-r--r-- | src/code/z_camera.c | 10148 | ||||
| -rw-r--r-- | src/code/z_camera_data.c | 3573 | ||||
| -rw-r--r-- | src/code/z_demo.c | 49 | ||||
| -rw-r--r-- | src/code/z_horse.c | 2 | ||||
| -rw-r--r-- | src/code/z_olib.c | 26 | ||||
| -rw-r--r-- | src/code/z_onepointdemo.c | 34 | ||||
| -rw-r--r-- | src/code/z_play.c | 100 | ||||
| -rw-r--r-- | src/code/z_player_lib.c | 2 | ||||
| -rw-r--r-- | src/code/z_quake.c | 44 | ||||
| -rw-r--r-- | src/code/z_room.c | 9 |
13 files changed, 11110 insertions, 3175 deletions
diff --git a/src/code/db_camera.c b/src/code/db_camera.c index fc97d1ebd..d29093583 100644 --- a/src/code/db_camera.c +++ b/src/code/db_camera.c @@ -1,24 +1,96 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B3B50.s") +extern GlobalContext* D_80161100; +extern s32 D_8012CED8; +extern s32 D_8012CED4; +extern s32 D_8012CED0; +extern char D_801612D0[0x1A]; +extern char D_801612EA; +extern DBCamera* D_80161108; +extern s16 D_80161148; +extern s16 D_8016114A; +extern s16 D_8016111A; +extern s16 D_8016110C; + +typedef struct { + char state; + s16 mode; + CutsceneCameraPoint* eyePoints; + CutsceneCameraPoint* atPoints; + s16 frameCnt; + s16 csPointsCnt; +} DBCSEditorSlot; + +extern DBCSEditorSlot sDbgEditorSlots[]; +extern char sDbgEditorStates[]; + +// DbgCamera_Vec3fVecSphGeoAdd +Vec3f* func_800B3B50(Vec3f* dest, Vec3f* a, VecSph* b) { + Vec3f copy, vecB; + OLib_VecSphGeoToVec3f(&vecB, b); + + copy.x = a->x + vecB.x; + copy.y = a->y + vecB.y; + copy.z = a->z + vecB.z; + + *dest = copy; + return dest; +} #pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B3BD4.s") #pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B3DF8.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B3EBC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B3EFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B3F38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B3F54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B3F94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B3FF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B404C.s") +void func_800B3EBC(Vec3s* src, Vec3f* dest) { + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; +} + +void func_800B3EFC(Vec3f* src, Vec3s* dest) { + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; +} + +void func_800B3F38(Vec3f* src, Vec3f* dest) { + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; +} + +void func_800B3F54(Vec3s* src, Vec3f* dest) { + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; +} + +void func_800B3F94(PosRot* arg0, Vec3f* arg1, Vec3s* arg2) { + VecSph sp28; + Vec3f sp1C; + + OLib_Vec3fDiffToVecSphGeo(&sp28, &arg0->pos, arg1); + sp28.yaw -= arg0->rot.y; + OLib_VecSphGeoToVec3f((Vec3f*)&sp1C, &sp28); + func_800B3EFC(&sp1C, arg2); +} + +void func_800B3FF4(PosRot* arg0, Vec3f* arg1, Vec3f* arg2) { + VecSph sp28; + Vec3f sp1C; + + func_800B3F38(arg1, &sp1C); + OLib_Vec3fToVecSphGeo(&sp28, &sp1C); + sp28.yaw += arg0->rot.y; + func_800B3B50(arg2, arg0, &sp28); +} + +void func_800B404C(s32 arg0, Vec3s* arg1, Vec3f* arg2) { + Vec3f sp1C; + + func_800B3EBC(arg1, &sp1C); + func_800B3FF4(arg0, &sp1C, arg2); +} #pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B4088.s") @@ -30,7 +102,25 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B44E0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B4920.s") +/** + * Prints individual csSlot point information + */ +void func_800B4920(char* varName, s16 pointCnt, CutsceneCameraPoint* csPoints) { + s32 i; + CutsceneCameraPoint* csPoint; + + osSyncPrintf("@@@static SplinedatZ %s[] = {\n", varName); + for (i = 0, csPoint = csPoints; i < pointCnt; i++, csPoint++) { + osSyncPrintf("@@@ /* key frame %2d */ {\n", i); + osSyncPrintf("@@@ /* code */ %d,\n", csPoint->continueFlag); + osSyncPrintf("@@@ /* z */ %d,\n", csPoint->cameraRoll); + osSyncPrintf("@@@ /* T */ %d,\n", csPoint->nextPointFrame); + osSyncPrintf("@@@ /* zoom */ %f,\n", csPoint->viewAngle); + osSyncPrintf("@@@ /* pos */ { %d, %d, %d }\n", csPoint->pos.x, csPoint->pos.y, csPoint->pos.z); + osSyncPrintf("@@@ },\n"); + } + osSyncPrintf("@@@};\n@@@\n"); +} #pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B4A68.s") @@ -40,28 +130,154 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B4B20.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B4D58.s") +void DbgCamera_Init(DBCamera* dbCamera, Camera* camera) { + dbCamera->unk_10C6.x = dbCamera->unk_10C6.y = dbCamera->unk_10C6.z = 0; + dbCamera->unk_44 = 0; + dbCamera->unk_00 = 0; + dbCamera->unk_34 = 0; + dbCamera->unk_3C = 0; + dbCamera->unk_38 = -1; + dbCamera->unk_40 = -1; + dbCamera->unk_4C = 0; + dbCamera->fov = 0.0f; + dbCamera->unk_50 = 0.0f; + D_80161100 = camera->globalCtx; + dbCamera->unk_7C = 0; + dbCamera->unk_7E = -1; + dbCamera->unk_80 = 1; + dbCamera->unk_82 = 0; + dbCamera->unk_84 = 0; + dbCamera->unk_86 = 0; + dbCamera->unk_78 = 0; + dbCamera->unk_7A = 0; + dbCamera->unk_10C0.x = 0; + dbCamera->unk_10C0.y = 0; + dbCamera->unk_10C0.z = 0; + dbCamera->unk_6C = dbCamera->unk_70 = dbCamera->unk_74 = 0; +} + +void DbgCamera_Enable(DBCamera* dbCamera, Camera* camera) { + dbCamera->at = camera->at; + dbCamera->eye = camera->eye; + dbCamera->up = camera->up; + dbCamera->fov = camera->fov; + dbCamera->unk_4C = 0; + dbCamera->unk_80 = 1; + dbCamera->unk_82 = 0; + dbCamera->unk_84 = 0; + dbCamera->unk_86 = 1; + dbCamera->unk_88 = 1; + dbCamera->unk_78 = 0; + dbCamera->unk_7A = 0; + dbCamera->unk_50 = 0.0f; + func_800B4088(dbCamera, camera); +} + +#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/DbgCamera_Update.s") + +s32 func_800B8730(void) { + s32 temp_v1; + void* phi_v0; + s32 phi_v1; + + for (phi_v1 = 0; phi_v1 < 0x1A; phi_v1++) { + if (D_801612D0[phi_v1] != 'O') { + return phi_v1 + 'A'; + } + } + return '?'; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B4DE4.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B87D8.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B4E7C.s") +/** + * Clears a DBCSEditorSlot + */ +void func_800B8978(s32 editorSlot, s32 free) { + + if (sDbgEditorSlots[editorSlot].state != '?') { + sDbgEditorStates[sDbgEditorSlots[editorSlot].state] = 'X'; + } + if (free) { + DebugArena_FreeDebug(sDbgEditorSlots[editorSlot].atPoints, "../db_camera.c", 2784); + DebugArena_FreeDebug(sDbgEditorSlots[editorSlot].eyePoints, "../db_camera.c", 2785); + } + sDbgEditorSlots[editorSlot].state = '?'; + sDbgEditorSlots[editorSlot].atPoints = NULL; + sDbgEditorSlots[editorSlot].eyePoints = NULL; + sDbgEditorSlots[editorSlot].mode = 0; + sDbgEditorSlots[editorSlot].frameCnt = 0; + sDbgEditorSlots[editorSlot].csPointsCnt = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B8730.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B8A0C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B87D8.s") +extern s32 D_801612EC; -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B8978.s") +s32 func_800B8BA4(void) { + return D_801612EC; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B8A0C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B8BB0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B8DB0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B8BA4.s") +void func_800B8F30(char* arg0) { + Mempak_DeleteFile(2, *arg0); +} #pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B8F58.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B9060.s") +/** + * Prints cs editor slot inforation + */ +void func_800B9060(s32 arg0) { + DBCSEditorSlot* csSlot; + s32 i; + + Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + osSyncPrintf("@@@\n@@@\n@@@/* ****** spline point data ** start here ***** */\n@@@\n"); + for (i = 0, csSlot = sDbgEditorSlots; i < 0xF; i++, csSlot++) { + if (csSlot->csPointsCnt != 0) { + if (i != 0) { + osSyncPrintf("@@@\n@@@/* ** %d ** */\n@@@\n", i); + } + func_800B4920("Lookat", csSlot->csPointsCnt, csSlot->atPoints); + func_800B4920("Position", csSlot->csPointsCnt, csSlot->eyePoints); + osSyncPrintf("@@@static short nPoints = %d;\n@@@\n", csSlot->csPointsCnt); + osSyncPrintf("@@@static short nFrames = %d;\n@@@\n", csSlot->frameCnt); + osSyncPrintf("@@@static short Mode = %d;\n@@@\n", csSlot->mode); + } + } + osSyncPrintf("@@@\n@@@\n@@@/* ****** spline point data ** finish! ***** */\n@@@\n"); +} #pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B91B0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B958C.s") +/** + * Initalizes the custscene editor + */ +void DbgCamera_FirstInit(Camera* camera, DBCamera* dbCamera) { + s32 temp_s0; + u32 temp_v0; + u32 phi_v0; + s32 i; + char* p; + + D_801612EA = '*'; + for (p = D_801612D0; p < &D_801612D0[0x1A]; p++) { + *p = 'X'; + } + + for (i = 0; i < 0xF; i++) { + func_800B8978(i, 0); + } + + D_80161108 = dbCamera; + D_8016110C = 0; + D_80161148 = 0; + D_8016114A = -1; + D_8016111A = 0; +} #pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_800B9638.s") diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 0595228cd..e10b67783 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -952,7 +952,7 @@ f32 Actor_HeightDiff(Actor* actorA, Actor* actorB) { return actorB->posRot.pos.y - actorA->posRot.pos.y; } -f32 Player_GetCameraYOffset(Player* player) { +f32 Player_GetHeight(Player* player) { f32 offset = (player->stateFlags1 & 0x800000) ? 32.0f : 0.0f; if (LINK_IS_ADULT) { @@ -1012,7 +1012,7 @@ void func_8002DE04(GlobalContext* globalCtx, Actor* actorA, Actor* actorB) { void func_8002DE74(GlobalContext* globalCtx, Player* player) { if ((globalCtx->roomCtx.curRoom.unk_03 != 4) && func_800C0CB8(globalCtx)) { - func_8005A77C(Gameplay_GetCamera(globalCtx, 0), 6); + Camera_ChangeSetting(Gameplay_GetCamera(globalCtx, 0), CAM_SET_HORSE0); } } @@ -1206,7 +1206,7 @@ void func_8002E4B4(GlobalContext* globalCtx, Actor* actor, f32 arg2, f32 arg3, f u32 sp60; CollisionPoly* sp5C; f32 sp58; - UNK_TYPE sp54; + WaterBox* sp54; f32 sp50; Vec3f ripplePos; @@ -2166,10 +2166,10 @@ void Actor_Draw(GlobalContext* globalCtx, Actor* actor) { Lights_Draw(lights, globalCtx->state.gfxCtx); if (actor->flags & 0x1000) { - func_800D1694(actor->posRot.pos.x + globalCtx->mainCamera.unk_80.x, + func_800D1694(actor->posRot.pos.x + globalCtx->mainCamera.skyboxOffset.x, actor->posRot.pos.y + - (f32)((actor->shape.unk_08 * actor->scale.y) + globalCtx->mainCamera.unk_80.y), - actor->posRot.pos.z + globalCtx->mainCamera.unk_80.z, &actor->shape.rot); + (f32)((actor->shape.unk_08 * actor->scale.y) + globalCtx->mainCamera.skyboxOffset.y), + actor->posRot.pos.z + globalCtx->mainCamera.skyboxOffset.z, &actor->shape.rot); } else { func_800D1694(actor->posRot.pos.x, actor->posRot.pos.y + (actor->shape.unk_08 * actor->scale.y), actor->posRot.pos.z, &actor->shape.rot); @@ -2846,7 +2846,7 @@ Actor* Actor_Delete(ActorContext* actorCtx, Actor* actor, GlobalContext* globalC if ((player != NULL) && (actor == player->unk_664)) { func_8008EDF0(player); - func_8005A444(Gameplay_GetCamera(globalCtx, Gameplay_GetActiveCamId(globalCtx)), 0); + Camera_ChangeMode(Gameplay_GetCamera(globalCtx, Gameplay_GetActiveCamId(globalCtx)), 0); } if (actor == actorCtx->targetCtx.arrowPointedActor) { @@ -3831,7 +3831,7 @@ s16 func_80034DD4(Actor* actor, GlobalContext* globalCtx, s16 arg2, f32 arg3) { Player* player = PLAYER; f32 var; - if ((globalCtx->csCtx.state != 0) || (D_8011D394 != 0)) { + if ((globalCtx->csCtx.state != 0) || (gDbgCamEnabled != 0)) { var = Math_Vec3f_DistXYZ(&actor->posRot.pos, &globalCtx->view.eye) * 0.25f; } else { var = Math_Vec3f_DistXYZ(&actor->posRot.pos, &player->actor.posRot.pos); @@ -5474,7 +5474,7 @@ s32 func_80038154(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, Vec3s* ar actor->posRot2.pos = actor->posRot.pos; actor->posRot2.pos.y += arg4; - if (!(((globalCtx->csCtx.state != 0) || (D_8011D394 != 0)) && (gSaveContext.entranceIndex == 0x00EE))) { + if (!(((globalCtx->csCtx.state != 0) || (gDbgCamEnabled != 0)) && (gSaveContext.entranceIndex == 0x00EE))) { var = actor->yawTowardsLink - actor->shape.rot.y; abs_var = ABS(var); if (abs_var >= 0x4300) { @@ -5483,7 +5483,7 @@ s32 func_80038154(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, Vec3s* ar } } - if (((globalCtx->csCtx.state != 0) || (D_8011D394 != 0)) && (gSaveContext.entranceIndex == 0x00EE)) { + if (((globalCtx->csCtx.state != 0) || (gDbgCamEnabled != 0)) && (gSaveContext.entranceIndex == 0x00EE)) { sp2C = globalCtx->view.eye; } else { sp2C = player->actor.posRot2.pos; @@ -5503,7 +5503,7 @@ s32 func_80038290(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, Vec3s* ar actor->posRot2.pos = arg4; - if (!(((globalCtx->csCtx.state != 0) || (D_8011D394 != 0)) && (gSaveContext.entranceIndex == 0x00EE))) { + if (!(((globalCtx->csCtx.state != 0) || (gDbgCamEnabled != 0)) && (gSaveContext.entranceIndex == 0x00EE))) { var = actor->yawTowardsLink - actor->shape.rot.y; abs_var = ABS(var); if (abs_var >= 0x4300) { @@ -5512,7 +5512,7 @@ s32 func_80038290(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, Vec3s* ar } } - if (((globalCtx->csCtx.state != 0) || (D_8011D394 != 0)) && (gSaveContext.entranceIndex == 0x00EE)) { + if (((globalCtx->csCtx.state != 0) || (gDbgCamEnabled != 0)) && (gSaveContext.entranceIndex == 0x00EE)) { sp24 = globalCtx->view.eye; } else { sp24 = player->actor.posRot2.pos; diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c index 8dc88a5ac..f92940126 100644 --- a/src/code/z_bgcheck.c +++ b/src/code/z_bgcheck.c @@ -354,7 +354,7 @@ void func_80041978(s32 iParm1, s32 iParm2) { #pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800419B0.s") -u32 func_80041A28(CollisionContext* a0, u32 a1, u32 a2) { +s32 func_80041A28(CollisionContext* a0, CollisionPoly* a1, u32 a2) { u32 uVar1; uVar1 = func_800419B0(a0, a1, a2, 0); @@ -436,9 +436,9 @@ s32 func_80042108(CollisionContext* a0, CollisionPoly* a1, u32 a2) { #pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_80042244.s") -u8 func_80042538(CollisionContext* colCtx, s32 iParm2) { - u32 var1 = *(u32*)(iParm2 + 0xc); - return var1; +u32 func_80042538(CollisionContext* colCtx, WaterBox* arg1) { + u32 unk0C = arg1->unk_0C; + return unk0C & 0xFF; } #pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_80042548.s") diff --git a/src/code/z_camera.c b/src/code/z_camera.c index c0822b1ab..2a7d058d3 100644 --- a/src/code/z_camera.c +++ b/src/code/z_camera.c @@ -1,2576 +1,1901 @@ +#include "ultra64.h" #include "global.h" #include "vt.h" +#include "overlays/actors/ovl_En_Horse/z_en_horse.h" -typedef struct { - s16 val; - s16 param; -} CameraModeValue; +s16 Camera_ChangeSettingFlags(Camera* camera, s16 setting, s16 flags); +s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags); +s32 Camera_QRegInit(void); +s32 Camera_CheckWater(Camera* camera); -typedef struct { - s16 funcIdx; - s16 valueCnt; - CameraModeValue* values; -} CameraMode; - -typedef struct { - union { - u32 unk_00; - struct { - u32 unk_bit0 : 1; - u32 unk_bit1 : 1; - u32 validModes : 30; - }; - }; - CameraMode* cameraModes; -} CameraSetting; - -typedef union { - s16 sh[2]; - s32 w; -} u_D_8011D3A0; - -typedef enum { - CAM_SET_NONE, - CAM_SET_NORMAL0, - CAM_SET_NORMAL1, - CAM_SET_DUNGEON0, - CAM_SET_DUNGEON1, - CAM_SET_NORMAL3, - CAM_SET_HORSE0, - CAM_SET_BOSS_GOMA, - CAM_SET_BOSS_DODO, - CAM_SET_BOSS_BARI, - CAM_SET_BOSS_FGANON, - CAM_SET_BOSS_BAL, - CAM_SET_BOSS_SHADES, - CAM_SET_BOSS_MOFA, - CAM_SET_TWIN0, - CAM_SET_TWIN1, - CAM_SET_BOSS_GANON1, - CAM_SET_BOSS_GANON2, - CAM_SET_TOWER0, - CAM_SET_TOWER1, - CAM_SET_FIXED0, - CAM_SET_FIXED1, - CAM_SET_CIRCLE0, - CAM_SET_CIRCLE2, - CAM_SET_CIRCLE3, - CAM_SET_PREREND0, - CAM_SET_PREREND1, - CAM_SET_PREREND3, - CAM_SET_DOOR0, - CAM_SET_DOORC, - CAM_SET_RAIL3, - CAM_SET_START0, - CAM_SET_START1, - CAM_SET_FREE0, - CAM_SET_FREE2, - CAM_SET_CIRCLE4, - CAM_SET_CIRCLE5, - CAM_SET_DEMO0, - CAM_SET_DEMO1, - CAM_SET_MORI1, - CAM_SET_ITEM0, - CAM_SET_ITEM1, - CAM_SET_DEMO3, - CAM_SET_DEMO4, - CAM_SET_UFOBEAN, - CAM_SET_LIFTBEAN, - CAM_SET_SCENE0, - CAM_SET_SCENE1, - CAM_SET_HIDAN1, - CAM_SET_HIDAN2, - CAM_SET_MORI2, - CAM_SET_MORI3, - CAM_SET_TAKO, - CAM_SET_SPOT05A, - CAM_SET_SPOT05B, - CAM_SET_HIDAN3, - CAM_SET_ITEM2, - CAM_SET_CIRCLE6, - CAM_SET_NORMAL2, - CAM_SET_FISHING, - CAM_SET_DEMOC, - CAM_SET_UO_FIBER, - CAM_SET_DUNGEON2, - CAM_SET_TEPPEN, - CAM_SET_CIRCLE7, - CAM_SET_NORMAL4, - CAM_SET_MAX -} CameraSettingType; - -typedef enum { - CAM_MODE_NORMAL, - CAM_MODE_PARALLEL, - CAM_MODE_KEEPON, - CAM_MODE_TALK, - CAM_MODE_BATTLE, - CAM_MODE_CLIMB, - CAM_MODE_SUBJECT, - CAM_MODE_BOWARROW, - CAM_MODE_BOWARROWZ, - CAM_MODE_FOOKSHOT, - CAM_MODE_BOOMERANG, - CAM_MODE_PACHINCO, - CAM_MODE_CLIMBZ, - CAM_MODE_JUMP, - CAM_MODE_HANG, - CAM_MODE_HANGZ, - CAM_MODE_FREEFALL, - CAM_MODE_CHARGE, - CAM_MODE_STILL, - CAM_MODE_PUSHPULL, - CAM_MODE_BOOKEEPON -} CameraModeType; - -/*==================================================================*/ -// Data -s16 sOREGInit[] = { - 0, 1, 5, 5, 5, 14500, 20, 16, 150, 25, 150, 6, 10, 10, 0, 0, 1, 100, - 250, 120, 80, 30, 120, 4, 1, 50, 20, 1800, 50, 50, 50, 20, 20, -10, -5460, -9100, - -6, 8, 15, 75, 60, 12, 110, 40, 50, 250, -10, 30, 30, 70, 20, 20, 20, -}; - -s16 sOREGInitCnt = 53; - -s16 sPREGInit[] = { - -20, 200, 300, 10, 12, 10, 35, 60, 60, 3, 0, -40, 20, 25, 45, -5, 15, 15, 20, 0, 0, 0, 6, 60, 30, 0, 5, -}; - -s16 sPREGInitCnt = 27; - -char sCameraSettingNames[][12] = { - "NONE ", "NORMAL0 ", "NORMAL1 ", "DUNGEON0 ", "DUNGEON1 ", "NORMAL3 ", "HORSE0 ", - "BOSS_GOMA ", "BOSS_DODO ", "BOSS_BARI ", "BOSS_FGANON", "BOSS_BAL ", "BOSS_SHADES", "BOSS_MOFA ", - "BOSS_TWIN0 ", "BOSS_TWIN1 ", "BOSS_GANON1", "BOSS_GANON2", "TOWER0 ", "TOWER1 ", "FIXED0 ", - "FIXED1 ", "CIRCLE0 ", "CIRCLE2 ", "CIRCLE3 ", "PREREND0 ", "PREREND1 ", "PREREND3 ", - "DOOR0 ", "DOORC ", "RAIL3 ", "START0 ", "START1 ", "FREE0 ", "FREE2 ", - "CIRCLE4 ", "CIRCLE5 ", "DEMO0 ", "DEMO1 ", "MORI1 ", "ITEM0 ", "ITEM1 ", - "DEMO3 ", "DEMO4 ", "UFOBEAN ", "LIFTBEAN ", "SCENE0 ", "SCENE1 ", "HIDAN1 ", - "HIDAN2 ", "MORI2 ", "MORI3 ", "TAKO ", "SPOT05A ", "SPOT05B ", "HIDAN3 ", - "ITEM2 ", "CIRCLE6 ", "NORMAL2 ", "FISHING ", "DEMOC ", "UO_FIBER ", "DUNGEON2 ", - "TEPPEN ", "CIRCLE7 ", "NORMAL4 ", -}; - -char sCameraModeNames[][12] = { - "NORMAL ", "PARALLEL ", "KEEPON ", "TALK ", "BATTLE ", "CLIMB ", "SUBJECT ", - "BOWARROW ", "BOWARROWZ ", "FOOKSHOT ", "BOOMERANG ", "PACHINCO ", "CLIMBZ ", "JUMP ", - "HANG ", "HANGZ ", "FREEFALL ", "CHARGE ", "STILL ", "PUSHPULL ", "BOOKEEPON ", -}; - -CameraModeValue D_8011A3A0[] = { - { -20, 0 }, { 200, 1 }, { 300, 2 }, { 10, 3 }, { 12, 4 }, { 10, 5 }, { 35, 6 }, { 60, 7 }, { 60, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011A3C8[] = { - { -20, 0 }, { 250, 1 }, { 0, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 45, 7 }, { 50, 8 }, { 8202, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011A3F4[] = { - { -20, 0 }, { 120, 1 }, { 140, 2 }, { 25, 13 }, { 45, 14 }, { -5, 15 }, { 15, 16 }, - { 15, 17 }, { 45, 7 }, { 50, 8 }, { 8193, 9 }, { -50, 11 }, { 30, 12 }, -}; - -CameraModeValue D_8011A428[] = { - { -30, 0 }, { 70, 1 }, { 200, 2 }, { 40, 13 }, { 10, 14 }, { 0, 15 }, - { 5, 16 }, { 70, 17 }, { 45, 7 }, { 50, 8 }, { 10, 4 }, { 13568, 9 }, -}; - -CameraModeValue D_8011A458[] = { - { -20, 0 }, { 180, 1 }, { 10, 13 }, { 80, 14 }, { 0, 15 }, { 10, 16 }, - { 25, 17 }, { 50, 7 }, { 80, 8 }, { 8194, 9 }, { -40, 11 }, { 25, 12 }, -}; - -CameraModeValue D_8011A488[] = { - { -20, 0 }, { 200, 1 }, { 300, 2 }, { 20, 18 }, { 5, 4 }, { 5, 5 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A4AC[] = { - { 0, 0 }, { 5, 1 }, { 50, 2 }, { 10, 4 }, { 0, 19 }, { 0, 20 }, { 0, 21 }, { 45, 7 }, { 0, 9 }, -}; - -CameraModeValue D_8011A4D0[] = { - { -7, 0 }, { 14, 1 }, { 50, 2 }, { 10, 4 }, { 0, 19 }, { -30, 20 }, { -5, 21 }, { 45, 7 }, { 8192, 9 }, -}; - -CameraModeValue D_8011A4F4[] = { - { 20, 0 }, { 70, 1 }, { 70, 2 }, { 10, 4 }, { -120, 19 }, { 20, 20 }, { 0, 21 }, { 45, 7 }, { 8192, 9 }, -}; - -CameraModeValue D_8011A518[] = { - { -20, 0 }, { 80, 1 }, { 250, 2 }, { 45, 3 }, { 60, 7 }, { 40, 8 }, { 6, 22 }, { 8192, 9 }, -}; - -CameraModeValue D_8011A538[] = { - { 5, 0 }, { 50, 1 }, { 50, 2 }, { 10, 4 }, { 0, 19 }, { 0, 20 }, { 0, 21 }, { 45, 7 }, { 8192, 9 }, -}; - -CameraModeValue D_8011A55C[] = { - { -7, 0 }, { 14, 1 }, { 50, 2 }, { 10, 4 }, { -9, 19 }, { -63, 20 }, { -30, 21 }, { 45, 7 }, { 8192, 9 }, -}; - -CameraModeValue D_8011A580[] = { - { -20, 0 }, { 200, 1 }, { 300, 2 }, { 20, 18 }, { 999, 4 }, { 5, 5 }, { 60, 7 }, { 40, 8 }, { 8198, 9 }, -}; - -CameraModeValue D_8011A5A4[] = { - { -20, 0 }, { 200, 1 }, { 300, 2 }, { 12, 4 }, { 35, 6 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A5C4[] = { - { -80, 0 }, { 200, 1 }, { 300, 2 }, { 40, 3 }, { 60, 7 }, { 10, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A5E0[] = { - { -120, 0 }, { 300, 1 }, { 300, 2 }, { 70, 3 }, { 45, 7 }, { 10, 8 }, { 8192, 9 }, -}; - -CameraModeValue D_8011A5FC[] = { - { -20, 0 }, { 200, 1 }, { 300, 2 }, { 15, 4 }, { 80, 6 }, { 60, 7 }, { 20, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A61C[] = { - { -20, 0 }, { 300, 1 }, { 50, 3 }, { 2, 4 }, { 80, 7 }, { 20, 8 }, { -4096, 9 }, -}; - -CameraModeValue D_8011A638[] = { - { -20, 0 }, { 200, 1 }, { 300, 2 }, { 10, 3 }, { 100, 4 }, { 10, 5 }, { 100, 6 }, { 60, 7 }, { 5, 8 }, { -4093, 9 }, -}; - -CameraModeValue D_8011A660[] = { - { 0, 0 }, { 250, 1 }, { 25, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 70, 7 }, { 30, 8 }, { 8298, 9 }, { -20, 11 }, { 30, 12 }, -}; - -CameraModeValue D_8011A68C[] = { - { -5, 0 }, { 120, 1 }, { 140, 2 }, { 5, 13 }, { 85, 14 }, { 10, 15 }, { 5, 16 }, - { 25, 17 }, { 45, 7 }, { 50, 8 }, { 8193, 9 }, { -15, 11 }, { 30, 12 }, -}; - -CameraModeValue D_8011A6C0[] = { - { 0, 0 }, { 200, 1 }, { 400, 2 }, { 10, 3 }, { 12, 4 }, { 20, 5 }, { 40, 6 }, { 60, 7 }, { 60, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011A6E8[] = { - { 0, 0 }, { 250, 1 }, { 0, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 45, 7 }, { 50, 8 }, { 8194, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011A714[] = { - { -20, 0 }, { 120, 1 }, { 140, 2 }, { 25, 13 }, { 45, 14 }, { -5, 15 }, { 15, 16 }, - { 15, 17 }, { 45, 7 }, { 50, 8 }, { 8193, 9 }, { -50, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011A748[] = { - { -20, 0 }, { 250, 1 }, { 10, 13 }, { 80, 14 }, { 0, 15 }, { 10, 16 }, - { 25, 17 }, { 50, 7 }, { 65, 8 }, { 8194, 9 }, { -40, 11 }, { 25, 12 }, -}; - -CameraModeValue D_8011A778[] = { - { -20, 0 }, { 80, 1 }, { 250, 2 }, { 6, 22 }, { 45, 3 }, { 60, 7 }, { 40, 8 }, { 8192, 9 }, -}; - -CameraModeValue D_8011A798[] = { - { 0, 0 }, { 250, 1 }, { 400, 2 }, { 15, 4 }, { 50, 6 }, { 60, 7 }, { 30, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A7B8[] = { - { 0, 0 }, { 200, 1 }, { 400, 2 }, { 30, 4 }, { 80, 6 }, { 60, 7 }, { 20, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A7D8[] = { - { -20, 0 }, { 200, 1 }, { 400, 2 }, { 20, 18 }, { 5, 4 }, { 5, 5 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A7FC[] = { - { -20, 0 }, { 250, 1 }, { 400, 2 }, { 20, 18 }, { 999, 4 }, { 5, 5 }, { 60, 7 }, { 40, 8 }, { 8198, 9 }, -}; - -CameraModeValue D_8011A820[] = { - { 0, 0 }, { 300, 1 }, { 50, 3 }, { 2, 4 }, { 80, 7 }, { 20, 8 }, { -4096, 9 }, -}; - -CameraModeValue D_8011A83C[] = { - { -80, 0 }, { 200, 1 }, { 400, 2 }, { 40, 3 }, { 60, 7 }, { 10, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A858[] = { - { -120, 0 }, { 400, 1 }, { 400, 2 }, { 70, 3 }, { 45, 7 }, { 10, 8 }, { 8192, 9 }, -}; - -CameraModeValue D_8011A874[] = { - { 0, 0 }, { 200, 1 }, { 400, 2 }, { 10, 3 }, { 100, 4 }, { 20, 5 }, { 100, 6 }, { 60, 7 }, { 5, 8 }, { -4093, 9 }, -}; - -CameraModeValue D_8011A89C[] = { - { -10, 0 }, { 150, 1 }, { 250, 2 }, { 5, 3 }, { 10, 4 }, { 5, 5 }, { 30, 6 }, { 60, 7 }, { 60, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011A8C4[] = { - { -20, 0 }, { 150, 1 }, { 0, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 45, 7 }, { 50, 8 }, { 8202, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011A8F0[] = { - { -20, 0 }, { 120, 1 }, { 140, 2 }, { 25, 13 }, { 45, 14 }, { -5, 15 }, { 15, 16 }, - { 15, 17 }, { 45, 7 }, { 50, 8 }, { 8193, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011A924[] = { - { -20, 0 }, { 180, 1 }, { 10, 13 }, { 80, 14 }, { 0, 15 }, { 10, 16 }, - { 25, 17 }, { 45, 7 }, { 80, 8 }, { 8194, 9 }, { -40, 11 }, { 25, 12 }, -}; - -CameraModeValue D_8011A954[] = { - { -10, 0 }, { 150, 1 }, { 250, 2 }, { 10, 4 }, { 50, 6 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A974[] = { - { -10, 0 }, { 150, 1 }, { 250, 2 }, { 10, 4 }, { 80, 6 }, { 60, 7 }, { 20, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A994[] = { - { -40, 0 }, { 150, 1 }, { 250, 2 }, { 20, 18 }, { 5, 4 }, { 5, 5 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011A9B8[] = { - { -40, 0 }, { 250, 1 }, { 250, 2 }, { 20, 18 }, { 999, 4 }, { 5, 5 }, { 60, 7 }, { 40, 8 }, { 8198, 9 }, -}; - -CameraModeValue D_8011A9DC[] = { - { -10, 0 }, { 300, 1 }, { 50, 3 }, { 2, 4 }, { 80, 7 }, { 20, 8 }, { -4096, 9 }, -}; - -CameraModeValue D_8011A9F8[] = { - { -80, 0 }, { 150, 1 }, { 250, 2 }, { 40, 3 }, { 60, 7 }, { 10, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011AA14[] = { - { -120, 0 }, { 250, 1 }, { 250, 2 }, { 70, 3 }, { 45, 7 }, { 10, 8 }, { 8192, 9 }, -}; - -CameraModeValue D_8011AA30[] = { - { -10, 0 }, { 150, 1 }, { 250, 2 }, { 5, 3 }, { 100, 4 }, { 5, 5 }, { 100, 6 }, { 60, 7 }, { 5, 8 }, { -4093, 9 }, -}; - -CameraModeValue D_8011AA58[] = { - { -40, 0 }, { 150, 1 }, { 150, 2 }, { 0, 3 }, { 10, 4 }, { 5, 5 }, { 30, 6 }, { 60, 7 }, { 60, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011AA80[] = { - { -20, 0 }, { 70, 1 }, { 200, 2 }, { 40, 13 }, { 10, 14 }, { 0, 15 }, - { 5, 16 }, { 70, 17 }, { 45, 7 }, { 50, 8 }, { 10, 4 }, { 13568, 9 }, -}; - -CameraModeValue D_8011AAB0[] = { - { -40, 0 }, { 150, 1 }, { 150, 2 }, { 10, 4 }, { 50, 6 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011AAD0[] = { - { -40, 0 }, { 150, 1 }, { 180, 2 }, { 12, 4 }, { 80, 6 }, { 60, 7 }, { 20, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011AAF0[] = { - { -40, 0 }, { 150, 1 }, { 150, 2 }, { 20, 18 }, { 5, 4 }, { 5, 5 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011AB14[] = { - { -40, 0 }, { 150, 1 }, { 150, 2 }, { 20, 18 }, { 999, 4 }, { 5, 5 }, { 60, 7 }, { 40, 8 }, { 8198, 9 }, -}; - -CameraModeValue D_8011AB38[] = { - { -40, 0 }, { 200, 1 }, { 50, 3 }, { 2, 4 }, { 80, 7 }, { 20, 8 }, { -4096, 9 }, -}; - -CameraModeValue D_8011AB54[] = { - { -80, 0 }, { 150, 1 }, { 150, 2 }, { 40, 3 }, { 60, 7 }, { 10, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011AB70[] = { - { -120, 0 }, { 150, 1 }, { 150, 2 }, { 70, 3 }, { 45, 7 }, { 10, 8 }, { 8192, 9 }, -}; - -CameraModeValue D_8011AB8C[] = { - { -40, 0 }, { 150, 1 }, { 150, 2 }, { 0, 3 }, { 100, 4 }, { 5, 5 }, { 100, 6 }, { 60, 7 }, { 5, 8 }, { -4093, 9 }, -}; - -CameraModeValue D_8011ABB4[] = { - { -40, 0 }, { 180, 1 }, { 25, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 60, 7 }, { 50, 8 }, { 8298, 9 }, { -20, 11 }, { 30, 12 }, -}; - -CameraModeValue D_8011ABE0[] = { - { -20, 0 }, { 280, 1 }, { 300, 2 }, { 20, 3 }, { 15, 4 }, { 5, 5 }, { 40, 6 }, { 60, 7 }, { 100, 8 }, { 4, 9 }, -}; - -CameraModeValue D_8011AC08[] = { - { -50, 0 }, { 250, 1 }, { 70, 3 }, { 0, 10 }, { 15, 4 }, { 5, 5 }, - { 60, 7 }, { 100, 8 }, { 8202, 9 }, { -50, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011AC34[] = { - { -30, 0 }, { 70, 1 }, { 200, 2 }, { 40, 13 }, { 10, 14 }, { 10, 15 }, - { 20, 16 }, { 70, 17 }, { 45, 7 }, { 10, 8 }, { 10, 4 }, { 13568, 9 }, -}; - -CameraModeValue D_8011AC64[] = { - { -40, 0 }, { 150, 1 }, { 250, 2 }, { -5, 3 }, { 18, 4 }, { 5, 5 }, { 60, 6 }, { 60, 7 }, { 40, 8 }, { 5, 9 }, -}; - -CameraModeValue D_8011AC8C[] = { - { -50, 0 }, { 220, 1 }, { 250, 2 }, { 10, 3 }, { 16, 4 }, { 20, 5 }, { 60, 7 }, { 100, 8 }, { 1536, 9 }, -}; - -CameraModeValue D_8011ACB0[] = { - { -40, 0 }, { 180, 1 }, { 220, 2 }, { -2, 3 }, { 12, 4 }, { 100, 5 }, { 45, 7 }, { 100, 8 }, { 9728, 9 }, -}; - -CameraModeValue D_8011ACD4[] = { - { -7, 0 }, { 14, 1 }, { 100, 2 }, { 10, 4 }, { 0, 19 }, { -30, 20 }, { -5, 21 }, { 40, 7 }, { 9728, 9 }, -}; - -CameraModeValue D_8011ACF8[] = { - { -60, 0 }, { 180, 1 }, { 220, 2 }, { 25, 13 }, { 45, 14 }, { -5, 15 }, { 15, 16 }, - { 15, 17 }, { 45, 7 }, { 50, 8 }, { 9729, 9 }, { -60, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011AD2C[] = { - { -60, 0 }, { 140, 1 }, { 200, 2 }, { 40, 13 }, { 10, 14 }, { 0, 15 }, - { 5, 16 }, { 70, 17 }, { 45, 7 }, { 50, 8 }, { 10, 4 }, { 13568, 9 }, -}; - -CameraModeValue D_8011AD5C[] = { - { -20, 0 }, { 150, 1 }, { 250, 2 }, { 0, 3 }, { 15, 4 }, { 5, 5 }, { 40, 6 }, { 60, 7 }, { 60, 8 }, { 1, 9 }, -}; - -CameraModeValue D_8011AD84[] = { - { -30, 0 }, { 150, 1 }, { 10, 13 }, { 40, 14 }, { -10, 15 }, { 0, 16 }, - { 25, 17 }, { 60, 7 }, { 40, 8 }, { 8194, 9 }, { -50, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011ADB4[] = { - { 0, 0 }, { 150, 1 }, { 300, 2 }, { 0, 3 }, { 12, 4 }, { 5, 5 }, { 70, 6 }, { 70, 7 }, { 40, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011ADDC[] = { - { -20, 0 }, { 160, 1 }, { 10, 13 }, { 60, 14 }, { -5, 15 }, { 0, 16 }, - { 25, 17 }, { 70, 7 }, { 50, 8 }, { 8194, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011AE0C[] = { - { -20, 0 }, { 150, 1 }, { 300, 2 }, { -5, 3 }, { 15, 4 }, { 5, 5 }, { 40, 6 }, { 70, 7 }, { 70, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011AE34[] = { - { -30, 0 }, { 125, 1 }, { 10, 13 }, { 10, 14 }, { 0, 15 }, { 0, 16 }, - { 50, 17 }, { 60, 7 }, { 50, 8 }, { 8194, 9 }, { -50, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011AE64[] = { - { 10, 0 }, { 150, 1 }, { 250, 2 }, { 0, 3 }, { 15, 4 }, { 15, 5 }, { 40, 6 }, { 60, 7 }, { 100, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011AE8C[] = { - { -20, 0 }, { 200, 1 }, { 45, 13 }, { 40, 14 }, { 5, 15 }, { -5, 16 }, - { 35, 17 }, { 60, 7 }, { 100, 8 }, { 8194, 9 }, { -40, 11 }, { 60, 12 }, -}; - -CameraModeValue D_8011AEBC[] = { - { -20, 0 }, { 500, 1 }, { 500, 2 }, { 10, 3 }, { 16, 4 }, { 10, 5 }, { 40, 6 }, { 60, 7 }, { 80, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011AEE4[] = { - { -20, 0 }, { 200, 1 }, { 20, 13 }, { 60, 14 }, { 0, 15 }, { 10, 16 }, - { 15, 17 }, { 45, 7 }, { 50, 8 }, { 8194, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011AF14[] = { - { -20, 0 }, { 500, 1 }, { 500, 2 }, { 10, 3 }, { 20, 4 }, { 10, 5 }, { 40, 6 }, { 60, 7 }, { 80, 8 }, { 131, 9 }, -}; - -CameraModeValue D_8011AF3C[] = { - { -20, 0 }, { 200, 1 }, { 20, 13 }, { 60, 14 }, { 0, 15 }, { 10, 16 }, - { 15, 17 }, { 45, 7 }, { 50, 8 }, { 8322, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011AF6C[] = { - { -20, 0 }, { 500, 1 }, { 500, 2 }, { 10, 3 }, { 20, 4 }, { 10, 5 }, { 80, 6 }, { 60, 7 }, { 80, 8 }, { 131, 9 }, -}; - -CameraModeValue D_8011AF94[] = { - { -20, 0 }, { 100, 1 }, { 150, 2 }, { -10, 3 }, { 15, 4 }, { 10, 5 }, { 40, 6 }, { 80, 7 }, { 60, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011AFBC[] = { - { -20, 0 }, { 200, 1 }, { 10, 13 }, { 80, 14 }, { -10, 15 }, { 10, 16 }, - { 25, 17 }, { 70, 7 }, { 40, 8 }, { 8194, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011AFEC[] = { - { -20, 0 }, { 150, 1 }, { 300, 2 }, { 0, 3 }, { 20, 4 }, { 10, 5 }, { 40, 6 }, { 60, 7 }, { 80, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011B014[] = { - { 0, 0 }, { 400, 1 }, { 0, 13 }, { 60, 14 }, { -10, 15 }, { 5, 16 }, - { 25, 17 }, { 45, 7 }, { 40, 8 }, { 8194, 9 }, { -20, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011B044[] = { - { -10, 0 }, { 150, 1 }, { 200, 2 }, { -10, 3 }, { 12, 4 }, { 10, 5 }, { 40, 6 }, { 60, 7 }, { 50, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011B06C[] = { - { 40, 0 }, { 330, 1 }, { 330, 2 }, { -5, 3 }, { 15, 4 }, { 15, 5 }, { 40, 6 }, { 60, 7 }, { 100, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011B094[] = { - { -40, 0 }, { 250, 1 }, { 0, 3 }, { 2, 4 }, { 80, 7 }, { 20, 8 }, { -4096, 9 }, -}; - -CameraModeValue D_8011B0B0[] = { - { -20, 0 }, { 500, 1 }, { 500, 2 }, { 10, 3 }, { 20, 4 }, { 10, 5 }, { 40, 6 }, { 60, 7 }, { 80, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011B0D8[] = { - { -20, 0 }, { 180, 1 }, { 20, 13 }, { 60, 14 }, { 0, 15 }, { 10, 16 }, - { 25, 17 }, { 45, 7 }, { 50, 8 }, { 8194, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011B108[] = { - { 0, 0 }, { 120, 1 }, { 280, 2 }, { 60, 23 }, { 8, 4 }, { 40, 6 }, { 60, 7 }, { 50, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011B12C[] = { - { 0, 0 }, { 120, 1 }, { 280, 2 }, { 60, 23 }, { 8, 4 }, { 40, 6 }, { 60, 7 }, { 50, 8 }, { 128, 9 }, -}; - -CameraModeValue D_8011B150[] = { - { 0, 0 }, { 270, 1 }, { 300, 2 }, { 120, 23 }, { 8, 4 }, { 60, 6 }, { 60, 7 }, { 100, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011B174[] = { - { 0, 0 }, { 270, 1 }, { 300, 2 }, { 120, 23 }, { 6, 4 }, { 60, 6 }, { 60, 7 }, { 100, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011B198[] = { - { -40, 0 }, - { 100, 4 }, - { 60, 7 }, - { 0, 9 }, -}; - -CameraModeValue D_8011B1A8[] = { - { -40, 0 }, - { 100, 4 }, - { 60, 7 }, - { 8192, 9 }, -}; - -CameraModeValue D_8011B1B8[] = { - { -40, 0 }, - { 100, 4 }, - { 60, 7 }, - { 13568, 9 }, -}; - -CameraModeValue D_8011B1C8[] = { - { -40, 0 }, - { 25, 4 }, - { 60, 7 }, - { 0, 9 }, -}; - -CameraModeValue D_8011B1D8[] = { - { -40, 0 }, { 50, 4 }, { 80, 5 }, { 60, 7 }, { 1, 9 }, -}; - -CameraModeValue D_8011B1EC[] = { - { -40, 0 }, - { 60, 7 }, - { 16128, 9 }, -}; - -CameraModeValue D_8011B1F8[] = { - { -40, 0 }, { 50, 4 }, { 80, 5 }, { 60, 7 }, { 4, 9 }, -}; - -CameraModeValue D_8011B20C[] = { - { 0, 9 }, -}; - -CameraModeValue D_8011B210[] = { - { 8192, 9 }, -}; - -CameraModeValue D_8011B214[] = { - { 60, 7 }, - { 0, 9 }, -}; - -CameraModeValue D_8011B21C[] = { - { 60, 7 }, - { 8192, 9 }, -}; - -CameraModeValue D_8011B224[] = { - { 30, 24 }, - { 0, 25 }, - { 4, 4 }, - { 13568, 9 }, -}; - -CameraModeValue D_8011B234[] = { - { -40, 0 }, - { 60, 7 }, - { 12800, 9 }, -}; - -CameraModeValue D_8011B240[] = { - { -5, 0 }, - { 60, 7 }, - { 12802, 9 }, -}; - -CameraModeValue D_8011B24C[] = { - { -5, 0 }, - { 60, 7 }, - { 12810, 9 }, -}; - -CameraModeValue D_8011B258[] = { - { 0, 0 }, { 2, 1 }, { 30, 2 }, { 10, 4 }, { 45, 7 }, { 12800, 9 }, -}; - -CameraModeValue D_8011B270[] = { - { 1, 9 }, -}; - -CameraModeValue D_8011B274[] = { - { -256, 9 }, -}; - -CameraModeValue D_8011B278[] = { - { -255, 9 }, -}; - -CameraModeValue D_8011B27C[] = { - { -40, 0 }, { 100, 4 }, { 80, 5 }, { 60, 7 }, { 0, 9 }, -}; - -CameraModeValue D_8011B290[] = { - { -40, 0 }, - { 60, 1 }, - { 60, 7 }, - { 2, 9 }, -}; - -CameraModeValue D_8011B2A0[] = { - { -30, 0 }, - { 45, 1 }, - { 100, 7 }, - { 8193, 9 }, -}; - -CameraModeValue D_8011B2B0[] = { - { 12800, 9 }, -}; - -CameraModeValue D_8011B2B4[] = { - { -50, 0 }, { 450, 1 }, { 40, 3 }, { 180, 10 }, { 5, 4 }, { 5, 5 }, - { 70, 7 }, { 30, 8 }, { 12, 9 }, { -50, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011B2E0[] = { - { 13569, 9 }, -}; - -CameraModeValue D_8011B2E4[] = { - { 60, 7 }, - { 30, 8 }, - { 12800, 9 }, -}; - -CameraModeValue D_8011B2F0[] = { - { 12818, 9 }, -}; - -CameraModeValue D_8011B2F4[] = { - { -50, 0 }, { 300, 1 }, { 300, 2 }, { 50, 3 }, { 20, 4 }, { 10, 5 }, { 50, 6 }, { 70, 7 }, { 40, 8 }, { 2, 9 }, -}; - -CameraModeValue D_8011B31C[] = { - { -50, 0 }, { 300, 1 }, { 10, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 45, 7 }, { 50, 8 }, { 8202, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011B348[] = { - { -50, 0 }, { 300, 1 }, { 300, 2 }, { 12, 4 }, { 35, 6 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011B368[] = { - { -80, 0 }, { 300, 1 }, { 300, 2 }, { 60, 3 }, { 70, 7 }, { 30, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011B384[] = { - { -120, 0 }, { 300, 1 }, { 300, 2 }, { 70, 3 }, { 50, 7 }, { 30, 8 }, { 8192, 9 }, -}; - -CameraModeValue D_8011B3A0[] = { - { -20, 0 }, { 300, 1 }, { 350, 2 }, { 50, 3 }, { 100, 4 }, - { 10, 5 }, { 100, 6 }, { 70, 7 }, { 30, 8 }, { -4094, 9 }, -}; - -CameraModeValue D_8011B3C8[] = { - { -50, 0 }, { 200, 1 }, { 200, 2 }, { 20, 3 }, { 16, 4 }, { 10, 5 }, { 50, 6 }, { 60, 7 }, { 50, 8 }, { 2, 9 }, -}; - -CameraModeValue D_8011B3F0[] = { - { -50, 0 }, { 200, 1 }, { 40, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 45, 7 }, { 50, 8 }, { 8202, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011B41C[] = { - { -50, 0 }, { 150, 1 }, { 250, 2 }, { 12, 4 }, { 35, 6 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011B43C[] = { - { -80, 0 }, { 200, 1 }, { 200, 2 }, { 40, 3 }, { 60, 7 }, { 30, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011B458[] = { - { -120, 0 }, { 200, 1 }, { 200, 2 }, { 60, 3 }, { 50, 7 }, { 30, 8 }, { 8192, 9 }, -}; - -CameraModeValue D_8011B474[] = { - { -20, 0 }, { 200, 1 }, { 250, 2 }, { 20, 3 }, { 100, 4 }, - { 10, 5 }, { 100, 6 }, { 60, 7 }, { 30, 8 }, { -4094, 9 }, -}; - -CameraModeValue D_8011B49C[] = { - { -30, 0 }, - { 60, 7 }, - { 266, 9 }, -}; - -CameraModeValue D_8011B4A8[] = { - { -20, 0 }, - { 150, 1 }, - { 60, 7 }, - { 528, 9 }, -}; - -CameraModeValue D_8011B4B8[] = { - { 0, 0 }, { 400, 1 }, { 500, 2 }, { 35, 3 }, { 14, 4 }, { 5, 5 }, { 20, 6 }, { 60, 7 }, { 40, 8 }, { 18, 9 }, -}; - -CameraModeValue D_8011B4E0[] = { - { -20, 0 }, { 250, 1 }, { 5, 13 }, { 10, 14 }, { 30, 15 }, { 20, 16 }, - { 25, 17 }, { 45, 7 }, { 60, 8 }, { 8194, 9 }, { -40, 11 }, { 25, 12 }, -}; - -CameraModeValue D_8011B510[] = { - { 0, 0 }, { 300, 1 }, { 500, 2 }, { 60, 3 }, { 8, 4 }, { 5, 5 }, { 60, 6 }, { 60, 7 }, { 30, 8 }, { 18, 9 }, -}; - -CameraModeValue D_8011B538[] = { - { -20, 0 }, { 500, 1 }, { 500, 2 }, { 80, 3 }, { 20, 4 }, { 10, 5 }, { 70, 6 }, { 70, 7 }, { 80, 8 }, { 18, 9 }, -}; - -CameraModeValue D_8011B560[] = { - { -20, 0 }, { 500, 1 }, { 80, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 70, 7 }, { 80, 8 }, { 8218, 9 }, { -40, 11 }, { 40, 12 }, -}; - -CameraModeValue D_8011B58C[] = { - { -20, 0 }, { 500, 1 }, { 80, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 60, 7 }, { 80, 8 }, { 8218, 9 }, { -40, 11 }, { 40, 12 }, -}; - -CameraModeValue D_8011B5B8[] = { - { -20, 0 }, { 500, 1 }, { 500, 2 }, { 80, 3 }, { 20, 4 }, { 10, 5 }, { 80, 6 }, { 60, 7 }, { 20, 8 }, { 18, 9 }, -}; - -CameraModeValue D_8011B5E0[] = { - { -20, 0 }, { 750, 1 }, { 750, 2 }, { 80, 3 }, { 20, 4 }, { 10, 5 }, { 70, 6 }, { 70, 7 }, { 80, 8 }, { 18, 9 }, -}; - -CameraModeValue D_8011B608[] = { - { -20, 0 }, { 750, 1 }, { 80, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 70, 7 }, { 80, 8 }, { 8218, 9 }, { -40, 11 }, { 40, 12 }, -}; - -CameraModeValue D_8011B634[] = { - { -20, 0 }, { 750, 1 }, { 80, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 70, 7 }, { 80, 8 }, { 8202, 9 }, { -40, 11 }, { 40, 12 }, -}; - -CameraModeValue D_8011B660[] = { - { -20, 0 }, { 750, 1 }, { 750, 2 }, { 80, 3 }, { 20, 4 }, { 10, 5 }, { 80, 6 }, { 70, 7 }, { 20, 8 }, { 18, 9 }, -}; - -CameraModeValue D_8011B688[] = { - { -20, 0 }, { 500, 1 }, { 500, 2 }, { 80, 3 }, { 20, 4 }, { 10, 5 }, { 70, 6 }, { 70, 7 }, { 80, 8 }, { 2, 9 }, -}; - -CameraModeValue D_8011B6B0[] = { - { -20, 0 }, { 500, 1 }, { 80, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 70, 7 }, { 80, 8 }, { 8202, 9 }, { -40, 11 }, { 40, 12 }, -}; - -CameraModeValue D_8011B6DC[] = { - { -20, 0 }, { 500, 1 }, { 80, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 60, 7 }, { 80, 8 }, { 8202, 9 }, { -40, 11 }, { 40, 12 }, -}; - -CameraModeValue D_8011B708[] = { - { -20, 0 }, { 500, 1 }, { 500, 2 }, { 80, 3 }, { 20, 4 }, { 10, 5 }, { 80, 6 }, { 60, 7 }, { 20, 8 }, { 2, 9 }, -}; - -CameraModeValue D_8011B730[] = { - { -30, 0 }, { 120, 1 }, { -10, 3 }, { 170, 10 }, { 0, 21 }, { 60, 7 }, { 9474, 9 }, { 25, 4 }, { 6, 22 }, -}; - -CameraModeValue D_8011B754[] = { - { 20, 4 }, - { 12800, 9 }, -}; - -CameraModeValue D_8011B75C[] = { - { -20, 0 }, { 200, 1 }, { 300, 2 }, { 10, 3 }, { 12, 4 }, { 10, 5 }, { 35, 6 }, { 60, 7 }, { 60, 8 }, { 2, 9 }, -}; - -CameraModeValue D_8011B784[] = { - { 0, 0 }, { 200, 1 }, { 300, 2 }, { 20, 3 }, { 12, 4 }, { 10, 5 }, { 35, 6 }, { 55, 7 }, { 60, 8 }, { 3842, 9 }, -}; - -CameraModeValue D_8011B7AC[] = { - { -20, 0 }, { 250, 1 }, { 0, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 45, 7 }, { 50, 8 }, { 12042, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011B7D8[] = { - { -20, 0 }, { 250, 1 }, { 0, 13 }, { 80, 14 }, { 0, 15 }, { 0, 16 }, - { 25, 17 }, { 55, 7 }, { 80, 8 }, { 12034, 9 }, { -40, 11 }, { 25, 12 }, -}; - -CameraModeValue D_8011B808[] = { - { -30, 0 }, { 70, 1 }, { 200, 2 }, { 40, 13 }, { 10, 14 }, { 0, 15 }, - { 5, 16 }, { 70, 17 }, { 45, 7 }, { 50, 8 }, { 10, 4 }, { 16160, 9 }, -}; - -CameraModeValue D_8011B838[] = { - { 0, 0 }, { 5, 1 }, { 50, 2 }, { 10, 4 }, { 0, 19 }, { 0, 20 }, { 0, 21 }, { 45, 7 }, { 3840, 9 }, -}; - -CameraModeValue D_8011B85C[] = { - { -20, 0 }, { 200, 1 }, { 300, 2 }, { 12, 4 }, { 35, 6 }, { 60, 7 }, { 40, 8 }, { 3840, 9 }, -}; - -CameraModeValue D_8011B87C[] = { - { -20, 0 }, { 200, 1 }, { 300, 2 }, { 15, 4 }, { 80, 6 }, { 60, 7 }, { 20, 8 }, { 3840, 9 }, -}; - -CameraModeValue D_8011B89C[] = { - { -80, 0 }, { 200, 1 }, { 300, 2 }, { 40, 3 }, { 60, 7 }, { 10, 8 }, { 3840, 9 }, -}; - -CameraModeValue D_8011B8B8[] = { - { -120, 0 }, { 300, 1 }, { 300, 2 }, { 70, 3 }, { 45, 7 }, { 10, 8 }, { 12032, 9 }, -}; - -CameraModeValue D_8011B8D4[] = { - { 16128, 9 }, -}; - -CameraModeValue D_8011B8D8[] = { - { 30, 0 }, { 200, 1 }, { 300, 2 }, { -20, 3 }, { 15, 4 }, { 5, 26 }, { 50, 6 }, { 70, 7 }, { 70, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011B900[] = { - { -30, 0 }, { 160, 1 }, { 10, 13 }, { 10, 14 }, { 0, 15 }, { 0, 16 }, - { 70, 17 }, { 60, 7 }, { 40, 8 }, { 8194, 9 }, { -50, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011B930[] = { - { -20, 0 }, { 350, 1 }, { 350, 2 }, { 20, 3 }, { 15, 4 }, { 5, 5 }, { 30, 6 }, { 60, 7 }, { 60, 8 }, { 3, 9 }, -}; - -CameraModeValue D_8011B958[] = { - { -20, 0 }, { 200, 1 }, { 0, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 45, 7 }, { 50, 8 }, { 8202, 9 }, { -40, 11 }, { 20, 12 }, -}; - -CameraModeValue D_8011B984[] = { - { -20, 0 }, { 180, 1 }, { 10, 13 }, { 80, 14 }, { -10, 15 }, { 10, 16 }, - { 25, 17 }, { 45, 7 }, { 80, 8 }, { 8194, 9 }, { -40, 11 }, { 25, 12 }, -}; - -CameraModeValue D_8011B9B4[] = { - { -20, 0 }, { 350, 1 }, { 350, 2 }, { 10, 4 }, { 50, 6 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011B9D4[] = { - { -20, 0 }, { 350, 1 }, { 350, 2 }, { 15, 4 }, { 80, 6 }, { 60, 7 }, { 20, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011B9F4[] = { - { -40, 0 }, { 350, 1 }, { 350, 2 }, { 20, 18 }, { 5, 4 }, { 5, 5 }, { 60, 7 }, { 40, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011BA18[] = { - { -40, 0 }, { 350, 1 }, { 350, 2 }, { 20, 18 }, { 999, 4 }, { 5, 5 }, { 60, 7 }, { 40, 8 }, { 8198, 9 }, -}; - -CameraModeValue D_8011BA3C[] = { - { -50, 0 }, { 350, 1 }, { 350, 2 }, { 40, 3 }, { 60, 7 }, { 10, 8 }, { 0, 9 }, -}; - -CameraModeValue D_8011BA58[] = { - { -100, 0 }, { 350, 1 }, { 350, 2 }, { 70, 3 }, { 45, 7 }, { 10, 8 }, { 8192, 9 }, -}; - -CameraModeValue D_8011BA74[] = { - { -10, 0 }, { 350, 1 }, { 350, 2 }, { 20, 3 }, { 100, 4 }, { 5, 5 }, { 100, 6 }, { 60, 7 }, { 5, 8 }, { -4093, 9 }, -}; - -CameraModeValue D_8011BA9C[] = { - { 0, 0 }, { 280, 1 }, { 25, 3 }, { 0, 10 }, { 5, 4 }, { 5, 5 }, - { 70, 7 }, { 30, 8 }, { 8298, 9 }, { -20, 11 }, { 30, 12 }, -}; - -CameraModeValue D_8011BAC8[] = { - { -10, 0 }, { 280, 1 }, { 320, 2 }, { -8, 3 }, { 20, 4 }, { 10, 5 }, { 80, 6 }, { 60, 7 }, { 80, 8 }, { 2, 9 }, -}; - -CameraModeValue D_8011BAF0[] = { - { -20, 0 }, { 180, 1 }, { 200, 2 }, { 35, 13 }, { 45, 14 }, { 0, 15 }, { -5, 16 }, - { 20, 17 }, { 50, 7 }, { 50, 8 }, { 8193, 9 }, { -50, 11 }, { 30, 12 }, -}; - -CameraModeValue D_8011BB24[] = { - { -80, 0 }, { 200, 1 }, { 250, 2 }, { 30, 13 }, { 10, 14 }, { -8, 15 }, - { -8, 16 }, { 30, 17 }, { 50, 7 }, { 50, 8 }, { 10, 4 }, { 13600, 9 }, -}; - -CameraModeValue D_8011BB54[] = { - { -30, 0 }, { 70, 1 }, { 200, 2 }, { 40, 13 }, { 10, 14 }, { 0, 15 }, - { 5, 16 }, { 70, 17 }, { 45, 7 }, { 50, 8 }, { 10, 4 }, { 13728, 9 }, -}; - -CameraMode D_8011BB84[] = { - { 2, 10, D_8011A3A0 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011A458 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5FC }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011BC2C[] = { - { 2, 10, D_8011A6C0 }, { 7, 11, D_8011A6E8 }, { 12, 13, D_8011A714 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011A748 }, { 23, 9, D_8011A7D8 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A778 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A7FC }, { 22, 8, D_8011A798 }, { 42, 7, D_8011A83C }, { 42, 7, D_8011A858 }, - { 22, 8, D_8011A7B8 }, { 30, 7, D_8011A820 }, { 2, 10, D_8011A874 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011BCD4[] = { - { 2, 10, D_8011A89C }, { 7, 11, D_8011A8C4 }, { 12, 13, D_8011A8F0 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011A924 }, { 23, 9, D_8011A994 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A778 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A9B8 }, { 22, 8, D_8011A954 }, { 42, 7, D_8011A9F8 }, { 42, 7, D_8011AA14 }, - { 22, 8, D_8011A974 }, { 30, 7, D_8011A9DC }, { 2, 10, D_8011AA30 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011BD7C[] = { - { 2, 10, D_8011AA58 }, { 7, 11, D_8011A8C4 }, { 12, 13, D_8011A714 }, { 14, 12, D_8011AA80 }, - { 27, 12, D_8011A924 }, { 23, 9, D_8011AAF0 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A778 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011AB14 }, { 22, 8, D_8011AAB0 }, { 42, 7, D_8011AB54 }, { 42, 7, D_8011AB70 }, - { 22, 8, D_8011AAD0 }, { 30, 7, D_8011AB38 }, { 2, 10, D_8011AB8C }, { 7, 11, D_8011ABB4 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011BE24[] = { - { 24, 10, D_8011ABE0 }, { 7, 11, D_8011AC08 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011AC34 }, - { 27, 12, D_8011A458 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 24, 10, D_8011AC64 }, { 0, 0, NULL }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, -}; - -// HORSE0 0x8500018F (10000101000000000000000110001111) -CameraMode D_8011BEC4[] = { - { 4, 9, D_8011AC8C }, { 4, 9, D_8011ACB0 }, { 12, 13, D_8011ACF8 }, { 14, 12, D_8011AD2C }, { 0, 0, NULL }, - { 0, 0, NULL }, { 0, 0, NULL }, { 19, 9, D_8011ACD4 }, { 19, 9, D_8011A4F4 }, -}; - -CameraMode D_8011BF0C[] = { - { 2, 10, D_8011AD5C }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011AD84 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A9DC }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011BFB4[] = { - { 2, 10, D_8011ADB4 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011ADDC }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C05C[] = { - { 2, 10, D_8011AE0C }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011AE34 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C104[] = { - { 2, 10, D_8011AE64 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011AE8C }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C1AC[] = { - { 2, 10, D_8011AEBC }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011AEE4 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C254[] = { - { 2, 10, D_8011AF14 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011AF3C }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 2, 10, D_8011AF6C }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 2, 10, D_8011AF6C }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C2FC[] = { - { 2, 10, D_8011AF94 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011AFBC }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C3A4[] = { - { 2, 10, D_8011AFEC }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011B014 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C44C[] = { - { 2, 10, D_8011B044 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011B014 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C4F4[] = { - { 2, 10, D_8011B06C }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011AE8C }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011B094 }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C59C[] = { - { 2, 10, D_8011B0B0 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011B0D8 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C644[] = { - { 3, 9, D_8011B108 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011A458 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 3, 9, D_8011B12C }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C6EC[] = { - { 3, 9, D_8011B150 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011A458 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 3, 9, D_8011B174 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C794[] = { - { 32, 4, D_8011B198 }, - { 0, 0, NULL }, - { 32, 4, D_8011B1A8 }, - { 32, 4, D_8011B1B8 }, -}; - -CameraMode D_8011C7B4[] = { - { 32, 4, D_8011B1C8 }, -}; - -CameraMode D_8011C7BC[] = { - { 33, 5, D_8011B1D8 }, -}; - -CameraMode D_8011C7C4[] = { - { 40, 3, D_8011B1EC }, -}; - -CameraMode D_8011C7CC[] = { - { 35, 5, D_8011B1F8 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011A748 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 0, 0, NULL }, { 0, 0, NULL }, { 0, 0, NULL }, - { 0, 0, NULL }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011C874[] = { - { 34, 1, D_8011B20C }, - { 0, 0, NULL }, - { 34, 1, D_8011B210 }, - { 34, 1, D_8011B210 }, -}; - -CameraMode D_8011C894[] = { - { 48, 2, D_8011B214 }, - { 0, 0, NULL }, - { 48, 2, D_8011B21C }, - { 11, 4, D_8011B224 }, -}; - -CameraMode D_8011C8B4[] = { - { 67, 1, D_8011B20C }, -}; - -CameraMode D_8011C8BC[] = { - { 44, 3, D_8011B234 }, -}; - -CameraMode D_8011C8C4[] = { - { 70, 3, D_8011B240 }, - { 70, 3, D_8011B24C }, -}; - -CameraMode D_8011C8D4[] = { - { 20, 6, D_8011B258 }, -}; - -CameraMode D_8011C8DC[] = { - { 41, 1, D_8011B20C }, -}; - -CameraMode D_8011C8E4[] = { - { 41, 1, D_8011B270 }, -}; - -CameraMode D_8011C8EC[] = { - { 47, 1, D_8011B274 }, -}; - -CameraMode D_8011C8F4[] = { - { 47, 1, D_8011B278 }, -}; - -CameraMode D_8011C8FC[] = { - { 33, 5, D_8011B27C }, -}; - -CameraMode D_8011C904[] = { - { 43, 4, D_8011B290 }, - { 43, 4, D_8011B2A0 }, -}; - -CameraMode D_8011C914[] = { - { 52, 1, D_8011B2B0 }, -}; - -CameraMode D_8011C91C[] = { - { 53, 1, D_8011B2B0 }, -}; - -CameraMode D_8011C924[] = { - { 7, 11, D_8011B2B4 }, - { 0, 0, NULL }, - { 0, 0, NULL }, - { 9, 1, D_8011B2E0 }, -}; - -CameraMode D_8011C944[] = { - { 54, 3, D_8011B2E4 }, -}; - -CameraMode D_8011C94C[] = { - { 55, 3, D_8011B2E4 }, -}; - -CameraMode D_8011C954[] = { - { 60, 1, D_8011B2F0 }, -}; - -CameraMode D_8011C95C[] = { - { 56, 1, D_8011B2B0 }, -}; - -CameraMode D_8011C964[] = { - { 2, 10, D_8011B2F4 }, { 7, 11, D_8011B31C }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011A748 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011B348 }, { 42, 7, D_8011B368 }, { 42, 7, D_8011B384 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011B3A0 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011CA0C[] = { - { 2, 10, D_8011B3C8 }, { 7, 11, D_8011B3F0 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011A748 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011B41C }, { 42, 7, D_8011B43C }, { 42, 7, D_8011B458 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011B474 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011CAB4[] = { - { 70, 3, D_8011B49C }, -}; - -CameraMode D_8011CABC[] = { - { 43, 4, D_8011B4A8 }, -}; - -CameraMode D_8011CAC4[] = { - { 68, 1, D_8011B20C }, -}; - -CameraMode D_8011CACC[] = { - { 65, 1, D_8011B2B0 }, -}; - -CameraMode D_8011CAD4[] = { - { 46, 1, D_8011B2B0 }, -}; - -CameraMode D_8011CADC[] = { - { 57, 1, D_8011B2B0 }, -}; - -CameraMode D_8011CAE4[] = { - { 2, 10, D_8011B4B8 }, { 7, 11, D_8011A8C4 }, { 12, 13, D_8011A8F0 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011B4E0 }, { 23, 9, D_8011A994 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A778 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A9B8 }, { 22, 8, D_8011A954 }, { 42, 7, D_8011A9F8 }, { 42, 7, D_8011AA14 }, - { 22, 8, D_8011A974 }, { 30, 7, D_8011A9DC }, { 2, 10, D_8011B510 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011CB8C[] = { - { 2, 10, D_8011B538 }, { 7, 11, D_8011B560 }, { 0, 0, NULL }, - { 0, 0, NULL }, { 7, 11, D_8011B58C }, { 2, 10, D_8011B5B8 }, -}; - -CameraMode D_8011CBBC[] = { - { 2, 10, D_8011B5E0 }, { 7, 11, D_8011B608 }, { 0, 0, NULL }, - { 0, 0, NULL }, { 7, 11, D_8011B634 }, { 2, 10, D_8011B660 }, -}; - -CameraMode D_8011CBEC[] = { - { 2, 10, D_8011B688 }, { 7, 11, D_8011B6B0 }, { 0, 0, NULL }, - { 0, 0, NULL }, { 7, 11, D_8011B6DC }, { 2, 10, D_8011B708 }, -}; - -CameraMode D_8011CC1C[] = { - { 15, 9, D_8011B730 }, -}; - -CameraMode D_8011CC24[] = { - { 61, 2, D_8011B754 }, -}; - -CameraMode D_8011CC2C[] = { - { 2, 10, D_8011B75C }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011A748 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011CCD4[] = { - { 2, 10, D_8011B784 }, { 7, 11, D_8011B7AC }, { 27, 12, D_8011B7D8 }, { 14, 12, D_8011B808 }, - { 27, 12, D_8011B7D8 }, { 0, 0, NULL }, { 19, 9, D_8011B838 }, { 0, 0, NULL }, - { 0, 0, NULL }, { 0, 0, NULL }, { 0, 0, NULL }, { 0, 0, NULL }, - { 0, 0, NULL }, { 22, 8, D_8011B85C }, { 42, 7, D_8011B89C }, { 42, 7, D_8011B8B8 }, - { 22, 8, D_8011B87C }, -}; - -CameraMode D_8011CD5C[] = { - { 50, 1, D_8011B8D4 }, -}; - -CameraMode D_8011CD64[] = { - { 2, 10, D_8011B8D8 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011B900 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011CE0C[] = { - { 2, 10, D_8011B930 }, { 7, 11, D_8011B958 }, { 12, 13, D_8011A8F0 }, { 14, 12, D_8011A428 }, - { 27, 12, D_8011B984 }, { 23, 9, D_8011B9F4 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A778 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011BA18 }, { 22, 8, D_8011B9B4 }, { 42, 7, D_8011BA3C }, { 42, 7, D_8011BA58 }, - { 22, 8, D_8011B9D4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011BA74 }, { 7, 11, D_8011BA9C }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011CEB4[] = { - { 2, 10, D_8011BAC8 }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011BAF0 }, { 14, 12, D_8011BB24 }, - { 27, 12, D_8011A458 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraMode D_8011CF5C[] = { - { 35, 5, D_8011B1F8 }, { 0, 0, NULL }, { 35, 5, D_8011B1F8 }, { 14, 12, D_8011A428 }, - { 0, 0, NULL }, { 0, 0, NULL }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 0, 0, NULL }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, -}; - -CameraMode D_8011CFBC[] = { - { 2, 10, D_8011B75C }, { 7, 11, D_8011A3C8 }, { 12, 13, D_8011A3F4 }, { 14, 12, D_8011BB54 }, - { 27, 12, D_8011A748 }, { 23, 9, D_8011A488 }, { 19, 9, D_8011A4AC }, { 19, 9, D_8011A4D0 }, - { 19, 9, D_8011A4F4 }, { 66, 8, D_8011A518 }, { 19, 9, D_8011A538 }, { 19, 9, D_8011A55C }, - { 23, 9, D_8011A580 }, { 22, 8, D_8011A5A4 }, { 42, 7, D_8011A5C4 }, { 42, 7, D_8011A5E0 }, - { 22, 8, D_8011A5A4 }, { 30, 7, D_8011A61C }, { 2, 10, D_8011A638 }, { 7, 11, D_8011A660 }, - { 12, 13, D_8011A68C }, -}; - -CameraSetting sCameraSettings[] = { - { { 0x00000000 }, NULL }, { { 0x051FFFFF }, D_8011BB84 }, { { 0x051FFFFF }, D_8011BC2C }, - { { 0x051FFFFF }, D_8011BCD4 }, { { 0x051FFFFF }, D_8011BD7C }, { { 0x050FF7FF }, D_8011BE24 }, - { { 0x8500018F }, D_8011BEC4 }, { { 0x051FFFFF }, D_8011BF0C }, { { 0x051FFFFF }, D_8011BFB4 }, - { { 0x051FFFFF }, D_8011C05C }, { { 0x051FFFFF }, D_8011C104 }, { { 0x051FFFFF }, D_8011C1AC }, - { { 0x051FFFFF }, D_8011C254 }, { { 0x051FFFFF }, D_8011C2FC }, { { 0x051FFFFF }, D_8011C3A4 }, - { { 0x051FFFFF }, D_8011C44C }, { { 0x051FFFFF }, D_8011C4F4 }, { { 0x051FFFFF }, D_8011C59C }, - { { 0x851FFFFF }, D_8011C644 }, { { 0x851FFFFF }, D_8011C6EC }, { { 0x8500000D }, D_8011C794 }, - { { 0x85000001 }, D_8011C7B4 }, { { 0x85000001 }, D_8011C7BC }, { { 0x85000001 }, D_8011C7C4 }, - { { 0x851E1FFF }, D_8011C7CC }, { { 0x8C00000D }, D_8011C874 }, { { 0x8C00000D }, D_8011C894 }, - { { 0x8C000001 }, D_8011C8B4 }, { { 0xC5000001 }, D_8011C8BC }, { { 0xC5000003 }, D_8011C8C4 }, - { { 0xC5000001 }, D_8011C8D4 }, { { 0xC5000001 }, D_8011C8DC }, { { 0xC5000001 }, D_8011C8E4 }, - { { 0x05000001 }, D_8011C8EC }, { { 0x05000001 }, D_8011C8F4 }, { { 0x85000001 }, D_8011C8FC }, - { { 0x05000003 }, D_8011C904 }, { { 0xCE000001 }, D_8011C914 }, { { 0x4E000001 }, D_8011C91C }, - { { 0x05000009 }, D_8011C924 }, { { 0x45000001 }, D_8011C944 }, { { 0x45000001 }, D_8011C94C }, - { { 0x45000001 }, D_8011C954 }, { { 0x45000001 }, D_8011C95C }, { { 0x451FFFFF }, D_8011C964 }, - { { 0x451FFFFF }, D_8011CA0C }, { { 0xC5000001 }, D_8011CAB4 }, { { 0x45000001 }, D_8011CABC }, - { { 0x05000001 }, D_8011CAC4 }, { { 0x45000001 }, D_8011CACC }, { { 0x45000001 }, D_8011CAD4 }, - { { 0x45000001 }, D_8011CADC }, { { 0x451FFFFF }, D_8011CAE4 }, { { 0x05000033 }, D_8011CB8C }, - { { 0x05000033 }, D_8011CBBC }, { { 0x05000033 }, D_8011CBEC }, { { 0x4A000001 }, D_8011CC1C }, - { { 0x05000001 }, D_8011CC24 }, { { 0x051FFFFF }, D_8011CC2C }, { { 0x0501E05F }, D_8011CCD4 }, - { { 0x45000001 }, D_8011CD5C }, { { 0x051FFFFF }, D_8011CD64 }, { { 0x051FFFFF }, D_8011CE0C }, - { { 0x051FFFFF }, D_8011CEB4 }, { { 0xC5000ECD }, D_8011CF5C }, { { 0x051FFFFF }, D_8011CFBC }, -}; - -s32 Camera_Normal0(Camera* camera); -s32 Camera_Normal1(Camera* camera); -s32 Camera_Normal2(Camera* camera); -s32 Camera_Normal3(Camera* camera); -s32 Camera_Normal4(Camera* camera); -s32 Camera_Parallel0(Camera* camera); -s32 Camera_Parallel1(Camera* camera); -s32 Camera_Parallel2(Camera* camera); -void Camera_Parallel3(Camera* camera); -s32 Camera_Parallel4(Camera* camera); -s32 Camera_KeepOn0(Camera* camera); -s32 Camera_KeepOn1(Camera* camera); -s32 Camera_KeepOn2(Camera* camera); -s32 Camera_KeepOn3(Camera* camera); -s32 Camera_KeepOn4(Camera* camera); -s32 Camera_Subj0(Camera* camera); -s32 Camera_Subj1(Camera* camera); -s32 Camera_Subj2(Camera* camera); -s32 Camera_Subj3(Camera* camera); -s32 Camera_Subj4(Camera* camera); -s32 Camera_Jump0(Camera* camera); -s32 Camera_Jump1(Camera* camera); -s32 Camera_Jump2(Camera* camera); -s32 Camera_Jump3(Camera* camera); -s32 Camera_Jump4(Camera* camera); -s32 Camera_Battle0(Camera* camera); -s32 Camera_Battle1(Camera* camera); -s32 Camera_Battle2(Camera* camera); -s32 Camera_Battle3(Camera* camera); -s32 Camera_Battle4(Camera* camera); -s32 Camera_Fixed0(Camera* camera); -s32 Camera_Fixed1(Camera* camera); -s32 Camera_Fixed2(Camera* camera); -s32 Camera_Fixed3(Camera* camera); -s32 Camera_Fixed4(Camera* camera); -s32 Camera_Data0(Camera* camera); -s32 Camera_Data1(Camera* camera); -s32 Camera_Data2(Camera* camera); -s32 Camera_Data3(Camera* camera); -s32 Camera_Data4(Camera* camera); -s32 Camera_Unique0(Camera* camera); -s32 Camera_Unique1(Camera* camera); -s32 Camera_Unique2(Camera* camera); -s32 Camera_Unique3(Camera* camera); -s32 Camera_Unique4(Camera* camera); -s32 Camera_Unique5(Camera* camera); -s32 Camera_Unique6(Camera* camera); -s32 Camera_Unique7(Camera* camera); -s32 Camera_Unique8(Camera* camera); -s32 Camera_Unique9(Camera* camera); -s32 Camera_Demo0(Camera* camera); -s32 Camera_Demo1(Camera* camera); -s32 Camera_Demo2(Camera* camera); -s32 Camera_Demo3(Camera* camera); -s32 Camera_Demo4(Camera* camera); -s32 Camera_Demo5(Camera* camera); -s32 Camera_Demo6(Camera* camera); -void Camera_Demo7(Camera* camera); -s32 Camera_Demo8(Camera* camera); -s32 Camera_Demo9(Camera* camera); -s32 Camera_Special0(Camera* camera); -s32 Camera_Special1(Camera* camera); -s32 Camera_Special2(Camera* camera); -s32 Camera_Special3(Camera* camera); -s32 Camera_Special4(Camera* camera); -s32 Camera_Special5(Camera* camera); -s32 Camera_Special6(Camera* camera); -s32 Camera_Special7(Camera* camera); -s32 Camera_Special8(Camera* camera); -s32 Camera_Special9(Camera* camera); - -void* sCameraFunctions[] = { - NULL, - Camera_Normal0, - Camera_Normal1, - Camera_Normal2, - Camera_Normal3, - Camera_Normal4, - Camera_Parallel0, - Camera_Parallel1, - Camera_Parallel2, - Camera_Parallel3, - Camera_Parallel4, - Camera_KeepOn0, - Camera_KeepOn1, - Camera_KeepOn2, - Camera_KeepOn3, - Camera_KeepOn4, - Camera_Subj0, - Camera_Subj1, - Camera_Subj2, - Camera_Subj3, - Camera_Subj4, - Camera_Jump0, - Camera_Jump1, - Camera_Jump2, - Camera_Jump3, - Camera_Jump4, - Camera_Battle0, - Camera_Battle1, - Camera_Battle2, - Camera_Battle3, - Camera_Battle4, - Camera_Fixed0, - Camera_Fixed1, - Camera_Fixed2, - Camera_Fixed3, - Camera_Fixed4, - Camera_Data0, - Camera_Data1, - Camera_Data2, - Camera_Data3, - Camera_Data4, - Camera_Unique0, - Camera_Unique1, - Camera_Unique2, - Camera_Unique3, - Camera_Unique4, - Camera_Unique5, - Camera_Unique6, - Camera_Unique7, - Camera_Unique8, - Camera_Unique9, - Camera_Demo0, - Camera_Demo1, - Camera_Demo2, - Camera_Demo3, - Camera_Demo4, - Camera_Demo5, - Camera_Demo6, - Camera_Demo7, - Camera_Demo8, - Camera_Demo9, - Camera_Special0, - Camera_Special1, - Camera_Special2, - Camera_Special3, - Camera_Special4, - Camera_Special5, - Camera_Special6, - Camera_Special7, - Camera_Special8, - Camera_Special9, -}; - -s32 sInitRegs = 1; // 8011D390 - -UNK_TYPE D_8011D394 = 0; -s32 D_8011D398 = -1; -s16 D_8011D39C = 0; // size = 4 ? -u_D_8011D3A0 D_8011D3A0 = { { - 0x0000, - 0x0001, -} }; - -s32 D_8011D3A4 = 0x02; -s32 D_8011D3A8 = 0x20; -s32 D_8011D3AC = -1; - -s16 D_8011D3B0[] = { - 0x0AAA, 0xF556, 0x1555, 0xEAAB, 0x2AAA, 0xD556, 0x3FFF, 0xC001, 0x5555, 0xAAAB, 0x6AAA, 0x9556, 0x7FFF, 0x0000, -}; - -s16 D_8011D3CC[] = { - 0x0000, 0x02C6, 0x058C, 0x0000, 0x0000, 0xFD3A, 0x0000, 0x0852, 0x0000, 0x0000, 0x0B18, 0x02C6, 0xFA74, 0x0000, -}; - -s32 D_8011D3E8 = 0; // size = 8? -s32 D_8011D3EC = 0; -s32 D_8011D3F0 = 0; - -s32 D_8011D3F4 = -16; - -char sCameraFunctionNames[][8] = { - "NONE ", "NORM0()", "NORM1()", "NORM2()", "NORM3()", "NORM4()", "PARA0()", "PARA1()", "PARA2()", "PARA3()", - "PARA4()", "KEEP0()", "KEEP1()", "KEEP2()", "KEEP3()", "KEEP4()", "SUBJ0()", "SUBJ1()", "SUBJ2()", "SUBJ3()", - "SUBJ4()", "JUMP0()", "JUMP1()", "JUMP2()", "JUMP3()", "JUMP4()", "BATT0()", "BATT1()", "BATT2()", "BATT3()", - "BATT4()", "FIXD0()", "FIXD1()", "FIXD2()", "FIXD3()", "FIXD4()", "DATA0()", "DATA1()", "DATA2()", "DATA3()", - "DATA4()", "UNIQ0()", "UNIQ1()", "UNIQ2()", "UNIQ3()", "UNIQ4()", "UNIQ5()", "UNIQ6()", "UNIQ7()", "UNIQ8()", - "UNIQ9()", "DEMO0()", "DEMO1()", "DEMO2()", "DEMO3()", "DEMO4()", "DEMO5()", "DEMO6()", "DEMO7()", "DEMO8()", - "DEMO9()", "SPEC0()", "SPEC1()", "SPEC2()", "SPEC3()", "SPEC4()", "SPEC5()", "SPEC6()", "SPEC7()", "SPEC8()", - "SPEC9()", "", "", "", "", "", -}; - -u8 D_8011D658[] = { - 0x42, 0x48, 0x00, 0x00, 0xEE, 0x3A, 0xD5, 0x58, 0x42, 0x96, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, - 0x42, 0xA0, 0x00, 0x00, 0xEE, 0x3A, 0x80, 0x08, 0x41, 0x70, 0x00, 0x00, 0xEE, 0x3A, 0x80, 0x08, -}; - -u8 D_8011D678[] = { - 0x00, 0x00, 0x00, 0x00, 0x42, 0x20, 0x00, 0x00, 0x41, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x42, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, - 0xC0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0xC0, 0x40, 0x00, 0x00, -}; - -s32 D_8011D6A8 = -200; - -u8 D_8011D6AC[] = { - 0x8F, 0xFF, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xFF, 0x03, 0x03, -}; - -u8 D_8011D6D8[] = { - 0x00, 0x13, 0x00, 0x00, 0x42, 0x34, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xA0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xFF, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, - 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, -}; - -u8 D_8011D724[] = { - 0x8F, 0xFF, 0x24, 0x24, 0x00, 0x01, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x00, 0x00, - 0xC1, 0xA0, 0x00, 0x00, 0x81, 0xFF, 0x21, 0x21, 0x00, 0x13, 0x00, 0x00, 0x42, 0x48, 0x00, 0x00, 0x3F, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x12, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x42, 0x70, - 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, - 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, -}; - -u8 D_8011D79C[] = { - 0xCF, 0xFF, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xC1, 0xFF, 0x03, 0x03, 0x00, 0x13, 0x00, 0x00, 0x42, 0x34, 0x00, 0x00, 0x3F, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xC1, 0x20, 0x00, 0x00, 0x40, 0xA0, 0x00, 0x00, 0xC1, 0xFF, 0x03, 0x03, 0x00, 0x09, 0x00, 0x00, 0x42, 0x70, - 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xFF, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, - 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, -}; - -u8 D_8011D83C[] = { - 0x83, 0xFF, 0x21, 0x41, 0x00, 0x14, 0x00, 0x00, 0x42, 0x34, 0x00, 0x00, 0x3E, 0x4C, 0xCC, 0xCD, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x00, 0x00, 0x12, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, - 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, -}; - -u8 D_8011D88C[] = { - 0x81, 0xFF, 0x03, 0x03, 0x00, 0x14, 0x00, 0x00, 0x42, 0x34, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, - 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, -}; - -u8 D_8011D8DC[] = { - 0x8F, 0xFF, 0x04, 0x04, 0x00, 0x14, 0x00, 0x01, 0x42, 0x48, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x40, 0xA0, 0x00, 0x00, 0x41, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x00, 0x00, - 0xC2, 0xA0, 0x00, 0x00, 0x82, 0xFF, 0x21, 0x21, 0x00, 0x05, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xA0, 0x00, 0x00, - 0x40, 0xA0, 0x00, 0x00, 0xC3, 0x48, 0x00, 0x00, 0x12, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x42, 0x70, - 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, - 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, -}; - -u8 D_8011D954[] = { - 0x0F, 0xFF, 0xC1, 0xC1, 0x00, 0x14, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x43, 0x7A, 0x00, 0x00, 0x83, 0xFF, 0x05, 0xB1, 0x00, 0x05, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x3D, 0xCC, - 0xCC, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x00, 0x00, 0x42, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x41, 0x20, 0x00, 0x00, 0x42, 0xC8, 0x00, 0x00, 0x82, 0xFF, 0x21, 0x21, 0x00, 0x05, 0x00, 0x02, 0x42, 0x70, - 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x41, 0xA0, 0x00, 0x00, 0xC3, 0x16, 0x00, 0x00, 0x12, 0xFF, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, - 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, -}; - -u8 D_8011D9F4[] = { - 0x8F, 0xFF, 0x05, 0x04, 0x00, 0x14, 0x00, 0x02, 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x40, 0xA0, 0x00, 0x00, 0x42, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xA0, 0x00, 0x00, - 0x43, 0x96, 0x00, 0x00, 0x82, 0xFF, 0x21, 0x21, 0x00, 0x05, 0x00, 0x02, 0x42, 0x70, 0x00, 0x00, 0x3F, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x41, 0xA0, 0x00, 0x00, 0xC3, 0x16, 0x00, 0x00, 0x12, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x42, 0x70, - 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, - 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, -}; - -u8 D_8011DA6C[] = { - 0x45, 0x3E, 0xA0, 0x00, 0x44, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xDB, 0x60, 0x00, - 0x45, 0x55, 0x70, 0x00, 0xC3, 0xBE, 0x00, 0x00, 0xC5, 0x43, 0x00, 0x00, 0x45, 0x45, 0x80, 0x00, - 0x43, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x20, 0x00, 0x00, 0x43, 0x70, 0x00, 0x00, -}; - -u8 D_8011DA9C[] = { - 0x45, 0x45, 0x80, 0x00, 0x45, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xBD, 0x60, 0x00, - 0x45, 0x81, 0x10, 0x00, 0xC4, 0x50, 0xC0, 0x00, 0xC5, 0x3E, 0x00, 0x00, 0x45, 0x81, 0x38, 0x00, - 0x43, 0x66, 0x00, 0x00, 0xC2, 0x48, 0x00, 0x00, 0x44, 0x16, 0x00, 0x00, 0xC2, 0x96, 0x00, 0x00, -}; - -u8 D_8011DACC[] = { - 0x44, 0xC4, 0x40, 0x00, 0x45, 0x66, 0x00, 0x00, 0x45, 0x67, 0x40, 0x00, 0x43, 0xC5, 0x80, 0x00, -}; - -u8 D_8011DADC[] = { - 0x43, 0xA0, 0x00, 0x00, 0x43, 0xA0, 0x00, 0x00, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -u8 D_8011DAEC[] = { - 0xF8, 0x30, 0xFC, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -s16 D_8011DAFC[] = { - 1, 2, 58, 3, 4, 62, -}; - -s16 D_8011DB08 = 1008; - -s16 D_8011DB0C = 342; - -s32 D_8011DB10 = 0; - -s32 D_8011DB14 = 0; - -// BSS -extern GlobalContext* D_8015BD7C; -extern DbgCamera D_8015BD80; -extern Vec3f D_8015BD84; -extern Vec3f D_8015BD90; -extern Vec3f D_8015BD9C; -extern f32 D_8015BDC8; -extern Vec3s D_8015CE46; -extern CollisionPoly* D_8015CE4C; +#define RELOAD_PARAMS \ + (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14 || R_RELOAD_CAM_PARAMS) -/*===============================================================*/ -typedef struct { - Vec3f unk_00; - Vec3f unk_0C; - CollisionPoly* unk_18; - char unk_1C[0x8]; - s32 unk_24; -} struct_80043D18; +#define PCT(x) ((x)*0.01f) +#define NEXTSETTING ((values++)->val) +#define NEXTPCT PCT(NEXTSETTING) + +#define ONEPOINTDEMO ((Unique9OnePointDemo*)camera->paramData) + +#define BGCAM_POS(v) ((v)[0]) +#define BGCAM_ROT(v) ((v)[1]) +#define BGCAM_FOV(v) ((v)[2].x) +#define BGCAM_JFIFID(v) ((v)[2].y) + +#define FLG_ADJSLOPE (1 << 0) +#define FLG_OFFGROUND (1 << 7) + +#include "z_camera_data.c" -f32 func_800437F0(f32 arg0, f32 arg1) { - f32 percent = 0.4f; - f32 ret = fabsf(arg1); +/*===============================================================*/ - if (arg0 < ret) { - ret = 1; - } else if (ret < (f32)arg0 * (1 - percent)) { //! float cast needed to match - ret = (SQ(arg1) * (1 - percent)) / SQ((1 - percent) * arg0); +/** + * Interpolates along a curve between 0 and 1 with a period of + * -a <= p <= a at time `b` + */ +f32 Camera_InterpolateCurve(f32 a, f32 b) { + f32 ret; + f32 absB; + f32 t = 0.4f; + f32 t2; + f32 t3; + f32 t4; + + absB = fabsf(b); + if (a < absB) { + ret = 1.0f; } else { - ret = 1 - (0.4f * SQ(arg0 - ret)) / SQ(0.4f * arg0); + t2 = 1.0f - t; + if ((a * t2) > absB) { + t3 = SQ(b) * (1.0f - t); + t4 = SQ(a * t2); + ret = t3 / t4; + } else { + t3 = SQ(a - absB) * t; + t4 = SQ(0.4f * a); + ret = 1.0f - (t3 / t4); + } } - return ret; } -f32 func_8004389C(f32 arg0, f32 arg1, f32 arg2, f32 arg3) { - f32 temp1 = arg0 - arg1; - f32 temp2; +/* + * Performs linear interpoloation between `cur` and `target`. If `cur` is within + * `minDiff` units, The result is rounded up to `target` + */ +f32 Camera_LERPCeilF(f32 target, f32 cur, f32 stepScale, f32 minDiff) { + f32 diff = target - cur; + f32 step; f32 ret; - if (fabsf(temp1) >= arg3) { - temp2 = temp1 * arg2; - ret = arg1 + temp2; + if (fabsf(diff) >= minDiff) { + step = diff * stepScale; + ret = cur + step; } else { - ret = arg0; + ret = target; } return ret; } -f32 func_800438DC(f32 arg0, f32 arg1, f32 arg2, f32 arg3) { - f32 temp1 = arg0 - arg1; - f32 temp2; +/* + * Performs linear interpoloation between `cur` and `target`. If `cur` is within + * `minDiff` units, The result is rounded down to `cur` + */ +f32 Camera_LERPFloorF(f32 target, f32 cur, f32 stepScale, f32 minDiff) { + f32 diff = target - cur; + f32 step; f32 ret; - if (fabsf(temp1) >= arg3) { - temp2 = temp1 * arg2; - ret = arg1 + temp2; + if (fabsf(diff) >= minDiff) { + step = diff * stepScale; + ret = cur + step; } else { - ret = arg1; + ret = cur; } return ret; } -s16 func_8004391C(s16 arg0, s16 arg1, f32 arg2, s16 arg3) { - s16 temp1 = arg0 - arg1; - s16 temp2; +/* + * Performs linear interpoloation between `cur` and `target`. If `cur` is within + * `minDiff` units, The result is rounded up to `target` + */ +s16 Camera_LERPCeilS(s16 target, s16 cur, f32 stepScale, s16 minDiff) { + s16 diff = target - cur; + s16 step; s32 ret; - if (ABS(temp1) >= arg3) { - temp2 = temp1 * arg2 + 0.5f; - ret = arg1 + temp2; + if (ABS(diff) >= minDiff) { + step = diff * stepScale + 0.5f; + ret = cur + step; } else { - ret = arg0; + ret = target; } return ret; } -s16 func_800439AC(s16 arg0, s16 arg1, f32 arg2, s16 arg3) { - s16 temp1 = arg0 - arg1; - s16 temp2; +/* + * Performs linear interpoloation between `cur` and `target`. If `cur` is within + * `minDiff` units, The result is rounded down to `cur` + */ +s16 Camera_LERPFloorS(s16 target, s16 cur, f32 stepScale, s16 minDiff) { + s16 diff = target - cur; + s16 step; s32 ret; - if (ABS(temp1) >= arg3) { - temp2 = temp1 * arg2 + 0.5f; - ret = arg1 + temp2; + if (ABS(diff) >= minDiff) { + step = diff * stepScale + 0.5f; + ret = cur + step; } else { - ret = arg1; + ret = cur; } return ret; } -void func_80043A3C(Vec3f* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4) { - arg1->x = func_8004389C(arg0->x, arg1->x, arg3, arg4); - arg1->y = func_8004389C(arg0->y, arg1->y, arg2, arg4); - arg1->z = func_8004389C(arg0->z, arg1->z, arg3, arg4); +/* + * Performs linear interpoloation between `cur` and `target`. If `cur` is within + * `minDiff` units, The result is rounded up to `target` + */ +void Camera_LERPCeilVec3f(Vec3f* target, Vec3f* cur, f32 yStepScale, f32 xzStepScale, f32 minDiff) { + cur->x = Camera_LERPCeilF(target->x, cur->x, xzStepScale, minDiff); + cur->y = Camera_LERPCeilF(target->y, cur->y, yStepScale, minDiff); + cur->z = Camera_LERPCeilF(target->z, cur->z, xzStepScale, minDiff); } void func_80043ABC(Camera* camera) { - camera->unk_C0.z = 100.0f; - camera->unk_C0.y = OREG(7); - camera->unk_C0.x = OREG(6); - camera->unk_CC.x = OREG(2) * 0.01f; - camera->unk_CC.y = OREG(3) * 0.01f; - camera->unk_CC.z = OREG(4) * 0.01f; + camera->yawUpdateRateInv = 100.0f; + camera->pitchUpdateRateInv = R_CAM_DEFA_PHI_UPDRATE; + camera->rUpdateRateInv = OREG(6); + camera->xzOffsetUpdateRate = PCT(OREG(2)); + camera->yOffsetUpdateRate = PCT(OREG(3)); + camera->fovUpdateRate = PCT(OREG(4)); } void func_80043B60(Camera* camera) { - camera->unk_C0.x = OREG(27); - camera->unk_C0.z = OREG(27); - camera->unk_C0.y = OREG(27); - camera->unk_CC.x = 0.001f; - camera->unk_CC.y = 0.001f; - camera->unk_CC.z = 0.001f; + camera->rUpdateRateInv = OREG(27); + camera->yawUpdateRateInv = OREG(27); + camera->pitchUpdateRateInv = OREG(27); + camera->xzOffsetUpdateRate = 0.001f; + camera->yOffsetUpdateRate = 0.001f; + camera->fovUpdateRate = 0.001f; } -Vec3f* func_80043BC4(Vec3f* arg0, Vec3s* arg1) { - Vec3f sp4; +Vec3f* Camera_Vec3sToVec3f(Vec3f* dest, Vec3s* src) { + Vec3f copy; - sp4.x = arg1->x; - sp4.y = arg1->y; - sp4.z = arg1->z; + copy.x = src->x; + copy.y = src->y; + copy.z = src->z; - *arg0 = sp4; - return arg0; + *dest = copy; + return dest; } -Vec3f* func_80043C28(Vec3f* arg0, Vec3f* arg1, VecSph* arg2) { - Vec3f sp24, sp18; - OLib_VecSphGeoToVec3f(&sp18, arg2); +Vec3f* Camera_Vec3fVecSphGeoAdd(Vec3f* dest, Vec3f* a, VecSph* b) { + Vec3f copy; + Vec3f vecB; + OLib_VecSphGeoToVec3f(&vecB, b); - sp24.x = arg1->x + sp18.x; - sp24.y = arg1->y + sp18.y; - sp24.z = arg1->z + sp18.z; + copy.x = a->x + vecB.x; + copy.y = a->y + vecB.y; + copy.z = a->z + vecB.z; - *arg0 = sp24; - return arg0; + *dest = copy; + return dest; } -Vec3f* func_80043CAC(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32 arg3) { - Vec3f sp4; +Vec3f* Camera_Vec3fTranslateByUnitVector(Vec3f* dest, Vec3f* src, Vec3f* unitVector, f32 uvScale) { + Vec3f copy; - sp4.x = arg1->x + (arg2->x * arg3); - sp4.y = arg1->y + (arg2->y * arg3); - sp4.z = arg1->z + (arg2->z * arg3); + copy.x = src->x + (unitVector->x * uvScale); + copy.y = src->y + (unitVector->y * uvScale); + copy.z = src->z + (unitVector->z * uvScale); - *arg0 = sp4; - return arg0; + *dest = copy; + return dest; } -s32 func_80043D18(Camera* camera, Vec3f* arg1, struct_80043D18* arg2) { - CollisionContext* colCtx; - Vec3f sp68, sp5C, sp50; - f32 temp_ret; - CollisionPoly* sp48; - s32 sp44; - VecSph sp3C; - - colCtx = &camera->globalCtx->colCtx; - OLib_Vec3fDiffToVecSphGeo(&sp3C, arg1, &arg2->unk_00); - sp3C.r += 8.0f; - func_80043C28(&sp5C, arg1, &sp3C); - - if (func_8003DD6C(colCtx, arg1, &sp5C, &sp68, &arg2->unk_18, 1, 1, 1, -1, &arg2->unk_24) == 0) { - OLib_Vec3fDistNormalize(&sp50, arg1, &arg2->unk_00); - - arg2->unk_0C.x = -sp50.x; - arg2->unk_0C.y = -sp50.y; - arg2->unk_0C.z = -sp50.z; - - sp68 = arg2->unk_00; - sp68.y += 5.0f; - temp_ret = func_8003CCA4(colCtx, &sp48, &sp44, &sp68); - - if ((arg2->unk_00.y - temp_ret) > 5.0f) { - arg2->unk_00.x += arg2->unk_0C.x; - arg2->unk_00.y += arg2->unk_0C.y; - arg2->unk_00.z += arg2->unk_0C.z; +/** + * Detects the collision poly between `from` and `to`, places collision info in `to` + */ +s32 Camera_BGCheckInfo(Camera* camera, Vec3f* from, CamColChk* to) { + CollisionContext* colCtx = &camera->globalCtx->colCtx; + Vec3f toNewPos; + Vec3f toPoint; + Vec3f fromToNorm; + f32 floorPolyY; + CollisionPoly* floorPoly; + s32 floorBgId; + VecSph fromToOffset; + + OLib_Vec3fDiffToVecSphGeo(&fromToOffset, from, &to->pos); + fromToOffset.r += 8.0f; + Camera_Vec3fVecSphGeoAdd(&toPoint, from, &fromToOffset); + + if (!func_8003DD6C(colCtx, from, &toPoint, &toNewPos, &to->poly, 1, 1, 1, -1, &to->bgId)) { + // no poly in path. + OLib_Vec3fDistNormalize(&fromToNorm, from, &to->pos); + + to->norm.x = -fromToNorm.x; + to->norm.y = -fromToNorm.y; + to->norm.z = -fromToNorm.z; + + toNewPos = to->pos; + toNewPos.y += 5.0f; + floorPolyY = func_8003CCA4(colCtx, &floorPoly, &floorBgId, &toNewPos); + + if ((to->pos.y - floorPolyY) > 5.0f) { + // if the y distance from the check point to the floor is more than 5 units + // the point is not colliding with any collision. + to->pos.x += to->norm.x; + to->pos.y += to->norm.y; + to->pos.z += to->norm.z; return 0; } - arg2->unk_18 = sp48; - sp68.y = temp_ret + 1.0f; - arg2->unk_24 = sp44; + to->poly = floorPoly; + toNewPos.y = floorPolyY + 1.0f; + to->bgId = floorBgId; } - arg2->unk_0C.x = arg2->unk_18->norm.x * (1.0f / 32767.0f); - arg2->unk_0C.y = arg2->unk_18->norm.y * (1.0f / 32767.0f); - arg2->unk_0C.z = arg2->unk_18->norm.z * (1.0f / 32767.0f); - arg2->unk_00.x = arg2->unk_0C.x + sp68.x; - arg2->unk_00.y = arg2->unk_0C.y + sp68.y; - arg2->unk_00.z = arg2->unk_0C.z + sp68.z; + to->norm.x = to->poly->norm.x * COLPOLY_NORM_FRAC; + to->norm.y = to->poly->norm.y * COLPOLY_NORM_FRAC; + to->norm.z = to->poly->norm.z * COLPOLY_NORM_FRAC; + to->pos.x = to->norm.x + toNewPos.x; + to->pos.y = to->norm.y + toNewPos.y; + to->pos.z = to->norm.z + toNewPos.z; - return sp44 + 1; + return floorBgId + 1; } -void func_80043F34(Camera* camera, Vec3f* arg1, Vec3f* arg2) { - struct_80043D18 sp20; - Vec3s unused; - - sp20.unk_00 = *arg2; - func_80043D18(camera, arg1, &sp20); - *arg2 = sp20.unk_00; +/** + * Detects if there is collision between `from` and `to` + */ +s32 Camera_BGCheck(Camera* camera, Vec3f* from, Vec3f* to) { + CamColChk toCol; + s32 bgId; + + toCol.pos = *to; + bgId = Camera_BGCheckInfo(camera, from, &toCol); + *to = toCol.pos; + return bgId; } -// 242 lines -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80043F94.s") +s32 func_80043F94(Camera* camera, Vec3f* from, CamColChk* to) { + CollisionContext* colCtx = &camera->globalCtx->colCtx; + Vec3f toNewPos; + Vec3f toPos; + Vec3f fromToNorm; + Vec3f playerFloorNormF; + f32 floorY; + CollisionPoly* floorPoly; + s32 bgId; + VecSph fromToGeo; + + OLib_Vec3fDiffToVecSphGeo(&fromToGeo, from, &to->pos); + fromToGeo.r += 8.0f; + Camera_Vec3fVecSphGeoAdd(&toPos, from, &fromToGeo); + if (!func_8003DD6C(colCtx, from, &toPos, &toNewPos, &to->poly, 1, 1, 1, -1, &to->bgId)) { + OLib_Vec3fDistNormalize(&fromToNorm, from, &to->pos); + to->norm.x = -fromToNorm.x; + to->norm.y = -fromToNorm.y; + to->norm.z = -fromToNorm.z; + toNewPos = to->pos; + toNewPos.y += 5.0f; + floorY = func_8003CCA4(colCtx, &floorPoly, &bgId, &toNewPos); + if ((to->pos.y - floorY) > 5.0f) { + // to is not on the ground or below it. + to->pos.x += to->norm.x; + to->pos.y += to->norm.y; + to->pos.z += to->norm.z; + return 0; + } + // to is touching the ground, move it up 1 unit. + to->poly = floorPoly; + toNewPos.y = floorY + 1.0f; + to->bgId = bgId; + } + to->norm.x = to->poly->norm.x * COLPOLY_NORM_FRAC; + to->norm.y = to->poly->norm.y * COLPOLY_NORM_FRAC; + to->norm.z = to->poly->norm.z * COLPOLY_NORM_FRAC; + if ((to->norm.y > 0.5f) || (to->norm.y < -0.8f)) { + to->pos.x = to->norm.x + toNewPos.x; + to->pos.y = to->norm.y + toNewPos.y; + to->pos.z = to->norm.z + toNewPos.z; + } else if (playerFloorPoly != NULL) { + playerFloorNormF.x = playerFloorPoly->norm.x * COLPOLY_NORM_FRAC; + playerFloorNormF.y = playerFloorPoly->norm.y * COLPOLY_NORM_FRAC; + playerFloorNormF.z = playerFloorPoly->norm.z * COLPOLY_NORM_FRAC; + if (Math3D_LineSegVsPlane(playerFloorNormF.x, playerFloorNormF.y, playerFloorNormF.z, playerFloorPoly->dist, + from, &toPos, &toNewPos, 1)) { + // line is from->to is touching the poly the player is on. + to->norm = playerFloorNormF; + to->poly = playerFloorPoly; + to->bgId = camera->bgCheckId; + to->pos.x = to->norm.x + toNewPos.x; + to->pos.y = to->norm.y + toNewPos.y; + to->pos.z = to->norm.z + toNewPos.z; + } else { + OLib_Vec3fDistNormalize(&fromToNorm, from, &to->pos); + to->norm.x = -fromToNorm.x; + to->norm.y = -fromToNorm.y; + to->norm.z = -fromToNorm.z; + to->pos.x += to->norm.x; + to->pos.y += to->norm.y; + to->pos.z += to->norm.z; + return 0; + } + } + return 1; +} void func_80044340(Camera* camera, Vec3f* arg1, Vec3f* arg2) { - struct_80043D18 sp20; + CamColChk sp20; Vec3s unused; - sp20.unk_00 = *arg2; + sp20.pos = *arg2; func_80043F94(camera, arg1, &sp20); - *arg2 = sp20.unk_00; + *arg2 = sp20.pos; } -s32 func_800443A0(Camera* camera, Vec3f* arg1, Vec3f* arg2) { +/** + * Checks if `from` to `to` is looking from the outside of a poly towards the front + */ +s32 Camera_CheckOOB(Camera* camera, Vec3f* from, Vec3f* to) { s32 pad; - Vec3f sp40; + Vec3f intersect; s32 pad2; - s32 sp38; - CollisionPoly* sp34; - CollisionContext* colCtx; - colCtx = &camera->globalCtx->colCtx; + s32 bgId; + CollisionPoly* poly; + CollisionContext* colCtx = &camera->globalCtx->colCtx; - sp34 = NULL; - if (func_8003DD6C(colCtx, arg1, arg2, &sp40, &sp34, 1, 1, 1, 0, &sp38) && (func_80038B7C(sp34, arg1) < 0.0f)) { + poly = NULL; + if (func_8003DD6C(colCtx, from, to, &intersect, &poly, 1, 1, 1, 0, &bgId) && (func_80038B7C(poly, from) < 0.0f)) { + // if there is a poly between `from` and `to` and the `from` is behind the poly. return true; } return false; } -f32 func_80044434(Camera* camera, Vec3f* arg1, Vec3f* arg2, s32* arg3) { - s32 sp2C; // unused - CollisionPoly* sp28; - f32 temp_ret = func_8003C940(&camera->globalCtx->colCtx, &sp28, arg3, arg2); - - if (temp_ret == -32000.0f) { - arg1->x = 0.0f; - arg1->z = 0.0f; - arg1->y = 1.0f; +/** + * Gets the floor position underneath `chkPos`, and returns the normal of the floor to `floorNorm`, + * and bgId to `bgId`. If no floor is found, then the normal is a flat surface pointing upwards. + */ +f32 Camera_GetFloorYNorm(Camera* camera, Vec3f* floorNorm, Vec3f* chkPos, s32* bgId) { + s32 pad; + CollisionPoly* floorPoly; + f32 floorY = func_8003C940(&camera->globalCtx->colCtx, &floorPoly, bgId, chkPos); + + if (floorY == BGCHECK_Y_MIN) { + // no floor + floorNorm->x = 0.0f; + floorNorm->y = 1.0f; + floorNorm->z = 0.0f; } else { - arg1->x = sp28->norm.x * (1.f / 32767.0f); - arg1->y = sp28->norm.y * (1.f / 32767.0f); - arg1->z = sp28->norm.z * (1.f / 32767.0f); + floorNorm->x = floorPoly->norm.x * COLPOLY_NORM_FRAC; + floorNorm->y = floorPoly->norm.y * COLPOLY_NORM_FRAC; + floorNorm->z = floorPoly->norm.z * COLPOLY_NORM_FRAC; } - return temp_ret; + return floorY; } -f32 func_80044510(Camera* camera, Vec3f* arg1) { - Vec3f sp2C, sp20; - s32 sp1C; +/** + * Gets the position of the floor from `pos` + */ +f32 Camera_GetFloorY(Camera* camera, Vec3f* pos) { + Vec3f posCheck; + Vec3f floorNorm; + s32 bgId; - sp2C = *arg1; - sp2C.y += 80.0f; + posCheck = *pos; + posCheck.y += 80.0f; - return func_80044434(camera, &sp20, &sp2C, &sp1C); + return Camera_GetFloorYNorm(camera, &floorNorm, &posCheck, &bgId); } -// 125 lines (loop) -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80044568.s") +/** + * Gets the position of the floor from `pos`, and if the floor is considered not solid, + * it checks the next floor below that up to 3 times. Returns the normal of the floor into `norm` + */ +f32 Camera_GetFloorYLayer(Camera* camera, Vec3f* norm, Vec3f* pos, u32* bgId) { + CollisionPoly* floorPoly; + CollisionContext* colCtx = &camera->globalCtx->colCtx; + f32 floorY; + s32 i; -s16 func_80044740(Camera* camera, s32 arg1) { - return func_80041A4C(&camera->globalCtx->colCtx, arg1, 50); + for (i = 3; i > 0; i--) { + floorY = func_8003CCA4(colCtx, &floorPoly, bgId, pos); + if (floorY == BGCHECK_Y_MIN || + (camera->playerGroundY < floorY && !((floorPoly->norm.y * COLPOLY_NORM_FRAC) > 0.5f))) { + // no floor, or player is below the floor and floor is not considered steep + norm->x = 0.0f; + norm->y = 1.0f; + norm->z = 0.0f; + floorY = BGCHECK_Y_MIN; + break; + } else if (func_80041D4C(colCtx, floorPoly, *bgId) == 1) { + // floor is not solid, check below that floor. + pos->y = floorY - 10.0f; + continue; + } else { + norm->x = floorPoly->norm.x * COLPOLY_NORM_FRAC; + norm->y = floorPoly->norm.y * COLPOLY_NORM_FRAC; + norm->z = floorPoly->norm.z * COLPOLY_NORM_FRAC; + break; + } + } + if (i == 0) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: foward check: too many layer!\n" VT_RST); + } + return floorY; } -struct_80041C10_ret* func_8004476C(Camera* camera) { - return func_80041C10(&camera->globalCtx->colCtx, camera->unk_148, 50); +/** + * Returns the CameraSettingType of the camera at index `camDataIdx` + */ +s16 Camera_GetCamDataSetting(Camera* camera, s32 camDataIdx) { + return func_80041A4C(&camera->globalCtx->colCtx, camDataIdx, 50); } -s32 func_8004479C(Camera* camera, s32* arg1, Vec3f* arg2) { - s32 temp_ret; - PosRot sp20; +/** + * Returns the scene camera info for the current camera data index + */ +Vec3s* Camera_GetCamBGData(Camera* camera) { + return func_80041C10(&camera->globalCtx->colCtx, camera->camDataIdx, 50); +} + +/** + * Gets the scene's camera index for the poly `poly`, returns -1 if + * there is no camera data for that poly. + */ +s32 Camera_GetDataIdxForPoly(Camera* camera, u32* bgId, CollisionPoly* poly) { + s32 camDataIdx; + PosRot playerPosRot; s32 ret; - func_8002EF44(&sp20, &camera->player->actor); - temp_ret = func_80041A28(&camera->globalCtx->colCtx, arg2, *arg1); + func_8002EF44(&playerPosRot, &camera->player->actor); // unused. + camDataIdx = func_80041A28(&camera->globalCtx->colCtx, poly, *bgId); - if (func_80041A4C(&camera->globalCtx->colCtx, temp_ret, *arg1) == 0) { + if (func_80041A4C(&camera->globalCtx->colCtx, camDataIdx, *bgId) == CAM_SET_NONE) { ret = -1; } else { - ret = temp_ret; + ret = camDataIdx; } return ret; } -s32 func_8004481C(Camera* camera, s16* arg1) { - CollisionPoly* sp44; - s32 sp40; // unused - s32 sp3C; - PosRot sp28; - - func_8002EF44(&sp28, &camera->player->actor); - sp28.pos.y += Player_GetCameraYOffset(camera->player); - if (func_8003C940(&camera->globalCtx->colCtx, &sp44, &sp3C, &sp28.pos) == -32000.0f) { - return 0; +/** + * Returns the scene camera info for the floor under the player. + * If there is no floor then there is no camera data, returns the number of + * pieces of data there are in `dataCnt` + */ +Vec3s* Camera_GetCamBgDataUnderPlayer(Camera* camera, u16* dataCnt) { + CollisionPoly* floorPoly; + s32 pad; + s32 bgId; + PosRot playerPosShape; + + func_8002EF44(&playerPosShape, &camera->player->actor); + playerPosShape.pos.y += Player_GetHeight(camera->player); + if (func_8003C940(&camera->globalCtx->colCtx, &floorPoly, &bgId, &playerPosShape.pos) == BGCHECK_Y_MIN) { + // no floor + return NULL; } - *arg1 = func_80041B80(&camera->globalCtx->colCtx, sp44, sp3C); - return func_80041C98(&camera->globalCtx->colCtx, sp44, sp3C); + *dataCnt = func_80041B80(&camera->globalCtx->colCtx, floorPoly, bgId); + return func_80041C98(&camera->globalCtx->colCtx, floorPoly, bgId); } -s32 func_800448CC(Camera* camera, f32* arg1) { - PosRot sp34; - s32 sp30; - s32 temp_ret; +/** + * Gets the Camera information for the water box the player is in. + * Returns -1 if the player is not in a water box, or does not have a swimming state. + * Returns -2 if there is no camera index for the water box. + * Returns the camera data index otherwise. + */ +s32 Camera_GetWaterBoxDataIdx(Camera* camera, f32* waterY) { + PosRot playerPosShape; + WaterBox* waterBox; + s32 ret; - func_8002EF44(&sp34, &camera->player->actor); - *arg1 = sp34.pos.y; + func_8002EF44(&playerPosShape, &camera->player->actor); + *waterY = playerPosShape.pos.y; - if (func_8004213C(camera->globalCtx, &camera->globalCtx->colCtx, sp34.pos.x, sp34.pos.z, arg1, &sp30) == 0) { - *arg1 = -32000.0f; + if (!func_8004213C(camera->globalCtx, &camera->globalCtx->colCtx, playerPosShape.pos.x, playerPosShape.pos.z, + waterY, &waterBox)) { + // player's position is not in a water box. + *waterY = BGCHECK_Y_MIN; return -1; } + if (!(camera->player->stateFlags1 & 0x8000000)) { - *arg1 = -32000.0f; + // player is not swimming + *waterY = BGCHECK_Y_MIN; return -1; } - temp_ret = func_80042538(&camera->globalCtx->colCtx, sp30); - if ((temp_ret <= 0) || (func_80042548(&camera->globalCtx->colCtx, sp30) <= 0)) { + ret = func_80042538(&camera->globalCtx->colCtx, waterBox); + if ((ret <= 0) || (func_80042548(&camera->globalCtx->colCtx, waterBox) <= 0)) { + // no camera data idx, or no CameraSettingType return -2; } - return temp_ret; + return ret; } -f32 func_800449AC(Camera* camera, Vec3f* arg1, s32* arg2) { - PosRot sp2C; - f32 sp28; - s32 sp24; - - func_8002EF44(&sp2C, &camera->player->actor); - sp28 = sp2C.pos.y; - - if (func_8004213C(camera->globalCtx, &camera->globalCtx->colCtx, arg1->x, arg1->z, &sp28, &sp24) == 0) { - return -32000.f; +/** + * Checks if `chkPos` is inside a waterbox. If there is no water box below `chkPos` + * or if `chkPos` is above the water surface, return BGCHECK_Y_MIN, output + * environment properites to `envProp` if `chkPos` is inside the waterbox. + */ +f32 Camera_GetWaterSurface(Camera* camera, Vec3f* chkPos, s32* envProp) { + PosRot playerPosRot; + f32 waterY; + WaterBox* waterBox; + + func_8002EF44(&playerPosRot, &camera->player->actor); + waterY = playerPosRot.pos.y; + + if (!func_8004213C(camera->globalCtx, &camera->globalCtx->colCtx, chkPos->x, chkPos->z, &waterY, &waterBox)) { + // chkPos is not within the x/z boundaries of a water box. + return BGCHECK_Y_MIN; } - if (sp28 < arg1->y) { - return -32000.f; + + if (waterY < chkPos->y) { + // the water's y position is below the check position + // the aka the position is NOT in the water. + return BGCHECK_Y_MIN; } - *arg2 = func_8004259C(&camera->globalCtx->colCtx, sp24); - return sp28; + *envProp = func_8004259C(&camera->globalCtx->colCtx, waterBox); + return waterY; } -s16 func_80044A74(Vec3f* arg0, Vec3f* arg1) { - return Math_atan2f(arg1->x - arg0->x, arg1->z - arg0->z) * (180.0f / M_PI) * (32767.5f / 180.0f) + 0.5f; +/** + * Calculates the angle between points `from` and `to` + */ +s16 Camera_XZAngle(Vec3f* to, Vec3f* from) { + return DEGF_TO_BINANG(RADF_TO_DEGF(Math_atan2f(from->x - to->x, from->z - to->z))); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80044ADC.s") +s16 func_80044ADC(Camera* camera, s16 yaw, s16 arg2) { + static f32 D_8015CE50; + static f32 D_8015CE54; + static CamColChk D_8015CE58; + Vec3f playerPos; + Vec3f rotatedPos; + Vec3f floorNorm; + f32 temp_f2; + s16 temp_s0; + s16 temp_s1; + f32 phi_f18; + f32 sinYaw; + f32 cosYaw; + u32 bgId; + f32 sp30; + f32 sp2C; + f32 phi_f16; + f32 playerHeight; + + sinYaw = Math_Sins(yaw); + cosYaw = Math_Coss(yaw); + playerHeight = Player_GetHeight(camera->player); + temp_f2 = PCT(OREG(19)) * playerHeight; + sp30 = PCT(OREG(17)) * playerHeight; + sp2C = PCT(OREG(18)) * playerHeight; + playerPos.x = camera->playerPosRot.pos.x; + playerPos.y = camera->playerGroundY + temp_f2; + playerPos.z = camera->playerPosRot.pos.z; + rotatedPos.x = playerPos.x + (sp30 * sinYaw); + rotatedPos.y = playerPos.y; + rotatedPos.z = playerPos.z + (sp30 * cosYaw); + if (arg2 || (camera->globalCtx->state.frames % 2) == 0) { + D_8015CE58.pos.x = playerPos.x + (sp2C * sinYaw); + D_8015CE58.pos.y = playerPos.y; + D_8015CE58.pos.z = playerPos.z + (sp2C * cosYaw); + Camera_BGCheckInfo(camera, &playerPos, &D_8015CE58); + if (arg2) { + D_8015CE50 = D_8015CE54 = camera->playerGroundY; + } + } else { + sp2C = OLib_Vec3fDistXZ(&playerPos, &D_8015CE58.pos); + D_8015CE58.pos.x += D_8015CE58.norm.x * 5.0f; + D_8015CE58.pos.y += D_8015CE58.norm.y * 5.0f; + D_8015CE58.pos.z += D_8015CE58.norm.z * 5.0f; + if (sp2C < sp30) { + sp30 = sp2C; + D_8015CE50 = D_8015CE54 = Camera_GetFloorYLayer(camera, &floorNorm, &D_8015CE58.pos, &bgId); + } else { + D_8015CE50 = Camera_GetFloorYLayer(camera, &floorNorm, &rotatedPos, &bgId); + D_8015CE54 = Camera_GetFloorYLayer(camera, &floorNorm, &D_8015CE58.pos, &bgId); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80044E68.s") + if (D_8015CE50 == BGCHECK_Y_MIN) { + D_8015CE50 = camera->playerGroundY; + } -f32 func_800450A4(Camera* camera, f32 arg1) { + if (D_8015CE54 == BGCHECK_Y_MIN) { + D_8015CE54 = D_8015CE50; + } + } + phi_f16 = PCT(OREG(20)) * (D_8015CE50 - camera->playerGroundY); + phi_f18 = (1.0f - PCT(OREG(20))) * (D_8015CE54 - camera->playerGroundY); + temp_s0 = DEGF_TO_BINANG(RADF_TO_DEGF(Math_atan2f(phi_f16, sp30))); + temp_s1 = DEGF_TO_BINANG(RADF_TO_DEGF(Math_atan2f(phi_f18, sp2C))); + return temp_s0 + temp_s1; +} + +Vec3f* Camera_CalcUpFromPitchYawRoll(Vec3f* dest, s16 pitch, s16 yaw, s16 roll) { + f32 sinPitch; + f32 cosPitch; + f32 sinYaw; + f32 cosYaw; + f32 sinNegRoll; + f32 cosNegRoll; + Vec3f spA4; + f32 pad; + f32 sp54; + f32 sp4C; + f32 cosPitchCosYawSinRoll; + f32 negSinPitch; + f32 temp_f10_2; + f32 cosPitchcosYaw; + f32 temp_f14; + f32 negSinPitchSinYaw; + f32 negSinPitchCosYaw; + f32 cosPitchSinYaw; + f32 temp_f4_2; + f32 temp_f6; + f32 temp_f8; + f32 temp_f8_2; + f32 temp_f8_3; + + sinPitch = Math_Sins(pitch); + cosPitch = Math_Coss(pitch); + sinYaw = Math_Sins(yaw); + cosYaw = Math_Coss(yaw); + negSinPitch = -sinPitch; + sinNegRoll = Math_Sins(-roll); + cosNegRoll = Math_Coss(-roll); + negSinPitchSinYaw = negSinPitch * sinYaw; + temp_f14 = 1.0f - cosNegRoll; + cosPitchSinYaw = cosPitch * sinYaw; + sp54 = SQ(cosPitchSinYaw); + sp4C = (cosPitchSinYaw * sinPitch) * temp_f14; + cosPitchcosYaw = cosPitch * cosYaw; + temp_f4_2 = ((1.0f - sp54) * cosNegRoll) + sp54; + cosPitchCosYawSinRoll = cosPitchcosYaw * sinNegRoll; + negSinPitchCosYaw = negSinPitch * cosYaw; + temp_f6 = (cosPitchcosYaw * cosPitchSinYaw) * temp_f14; + temp_f10_2 = sinPitch * sinNegRoll; + spA4.x = ((negSinPitchSinYaw * temp_f4_2) + (cosPitch * (sp4C - cosPitchCosYawSinRoll))) + + (negSinPitchCosYaw * (temp_f6 + temp_f10_2)); + sp54 = SQ(sinPitch); + temp_f4_2 = (sinPitch * cosPitchcosYaw) * temp_f14; + temp_f8_3 = cosPitchSinYaw * sinNegRoll; + temp_f8 = sp4C + cosPitchCosYawSinRoll; + spA4.y = ((negSinPitchSinYaw * temp_f8) + (cosPitch * (((1.0f - sp54) * cosNegRoll) + sp54))) + + (negSinPitchCosYaw * (temp_f4_2 - temp_f8_3)); + temp_f8_2 = temp_f6 - temp_f10_2; + spA4.z = ((negSinPitchSinYaw * temp_f8_2) + (cosPitch * (temp_f4_2 + temp_f8_3))) + + (negSinPitchCosYaw * (((1.0f - SQ(cosPitchcosYaw)) * cosNegRoll) + SQ(cosPitchcosYaw))); + *dest = spA4; + return dest; +} + +f32 Camera_ClampLERPScale(Camera* camera, f32 maxLERPScale) { f32 ret; - if (camera->unk_100 < (OREG(41) * 0.01f)) { - ret = OREG(41) * 0.01f; - } else if (arg1 <= camera->unk_100) { - ret = arg1; + if (camera->atLERPStepScale < PCT(R_AT_LERP_MIN)) { + ret = PCT(R_AT_LERP_MIN); + } else if (camera->atLERPStepScale >= maxLERPScale) { + ret = maxLERPScale; } else { - ret = OREG(42) * 0.01f * camera->unk_100; + ret = PCT(R_AT_LERP_SCALE) * camera->atLERPStepScale; } return ret; } -#ifdef NON_MATCHING void Camera_CopyModeValuesToPREG(Camera* camera, s16 mode) { + CameraModeValue* values; + CameraModeValue* valueP; s32 i; if (PREG(82)) { - osSyncPrintf("camera: res: stat (%d/%d/%d)\n", camera->unk_164, camera->setting, mode); + osSyncPrintf("camera: res: stat (%d/%d/%d)\n", camera->thisIdx, camera->setting, mode); } + + values = sCameraSettings[camera->setting].cameraModes[mode].values; + for (i = 0; i < sCameraSettings[camera->setting].cameraModes[mode].valueCnt; i++) { - CameraModeValue* phi_s0 = &sCameraSettings[camera->setting].cameraModes[mode].values[i]; - PREG(phi_s0->param) = phi_s0->val; + valueP = &values[i]; + PREG(valueP->param) = valueP->val; if (PREG(82)) { - osSyncPrintf("camera: res: PREG(%02d) = %d\n", phi_s0->param, phi_s0->val); + osSyncPrintf("camera: res: PREG(%02d) = %d\n", valueP->param, valueP->val); } } - camera->unk_15E = 0; + camera->animState = 0; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_CopyModeValuesToPREG.s") -#endif -#ifdef NON_MATCHING s32 Camera_CopyPREGToModeValues(Camera* camera) { - CameraModeValue* phi_s0; + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + CameraModeValue* valueP; s32 i; for (i = 0; i < sCameraSettings[camera->setting].cameraModes[camera->mode].valueCnt; i++) { - phi_s0 = &sCameraSettings[camera->setting].cameraModes[camera->mode].values[i]; - phi_s0->val = PREG(phi_s0->param); + valueP = &values[i]; + valueP->val = PREG(valueP->param); if (PREG(82)) { - osSyncPrintf("camera: res: %d = PREG(%02d)\n", phi_s0->val, phi_s0->param); + osSyncPrintf("camera: res: %d = PREG(%02d)\n", valueP->val, valueP->param); } } return true; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_CopyPREGToModeValues.s") -#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80045350.s") +#define SHRINKWIN_MASK (0xF000) +#define SHRINKWINVAL_MASK (0x7000) +#define SHRINKWIN_CURVAL (0x8000) +#define IFACE_ALPHA_MASK (0x0F00) -void* func_8004545C(Vec3f* arg0, s32 arg1, s32 arg2, struct_80043D18* arg3, struct_80043D18* arg4) { - Vec3f sp24; +void Camera_UpdateInterface(s16 flags) { + s16 interfaceAlpha; - if (func_800427B4(arg3->unk_18, arg4->unk_18, arg1, arg2, &sp24) == 0) { - osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: corner check no cross point %x %x\n" VT_RST, arg3, arg4); - *arg0 = arg3->unk_00; - return arg0; + if ((flags & SHRINKWIN_MASK) != SHRINKWIN_MASK) { + switch (flags & SHRINKWINVAL_MASK) { + case 0x1000: + sCameraShrinkWindowVal = 0x1A; + break; + case 0x2000: + sCameraShrinkWindowVal = 0x1B; + break; + case 0x3000: + sCameraShrinkWindowVal = 0x20; + break; + default: + sCameraShrinkWindowVal = 0; + break; + } + + if (flags & SHRINKWIN_CURVAL) { + ShrinkWindow_SetCurrentVal(sCameraShrinkWindowVal); + } else { + ShrinkWindow_SetVal(sCameraShrinkWindowVal); + } } - *arg0 = sp24; - return arg0; + if ((flags & IFACE_ALPHA_MASK) != IFACE_ALPHA_MASK) { + interfaceAlpha = (flags & IFACE_ALPHA_MASK) >> 8; + if (interfaceAlpha == 0) { + interfaceAlpha = 0x32; + } + if (interfaceAlpha != sCameraInterfaceAlpha) { + sCameraInterfaceAlpha = interfaceAlpha; + Interface_ChangeAlpha(sCameraInterfaceAlpha); + } + } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80045508.s") +Vec3f* Camera_BGCheckCorner(Vec3f* dst, Vec3f* linePointA, Vec3f* linePointB, CamColChk* pointAColChk, + CamColChk* pointBColChk) { + Vec3f closestPoint; -#ifdef NON_MATCHING -// CLOSE: stack is 4 bytes too big -f32 func_80045714(Vec3f* arg0, s16 arg1, s16 arg2, f32 arg3) { - VecSph sp1C; - f32 sp18; + if (!func_800427B4(pointAColChk->poly, pointBColChk->poly, linePointA, linePointB, &closestPoint)) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: corner check no cross point %x %x\n" VT_RST, pointAColChk, + pointBColChk); + *dst = pointAColChk->pos; + return dst; + } - OLib_Vec3fToVecSphGeo(&sp1C, arg0); - sp18 = Math_Coss(sp1C.pitch); - sp18 = fabsf(Math_Coss(arg1 - sp1C.yaw) * sp18); - return Math_Coss(arg1 - arg2) * (sp18 * arg3); + *dst = closestPoint; + return dst; } -#else -f32 func_80045714(Vec3f* a, s16 b, s16 c, f32 arg3); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80045714.s") -#endif -f32 OLib_ClampMaxDist(f32, f32); +/** + * Checks collision between at and eyeNext, if `checkEye` is set, if there is no collsion between + * eyeNext->at, then eye->at is also checked. + * Returns: + * 0 if no collsion is found between at->eyeNext + * 2 if the angle between the polys is between 60 degrees and 120 degrees + * 3 ? + * 6 if the angle between the polys is greater than 120 degrees + */ +s32 func_80045508(Camera* camera, VecSph* diffSph, CamColChk* eyeChk, CamColChk* atChk, s16 checkEye) { + Vec3f* at = &camera->at; + Vec3f* eye = &camera->eye; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f eyePos; + s32 atEyeBgId; + s32 eyeAtBgId; + s32 ret; + f32 cosEyeAt; -s32 func_800457A8(Camera* camera, VecSph* arg1, f32 arg2, s16 arg3) { - f32 unused; - Vec3f sp50; - Vec3f sp44; - s32 unused2; - PosRot* sp2C; - f32 temp_ret; + eyeChk->pos = camera->eyeNext; + + ret = 0; + + atEyeBgId = Camera_BGCheckInfo(camera, at, eyeChk); + if (atEyeBgId != 0) { + // collision found between at->eye + atChk->pos = camera->at; + + OLib_Vec3fToVecSphGeo(&eyeChk->sphNorm, &eyeChk->norm); + + if (eyeChk->sphNorm.pitch >= 0x2EE1) { + eyeChk->sphNorm.yaw = diffSph->yaw; + } + + eyeAtBgId = Camera_BGCheckInfo(camera, eyeNext, atChk); + + if (eyeAtBgId == 0) { + // no collision from eyeNext->at + if (checkEye & 1) { + + atChk->pos = *at; + eyePos = *eye; + + if (Camera_BGCheckInfo(camera, &eyePos, atChk) == 0) { + // no collision from eye->at + return 3; + } else if (eyeChk->poly == atChk->poly) { + // at->eye and eye->at is the same poly + return 3; + } + } else { + return 3; + } + } else if (eyeChk->poly == atChk->poly) { + // at->eyeNext and eyeNext->at is the same poly + return 3; + } + + OLib_Vec3fToVecSphGeo(&atChk->sphNorm, &atChk->norm); + + if (atChk->sphNorm.pitch >= 0x2EE1) { + atChk->sphNorm.yaw = BINANG_ROT180(diffSph->yaw); + } + + if (atEyeBgId != eyeAtBgId) { + // different bgIds for at->eye[Next] and eye[Next]->at + ret = 3; + } else { + cosEyeAt = Math3D_Cos(&eyeChk->norm, &atChk->norm); + if (cosEyeAt < -0.5f) { + ret = 6; + } else if (cosEyeAt > 0.5f) { + ret = 3; + } else { + ret = 2; + } + } + } + return ret; +} + +/** + * Calculates how much to adjust the camera at's y value when on a slope. + */ +f32 Camera_CalcSlopeYAdj(Vec3f* floorNorm, s16 playerYRot, s16 eyeAtYaw, f32 adjAmt) { + f32 tmp; + VecSph floorNormSph; + + OLib_Vec3fToVecSphGeo(&floorNormSph, floorNorm); - temp_ret = Player_GetCameraYOffset(camera->player); + tmp = Math_Coss(floorNormSph.pitch) * Math_Coss(playerYRot - floorNormSph.yaw); + return (fabsf(tmp) * adjAmt) * Math_Coss(playerYRot - eyeAtYaw); +} + +/** + * Calculates new at vector for the camera pointing in `eyeAtDir` + */ +s32 Camera_CalcAtDefault(Camera* camera, VecSph* eyeAtDir, f32 extraYOffset, s16 calcSlope) { + Vec3f* at = &camera->at; + Vec3f posOffsetTarget; + Vec3f atTarget; + s32 pad2; + PosRot* playerPosRot = &camera->playerPosRot; + f32 yOffset; + + yOffset = Player_GetHeight(camera->player); - sp50.x = 0.f; - sp50.z = 0.f; - sp50.y = temp_ret + arg2; + posOffsetTarget.x = 0.f; + posOffsetTarget.y = yOffset + extraYOffset; + posOffsetTarget.z = 0.f; - sp2C = &camera->playerPosRot; - if (arg3 != 0) { - sp50.y -= OLib_ClampMaxDist(func_80045714(&camera->unk_108, sp2C->rot.y, arg1->yaw, OREG(9)), temp_ret); + if (calcSlope) { + posOffsetTarget.y -= OLib_ClampMaxDist( + Camera_CalcSlopeYAdj(&camera->floorNorm, playerPosRot->rot.y, eyeAtDir->yaw, OREG(9)), yOffset); } - func_80043A3C(&sp50, &camera->unk_E4, camera->unk_CC.y, camera->unk_CC.x, 0.1f); - sp44.x = sp2C->pos.x + camera->unk_E4.x; - sp44.y = sp2C->pos.y + camera->unk_E4.y; - sp44.z = sp2C->pos.z + camera->unk_E4.z; - func_80043A3C(&sp44, &camera->at, camera->unk_100, camera->unk_100, 0.2f); + Camera_LERPCeilVec3f(&posOffsetTarget, &camera->posOffset, camera->yOffsetUpdateRate, camera->xzOffsetUpdateRate, + 0.1f); - return 1; + atTarget.x = playerPosRot->pos.x + camera->posOffset.x; + atTarget.y = playerPosRot->pos.y + camera->posOffset.y; + atTarget.z = playerPosRot->pos.z + camera->posOffset.z; + + Camera_LERPCeilVec3f(&atTarget, at, camera->atLERPStepScale, camera->atLERPStepScale, 0.2f); + + return true; } -#ifdef NON_MATCHING -// CLOSE: regalloc -s32 func_800458D4(Camera* camera, VecSph* arg1, f32 arg2, f32* arg3, s16 arg4) { +s32 func_800458D4(Camera* camera, VecSph* eyeAtDir, f32 arg2, f32* arg3, s16 arg4) { f32 phi_f2; - Vec3f sp60; - Vec3f sp54; - f32 temp_ret; - PosRot* temp_s1; - f32 sp48; + Vec3f posOffsetTarget; + Vec3f atTarget; + f32 eyeAtAngle; + PosRot* playerPosRot = &camera->playerPosRot; + f32 deltaY; s32 pad[2]; - sp60.y = Player_GetCameraYOffset(camera->player) + arg2; - sp60.x = 0.0f; - sp60.z = 0.0f; + posOffsetTarget.y = Player_GetHeight(camera->player) + arg2; + posOffsetTarget.x = 0.0f; + posOffsetTarget.z = 0.0f; - temp_s1 = &camera->playerPosRot; - if (arg4 != 0) { - sp60.y -= func_80045714(&camera->unk_108, temp_s1->rot.y, arg1->yaw, OREG(9)); + if (arg4) { + posOffsetTarget.y -= Camera_CalcSlopeYAdj(&camera->floorNorm, playerPosRot->rot.y, eyeAtDir->yaw, OREG(9)); } - sp48 = temp_s1->pos.y - *arg3; - temp_ret = Math_atan2f(sp48, OLib_Vec3fDistXZ(&camera->at, &camera->eye)); // f2 and f14 are swapped + deltaY = playerPosRot->pos.y - *arg3; + eyeAtAngle = Math_atan2f(deltaY, OLib_Vec3fDistXZ(&camera->at, &camera->eye)); - if (OREG(32) * (M_PI / 180) < temp_ret) { - phi_f2 = 1.0f - sinf(temp_ret - OREG(32) * (M_PI / 180)); - } else if (OREG(33) * (M_PI / 180) > temp_ret) { - phi_f2 = 1.0f - sinf(OREG(33) * (M_PI / 180) - temp_ret); + if (eyeAtAngle > DEGF_TO_RADF(OREG(32))) { + if (1) {} + phi_f2 = 1.0f - sinf(DEGF_TO_RADF(eyeAtAngle - OREG(32))); + } else if (eyeAtAngle < DEGF_TO_RADF(OREG(33))) { + phi_f2 = 1.0f - sinf(DEGF_TO_RADF(OREG(33)) - eyeAtAngle); } else { phi_f2 = 1.0f; } - sp60.y -= sp48 * phi_f2; - func_80043A3C(&sp60, &camera->unk_E4, OREG(29) * 0.01f, OREG(30) * 0.01f, 0.1f); + posOffsetTarget.y -= deltaY * phi_f2; + Camera_LERPCeilVec3f(&posOffsetTarget, &camera->posOffset, PCT(OREG(29)), PCT(OREG(30)), 0.1f); + + atTarget.x = playerPosRot->pos.x + camera->posOffset.x; + atTarget.y = playerPosRot->pos.y + camera->posOffset.y; + atTarget.z = playerPosRot->pos.z + camera->posOffset.z; - sp54.x = temp_s1->pos.x + camera->unk_E4.x; - sp54.y = temp_s1->pos.y + camera->unk_E4.y; - sp54.z = temp_s1->pos.z + camera->unk_E4.z; - func_80043A3C(&sp54, &camera->at, camera->unk_100, camera->unk_100, 0.2f); + Camera_LERPCeilVec3f(&atTarget, &camera->at, camera->atLERPStepScale, camera->atLERPStepScale, 0.2f); return 1; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800458D4.s") -#endif -s32 func_80045B08(Camera* camera, VecSph* arg1, f32 arg2, s16 arg3) { +s32 func_80045B08(Camera* camera, VecSph* eyeAtDir, f32 yExtra, s16 arg3) { f32 phi_f2; - Vec3f sp48; - Vec3f sp3C; + Vec3f posOffsetTarget; + Vec3f atTarget; f32 sp38; // unused f32 temp_ret; - PosRot* temp_s1; + PosRot* playerPosRot = &camera->playerPosRot; - sp48.y = Player_GetCameraYOffset(camera->player) + arg2; - sp48.x = 0.0f; - sp48.z = 0.0f; + posOffsetTarget.y = Player_GetHeight(camera->player) + yExtra; + posOffsetTarget.x = 0.0f; + posOffsetTarget.z = 0.0f; temp_ret = Math_Sins(arg3); - temp_s1 = &camera->playerPosRot; if (temp_ret < 0.0f) { - phi_f2 = Math_Coss(temp_s1->rot.y - arg1->yaw); + phi_f2 = Math_Coss(playerPosRot->rot.y - eyeAtDir->yaw); } else { - phi_f2 = -Math_Coss(temp_s1->rot.y - arg1->yaw); + phi_f2 = -Math_Coss(playerPosRot->rot.y - eyeAtDir->yaw); } - sp48.y -= temp_ret * phi_f2 * OREG(9); - func_80043A3C(&sp48, &camera->unk_E4, camera->unk_CC.y, camera->unk_CC.x, 0.1f); + posOffsetTarget.y -= temp_ret * phi_f2 * OREG(9); + Camera_LERPCeilVec3f(&posOffsetTarget, &camera->posOffset, camera->yOffsetUpdateRate, camera->xzOffsetUpdateRate, + 0.1f); - sp3C.x = temp_s1->pos.x + camera->unk_E4.x; - sp3C.y = temp_s1->pos.y + camera->unk_E4.y; - sp3C.z = temp_s1->pos.z + camera->unk_E4.z; - func_80043A3C(&sp3C, &camera->at, camera->unk_100, camera->unk_100, 0.2f); + atTarget.x = playerPosRot->pos.x + camera->posOffset.x; + atTarget.y = playerPosRot->pos.y + camera->posOffset.y; + atTarget.z = playerPosRot->pos.z + camera->posOffset.z; + Camera_LERPCeilVec3f(&atTarget, &camera->at, camera->atLERPStepScale, camera->atLERPStepScale, 0.2f); return 1; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80045C74.s") +/** + * Adjusts the camera's at position for Camera_Parallel1 + */ +s32 Camera_CalcAtForParallel(Camera* camera, VecSph* arg1, f32 arg2, f32* arg3, s16 arg4) { + Vec3f* at = &camera->at; + Vec3f posOffsetTarget; + Vec3f atTarget; + Vec3f* eye = &camera->eye; + PosRot* playerPosRot = &camera->playerPosRot; + f32 temp_f2; + f32 phi_f16; + f32 sp54; + f32 phi_f20; + f32 temp_f0_4; + + temp_f0_4 = Player_GetHeight(camera->player); + posOffsetTarget.x = 0.0f; + posOffsetTarget.y = temp_f0_4 + arg2; + posOffsetTarget.z = 0.0f; + + if (PREG(76) && arg4) { + posOffsetTarget.y -= Camera_CalcSlopeYAdj(&camera->floorNorm, playerPosRot->rot.y, arg1->yaw, OREG(9)); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800460A8.s") + if (camera->playerGroundY == camera->playerPosRot.pos.y || camera->player->actor.gravity > -0.1f || + camera->player->stateFlags1 & 0x200000) { + *arg3 = Camera_LERPCeilF(playerPosRot->pos.y, *arg3, PCT(OREG(43)), 0.1f); + phi_f20 = playerPosRot->pos.y - *arg3; + posOffsetTarget.y -= phi_f20; + Camera_LERPCeilVec3f(&posOffsetTarget, &camera->posOffset, camera->yOffsetUpdateRate, + camera->xzOffsetUpdateRate, 0.1f); + } else { + if (!PREG(75)) { + phi_f20 = playerPosRot->pos.y - *arg3; + sp54 = OLib_Vec3fDistXZ(at, &camera->eye); + phi_f16 = sp54; + Math_atan2f(phi_f20, sp54); + temp_f2 = Math_tanf(DEG_TO_RAD(camera->fov * 0.4f)) * phi_f16; + if (temp_f2 < phi_f20) { + *arg3 += phi_f20 - temp_f2; + phi_f20 = temp_f2; + } else if (phi_f20 < -temp_f2) { + *arg3 += phi_f20 + temp_f2; + phi_f20 = -temp_f2; + } + posOffsetTarget.y -= phi_f20; + } else { + phi_f20 = playerPosRot->pos.y - *arg3; + temp_f2 = Math_atan2f(phi_f20, OLib_Vec3fDistXZ(at, eye)); + if (DEG_TO_RAD(OREG(32)) < temp_f2) { + phi_f16 = 1 - sinf(temp_f2 - DEG_TO_RAD(OREG(32))); + } else if (temp_f2 < DEG_TO_RAD(OREG(33))) { + phi_f16 = 1 - sinf(DEG_TO_RAD(OREG(33)) - temp_f2); + } else { + phi_f16 = 1; + } + posOffsetTarget.y -= phi_f20 * phi_f16; + } + Camera_LERPCeilVec3f(&posOffsetTarget, &camera->posOffset, PCT(OREG(29)), PCT(OREG(30)), 0.1f); + camera->yOffsetUpdateRate = PCT(OREG(29)); + camera->xzOffsetUpdateRate = PCT(OREG(30)); + } + atTarget.x = playerPosRot->pos.x + camera->posOffset.x; + atTarget.y = playerPosRot->pos.y + camera->posOffset.y; + atTarget.z = playerPosRot->pos.z + camera->posOffset.z; + Camera_LERPCeilVec3f(&atTarget, at, camera->atLERPStepScale, camera->atLERPStepScale, 0.2f); + return 1; +} -s32 func_800466F8(Camera* camera, VecSph* arg1, f32 arg2, f32* arg3, s16 arg4) { - s32 phi_v0; - Vec3f sp60; - Vec3f sp54; - f32 sp50; // unused - f32 sp4C; // unused - f32 sp48; // I doubt this is a Vec3f - Player* sp44; - PosRot sp30; +/** + * Adjusts at position for Camera_Battle1 and Camera_KeepOn1 + */ +s32 Camera_CalcAtForLockOn(Camera* camera, VecSph* eyeAtDir, Vec3f* targetPos, f32 yOffset, f32 distance, + f32* yPosOffset, VecSph* outPlayerToTargetDir, s16 flags) { + Vec3f* at = &camera->at; + Vec3f tmpPos0; + Vec3f tmpPos1; + Vec3f lookFromOffset; + Vec3f* floorNorm = &camera->floorNorm; + VecSph playerToTargetDir; + PosRot* playerPosRot = &camera->playerPosRot; + f32 yPosDelta; + f32 phi_f16; + f32 eyeAtDist; + f32 temp_f0_2; + f32 playerHeight; + + playerHeight = Player_GetHeight(camera->player); + tmpPos0.x = 0.0f; + tmpPos0.y = playerHeight + yOffset; + tmpPos0.z = 0.0f; + if (PREG(76) && (flags & FLG_ADJSLOPE)) { + tmpPos0.y -= Camera_CalcSlopeYAdj(floorNorm, playerPosRot->rot.y, eyeAtDir->yaw, OREG(9)); + } + + // tmpPos1 is player's head + tmpPos1 = playerPosRot->pos; + tmpPos1.y += playerHeight; + OLib_Vec3fDiffToVecSphGeo(outPlayerToTargetDir, &tmpPos1, targetPos); + playerToTargetDir = *outPlayerToTargetDir; + if (distance < playerToTargetDir.r) { + playerToTargetDir.r = playerToTargetDir.r * PCT(OREG(38)); + } else { + // ratio of player's height off ground to player's height. + temp_f0_2 = OLib_ClampMaxDist((playerPosRot->pos.y - camera->playerGroundY) / playerHeight, 1.0f); + playerToTargetDir.r = + (playerToTargetDir.r * PCT(OREG(39))) - + (((PCT(OREG(39)) - PCT(OREG(38))) * playerToTargetDir.r) * (playerToTargetDir.r / distance)); + playerToTargetDir.r = playerToTargetDir.r - (playerToTargetDir.r * temp_f0_2) * temp_f0_2; + } + + if (flags & FLG_OFFGROUND) { + playerToTargetDir.r *= 0.2f; + camera->xzOffsetUpdateRate = camera->yOffsetUpdateRate = .01f; + } + + OLib_VecSphGeoToVec3f(&lookFromOffset, &playerToTargetDir); + + if (PREG(89)) { + osSyncPrintf("%f (%f %f %f) %f\n", playerToTargetDir.r / distance, lookFromOffset.x, lookFromOffset.y, + lookFromOffset.z, camera->atLERPStepScale); + } - sp48 = Player_GetCameraYOffset(camera->player); - sp44 = camera->player; - func_8002EF44(&sp30, sp44->rideActor); + tmpPos0.x = tmpPos0.x + lookFromOffset.x; + tmpPos0.y = tmpPos0.y + lookFromOffset.y; + tmpPos0.z = tmpPos0.z + lookFromOffset.z; - if ((*(s32*)((s32)(sp44->rideActor) + 0x1F0) & 4) != 0) { // actors aren't this big, is rideActor a different type? - phi_v0 = 1; + if (camera->playerGroundY == camera->playerPosRot.pos.y || camera->player->actor.gravity > -0.1f || + camera->player->stateFlags1 & 0x200000) { + *yPosOffset = Camera_LERPCeilF(playerPosRot->pos.y, *yPosOffset, PCT(OREG(43)), 0.1f); + yPosDelta = playerPosRot->pos.y - *yPosOffset; + tmpPos0.y -= yPosDelta; + Camera_LERPCeilVec3f(&tmpPos0, &camera->posOffset, camera->yOffsetUpdateRate, camera->xzOffsetUpdateRate, 0.1f); } else { - phi_v0 = 0; + if (!(flags & FLG_OFFGROUND)) { + yPosDelta = playerPosRot->pos.y - *yPosOffset; + eyeAtDist = OLib_Vec3fDistXZ(at, &camera->eye); + phi_f16 = eyeAtDist; + Math_atan2f(yPosDelta, eyeAtDist); + temp_f0_2 = Math_tanf(DEG_TO_RAD(camera->fov * 0.4f)) * phi_f16; + if (temp_f0_2 < yPosDelta) { + *yPosOffset = *yPosOffset + (yPosDelta - temp_f0_2); + yPosDelta = temp_f0_2; + } else if (yPosDelta < -temp_f0_2) { + *yPosOffset = *yPosOffset + (yPosDelta + temp_f0_2); + yPosDelta = -temp_f0_2; + } + tmpPos0.y = tmpPos0.y - yPosDelta; + } else { + yPosDelta = playerPosRot->pos.y - *yPosOffset; + temp_f0_2 = Math_atan2f(yPosDelta, OLib_Vec3fDistXZ(at, &camera->eye)); + + if (temp_f0_2 > DEG_TO_RAD(OREG(32))) { + phi_f16 = 1.0f - sinf(temp_f0_2 - DEG_TO_RAD(OREG(32))); + } else if (temp_f0_2 < DEG_TO_RAD(OREG(33))) { + phi_f16 = 1.0f - sinf(DEG_TO_RAD(OREG(33)) - temp_f0_2); + } else { + phi_f16 = 1.0f; + } + tmpPos0.y -= (yPosDelta * phi_f16); + } + + Camera_LERPCeilVec3f(&tmpPos0, &camera->posOffset, PCT(OREG(29)), PCT(OREG(30)), 0.1f); + camera->yOffsetUpdateRate = PCT(OREG(29)); + camera->xzOffsetUpdateRate = PCT(OREG(30)); } - if (phi_v0 != 0) { - sp30.pos.y -= 49.f; - *arg3 = func_8004389C(sp30.pos.y, *arg3, 0.1f, 0.2f); - camera->unk_100 = func_8004389C(0.4f, camera->unk_100, 0.2f, 0.02f); + tmpPos1.x = playerPosRot->pos.x + camera->posOffset.x; + tmpPos1.y = playerPosRot->pos.y + camera->posOffset.y; + tmpPos1.z = playerPosRot->pos.z + camera->posOffset.z; + Camera_LERPCeilVec3f(&tmpPos1, at, camera->atLERPStepScale, camera->atLERPStepScale, 0.2f); + return 1; +} + +s32 Camera_CalcAtForHorse(Camera* camera, VecSph* eyeAtDir, f32 yOffset, f32* yPosOffset, s16 calcSlope) { + Vec3f* at = &camera->at; + Vec3f posOffsetTarget; + Vec3f atTarget; + s32 pad; + s32 pad2; + f32 playerHeight; + Player* player; + PosRot horsePosRot; + + playerHeight = Player_GetHeight(camera->player); + player = camera->player; + func_8002EF44(&horsePosRot, player->rideActor); + + if (EN_HORSE_CHECK_5((EnHorse*)player->rideActor)) { + horsePosRot.pos.y -= 49.f; + *yPosOffset = Camera_LERPCeilF(horsePosRot.pos.y, *yPosOffset, 0.1f, 0.2f); + camera->atLERPStepScale = Camera_LERPCeilF(0.4f, camera->atLERPStepScale, 0.2f, 0.02f); } else { - *arg3 = func_8004389C(sp30.pos.y, *arg3, 0.5f, 0.2f); + *yPosOffset = Camera_LERPCeilF(horsePosRot.pos.y, *yPosOffset, 0.5f, 0.2f); } - sp60.x = 0.0f; - sp60.z = 0.0f; - sp60.y = sp48 + arg2; + posOffsetTarget.x = 0.0f; + posOffsetTarget.y = playerHeight + yOffset; + posOffsetTarget.z = 0.0f; - if (arg4 != 0) { - sp60.y -= func_80045714(&camera->unk_108, camera->playerPosRot.rot.y, arg1->yaw, OREG(9)); + if (calcSlope != 0) { + posOffsetTarget.y -= + Camera_CalcSlopeYAdj(&camera->floorNorm, camera->playerPosRot.rot.y, eyeAtDir->yaw, OREG(9)); } - func_80043A3C(&sp60, &camera->unk_E4, camera->unk_CC.y, camera->unk_CC.x, 0.1f); + Camera_LERPCeilVec3f(&posOffsetTarget, &camera->posOffset, camera->yOffsetUpdateRate, camera->xzOffsetUpdateRate, + 0.1f); - sp54.x = camera->unk_E4.x + sp30.pos.x; - sp54.y = camera->unk_E4.y + sp30.pos.y; - sp54.z = camera->unk_E4.z + sp30.pos.z; - func_80043A3C(&sp54, &camera->at, camera->unk_100, camera->unk_100, 0.2f); + atTarget.x = camera->posOffset.x + horsePosRot.pos.x; + atTarget.y = camera->posOffset.y + horsePosRot.pos.y; + atTarget.z = camera->posOffset.z + horsePosRot.pos.z; + Camera_LERPCeilVec3f(&atTarget, at, camera->atLERPStepScale, camera->atLERPStepScale, 0.2f); return 1; } -void func_800468CC(Camera* camera, f32 arg1, f32 arg2, f32 arg3) { - f32 sp1C; - f32 phi_f12; +f32 Camera_LERPClampDist(Camera* camera, f32 dist, f32 min, f32 max) { + f32 distTarget; + f32 rUpdateRateInvTarget; - if (arg1 < arg2) { - sp1C = arg2; - phi_f12 = OREG(6); - } else if (arg3 < arg1) { - sp1C = arg3; - phi_f12 = OREG(6); + if (dist < min) { + distTarget = min; + rUpdateRateInvTarget = OREG(6); + } else if (dist > max) { + distTarget = max; + rUpdateRateInvTarget = OREG(6); } else { - sp1C = arg1; - phi_f12 = 1.0f; + distTarget = dist; + rUpdateRateInvTarget = 1.0f; } - camera->unk_C0.x = func_8004389C(phi_f12, camera->unk_C0.x, OREG(25) * 0.01f, 0.1f); - func_8004389C(sp1C, camera->dist, 1.f / camera->unk_C0.x, 0.2f); + camera->rUpdateRateInv = Camera_LERPCeilF(rUpdateRateInvTarget, camera->rUpdateRateInv, PCT(OREG(25)), 0.1f); + return Camera_LERPCeilF(distTarget, camera->dist, 1.f / camera->rUpdateRateInv, 0.2f); } -f32 func_800469C0(Camera* camera, f32 arg1, f32 arg2, f32 arg3, s16 arg4) { - f32 sp1C; - f32 phi_f12; +f32 Camera_ClampDist(Camera* camera, f32 dist, f32 minDist, f32 maxDist, s16 timer) { + f32 distTarget; + f32 rUpdateRateInvTarget; - if (arg1 < arg2) { - sp1C = arg2; + if (dist < minDist) { + distTarget = minDist; - if (arg4 != 0) { - phi_f12 = OREG(6) * 0.5f; - } else { - phi_f12 = OREG(6); - } - } else if (arg3 < arg1) { - sp1C = arg3; + rUpdateRateInvTarget = timer != 0 ? OREG(6) * 0.5f : OREG(6); + } else if (maxDist < dist) { + distTarget = maxDist; - if (arg4 != 0) { - phi_f12 = OREG(6) * 0.5f; - } else { - phi_f12 = OREG(6); - } + rUpdateRateInvTarget = timer != 0 ? OREG(6) * 0.5f : OREG(6); } else { - sp1C = arg1; + distTarget = dist; - if (arg4 != 0) { - phi_f12 = OREG(6); - } else { - phi_f12 = 1.0f; - } + rUpdateRateInvTarget = timer != 0 ? OREG(6) : 1.0f; } - camera->unk_C0.x = func_8004389C(phi_f12, camera->unk_C0.x, OREG(25) * 0.01f, 0.1f); - return func_8004389C(sp1C, camera->dist, 1.f / camera->unk_C0.x, 0.2f); + camera->rUpdateRateInv = Camera_LERPCeilF(rUpdateRateInvTarget, camera->rUpdateRateInv, PCT(OREG(25)), 0.1f); + return Camera_LERPCeilF(distTarget, camera->dist, 1.0f / camera->rUpdateRateInv, 0.2f); } -#ifdef NON_MATCHING -// lots of regalloc and stack issues, but that's it -void func_80046B44(Camera* camera, s16 arg1, s16 arg2, s16 arg3) { - s32 pad[2]; - s16 sp1C; - s16 phi_v1; - s16 phi_v0; +s16 Camera_CalcDefaultPitch(Camera* camera, s16 arg1, s16 arg2, s16 arg3) { + f32 pad; f32 phi_a2; + f32 t; + s16 phi_v0; + s16 phi_v1; + s16 sp1C; phi_v1 = ABS(arg1); phi_v0 = arg3 > 0 ? (s16)(Math_Coss(arg3) * arg3) : arg3; sp1C = arg2 - phi_v0; + if (ABS(sp1C) < phi_v1) { - phi_a2 = (1.0f / camera->unk_C0.y) * 3.0f; + phi_a2 = (1.0f / camera->pitchUpdateRateInv) * 3.0f; } else { - phi_a2 = (1.0f / camera->unk_C0.y) * func_800437F0(0.8f, 1.0f - phi_v0 * (1.0f / OREG(5))); + t = phi_v1 * (1.0f / R_CAM_MAX_PHI); + pad = Camera_InterpolateCurve(0.8f, 1.0f - t); + phi_a2 = (1.0f / camera->pitchUpdateRateInv) * pad; } - func_8004391C(sp1C, arg1, phi_a2, 0xa); + return Camera_LERPCeilS(sp1C, arg1, phi_a2, 0xA); } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80046B44.s") -#endif -#ifdef NON_MATCHING -// stack, regalloc, tiny bit of ordering -s16 func_80046CB4(Camera* camera, s16 arg1, s16 arg2, f32 arg3, f32 arg4) { - f32 sp34; - s16 sp1C; - f32 temp_ret; - f32 phi_f14; - s16 temp; - - if (camera->unk_D8 > 0.001f) { - temp = arg1 - 0x7FFF; - sp1C = arg2 - temp; - phi_f14 = (s16)(sp1C - 0x7FFF) * (1.0f / 32767.0f); +s16 Camera_CalcDefaultYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 accel) { + f32 velocity; + s16 angDelta; + f32 updSpeed; + f32 speedT; + f32 velFactor; + f32 yawUpdRate; + + if (camera->xzSpeed > 0.001f) { + angDelta = target - BINANG_ROT180(cur); + speedT = BINANG_ROT180(angDelta) * COLPOLY_NORM_FRAC; } else { - temp = arg1 - 0x7FFF; - sp1C = arg2 - temp; - phi_f14 = OREG(48) * 0.01f; + angDelta = target - BINANG_ROT180(cur); + speedT = PCT(OREG(48)); } - temp_ret = func_800437F0(arg3, phi_f14); - sp34 = ((1.0f - temp_ret) * arg4) + temp_ret; - if (sp34 < 0.0f) { - sp34 = 0.0f; + + updSpeed = Camera_InterpolateCurve(arg3, speedT); + + velocity = updSpeed + (1.0f - updSpeed) * accel; + + if (velocity < 0.0f) { + velocity = 0.0f; } - // ordering stuff here - return arg1 + (s16)(sp1C * sp34 * (1.0f / camera->unk_C0.z) * func_800437F0(0.5f, camera->unk_E0)) + arg1; + + velFactor = Camera_InterpolateCurve(0.5f, camera->speedRatio); + yawUpdRate = 1.0f / camera->yawUpdateRateInv; + return cur + (s16)(angDelta * velocity * velFactor * yawUpdRate); } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80046CB4.s") -#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80046E20.s") +void func_80046E20(Camera* camera, VecSph* eyeAdjustment, f32 minDist, f32 arg3, f32* arg4, SwingAnimation* anim) { + static CamColChk atEyeColChk; + static CamColChk eyeAtColChk; + static CamColChk newEyeColChk; + Vec3f* eye = &camera->eye; + s32 temp_v0; + Vec3f* at = &camera->at; + Vec3f peekAroundPoint; + Vec3f* eyeNext = &camera->eyeNext; + f32 temp_f0; + VecSph newEyeAdjustment; + VecSph sp40; -s32 func_80047394(Camera* camera) { - return 1; + temp_v0 = func_80045508(camera, eyeAdjustment, &atEyeColChk, &eyeAtColChk, !anim->unk_18); + + switch (temp_v0) { + case 1: + case 2: + // angle between polys is between 60 and 120 degrees. + Camera_BGCheckCorner(&anim->collisionClosePoint, at, eyeNext, &atEyeColChk, &eyeAtColChk); + peekAroundPoint.x = anim->collisionClosePoint.x + (atEyeColChk.norm.x + eyeAtColChk.norm.x); + peekAroundPoint.y = anim->collisionClosePoint.y + (atEyeColChk.norm.y + eyeAtColChk.norm.y); + peekAroundPoint.z = anim->collisionClosePoint.z + (atEyeColChk.norm.z + eyeAtColChk.norm.z); + + temp_f0 = OLib_Vec3fDist(at, &atEyeColChk.pos); + *arg4 = temp_f0 > minDist ? 1.0f : temp_f0 / minDist; + + anim->swingUpdateRate = PCT(OREG(10)); + anim->unk_18 = 1; + anim->atEyePoly = eyeAtColChk.poly; + OLib_Vec3fDiffToVecSphGeo(&newEyeAdjustment, at, &peekAroundPoint); + + newEyeAdjustment.r = eyeAdjustment->r; + Camera_Vec3fVecSphGeoAdd(eye, at, &newEyeAdjustment); + newEyeColChk.pos = *eye; + if (Camera_BGCheckInfo(camera, at, &newEyeColChk) == 0) { + // no collision found between at->newEyePos + newEyeAdjustment.yaw += BINANG_SUB(eyeAdjustment->yaw, newEyeAdjustment.yaw) >> 1; + newEyeAdjustment.pitch += BINANG_SUB(eyeAdjustment->pitch, newEyeAdjustment.pitch) >> 1; + Camera_Vec3fVecSphGeoAdd(eye, at, &newEyeAdjustment); + if (atEyeColChk.sphNorm.pitch < 0x2AA8) { + // ~ 60 degrees + anim->unk_16 = newEyeAdjustment.yaw; + anim->unk_14 = newEyeAdjustment.pitch; + } else { + anim->unk_16 = eyeAdjustment->yaw; + anim->unk_14 = eyeAdjustment->pitch; + } + peekAroundPoint.x = anim->collisionClosePoint.x - (atEyeColChk.norm.x + eyeAtColChk.norm.x); + peekAroundPoint.y = anim->collisionClosePoint.y - (atEyeColChk.norm.y + eyeAtColChk.norm.y); + peekAroundPoint.z = anim->collisionClosePoint.z - (atEyeColChk.norm.z + eyeAtColChk.norm.z); + OLib_Vec3fDiffToVecSphGeo(&newEyeAdjustment, at, &peekAroundPoint); + newEyeAdjustment.r = eyeAdjustment->r; + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &newEyeAdjustment); + break; + } + + camera->eye = newEyeColChk.pos; + atEyeColChk = newEyeColChk; + + case 3: + case 6: + if (anim->unk_18 != 0) { + anim->swingUpdateRateTimer = OREG(52); + anim->unk_18 = 0; + *eyeNext = *eye; + } + + temp_f0 = OLib_Vec3fDist(at, &atEyeColChk.pos); + *arg4 = temp_f0 > minDist ? 1.0f : temp_f0 / minDist; + + anim->swingUpdateRate = *arg4 * arg3; + + Camera_Vec3fTranslateByUnitVector(eye, &atEyeColChk.pos, &atEyeColChk.norm, 1.0f); + anim->atEyePoly = NULL; + if (temp_f0 < OREG(21)) { + sp40.yaw = eyeAdjustment->yaw; + sp40.pitch = Math_Sins(atEyeColChk.sphNorm.pitch + 0x3FFF) * 16380.0f; + sp40.r = (OREG(21) - temp_f0) * PCT(OREG(22)); + Camera_Vec3fVecSphGeoAdd(eye, eye, &sp40); + } + break; + default: + if (anim->unk_18 != 0) { + anim->swingUpdateRateTimer = OREG(52); + *eyeNext = *eye; + anim->unk_18 = 0; + } + anim->swingUpdateRate = arg3; + anim->atEyePoly = NULL; + eye->x = atEyeColChk.pos.x + atEyeColChk.norm.x; + eye->y = atEyeColChk.pos.y + atEyeColChk.norm.y; + eye->z = atEyeColChk.pos.z + atEyeColChk.norm.z; + break; + } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Normal1.s") +s32 Camera_Noop(Camera* camera) { + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Normal2.s") -#define NEXTSETTING ((values++)->val) -#ifdef NON_MATCHING -s32 Camera_Normal3(Camera* camera) { +s32 Camera_Normal1(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + f32 spA0; + f32 sp9C; f32 sp98; f32 sp94; - f32 sp90; - f32 sp8C; - VecSph sp84; - VecSph sp7C; - VecSph sp74; - Vec3f* sp48; - Vec3f* sp44; - Vec3f* sp40; - f32 temp_f0; - f32 temp_f0_3; - f32 temp_f16; - f32 temp_f16_2; - f32 temp_f2; - f32 temp_f6; - s16 temp_t3; - s16 temp_v0_2; - s16 temp_v0_3; - s16 temp_v0_4; - s32 temp_a0; - s16 phi_v1; - s32 phi_v1_2; - s32 phi_a0; - CameraModeValue* values; - Normal3* normal3 = &camera->unk_00.normal3; - Normal3_Unk20* unk20; - PosRot* playerPostRot; + Vec3f sp88; + s16 wiggleAdj; + s16 t; + VecSph eyeAdjustment; + VecSph atEyeGeo; + VecSph atEyeNextGeo; + PosRot* playerPosRot = &camera->playerPosRot; + Normal1* norm1 = (Normal1*)camera->paramData; + Normal1Anim* anim = &norm1->anim; + f32 playerHeight; + f32 rate = 0.1f; + + playerHeight = Player_GetHeight(camera->player); + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM) - PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight)); + sp94 = yNormal * PCT(playerHeight); + + norm1->yOffset = NEXTSETTING * sp94; + norm1->distMin = NEXTSETTING * sp94; + norm1->distMax = NEXTSETTING * sp94; + norm1->pitchTarget = DEGF_TO_BINANG(NEXTSETTING); + norm1->unk_0C = NEXTSETTING; + norm1->unk_10 = NEXTSETTING; + norm1->unk_14 = NEXTPCT; + norm1->fovTarget = NEXTSETTING; + norm1->atLERPScaleMax = NEXTPCT; + norm1->interfaceFlags = NEXTSETTING; + } - temp_f2 = Player_GetCameraYOffset(camera->player); - if ((((camera->unk_15E == 0) || (camera->unk_15E == 0xA)) || (camera->unk_15E == 0x14)) || QREG(0)) { - temp_f2 *= 0.01f; - values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; - // temp_t2 = sCameraSettings[camera->setting].unk_00 + (camera->mode * 8); - // temp_t3 = *temp_t2->unk4; - // temp_v0 = temp_t2->unk4 + 0x20; - normal3->unk_00 = temp_f2 * NEXTSETTING; - // normal3->unk_00 = (f32) ((f32) temp_t3 * temp_f2); + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } - normal3->unk_04 = temp_f2 * NEXTSETTING; - // normal3->unk_04 = (f32) ((f32) temp_v0->unk-1C * temp_f2); + sCameraInterfaceFlags = norm1->interfaceFlags; - normal3->unk_08 = temp_f2 * NEXTSETTING; - // normal3->unk_08 = (f32) ((f32) temp_v0->unk-18 * temp_f2); + OLib_Vec3fDiffToVecSphGeo(&atEyeGeo, at, eye); + OLib_Vec3fDiffToVecSphGeo(&atEyeNextGeo, at, eyeNext); - normal3->unk_1C = (65535.0f / 360.0f) * NEXTSETTING + 0.5f; - // normal3->unk_1C = (s16) (s32) (((f32) temp_v0->unk-14 * 182.0416717529297f) + 0.5f); + switch (camera->animState) { + case 0x14: + camera->yawUpdateRateInv = OREG(27); + camera->pitchUpdateRateInv = OREG(27); + case 0: + case 0xA: + case 0x19: + anim->swing.atEyePoly = NULL; + anim->slopePitchAdj = 0; + anim->unk_28 = 0xA; + anim->swing.unk_16 = anim->swing.unk_14 = anim->swing.unk_18 = 0; + anim->swing.swingUpdateRate = norm1->unk_0C; + anim->yOffset = camera->playerPosRot.pos.y; + anim->unk_20 = camera->xzSpeed; + anim->swing.swingUpdateRateTimer = 0; + anim->swingYawTarget = atEyeGeo.yaw; + sUpdateCameraDirection = 0; + anim->startSwingTimer = OREG(50) + OREG(51); + break; + default: + break; + } + + camera->animState = 1; + sUpdateCameraDirection = 1; + + if (anim->unk_28 != 0) { + anim->unk_28--; + } + + if (camera->xzSpeed > 0.001f) { + anim->startSwingTimer = OREG(50) + OREG(51); + } else if (anim->startSwingTimer > 0) { + if (anim->startSwingTimer > OREG(50)) { + anim->swingYawTarget = atEyeGeo.yaw + (BINANG_SUB(BINANG_ROT180(camera->playerPosRot.rot.y), atEyeGeo.yaw) / + anim->startSwingTimer); + } + anim->startSwingTimer--; + } + + spA0 = camera->speedRatio * PCT(OREG(25)); + sp9C = camera->speedRatio * PCT(OREG(26)); + sp98 = anim->swing.unk_18 != 0 ? PCT(OREG(25)) : spA0; + + sp94 = (camera->xzSpeed - anim->unk_20) * (0.3333329856395721435546875f); + if (sp94 > 1.0f) { + sp94 = 1.0f; + } + if (sp94 > -1.0f) { + sp94 = -1.0f; + } + + anim->unk_20 = camera->xzSpeed; + + if (anim->swing.swingUpdateRateTimer != 0) { + camera->yawUpdateRateInv = + Camera_LERPCeilF(anim->swing.swingUpdateRate + (f32)(anim->swing.swingUpdateRateTimer * 2), + camera->yawUpdateRateInv, sp98, rate); + camera->pitchUpdateRateInv = + Camera_LERPCeilF((f32)R_CAM_DEFA_PHI_UPDRATE + (f32)(anim->swing.swingUpdateRateTimer * 2), + camera->pitchUpdateRateInv, sp9C, rate); + anim->swing.swingUpdateRateTimer--; + } else { + camera->yawUpdateRateInv = + Camera_LERPCeilF(anim->swing.swingUpdateRate - ((OREG(49) * 0.01f) * anim->swing.swingUpdateRate * sp94), + camera->yawUpdateRateInv, sp98, rate); + camera->pitchUpdateRateInv = Camera_LERPCeilF(R_CAM_DEFA_PHI_UPDRATE, camera->pitchUpdateRateInv, sp9C, rate); + } - normal3->unk_0C = NEXTSETTING; - // normal3->unk_0C = (f32) temp_v0->unk-10; + camera->pitchUpdateRateInv = Camera_LERPCeilF(R_CAM_DEFA_PHI_UPDRATE, camera->pitchUpdateRateInv, sp9C, rate); + camera->xzOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(2)), camera->xzOffsetUpdateRate, spA0, rate); + camera->yOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(3)), camera->yOffsetUpdateRate, sp9C, rate); + camera->fovUpdateRate = Camera_LERPCeilF(PCT(OREG(4)), camera->yOffsetUpdateRate, camera->speedRatio * 0.05f, rate); - normal3->unk_10 = NEXTSETTING; - // normal3->unk_10 = (f32) temp_v0->unk-C; + if (norm1->interfaceFlags & 1) { + t = func_80044ADC(camera, BINANG_ROT180(atEyeGeo.yaw), 0); + sp9C = ((1.0f / norm1->unk_10) * 0.5f) * (1.0f - camera->speedRatio); + anim->slopePitchAdj = Camera_LERPCeilS(t, anim->slopePitchAdj, ((1.0f / norm1->unk_10) * 0.5f) + sp9C, 0xF); + } else { + anim->slopePitchAdj = 0; + if (camera->playerGroundY == camera->playerPosRot.pos.y) { + anim->yOffset = camera->playerPosRot.pos.y; + } + } - normal3->unk_14 = NEXTSETTING; - // normal3->unk_14 = (f32) temp_v0->unk-8; + spA0 = ((anim->swing.unk_18 != 0) && (norm1->yOffset > -40.0f)) + ? (sp9C = Math_Sins(anim->swing.unk_14), ((-40.0f * sp9C) + (norm1->yOffset * (1.0f - sp9C)))) + : norm1->yOffset; - normal3->unk_18 = NEXTSETTING * 0.01f; - // normal3->unk_18 = (f32) ((f32) temp_v0->unk-4 * 0.009999999776482582f); + if (norm1->interfaceFlags & 0x80) { + func_800458D4(camera, &atEyeNextGeo, spA0, &anim->yOffset, norm1->interfaceFlags & 1); + } else if (norm1->interfaceFlags & 0x20) { + func_80045B08(camera, &atEyeNextGeo, spA0, anim->slopePitchAdj); + } else { + Camera_CalcAtDefault(camera, &atEyeNextGeo, spA0, norm1->interfaceFlags & 1); + } - normal3->unk_1E = NEXTSETTING; - // normal3->unk_1E = (s16) temp_v0->unk0; + OLib_Vec3fDiffToVecSphGeo(&eyeAdjustment, at, eyeNext); + + camera->dist = eyeAdjustment.r = + Camera_ClampDist(camera, eyeAdjustment.r, norm1->distMin, norm1->distMax, anim->unk_28); + + if (anim->startSwingTimer <= 0) { + eyeAdjustment.pitch = atEyeNextGeo.pitch; + eyeAdjustment.yaw = + Camera_LERPCeilS(anim->swingYawTarget, atEyeNextGeo.yaw, 1.0f / camera->yawUpdateRateInv, 0xA); + } else if (anim->swing.unk_18 != 0) { + eyeAdjustment.yaw = + Camera_LERPCeilS(anim->swing.unk_16, atEyeNextGeo.yaw, 1.0f / camera->yawUpdateRateInv, 0xA); + eyeAdjustment.pitch = + Camera_LERPCeilS(anim->swing.unk_14, atEyeNextGeo.pitch, 1.0f / camera->yawUpdateRateInv, 0xA); + } else { + // rotate yaw to follow player. + eyeAdjustment.yaw = + Camera_CalcDefaultYaw(camera, atEyeNextGeo.yaw, camera->playerPosRot.rot.y, norm1->unk_14, sp94); + eyeAdjustment.pitch = + Camera_CalcDefaultPitch(camera, atEyeNextGeo.pitch, norm1->pitchTarget, anim->slopePitchAdj); + } + + // set eyeAdjustment pitch from 79.65 degrees to -85 degrees + if (eyeAdjustment.pitch > 0x38A4) { + eyeAdjustment.pitch = 0x38A4; + } + if (eyeAdjustment.pitch < -0x3C8C) { + eyeAdjustment.pitch = -0x3C8C; } - if (QREG(0)) { + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeAdjustment); + if ((camera->status == CAM_STAT_ACTIVE) && (!(norm1->interfaceFlags & 0x10))) { + anim->swingYawTarget = BINANG_ROT180(camera->playerPosRot.rot.y); + if (anim->startSwingTimer > 0) { + func_80046E20(camera, &eyeAdjustment, norm1->distMin, norm1->unk_0C, &sp98, &anim->swing); + } else { + sp88 = *eyeNext; + anim->swing.swingUpdateRate = camera->yawUpdateRateInv = norm1->unk_0C * 2.0f; + if (Camera_BGCheck(camera, at, &sp88)) { + anim->swingYawTarget = atEyeNextGeo.yaw; + anim->startSwingTimer = -1; + } else { + *eye = *eyeNext; + } + anim->swing.unk_18 = 0; + } + + if (anim->swing.unk_18 != 0) { + camera->inputDir.y = + Camera_LERPCeilS(camera->inputDir.y + BINANG_SUB(BINANG_ROT180(anim->swing.unk_16), camera->inputDir.y), + camera->inputDir.y, 1.0f - (0.99f * sp98), 0xA); + } + + if (norm1->interfaceFlags & 4) { + camera->inputDir.x = -atEyeGeo.pitch; + camera->inputDir.y = BINANG_ROT180(atEyeGeo.yaw); + camera->inputDir.z = 0; + } else { + OLib_Vec3fDiffToVecSphGeo(&eyeAdjustment, eye, at); + camera->inputDir.x = eyeAdjustment.pitch; + camera->inputDir.y = eyeAdjustment.yaw; + camera->inputDir.z = 0; + } + + // crit wiggle + if (gSaveContext.health <= 16 && ((camera->globalCtx->state.frames % 256) == 0)) { + wiggleAdj = Math_Rand_ZeroOne() * 10000.0f; + camera->inputDir.y = wiggleAdj + camera->inputDir.y; + } + } else { + anim->swing.swingUpdateRate = norm1->unk_0C; + anim->swing.unk_18 = 0; + sUpdateCameraDirection = 0; + *eye = *eyeNext; + } + + spA0 = (gSaveContext.health <= 16 ? 0.8f : 1.0f); + camera->fov = Camera_LERPCeilF(norm1->fovTarget * spA0, camera->fov, camera->fovUpdateRate, 1.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5f, 0xA); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, norm1->atLERPScaleMax); + return 1; +} + +s32 Camera_Normal2(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + CamColChk bgChk; + s16 phi_a0; + s16 phi_a1; + f32 spA4; + f32 spA0; + VecSph adjSph; + VecSph sp90; + VecSph sp88; + VecSph atToEyeDir; + VecSph atToEyeNextDir; + PosRot* playerPosRot = &camera->playerPosRot; + Normal2* norm2 = (Normal2*)camera->paramData; + Normal2Anim* anim = &norm2->anim; + s32 pad; + Vec3s* bgData; + f32 playerHeight; + f32 yNormal; + + playerHeight = Player_GetHeight(camera->player); + yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight)); + + if (R_RELOAD_CAM_PARAMS) { Camera_CopyPREGToModeValues(camera); } - sp48 = &camera->eye; - sp44 = &camera->at; - sp40 = &camera->eyeNext; - playerPostRot = &camera->playerPosRot; - OLib_Vec3fDiffToVecSphGeo(&sp7C, sp44, sp48); - OLib_Vec3fDiffToVecSphGeo(&sp74, sp44, sp40); - D_8011D3E8 = 1; - D_8011D3A0.w = normal3->unk_1E; - unk20 = &normal3->unk_20; + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + norm2->unk_00 = NEXTPCT * playerHeight * yNormal; + norm2->unk_04 = NEXTPCT * playerHeight * yNormal; + norm2->unk_08 = NEXTPCT * playerHeight * yNormal; + norm2->unk_1C = DEGF_TO_BINANG(NEXTSETTING); + norm2->unk_0C = NEXTSETTING; + norm2->unk_10 = NEXTPCT; + norm2->unk_14 = NEXTSETTING; + norm2->unk_18 = NEXTPCT; + norm2->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + sCameraInterfaceFlags = norm2->interfaceFlags; - // ordering here. - switch (camera->unk_15E) { + switch (camera->animState) { case 0: case 0xA: case 0x14: case 0x19: - unk20->unk_0C = 0; - unk20->unk_24 = 0; - unk20->unk_1C = 0; - unk20->unk_14 = unk20->unk_16 = unk20->unk_18 = 0; - // unk20->unk_14 = (s16) unk20->unk_18; - // unk20->unk_16 = (s16) unk20->unk_18; - - unk20->unk_20 = camera->unk_104; - unk20->unk_10 = normal3->unk_0C; - unk20->unk_2A = 0xA; - unk20->unk_26 = (1.0f / OREG(23)) * (s16)(playerPostRot->rot.y - 0x7FFF - sp7C.yaw); - unk20->unk_28 = OREG(23); - camera->unk_15E = 1; - unk20->unk_1A = 0; + bgData = Camera_GetCamBGData(camera); + Camera_Vec3sToVec3f(&anim->unk_00, &BGCAM_POS(bgData)); + anim->unk_20 = BGCAM_ROT(bgData).x; + anim->unk_22 = BGCAM_ROT(bgData).y; + anim->unk_24 = playerPosRot->pos.y; + anim->unk_1C = BGCAM_FOV(bgData) == -1 + ? norm2->unk_14 + : BGCAM_FOV(bgData) >= 0x169 ? PCT(BGCAM_FOV(bgData)) : BGCAM_FOV(bgData); + + anim->unk_28 = BGCAM_JFIFID(bgData) == -1 ? 0 : BGCAM_JFIFID(bgData); + + anim->unk_18 = 0.0f; + + if (norm2->interfaceFlags & 4) { + sp88.pitch = anim->unk_20; + sp88.yaw = anim->unk_22 + 0x3FFF; + sp88.r = 100.0f; + OLib_VecSphGeoToVec3f(&anim->unk_0C, &sp88); + } + + camera->animState = 1; + camera->yawUpdateRateInv = 50.0f; break; default: + if (camera->playerGroundY == playerPosRot->pos.y) { + anim->unk_24 = playerPosRot->pos.y; + } break; } - DECR(unk20->unk_2A); - /*temp_v0_2 = unk20->unk_2A; - if (temp_v0_2 != 0) { - unk20->unk_2A = (s16) (temp_v0_2 - 1); - } - */ - temp_f6 = OREG(25) * 0.01f; - temp_f16 = temp_f6 * camera->unk_E0; - sp94 = (OREG(26) * 0.01f) * camera->unk_E0; - temp_v0_3 = unk20->unk_1A; - if (temp_v0_3 != 0) { - camera->unk_C0.z = func_8004389C(normal3->unk_0C + (temp_v0_3 * 2), camera->unk_C0.z, temp_f16, 0.1f); - camera->unk_C0.y = func_8004389C((f32)OREG(7) + (unk20->unk_1A * 2), camera->unk_C0.y, sp94, 0.1f); - unk20->unk_1A--; - } else { - camera->unk_C0.z = func_8004389C(normal3->unk_0C, camera->unk_C0.z, temp_f16, 0.1f); - camera->unk_C0.y = func_8004389C(OREG(7), camera->unk_C0.y, sp94, 0.1f); - } - camera->unk_CC.x = func_8004389C(OREG(2) * 0.01f, camera->unk_CC.x, temp_f16, 0.1f); - camera->unk_CC.y = func_8004389C(OREG(3) * 0.01f, camera->unk_CC.y, sp94, 0.1f); - camera->unk_CC.z = func_8004389C(OREG(4) * 0.01f, camera->unk_CC.z, sp94, 0.1f); - temp_f0 = (1.0f / normal3->unk_10) * 0.5f; - unk20->unk_24 = func_8004391C(func_80044ADC(camera, sp7C.yaw - 0x7FFF, 1), unk20->unk_24, - temp_f0 + (temp_f0 * (1.0f - camera->unk_E0)), 0xF); - func_800466F8(camera, &sp74, normal3->unk_00, &unk20->unk_20, 1); - sp90 = (normal3->unk_08 + normal3->unk_04) * 0.5f; - OLib_Vec3fDiffToVecSphGeo(&sp84, sp44, sp40); - sp84.r = func_800469C0(camera, sp84.r, normal3->unk_04, normal3->unk_08, unk20->unk_2A); - camera->dist = sp84.r; - if (0.001f < camera->unk_D8) { + + OLib_Vec3fDiffToVecSphGeo(&atToEyeDir, at, eye); + OLib_Vec3fDiffToVecSphGeo(&atToEyeNextDir, at, eyeNext); + + camera->speedRatio *= 0.5f; + spA4 = PCT(OREG(25)) * camera->speedRatio; + spA0 = PCT(OREG(26)) * camera->speedRatio; + + camera->yawUpdateRateInv = + Camera_LERPCeilF(norm2->unk_0C, camera->yawUpdateRateInv * camera->speedRatio, PCT(OREG(25)), 0.1f); + camera->pitchUpdateRateInv = Camera_LERPCeilF(OREG(7), camera->pitchUpdateRateInv, spA0, 0.1f); + camera->xzOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(2)), camera->xzOffsetUpdateRate, spA4, 0.1f); + camera->yOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(3)), camera->yOffsetUpdateRate, spA0, 0.1f); + camera->fovUpdateRate = Camera_LERPCeilF(PCT(OREG(4)), camera->yOffsetUpdateRate, camera->speedRatio * 0.05f, 0.1f); + + if (!(norm2->interfaceFlags & 0x80)) { + Camera_CalcAtDefault(camera, &atToEyeNextDir, norm2->unk_00, norm2->interfaceFlags & 1); + } else { + func_800458D4(camera, &atToEyeNextDir, norm2->unk_00, &anim->unk_24, norm2->interfaceFlags & 1); + } + + if (norm2->interfaceFlags & 4) { + anim->unk_00.x = playerPosRot->pos.x + anim->unk_0C.x; + anim->unk_00.z = playerPosRot->pos.z + anim->unk_0C.z; + } + + anim->unk_00.y = playerPosRot->pos.y; + + OLib_Vec3fDiffToVecSphGeo(&sp88, &anim->unk_00, at); + OLib_Vec3fDiffToVecSphGeo(&sp90, at, eyeNext); + + phi_a1 = (anim->unk_28 & 2 ? anim->unk_22 : norm2->unk_1C); + phi_a0 = BINANG_SUB(sp90.yaw, sp88.yaw); + if ((phi_a1 < 0x4000 && ABS(phi_a0) > phi_a1) || (phi_a1 >= 0x4000 && ABS(phi_a0) < phi_a1)) { + + phi_a0 = (phi_a0 < 0 ? -phi_a1 : phi_a1); + phi_a0 += sp88.yaw; + adjSph.yaw = + Camera_LERPCeilS(phi_a0, atToEyeDir.yaw, (1.0f / camera->yawUpdateRateInv) * camera->speedRatio, 0xA); + if (anim->unk_28 & 1) { + adjSph.pitch = Camera_CalcDefaultPitch(camera, atToEyeNextDir.pitch, anim->unk_20, 0); + } else { + adjSph.pitch = atToEyeDir.pitch; + } + } else { + adjSph = sp90; + } + + camera->dist = adjSph.r = Camera_ClampDist(camera, sp90.r, norm2->unk_04, norm2->unk_08, 0); + + if (!(anim->unk_28 & 1)) { + if (adjSph.pitch >= 0xE39) { + adjSph.pitch += (BINANG_SUB(0xE38, adjSph.pitch) >> 2); + } + + if (adjSph.pitch < 0) { + adjSph.pitch += (BINANG_SUB(-0x38E, adjSph.pitch) >> 2); + } + } + + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &adjSph); + + if (camera->status == CAM_STAT_ACTIVE) { + bgChk.pos = *eyeNext; + if ((camera->globalCtx->envCtx.skyDisabled == 0) || norm2->interfaceFlags & 0x10) { + Camera_BGCheckInfo(camera, at, &bgChk); + *eye = bgChk.pos; + } else { + func_80043F94(camera, at, &bgChk); + *eye = bgChk.pos; + OLib_Vec3fDiffToVecSphGeo(&adjSph, eye, at); + camera->inputDir.x = adjSph.pitch; + camera->inputDir.y = adjSph.yaw; + camera->inputDir.z = 0; + } + } + + camera->fov = Camera_LERPCeilF(anim->unk_1C, camera->fov, camera->fovUpdateRate, 1.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5f, 0xA); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, norm2->unk_18); + return 1; +} + +// riding epona +s32 Camera_Normal3(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + f32 sp98; + f32 sp94; + f32 sp90; + f32 sp8C; + VecSph sp84; + VecSph sp7C; + VecSph sp74; + PosRot* playerPosRot = &camera->playerPosRot; + f32 temp_f0; + f32 temp_f6; + s16 phi_a0; + s16 t2; + Normal3* norm3 = (Normal3*)camera->paramData; + Normal3Anim* anim = &norm3->anim; + f32 playerHeight; + + playerHeight = Player_GetHeight(camera->player); + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + norm3->yOffset = NEXTSETTING * PCT(playerHeight); + norm3->distMin = NEXTSETTING * PCT(playerHeight); + norm3->distMax = NEXTSETTING * PCT(playerHeight); + norm3->pitchTarget = DEGF_TO_BINANG(NEXTSETTING); + norm3->yawUpdateSpeed = NEXTSETTING; + norm3->unk_10 = NEXTSETTING; + norm3->fovTarget = NEXTSETTING; + norm3->maxAtLERPScale = NEXTPCT; + norm3->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + OLib_Vec3fDiffToVecSphGeo(&sp7C, at, eye); + OLib_Vec3fDiffToVecSphGeo(&sp74, at, eyeNext); + + sUpdateCameraDirection = true; + sCameraInterfaceFlags = norm3->interfaceFlags; + switch (camera->animState) { + case 0: + case 0xA: + case 0x14: + case 0x19: + anim->swing.atEyePoly = NULL; + anim->curPitch = 0; + anim->unk_1C = 0.0f; + anim->unk_20 = camera->playerGroundY; + anim->swing.unk_16 = anim->swing.unk_14 = anim->swing.unk_18 = 0; + anim->swing.swingUpdateRate = norm3->yawUpdateSpeed; + anim->yawUpdAmt = BINANG_SUB(BINANG_ROT180(playerPosRot->rot.y), sp7C.yaw) * (1.0f / OREG(23)); + anim->distTimer = 10; + anim->yawTimer = OREG(23); + camera->animState = 1; + anim->swing.swingUpdateRateTimer = 0; + } + + if (anim->distTimer != 0) { + anim->distTimer--; + } + + sp98 = PCT(OREG(25)) * camera->speedRatio; + sp94 = PCT(OREG(26)) * camera->speedRatio; + + if (anim->swing.swingUpdateRateTimer != 0) { + camera->yawUpdateRateInv = Camera_LERPCeilF(norm3->yawUpdateSpeed + (anim->swing.swingUpdateRateTimer * 2), + camera->yawUpdateRateInv, sp98, 0.1f); + camera->pitchUpdateRateInv = Camera_LERPCeilF((f32)OREG(7) + (anim->swing.swingUpdateRateTimer * 2), + camera->pitchUpdateRateInv, sp94, 0.1f); + if (!sp98) {} + anim->swing.swingUpdateRateTimer--; + } else { + camera->yawUpdateRateInv = Camera_LERPCeilF(norm3->yawUpdateSpeed, camera->yawUpdateRateInv, sp98, 0.1f); + camera->pitchUpdateRateInv = Camera_LERPCeilF(OREG(7), camera->pitchUpdateRateInv, sp94, 0.1f); + } + + camera->xzOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(2)), camera->xzOffsetUpdateRate, sp98, 0.1f); + camera->yOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(3)), camera->yOffsetUpdateRate, sp94, 0.1f); + camera->fovUpdateRate = Camera_LERPCeilF(PCT(OREG(4)), camera->fovUpdateRate, sp94, 0.1f); + + t2 = func_80044ADC(camera, BINANG_ROT180(sp7C.yaw), 1); + sp94 = ((1.0f / norm3->unk_10) * 0.5f); + temp_f0 = (((1.0f / norm3->unk_10) * 0.5f) * (1.0f - camera->speedRatio)); + anim->curPitch = Camera_LERPCeilS(t2, anim->curPitch, sp94 + temp_f0, 0xF); + + Camera_CalcAtForHorse(camera, &sp74, norm3->yOffset, &anim->unk_20, 1); + sp90 = (norm3->distMax + norm3->distMin) * 0.5f; + OLib_Vec3fDiffToVecSphGeo(&sp84, at, eyeNext); + camera->dist = sp84.r = Camera_ClampDist(camera, sp84.r, norm3->distMin, norm3->distMax, anim->distTimer); + if (camera->xzSpeed > 0.001f) { sp84.r += (sp90 - sp84.r) * 0.002f; } - sp84.pitch = func_8004391C(normal3->unk_1C - unk20->unk_24, sp74.pitch, 1.0f / camera->unk_C0.y, 0xA); + phi_a0 = BINANG_SUB(norm3->pitchTarget, anim->curPitch); + sp84.pitch = Camera_LERPCeilS(phi_a0, sp74.pitch, 1.0f / camera->pitchUpdateRateInv, 0xA); + if (OREG(5) < sp84.pitch) { sp84.pitch = OREG(5); } @@ -2578,156 +1903,2483 @@ s32 Camera_Normal3(Camera* camera) { sp84.pitch = OREG(34); } - // Probably some type of abs/clamp. - temp_a0 = playerPostRot->rot.y - (sp74.yaw - 0x7FFF); - phi_v1_2 = -temp_a0; - if (temp_a0 >= 0) { - phi_v1_2 = temp_a0; - } - phi_a0 = temp_a0; - if (phi_v1_2 >= 0x2AF9) { - if (temp_a0 > 0) { + phi_a0 = BINANG_SUB(playerPosRot->rot.y, BINANG_ROT180(sp74.yaw)); + if (ABS(phi_a0) > 0x2AF8) { + if (phi_a0 > 0) { phi_a0 = 0x2AF8; } else { phi_a0 = -0x2AF8; } } - temp_f16_2 = (phi_a0 * ((camera->unk_E0 * (1.0f - 0.5f)) + 0.5f)) / camera->unk_C0.z; - if ((150.0f * (1.0f - camera->unk_E0)) < fabsf(temp_f16_2)) { - sp84.yaw = sp74.yaw + temp_f16_2; - // sp8A = sp74.yaw + temp_f16_2; - } else { - sp84.yaw = sp74.yaw; - // sp8A = sp7A; - } - if (unk20->unk_28 > 0) { - sp84.yaw += unk20->unk_26; - // sp8A = sp8A + unk20->unk_26; - unk20->unk_28--; + sp90 = 1.0f; + sp98 = 0.5; + sp94 = camera->speedRatio; + sp90 -= sp98; + sp98 = sp98 + (sp94 * sp90); + sp98 = (sp98 * phi_a0) / camera->yawUpdateRateInv; + + sp84.yaw = fabsf(sp98) > (150.0f * (1.0f - camera->speedRatio)) ? (s16)(sp74.yaw + sp98) : sp74.yaw; + + if (anim->yawTimer > 0) { + sp84.yaw += anim->yawUpdAmt; + anim->yawTimer--; } - func_80043C28(sp40, sp44, &sp84); - if (camera->status == 7) { - func_80046E20(camera, &sp84, normal3->unk_04, normal3->unk_0C, &sp8C, &normal3->unk_20); + + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &sp84); + + if (camera->status == CAM_STAT_ACTIVE) { + func_80046E20(camera, &sp84, norm3->distMin, norm3->yawUpdateSpeed, &sp8C, &anim->swing); } else { - *sp48 = *sp40; + *eye = *eyeNext; } - camera->fov = func_8004389C(normal3->unk_14, camera->fov, camera->unk_CC.z, 1.0f); - camera->roll = func_8004391C(0, camera->roll, 0.5f, 0xA); - camera->unk_100 = func_800450A4(camera, normal3->unk_18); + + camera->fov = Camera_LERPCeilF(norm3->fovTarget, camera->fov, camera->fovUpdateRate, 1.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5f, 0xA); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, norm3->maxAtLERPScale); return 1; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Normal3.s") -#endif s32 Camera_Normal4(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Normal0(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Parallel1.s") +s32 Camera_Parallel1(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + f32 spB8; + f32 spB4; + s16 tangle; + VecSph spA8; + VecSph atToEyeDir; + VecSph atToEyeNextDir; + PosRot* playerPosRot = &camera->playerPosRot; + CamColChk sp6C; + s16 sp6A; + s16 phi_a0; + Parallel1* para1 = (Parallel1*)camera->paramData; + Parallel1Anim* anim = ¶1->anim; + f32 pad2; + f32 playerHeight; + s32 pad3; + + playerHeight = Player_GetHeight(camera->player); + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(OREG(46))) - (PCT(OREG(46)) * (68.0f / playerHeight)); + para1->unk_00 = NEXTPCT * playerHeight * yNormal; + ; + para1->distTarget = NEXTPCT * playerHeight * yNormal; + para1->pitchTarget = DEGF_TO_BINANG(NEXTSETTING); + para1->yawTarget = DEGF_TO_BINANG(NEXTSETTING); + para1->unk_08 = NEXTSETTING; + para1->unk_0C = NEXTSETTING; + para1->fovTarget = NEXTSETTING; + para1->unk_14 = NEXTPCT; + para1->interfaceFlags = NEXTSETTING; + para1->unk_18 = NEXTPCT * playerHeight * yNormal; + para1->unk_1C = NEXTPCT; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + OLib_Vec3fDiffToVecSphGeo(&atToEyeDir, at, eye); + OLib_Vec3fDiffToVecSphGeo(&atToEyeNextDir, at, eyeNext); + + switch (camera->animState) { + case 0: + case 0xA: + case 0x14: + case 0x19: + anim->unk_16 = 0; + anim->unk_10 = 0; + if (para1->interfaceFlags & 4) { + anim->animTimer = 20; + } else { + anim->animTimer = OREG(23); + } + anim->unk_00.x = 0.0f; + anim->yTarget = playerPosRot->pos.y - camera->playerPosDelta.y; + camera->animState++; + } + + if (anim->animTimer != 0) { + if (para1->interfaceFlags & 2) { + // Rotate para1->yawTarget degrees from behind the player. + anim->yawTarget = BINANG_ROT180(playerPosRot->rot.y) + para1->yawTarget; + } else if (para1->interfaceFlags & 4) { + // rotate to para1->yawTarget + anim->yawTarget = para1->yawTarget; + } else { + // leave the rotation alone. + anim->yawTarget = atToEyeNextDir.yaw; + } + } else { + if (para1->interfaceFlags & 0x20) { + anim->yawTarget = BINANG_ROT180(playerPosRot->rot.y) + para1->yawTarget; + } + sCameraInterfaceFlags = para1->interfaceFlags; + } + + anim->pitchTarget = para1->pitchTarget; + + if (camera->animState == 0x15) { + anim->unk_16 = 1; + camera->animState = 1; + } else if (camera->animState == 0xB) { + camera->animState = 1; + } + + spB8 = PCT(OREG(25)) * camera->speedRatio; + spB4 = PCT(OREG(26)) * camera->speedRatio; + + camera->rUpdateRateInv = Camera_LERPCeilF(OREG(6), camera->rUpdateRateInv, spB8, 0.1f); + camera->yawUpdateRateInv = Camera_LERPCeilF(para1->unk_08, camera->yawUpdateRateInv, spB8, 0.1f); + camera->pitchUpdateRateInv = Camera_LERPCeilF(2.0f, camera->pitchUpdateRateInv, spB4, 0.1f); + camera->xzOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(2)), camera->xzOffsetUpdateRate, spB8, 0.1f); + camera->yOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(3)), camera->yOffsetUpdateRate, spB4, 0.1f); + camera->fovUpdateRate = Camera_LERPCeilF(PCT(OREG(4)), camera->fovUpdateRate, camera->speedRatio * 0.05f, 0.1f); + + if (para1->interfaceFlags & 1) { + tangle = func_80044ADC(camera, BINANG_ROT180(atToEyeDir.yaw), 1); + + spB8 = ((1.0f / para1->unk_0C) * 0.3f); + pad2 = (((1.0f / para1->unk_0C) * 0.7f) * (1.0f - camera->speedRatio)); + anim->unk_10 = Camera_LERPCeilS(tangle, anim->unk_10, spB8 + pad2, 0xF); + } else { + anim->unk_10 = 0; + } + + if (camera->playerGroundY == camera->playerPosRot.pos.y || camera->player->actor.gravity > -0.1f || + camera->player->stateFlags1 & 0x200000) { + anim->yTarget = playerPosRot->pos.y; + sp6A = 0; + } else { + sp6A = 1; + } + + if (!(para1->interfaceFlags & 0x80) && !sp6A) { + Camera_CalcAtForParallel(camera, &atToEyeNextDir, para1->unk_00, &anim->yTarget, para1->interfaceFlags & 1); + } else { + func_800458D4(camera, &atToEyeNextDir, para1->unk_18, &anim->yTarget, para1->interfaceFlags & 1); + } + + if (anim->animTimer != 0) { + camera->unk_14C |= 0x20; + tangle = (((anim->animTimer + 1) * anim->animTimer) >> 1); + spA8.yaw = atToEyeDir.yaw + ((BINANG_SUB(anim->yawTarget, atToEyeDir.yaw) / tangle) * anim->animTimer); + spA8.pitch = atToEyeDir.pitch; + spA8.r = atToEyeDir.r; + anim->animTimer--; + } else { + anim->unk_16 = 0; + camera->dist = Camera_LERPCeilF(para1->distTarget, camera->dist, 1.0f / camera->rUpdateRateInv, 2.0f); + OLib_Vec3fDiffToVecSphGeo(&spA8, at, eyeNext); + spA8.r = camera->dist; + + if (para1->interfaceFlags & 0x40) { + spA8.yaw = Camera_LERPCeilS(anim->yawTarget, atToEyeNextDir.yaw, 0.6f, 0xA); + } else { + spA8.yaw = Camera_LERPCeilS(anim->yawTarget, atToEyeNextDir.yaw, 0.8f, 0xA); + } + + if (para1->interfaceFlags & 1) { + phi_a0 = BINANG_SUB(anim->pitchTarget, anim->unk_10); + } else { + phi_a0 = anim->pitchTarget; + } + + spA8.pitch = Camera_LERPCeilS(phi_a0, atToEyeNextDir.pitch, 1.0f / camera->pitchUpdateRateInv, 4); + + if (spA8.pitch > OREG(5)) { + spA8.pitch = OREG(5); + } + + if (spA8.pitch < OREG(34)) { + spA8.pitch = OREG(34); + } + } + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &spA8); + if (camera->status == CAM_STAT_ACTIVE) { + sp6C.pos = *eyeNext; + if (camera->globalCtx->envCtx.skyDisabled == 0 || para1->interfaceFlags & 0x10) { + Camera_BGCheckInfo(camera, at, &sp6C); + *eye = sp6C.pos; + } else { + func_80043F94(camera, at, &sp6C); + *eye = sp6C.pos; + OLib_Vec3fDiffToVecSphGeo(&spA8, eye, at); + camera->inputDir.x = spA8.pitch; + camera->inputDir.y = spA8.yaw; + camera->inputDir.z = 0; + } + } + camera->fov = Camera_LERPCeilF(para1->fovTarget, camera->fov, camera->fovUpdateRate, 1.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5, 0xA); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, sp6A ? para1->unk_1C : para1->unk_14); +} s32 Camera_Parallel2(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -void Camera_Parallel3(Camera* camera) { - CameraModeValue* reg = &sCameraSettings[camera->setting].cameraModes[camera->mode].values[0]; - s16 val = reg->val; +s32 Camera_Parallel3(Camera* camera) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + s16 val = NEXTSETTING; + + sCameraInterfaceFlags = val; - D_8011D3A0.w = val; if (val & 1) { camera->unk_14C |= 0x400; } if (val & 2) { camera->unk_14C |= 0x10; } + // @bug doesn't return } s32 Camera_Parallel4(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Parallel0(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Jump1.s") +/** + * Generic jump, jumping off ledges + */ +s32 Camera_Jump1(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + s32 pad2; + f32 spA4; + Vec3f newEye; + VecSph eyeAtOffset; + VecSph eyeNextAtOffset; + VecSph eyeDiffSph; + VecSph eyeDiffTarget; + PosRot* playerPosRot = &camera->playerPosRot; + PosRot playerPosRot2; + s16 tangle; + Jump1* jump1 = (Jump1*)camera->paramData; + Jump1Anim* anim = &jump1->anim; + s32 pad; + f32 playerHeight; + + playerHeight = Player_GetHeight(camera->player); + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight)); + jump1->atYOffset = PCT(NEXTSETTING) * playerHeight * yNormal; + jump1->distMin = PCT(NEXTSETTING) * playerHeight * yNormal; + jump1->distMax = PCT(NEXTSETTING) * playerHeight * yNormal; + jump1->yawUpateRateTarget = NEXTSETTING; + jump1->maxYawUpdate = PCT(NEXTSETTING); + jump1->unk_14 = NEXTSETTING; + jump1->atLERPScaleMax = PCT(NEXTSETTING); + jump1->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + // playerPosRot2 never gets used. + func_8002EEE4(&playerPosRot2, &camera->player->actor); + + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, at, eye); + OLib_Vec3fDiffToVecSphGeo(&eyeNextAtOffset, at, eyeNext); + + sCameraInterfaceFlags = jump1->interfaceFlags; + + if (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14) { + anim->swing.unk_16 = anim->swing.unk_18 = 0; + anim->swing.atEyePoly = NULL; + anim->unk_20.pitch = 0; + anim->unk_20.yaw = 0xC8; + anim->swing.swingUpdateRateTimer = 0; + anim->swing.swingUpdateRate = jump1->yawUpateRateTarget; + anim->unk_1C = playerPosRot->pos.y - camera->playerPosDelta.y; + anim->unk_20.r = eyeAtOffset.r; + camera->posOffset.y -= camera->playerPosDelta.y; + camera->xzOffsetUpdateRate = (1.0f / 10000.0f); + camera->animState++; + } + + if (anim->swing.swingUpdateRateTimer != 0) { + camera->yawUpdateRateInv = Camera_LERPCeilF(jump1->yawUpateRateTarget + anim->swing.swingUpdateRateTimer, + camera->yawUpdateRateInv, PCT(OREG(26)), 0.1f); + camera->pitchUpdateRateInv = Camera_LERPCeilF((f32)R_CAM_DEFA_PHI_UPDRATE + anim->swing.swingUpdateRateTimer, + camera->pitchUpdateRateInv, PCT(OREG(26)), 0.1f); + anim->swing.swingUpdateRateTimer--; + } else { + camera->yawUpdateRateInv = + Camera_LERPCeilF(jump1->yawUpateRateTarget, camera->yawUpdateRateInv, PCT(OREG(26)), 0.1f); + camera->pitchUpdateRateInv = + Camera_LERPCeilF((f32)R_CAM_DEFA_PHI_UPDRATE, camera->pitchUpdateRateInv, PCT(OREG(26)), 0.1f); + } + + camera->xzOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(2)), camera->xzOffsetUpdateRate, PCT(OREG(25)), 0.1f); + camera->yOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(3)), camera->yOffsetUpdateRate, PCT(OREG(26)), 0.1f); + camera->fovUpdateRate = Camera_LERPCeilF(PCT(OREG(4)), camera->yOffsetUpdateRate, 0.05f, 0.1f); + + func_800458D4(camera, &eyeNextAtOffset, jump1->atYOffset, &anim->unk_1C, 0); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Jump2.s") + eyeDiffSph = eyeAtOffset; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Jump3.s") + OLib_Vec3fDiffToVecSphGeo(&eyeDiffTarget, at, eye); + + eyeDiffSph.r = Camera_LERPCeilF(eyeDiffTarget.r, eyeAtOffset.r, PCT(OREG(29)), 1.0f); + eyeDiffSph.pitch = Camera_LERPCeilS(eyeDiffTarget.pitch, eyeAtOffset.pitch, PCT(OREG(29)), 0xA); + + if (anim->swing.unk_18) { + eyeDiffSph.yaw = + Camera_LERPCeilS(anim->swing.unk_16, eyeNextAtOffset.yaw, 1.0f / camera->yawUpdateRateInv, 0xA); + eyeDiffSph.pitch = + Camera_LERPCeilS(anim->swing.unk_14, eyeNextAtOffset.pitch, 1.0f / camera->yawUpdateRateInv, 0xA); + } else { + eyeDiffSph.yaw = + Camera_CalcDefaultYaw(camera, eyeNextAtOffset.yaw, camera->playerPosRot.rot.y, jump1->maxYawUpdate, 0.0f); + } + + // Clamp the eye->at distance to jump1->distMin < eyeDiffSph.r < jump1->distMax + if (eyeDiffSph.r < jump1->distMin) { + eyeDiffSph.r = jump1->distMin; + } else if (eyeDiffSph.r > jump1->distMax) { + eyeDiffSph.r = jump1->distMax; + } + + // Clamp the phi rotation at R_CAM_MAX_PHI AND R_CAM_MIN_PHI2 + if (eyeDiffSph.pitch > R_CAM_MAX_PHI) { + eyeDiffSph.pitch = R_CAM_MAX_PHI; + } else if (eyeDiffSph.pitch < R_CAM_MIN_PHI2) { + eyeDiffSph.pitch = R_CAM_MIN_PHI2; + } + + Camera_Vec3fVecSphGeoAdd(&newEye, at, &eyeDiffSph); + eyeNext->x = newEye.x; + eyeNext->z = newEye.z; + eyeNext->y += (newEye.y - eyeNext->y) * PCT(OREG(31)); + if ((camera->status == CAM_STAT_ACTIVE) && !(jump1->interfaceFlags & 0x10)) { + func_80046E20(camera, &eyeDiffSph, jump1->distMin, jump1->yawUpateRateTarget, &spA4, &anim->swing); + if (jump1->interfaceFlags & 4) { + camera->inputDir.x = -eyeAtOffset.pitch; + camera->inputDir.y = BINANG_ROT180(eyeAtOffset.yaw); + camera->inputDir.z = 0; + } else { + OLib_Vec3fDiffToVecSphGeo(&eyeDiffSph, eye, at); + camera->inputDir.x = eyeDiffSph.pitch; + camera->inputDir.y = eyeDiffSph.yaw; + camera->inputDir.z = 0; + } + if (anim->swing.unk_18) { + camera->inputDir.y = + Camera_LERPCeilS(camera->inputDir.y + BINANG_SUB(BINANG_ROT180(anim->swing.unk_16), camera->inputDir.y), + camera->inputDir.y, 1.0f - (0.99f * spA4), 0xA); + } + } else { + anim->swing.swingUpdateRate = jump1->yawUpateRateTarget; + anim->swing.unk_18 = 0; + sUpdateCameraDirection = 0; + *eye = *eyeNext; + } + + camera->dist = OLib_Vec3fDist(at, eye); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5f, 0xA); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, jump1->atLERPScaleMax); + return true; +} + +// Climbing ladders/vines +s32 Camera_Jump2(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f bgChkPos; + Vec3f floorNorm; + VecSph adjAtToEyeDir; + VecSph bgChkPara; + VecSph atToEyeNextDir; + VecSph atToEyeDir; + f32 temp_f14; + f32 temp_f16; + f32 sp90; + f32 sp8C; + s32 bgId; + CamColChk camBgChk; + PosRot* playerPosRot = &camera->playerPosRot; + s16 yawDiff; + s16 playerYawRot180; + Jump2* jump2 = (Jump2*)camera->paramData; + Jump2Anim* anim = &jump2->anim; + CameraModeValue* values; + f32 playerHeight; + f32 yNormal; + + playerHeight = Player_GetHeight(camera->player); + + if (RELOAD_PARAMS) { + values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + yNormal = (1.0f + PCT(OREG(46))) - (PCT(OREG(46)) * (68.0f / playerHeight)); + jump2->atYOffset = + PCT((camera->playerPosDelta.y > 0.0f ? -10.0f : 10.0f) + NEXTSETTING) * playerHeight * yNormal; + jump2->minDist = NEXTPCT * playerHeight * yNormal; + jump2->maxDist = NEXTPCT * playerHeight * yNormal; + jump2->minMaxDistFactor = NEXTPCT; + jump2->yawUpdRateTarget = NEXTSETTING; + jump2->xzUpdRateTarget = NEXTPCT; + jump2->fovTarget = NEXTSETTING; + jump2->atLERPStepScale = NEXTPCT; + jump2->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + OLib_Vec3fDiffToVecSphGeo(&atToEyeDir, at, eye); + OLib_Vec3fDiffToVecSphGeo(&atToEyeNextDir, at, eyeNext); + + sCameraInterfaceFlags = jump2->interfaceFlags; + + if (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14) { + bgChkPos = playerPosRot->pos; + anim->floorY = Camera_GetFloorY(camera, &bgChkPos); + anim->yawTarget = atToEyeNextDir.yaw; + anim->initYawDiff = 0; + if (anim->floorY == BGCHECK_Y_MIN) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: climb: no floor \n" VT_RST); + anim->onFloor = -1; + anim->floorY = playerPosRot->pos.y - 1000.0f; + } else if (playerPosRot->pos.y - anim->floorY < playerHeight) { + // player's model is within the height of the floor. + anim->onFloor = 1; + } else { + anim->onFloor = -1; + } + + yawDiff = BINANG_SUB(BINANG_ROT180(playerPosRot->rot.y), atToEyeNextDir.yaw); + anim->initYawDiff = ((yawDiff / OREG(23)) / 4) * 3; + if (jump2->interfaceFlags & 2) { + anim->yawAdj = 0xA; + } else { + anim->yawAdj = 0x2710; + } + + playerPosRot->pos.x -= camera->playerPosDelta.x; + playerPosRot->pos.y -= camera->playerPosDelta.y; + playerPosRot->pos.z -= camera->playerPosDelta.z; + anim->animTimer = OREG(23); + camera->animState++; + camera->atLERPStepScale = jump2->atLERPStepScale; + } + + sp90 = PCT(OREG(25)) * camera->speedRatio; + sp8C = PCT(OREG(26)) * camera->speedRatio; + camera->yawUpdateRateInv = Camera_LERPCeilF(jump2->yawUpdRateTarget, camera->yawUpdateRateInv, sp90, 0.1f); + camera->xzOffsetUpdateRate = Camera_LERPCeilF(jump2->xzUpdRateTarget, camera->xzOffsetUpdateRate, sp90, 0.1f); + camera->yOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(3)), camera->yOffsetUpdateRate, sp8C, 0.1f); + + camera->fovUpdateRate = Camera_LERPCeilF(PCT(OREG(4)), camera->yOffsetUpdateRate, camera->speedRatio * 0.05f, 0.1f); + camera->rUpdateRateInv = OREG(27); + + Camera_CalcAtDefault(camera, &atToEyeNextDir, jump2->atYOffset, 0); + OLib_Vec3fDiffToVecSphGeo(&adjAtToEyeDir, at, eye); + + temp_f16 = jump2->minDist; + sp90 = jump2->maxDist + (jump2->maxDist * jump2->minMaxDistFactor); + temp_f14 = temp_f16 - (jump2->minDist * jump2->minMaxDistFactor); + + if (adjAtToEyeDir.r > sp90) { + adjAtToEyeDir.r = sp90; + } else if (adjAtToEyeDir.r < temp_f14) { + adjAtToEyeDir.r = temp_f14; + } + + yawDiff = BINANG_SUB(BINANG_ROT180(playerPosRot->rot.y), adjAtToEyeDir.yaw); + if (anim->animTimer != 0) { + anim->yawTarget = BINANG_ROT180(playerPosRot->rot.y); + anim->animTimer--; + adjAtToEyeDir.yaw = Camera_LERPCeilS(anim->yawTarget, atToEyeNextDir.yaw, 0.5f, 0xA); + } else if (anim->yawAdj < ABS(yawDiff)) { + playerYawRot180 = BINANG_ROT180(playerPosRot->rot.y); + adjAtToEyeDir.yaw = Camera_LERPFloorS( + ((yawDiff < 0) ? (s16)(playerYawRot180 + anim->yawAdj) : (s16)(playerYawRot180 - anim->yawAdj)), + atToEyeNextDir.yaw, 0.1f, 0xA); + } else { + adjAtToEyeDir.yaw = Camera_LERPCeilS(adjAtToEyeDir.yaw, atToEyeNextDir.yaw, 0.25f, 0xA); + } + + // Check the floor at the top of the climb + bgChkPos.x = playerPosRot->pos.x + (Math_Sins(playerPosRot->rot.y) * 25.0f); + bgChkPos.y = playerPosRot->pos.y + (playerHeight * 2.2f); + bgChkPos.z = playerPosRot->pos.z + (Math_Coss(playerPosRot->rot.y) * 25.0f); + + sp90 = Camera_GetFloorYNorm(camera, &floorNorm, &bgChkPos, &bgId); + if ((sp90 != BGCHECK_Y_MIN) && (playerPosRot->pos.y < sp90)) { + // top of the climb is within 2.2x of the player's height. + camera->pitchUpdateRateInv = Camera_LERPCeilF(20.0f, camera->pitchUpdateRateInv, PCT(OREG(26)), 0.1f); + camera->rUpdateRateInv = Camera_LERPCeilF(20.0f, camera->rUpdateRateInv, PCT(OREG(26)), 0.1f); + adjAtToEyeDir.pitch = Camera_LERPCeilS(0x1F4, atToEyeNextDir.pitch, 1.0f / camera->pitchUpdateRateInv, 0xA); + } else if ((playerPosRot->pos.y - anim->floorY) < playerHeight) { + // player is within his height of the ground. + camera->pitchUpdateRateInv = Camera_LERPCeilF(20.0f, camera->pitchUpdateRateInv, PCT(OREG(26)), 0.1f); + camera->rUpdateRateInv = Camera_LERPCeilF(20.0f, camera->rUpdateRateInv, PCT(OREG(26)), 0.1f); + adjAtToEyeDir.pitch = Camera_LERPCeilS(0x1F4, atToEyeNextDir.pitch, 1.0f / camera->pitchUpdateRateInv, 0xA); + } else { + camera->pitchUpdateRateInv = 100.0f; + camera->rUpdateRateInv = 100.0f; + } + + // max pitch to +/- ~ 60 degrees + if (adjAtToEyeDir.pitch > 0x2AF8) { + adjAtToEyeDir.pitch = 0x2AF8; + } + + if (adjAtToEyeDir.pitch < -0x2AF8) { + adjAtToEyeDir.pitch = -0x2AF8; + } + + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &adjAtToEyeDir); + camBgChk.pos = *eyeNext; + if (Camera_BGCheckInfo(camera, at, &camBgChk)) { + // Collision detected between at->eyeNext, Check if collision between + // at->eyeNext, but parallel to at (pitch = 0). + bgChkPos = camBgChk.pos; + bgChkPara.r = adjAtToEyeDir.r; + bgChkPara.pitch = 0; + bgChkPara.yaw = adjAtToEyeDir.yaw; + Camera_Vec3fVecSphGeoAdd(&camBgChk.pos, at, &bgChkPara); + if (Camera_BGCheckInfo(camera, at, &camBgChk)) { + // Collision found between parallel at->eyeNext, set eye position to + // first collsion point. + *eye = bgChkPos; + } else { + // no collision found with the parallel at->eye, animate to be parallel + adjAtToEyeDir.pitch = Camera_LERPCeilS(0, adjAtToEyeDir.pitch, 0.2f, 0xA); + Camera_Vec3fVecSphGeoAdd(eye, at, &adjAtToEyeDir); + // useless? + Camera_BGCheck(camera, at, eye); + } + } else { + // no collision detected. + *eye = *eyeNext; + } + + camera->dist = adjAtToEyeDir.r; + camera->fov = Camera_LERPCeilF(jump2->fovTarget, camera->fov, camera->fovUpdateRate, 1.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5f, 0xA); + return true; +} + +// swimming +s32 Camera_Jump3(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + s32 prevMode; + f32 spC4; + f32 spC0; + f32 spBC; + Vec3f spB0; // unused + VecSph eyeDiffSph; + PosRot* playerPosRot = &camera->playerPosRot; + Jump3* jump3 = (Jump3*)camera->paramData; + VecSph eyeAtOffset; + VecSph eyeNextAtOffset; + s32 pad; + s32 pad2; + CameraModeValue* values; + f32 t2; + f32 phi_f0; + f32 phi_f2; + f32 playerHeight; + PosRot playerPosRot2; + f32 yNormal; + f32 temp_f18; + s32 modeSwitch; + f32 temp_f2_2; + Jump3Anim* anim = &jump3->anim; + + playerHeight = Player_GetHeight(camera->player); + func_8002EEE4(&playerPosRot2, &camera->player->actor); + + modeSwitch = false; + if (((camera->waterYPos - eye->y) < OREG(44) || (camera->animState == 0))) { + if (anim->mode != CAM_MODE_NORMAL) { + anim->mode = CAM_MODE_NORMAL; + modeSwitch = true; + } + } else if (((camera->waterYPos - eye->y) > OREG(45)) && (anim->mode != CAM_MODE_BOOMERANG)) { + anim->mode = CAM_MODE_BOOMERANG; + modeSwitch = true; + } + + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, at, eye); + OLib_Vec3fDiffToVecSphGeo(&eyeNextAtOffset, at, eyeNext); + + if (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14 || modeSwitch || + R_RELOAD_CAM_PARAMS) { + values = sCameraSettings[camera->setting].cameraModes[anim->mode].values; + yNormal = ((1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight))); + t2 = PCT(playerHeight) * yNormal; + jump3->yOffset = NEXTSETTING * t2; + jump3->distMin = NEXTSETTING * t2; + jump3->distMax = NEXTSETTING * t2; + jump3->pitchTarget = DEGF_TO_BINANG(NEXTSETTING); + jump3->swingUpdateRate = NEXTSETTING; + jump3->unk_10 = NEXTSETTING; + jump3->unk_14 = NEXTPCT; + jump3->fovTarget = NEXTSETTING; + jump3->unk_1C = NEXTPCT; + jump3->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + prevMode = camera->mode; + camera->mode = anim->mode; + Camera_CopyPREGToModeValues(camera); + camera->mode = prevMode; + } + + sCameraInterfaceFlags = jump3->interfaceFlags; + + switch (camera->animState) { + case 0: + case 0xA: + case 0x14: + case 0x19: + anim->swing.atEyePoly = NULL; + anim->unk_1C = camera->playerGroundY; + anim->swing.unk_16 = anim->swing.unk_14 = anim->swing.unk_18 = 0; + anim->animTimer = 0xA; + anim->swing.swingUpdateRate = jump3->swingUpdateRate; + camera->animState++; + anim->swing.swingUpdateRateTimer = 0; + break; + default: + if (anim->animTimer != 0) { + anim->animTimer--; + } + break; + } + + // unused + spB0 = *eye; + + spC4 = PCT(OREG(25)) * camera->speedRatio; + spC0 = camera->speedRatio * PCT(OREG(26)); + spBC = anim->swing.unk_18 != 0 ? PCT(OREG(25)) : spC4; + + if (anim->swing.swingUpdateRateTimer != 0) { + camera->yawUpdateRateInv = Camera_LERPCeilF( + anim->swing.swingUpdateRate + (anim->swing.swingUpdateRateTimer * 2), camera->yawUpdateRateInv, spC4, 0.1f); + camera->pitchUpdateRateInv = + Camera_LERPCeilF((anim->swing.swingUpdateRateTimer * 2) + 40.0f, camera->pitchUpdateRateInv, spC0, 0.1f); + anim->swing.swingUpdateRateTimer--; + } else { + camera->yawUpdateRateInv = Camera_LERPCeilF(anim->swing.swingUpdateRate, camera->yawUpdateRateInv, spBC, 0.1f); + camera->pitchUpdateRateInv = Camera_LERPCeilF(40.0f, camera->pitchUpdateRateInv, spC0, 0.1f); + } + + camera->xzOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(2)), camera->xzOffsetUpdateRate, spC4, 0.1f); + camera->yOffsetUpdateRate = Camera_LERPCeilF(PCT(OREG(3)), camera->yOffsetUpdateRate, spC0, 0.1f); + camera->fovUpdateRate = Camera_LERPCeilF(PCT(OREG(4)), camera->yOffsetUpdateRate, camera->speedRatio * 0.05f, 0.1f); + + Camera_CalcAtDefault(camera, &eyeNextAtOffset, jump3->yOffset, jump3->interfaceFlags); + OLib_Vec3fDiffToVecSphGeo(&eyeDiffSph, at, eyeNext); + + camera->dist = eyeDiffSph.r = + Camera_ClampDist(camera, eyeDiffSph.r, jump3->distMin, jump3->distMax, anim->animTimer); + + if (camera->playerGroundY <= playerPosRot->pos.y) { + phi_f0 = playerPosRot->pos.y - camera->playerGroundY; + } else { + phi_f0 = -(playerPosRot->pos.y - camera->playerGroundY); + } + + if (!(phi_f0 < 10.0f)) { + if (camera->waterYPos <= playerPosRot2.pos.y) { + phi_f2 = playerPosRot2.pos.y - camera->waterYPos; + } else { + phi_f2 = -(playerPosRot2.pos.y - camera->waterYPos); + } + if (!(phi_f2 < 50.0f)) { + camera->pitchUpdateRateInv = 100.0f; + } + } + if (anim->swing.unk_18 != 0) { + eyeDiffSph.yaw = + Camera_LERPCeilS(anim->swing.unk_16, eyeNextAtOffset.yaw, 1.0f / camera->yawUpdateRateInv, 0xA); + eyeDiffSph.pitch = + Camera_LERPCeilS(anim->swing.unk_14, eyeNextAtOffset.pitch, 1.0f / camera->yawUpdateRateInv, 0xA); + } else { + eyeDiffSph.yaw = Camera_CalcDefaultYaw(camera, eyeNextAtOffset.yaw, playerPosRot->rot.y, jump3->unk_14, 0.0f); + eyeDiffSph.pitch = Camera_CalcDefaultPitch(camera, eyeNextAtOffset.pitch, jump3->pitchTarget, 0); + } + + if (eyeDiffSph.pitch > OREG(5)) { + eyeDiffSph.pitch = OREG(5); + } + + if (eyeDiffSph.pitch < OREG(34)) { + eyeDiffSph.pitch = OREG(34); + } + + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeDiffSph); + if ((camera->status == CAM_STAT_ACTIVE) && !(jump3->interfaceFlags & 0x10)) { + func_80046E20(camera, &eyeDiffSph, jump3->distMin, jump3->swingUpdateRate, &spBC, &anim->swing); + if (jump3->interfaceFlags & 4) { + camera->inputDir.x = -eyeAtOffset.pitch; + camera->inputDir.y = BINANG_ROT180(eyeAtOffset.yaw); + camera->inputDir.z = 0; + } else { + OLib_Vec3fDiffToVecSphGeo(&eyeDiffSph, eye, at); + camera->inputDir.x = eyeDiffSph.pitch; + camera->inputDir.y = eyeDiffSph.yaw; + camera->inputDir.z = 0; + } + + if (anim->swing.unk_18 != 0) { + camera->inputDir.y = + Camera_LERPCeilS(camera->inputDir.y + BINANG_SUB(BINANG_ROT180(anim->swing.unk_16), camera->inputDir.y), + camera->inputDir.y, 1.0f - (0.99f * spBC), 0xA); + } + } else { + anim->swing.swingUpdateRate = jump3->swingUpdateRate; + anim->swing.unk_18 = 0; + sUpdateCameraDirection = 0; + *eye = *eyeNext; + } + camera->fov = Camera_LERPCeilF(jump3->fovTarget, camera->fov, camera->fovUpdateRate, 1.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5f, 0xA); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, jump3->unk_1C); + return true; +} s32 Camera_Jump4(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Jump0(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Battle1.s") +s32 Camera_Battle1(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f sp128; + Vec3f playerHead; + Vec3f targetPos; + f32 var3; + f32 var2; + f32 temp_f0_2; + f32 temp_f12_2; + f32 spFC; + f32 spF8; + f32 swingAngle; + f32 temp_f2_2; + f32 temp_f14; + s32 skipEyeAtCalc; + f32 distRatio; + CamColChk spBC; + VecSph spB4; + VecSph atToTargetDir; + VecSph playerToTargetDir; + VecSph atToEyeDir; + VecSph atToEyeNextDir; + PosRot* playerPosRot = &camera->playerPosRot; + s16 tmpAng1; + s16 tmpAng2; + Player* player; + s16 sp86; + s16 isOffGround; + f32 distance; + f32 sp7C; + f32 sp78; + f32 fov; + Battle1* batt1 = (Battle1*)camera->paramData; + Battle1Anim* anim = &batt1->anim; + s32 pad; + f32 playerHeight; + + skipEyeAtCalc = false; + player = camera->player; + playerHeight = Player_GetHeight(camera->player); + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(OREG(46))) - (PCT(OREG(46)) * (68.0f / playerHeight)); + batt1->yOffset = NEXTPCT * playerHeight * yNormal; + batt1->distance = NEXTSETTING; + batt1->swingYawInitial = NEXTSETTING; + batt1->swingYawFinal = NEXTSETTING; + batt1->swingPitchInitial = NEXTSETTING; + batt1->swingPitchFinal = NEXTSETTING; + batt1->swingPitchAdj = NEXTPCT; + batt1->fov = NEXTSETTING; + batt1->atLERPScaleOnGround = NEXTPCT; + batt1->flags = NEXTSETTING; + batt1->yOffsetOffGround = NEXTPCT * playerHeight * yNormal; + batt1->atLERPScaleOffGround = NEXTPCT; + anim->chargeTimer = 40; + anim->unk_10 = PCT(OREG(12)); + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + distance = batt1->distance; + sp7C = batt1->swingPitchInitial; + sp78 = batt1->swingPitchFinal; + fov = batt1->fov; + + if (camera->player->stateFlags1 & 0x1000) { + // charging sword. + anim->unk_10 = Camera_LERPCeilF(PCT(OREG(12)) * 0.5f, anim->unk_10, PCT(OREG(25)), 0.1f); + camera->xzOffsetUpdateRate = Camera_LERPCeilF(0.2f, camera->xzOffsetUpdateRate, PCT(OREG(25)), 0.1f); + camera->yOffsetUpdateRate = Camera_LERPCeilF(0.2f, camera->yOffsetUpdateRate, PCT(OREG(25)), 0.1f); + if (anim->chargeTimer >= -19) { + anim->chargeTimer--; + } else { + distance = 250.0f; + sp7C = 50.0f; + sp78 = 40.0f; + fov = 60.0f; + } + } else if (anim->chargeTimer < 0) { + distance = 250.0f; + sp7C = 50.0f; + sp78 = 40.0f; + fov = 60.0f; + anim->chargeTimer++; + } else { + anim->chargeTimer = 40; + anim->unk_10 = Camera_LERPCeilF(PCT(OREG(12)), anim->unk_10, PCT(OREG(25)), 0.1f); + camera->xzOffsetUpdateRate = + Camera_LERPCeilF(PCT(OREG(40)), camera->xzOffsetUpdateRate, PCT(OREG(25)) * camera->speedRatio, 0.1f); + camera->yOffsetUpdateRate = + Camera_LERPCeilF(PCT(OREG(40)), camera->yOffsetUpdateRate, PCT(OREG(26)) * camera->speedRatio, 0.1f); + } + camera->fovUpdateRate = Camera_LERPCeilF(PCT(OREG(4)), camera->fovUpdateRate, camera->speedRatio * 0.05f, 0.1f); + playerHeight += batt1->yOffset; + OLib_Vec3fDiffToVecSphGeo(&atToEyeDir, at, eye); + OLib_Vec3fDiffToVecSphGeo(&atToEyeNextDir, at, eyeNext); + if (camera->target == NULL || camera->target->update == NULL) { + if (camera->target == NULL) { + osSyncPrintf( + VT_COL(YELLOW, BLACK) "camera: warning: battle: target is not valid, change parallel\n" VT_RST); + } + camera->target = NULL; + Camera_ChangeMode(camera, CAM_MODE_TARGET); + return true; + } + + sCameraInterfaceFlags = batt1->flags; + + if (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14) { + anim->unk_14 = 0; + anim->roll = 0.0f; + anim->target = camera->target; + camera->animState++; + if (anim->target->id > 0) { + osSyncPrintf("camera: battle: target actor name " VT_FGCOL(BLUE) "%d" VT_RST "\n", anim->target->id); + } else { + osSyncPrintf("camera: battle: target actor name " VT_COL(RED, WHITE) "%d" VT_RST "\n", anim->target->id); + camera->target = NULL; + Camera_ChangeMode(camera, CAM_MODE_TARGET); + return true; + } + anim->animTimer = OREG(23) + OREG(24); + anim->initialEyeToAtYaw = atToEyeDir.yaw; + anim->initialEyeToAtPitch = atToEyeDir.pitch; + anim->initialEyeToAtDist = atToEyeDir.r; + anim->yPosOffset = playerPosRot->pos.y - camera->playerPosDelta.y; + } + + if (camera->status == CAM_STAT_ACTIVE) { + sUpdateCameraDirection = 1; + camera->inputDir.x = -atToEyeDir.pitch; + camera->inputDir.y = BINANG_ROT180(atToEyeDir.yaw); + camera->inputDir.z = 0; + } + + if (camera->playerGroundY == camera->playerPosRot.pos.y || camera->player->actor.gravity > -0.1f || + camera->player->stateFlags1 & 0x200000) { + isOffGround = false; + anim->yPosOffset = playerPosRot->pos.y; + } else { + isOffGround = true; + } + + if (anim->animTimer == 0) { + camera->atLERPStepScale = + Camera_ClampLERPScale(camera, isOffGround ? batt1->atLERPScaleOffGround : batt1->atLERPScaleOnGround); + } + func_8002EEE4(&camera->targetPosRot, camera->target); + if (anim->target != camera->target) { + osSyncPrintf("camera: battle: change target %d -> " VT_FGCOL(BLUE) "%d" VT_RST "\n", anim->target->id, + camera->target->id); + camera->animState = 0; + return true; + } + + Camera_CalcAtForLockOn(camera, &atToEyeNextDir, &camera->targetPosRot.pos, + isOffGround ? batt1->yOffsetOffGround : batt1->yOffset, distance, &anim->yPosOffset, + &playerToTargetDir, (isOffGround ? 0x81 : 1) | batt1->flags); + tmpAng2 = playerToTargetDir.yaw; + playerHead = playerPosRot->pos; + playerHead.y += playerHeight; + OLib_Vec3fDiffToVecSphGeo(&playerToTargetDir, &playerHead, &camera->targetPosRot.pos); + distRatio = playerToTargetDir.r > distance ? 1 : playerToTargetDir.r / distance; + targetPos = camera->targetPosRot.pos; + OLib_Vec3fDiffToVecSphGeo(&atToTargetDir, at, &targetPos); + atToTargetDir.r = distance - ((atToTargetDir.r <= distance ? atToTargetDir.r : distance) * 0.5f); + swingAngle = batt1->swingYawInitial + ((batt1->swingYawFinal - batt1->swingYawInitial) * (1.1f - distRatio)); + spF8 = OREG(13) + swingAngle; + + spB4.r = camera->dist = Camera_LERPCeilF(distance, camera->dist, PCT(OREG(11)), 2.0f); + spB4.yaw = atToEyeNextDir.yaw; + tmpAng1 = BINANG_SUB(atToTargetDir.yaw, BINANG_ROT180(atToEyeNextDir.yaw)); + if (anim->animTimer != 0) { + if (anim->animTimer >= OREG(24)) { + sp86 = anim->animTimer - OREG(24); + OLib_Vec3fDiffToVecSphGeo(&playerToTargetDir, at, eye); + playerToTargetDir.yaw = BINANG_ROT180(tmpAng2); + + var2 = 1.0f / OREG(23); + var3 = (anim->initialEyeToAtDist - playerToTargetDir.r) * var2; + tmpAng1 = BINANG_SUB(anim->initialEyeToAtYaw, playerToTargetDir.yaw) * var2; + tmpAng2 = BINANG_SUB(anim->initialEyeToAtPitch, playerToTargetDir.pitch) * var2; + + spB4.r = Camera_LERPCeilF(playerToTargetDir.r + (var3 * sp86), atToEyeDir.r, PCT(OREG(28)), 1.0f); + spB4.yaw = Camera_LERPCeilS(playerToTargetDir.yaw + (tmpAng1 * sp86), atToEyeDir.yaw, PCT(OREG(28)), 0xA); + spB4.pitch = + Camera_LERPCeilS(playerToTargetDir.pitch + (tmpAng2 * sp86), atToEyeDir.pitch, PCT(OREG(28)), 0xA); + } else { + skipEyeAtCalc = true; + } + anim->animTimer--; + } else if (ABS(tmpAng1) > DEGF_TO_BINANG(swingAngle)) { + spFC = BINANG_TO_DEGF(tmpAng1); + temp_f2_2 = swingAngle + (spF8 - swingAngle) * (OLib_ClampMaxDist(atToTargetDir.r, spB4.r) / spB4.r); + temp_f12_2 = ((temp_f2_2 * temp_f2_2) - 2.0f) / (temp_f2_2 - 360.0f); + var2 = ((temp_f12_2 * spFC) + (2.0f - (360.0f * temp_f12_2))); + temp_f14 = SQ(spFC) / var2; + tmpAng2 = tmpAng1 >= 0 ? DEGF_TO_BINANG(temp_f14) : (-DEGF_TO_BINANG(temp_f14)); + spB4.yaw = BINANG_ROT180((s16)(BINANG_ROT180(atToEyeNextDir.yaw) + tmpAng2)); + } else { + spFC = 0.05f; + spFC = (1 - camera->speedRatio) * spFC; + tmpAng2 = tmpAng1 >= 0 ? DEGF_TO_BINANG(swingAngle) : -DEGF_TO_BINANG(swingAngle); + spB4.yaw = atToEyeNextDir.yaw - (s16)((tmpAng2 - tmpAng1) * spFC); + } + + if (!skipEyeAtCalc) { + var3 = atToTargetDir.pitch * batt1->swingPitchAdj; + var2 = F32_LERPIMP(sp7C, sp78, distRatio); + tmpAng1 = DEGF_TO_BINANG(var2) - (s16)(playerToTargetDir.pitch * (.5f + distRatio * (1.0f - .5f))); + tmpAng1 += (s16)(var3); + + if (tmpAng1 < -0x2AA8) { + tmpAng1 = -0x2AA8; + } else if (tmpAng1 > 0x2AA8) { + tmpAng1 = 0x2AA8; + } + + spB4.pitch = Camera_LERPCeilS(tmpAng1, atToEyeNextDir.pitch, anim->unk_10, 0xA); + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &spB4); + spBC.pos = *eyeNext; + if (camera->status == CAM_STAT_ACTIVE) { + if (camera->globalCtx->envCtx.skyDisabled == 0 || batt1->flags & 1) { + Camera_BGCheckInfo(camera, at, &spBC); + } else if (batt1->flags & 2) { + func_80043F94(camera, at, &spBC); + } else { + OLib_Vec3fDistNormalize(&sp128, at, &spBC.pos); + spBC.pos.x -= sp128.x; + spBC.pos.y -= sp128.y; + spBC.pos.z -= sp128.z; + } + *eye = spBC.pos; + } else { + *eye = *eyeNext; + } + } + anim->roll += (((OREG(36) * camera->speedRatio) * (1.0f - distRatio)) - anim->roll) * PCT(OREG(37)); + camera->roll = DEGF_TO_BINANG(anim->roll); + camera->fov = Camera_LERPCeilF((player->swordState != 0 ? 0.8f : gSaveContext.health <= 0x10 ? 0.8f : 1.0f) * + (fov - ((fov * 0.05f) * distRatio)), + camera->fov, camera->fovUpdateRate, 1.0f); +} s32 Camera_Battle2(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Battle3(Camera* camera) { - func_80047394(camera); + Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Battle4.s") +/** + * Charging spin attack + * Camera zooms out slowly for 50 frames, then tilts up to a specified + * setting value. + */ +s32 Camera_Battle4(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + VecSph eyeNextOffset; + VecSph eyeAtOffset; + VecSph eyeNextAtOffset; + Battle4* batt4 = (Battle4*)camera->paramData; + Battle4Anim* anim = &batt4->anim; + s32 pad; + f32 playerHeight; + + playerHeight = Player_GetHeight(camera->player); + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight)); + batt4->yOffset = NEXTPCT * playerHeight * yNormal; + batt4->rTarget = NEXTPCT * playerHeight * yNormal; + batt4->pitchTarget = DEGF_TO_BINANG(NEXTSETTING); + batt4->lerpUpdateRate = NEXTPCT; + batt4->fovTarget = NEXTSETTING; + batt4->atLERPTarget = NEXTPCT; + batt4->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, at, eye); + OLib_Vec3fDiffToVecSphGeo(&eyeNextAtOffset, at, eyeNext); + + sCameraInterfaceFlags = batt4->interfaceFlags; + + switch (camera->animState) { + case 0: + case 0xA: + case 0x14: + anim->animTimer = 50; + camera->animState++; + } + + camera->yawUpdateRateInv = + Camera_LERPCeilF(batt4->lerpUpdateRate, camera->yawUpdateRateInv, PCT(OREG(25)) * camera->speedRatio, 0.1f); + camera->rUpdateRateInv = 1000.0f; + camera->pitchUpdateRateInv = 1000.0f; + camera->xzOffsetUpdateRate = Camera_LERPCeilF(0.025f, camera->xzOffsetUpdateRate, PCT(OREG(25)), 0.1f); + camera->yOffsetUpdateRate = + Camera_LERPCeilF(PCT(OREG(3)), camera->yOffsetUpdateRate, PCT(OREG(26)) * camera->speedRatio, 0.1f); + camera->fovUpdateRate = 0.0001f; + Camera_CalcAtDefault(camera, &eyeNextAtOffset, batt4->yOffset, 1); + if (anim->animTimer != 0) { + eyeNextOffset.yaw = eyeAtOffset.yaw; + eyeNextOffset.pitch = eyeAtOffset.pitch; + eyeNextOffset.r = eyeAtOffset.r; + anim->animTimer--; + } else { + eyeNextOffset.yaw = eyeAtOffset.yaw; + eyeNextOffset.pitch = Camera_LERPCeilS(batt4->pitchTarget, eyeAtOffset.pitch, batt4->lerpUpdateRate, 2); + eyeNextOffset.r = Camera_LERPCeilF(batt4->rTarget, eyeAtOffset.r, batt4->lerpUpdateRate, 0.001f); + } + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeNextOffset); + *eye = *eyeNext; + camera->dist = eyeNextOffset.r; + camera->fov = Camera_LERPCeilF(batt4->fovTarget, camera->fov, batt4->lerpUpdateRate, 1.0f); + camera->roll = 0; + camera->atLERPStepScale = Camera_ClampLERPScale(camera, batt4->atLERPTarget); + return true; +} s32 Camera_Battle0(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_KeepOn1.s") +// Targeting non-enemy +s32 Camera_KeepOn1(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f sp120; + Vec3f sp114; + Vec3f sp108; + f32 sp104; + f32 temp_f12_2; + f32 temp_f14; + f32 t1; + f32 spF4; + f32 spF0; + f32 spEC; + f32 spE8; + f32 t2; + s16 spE2; + s16 spE0; + VecSph spD8; + VecSph spD0; + VecSph spC8; + VecSph spC0; + VecSph spB8; + PosRot* playerPosRot = &camera->playerPosRot; + CamColChk sp8C; + s32 sp88; + f32 sp84; + s16 sp82; + s16 sp80; + KeepOn1* keep1 = (KeepOn1*)camera->paramData; + Keep1Anim* anim = &keep1->anim; + s16 t3; + f32 playerHeight; + + sp88 = 0; + playerHeight = Player_GetHeight(camera->player); + if ((camera->target == NULL) || (camera->target->update == NULL)) { + if (camera->target == NULL) { + osSyncPrintf( + VT_COL(YELLOW, BLACK) "camera: warning: keepon: target is not valid, change parallel\n" VT_RST); + } + camera->target = NULL; + Camera_ChangeMode(camera, CAM_MODE_TARGET); + return 1; + } + + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(OREG(46))) - (PCT(OREG(46)) * (68.0f / playerHeight)); + keep1->unk_00 = NEXTPCT * playerHeight * yNormal; + keep1->unk_04 = NEXTSETTING; + keep1->unk_08 = NEXTSETTING; + keep1->unk_0C = NEXTSETTING; + keep1->unk_10 = NEXTSETTING; + keep1->unk_14 = NEXTSETTING; + keep1->unk_18 = NEXTSETTING; + keep1->unk_1C = NEXTPCT; + keep1->unk_20 = NEXTSETTING; + keep1->unk_24 = NEXTPCT; + keep1->interfaceFlags = NEXTSETTING; + keep1->unk_28 = NEXTPCT * playerHeight * yNormal; + keep1->unk_2C = NEXTPCT; + } + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + playerHeight += keep1->unk_00; + OLib_Vec3fDiffToVecSphGeo(&spC0, at, eye); + OLib_Vec3fDiffToVecSphGeo(&spB8, at, eyeNext); + sCameraInterfaceFlags = keep1->interfaceFlags; + if (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14) { + camera->animState++; + anim->unk_10 = 0; + anim->unk_04 = 0.0f; + anim->unk_0C = camera->target; + anim->unk_16 = OREG(23) + OREG(24); + anim->unk_12 = spC0.yaw; + anim->unk_14 = spC0.pitch; + anim->unk_00 = spC0.r; + anim->unk_08 = playerPosRot->pos.y - camera->playerPosDelta.y; + } + if (camera->status == 7) { + sUpdateCameraDirection = 1; + camera->inputDir.x = -spC0.pitch; + camera->inputDir.y = BINANG_ROT180(spC0.yaw); + camera->inputDir.z = 0; + } + + sp104 = keep1->unk_04; + sp84 = 1; + + switch (camera->paramFlags & 0x18) { + case 8: + if ((camera->player->actor.type == 2) && (camera->player->interactRangeActor == camera->target)) { + PosRot sp54; + func_8002EEE4(&sp54, &camera->player->actor); + spC8.r = 60.0f; + spC8.yaw = camera->playerPosRot.rot.y; + spC8.pitch = 0x2EE0; + Camera_Vec3fVecSphGeoAdd(&camera->targetPosRot.pos, &sp54.pos, &spC8); + } else { + func_8002EEE4(&camera->targetPosRot, camera->target); + } + func_8002EEE4(&camera->targetPosRot, camera->target); + if (anim->unk_0C != camera->target) { + anim->unk_0C = camera->target; + camera->atLERPStepScale = 0.0f; + } + camera->xzOffsetUpdateRate = + Camera_LERPCeilF(1.0f, camera->xzOffsetUpdateRate, PCT(OREG(25)) * camera->speedRatio, 0.1f); + camera->yOffsetUpdateRate = + Camera_LERPCeilF(1.0f, camera->yOffsetUpdateRate, PCT(OREG(26)) * camera->speedRatio, 0.1f); + camera->fovUpdateRate = + Camera_LERPCeilF(PCT(OREG(4)), camera->fovUpdateRate, camera->speedRatio * 0.05f, 0.1f); + goto cont; + case 0x10: + anim->unk_0C = NULL; + cont: + if (camera->playerGroundY == camera->playerPosRot.pos.y || camera->player->actor.gravity > -0.1f || + camera->player->stateFlags1 & 0x200000) { + anim->unk_08 = playerPosRot->pos.y; + sp80 = 0; + } else { + sp80 = 1; + } + + Camera_CalcAtForLockOn(camera, &spB8, &camera->targetPosRot.pos, sp80 ? keep1->unk_28 : keep1->unk_00, + sp104, &anim->unk_08, &spC8, (sp80 ? 0x80 : 0) | keep1->interfaceFlags); + sp114 = playerPosRot->pos; + sp114.y += playerHeight; + OLib_Vec3fDiffToVecSphGeo(&spC8, &sp114, &camera->targetPosRot.pos); + sp84 = spC8.r > sp104 ? 1.0f : spC8.r / sp104; + break; + default: + *at = playerPosRot->pos; + at->y += playerHeight; + anim->unk_0C = NULL; + break; + } + OLib_Vec3fDiffToVecSphGeo(&spD8, at, eyeNext); + if (spD8.r < keep1->unk_04) { + sp104 = keep1->unk_04; + spE8 = OREG(6); + } else if (keep1->unk_08 < spD8.r) { + sp104 = keep1->unk_08; + spE8 = OREG(6); + } else { + sp104 = spD8.r; + spE8 = 1.0f; + } + + camera->rUpdateRateInv = Camera_LERPCeilF(spE8, camera->rUpdateRateInv, PCT(OREG(25)), 0.1f); + spD8.r = spE8 = camera->dist = Camera_LERPCeilF(sp104, camera->dist, 1.0f / camera->rUpdateRateInv, 0.2f); + sp108 = camera->targetPosRot.pos; + OLib_Vec3fDiffToVecSphGeo(&spD0, at, &sp108); + spD0.r = spE8 - ((spD0.r <= spE8 ? spD0.r : spE8) * 0.5f); + spEC = keep1->unk_0C + ((keep1->unk_10 - keep1->unk_0C) * (1.1f - sp84)); + spF0 = OREG(13) + spEC; + spD8.r = camera->dist = Camera_LERPCeilF(spE8, camera->dist, PCT(OREG(11)), 2.0f); + spD8.yaw = spB8.yaw; + spE2 = BINANG_SUB(spD0.yaw, BINANG_ROT180(spB8.yaw)); + if (anim->unk_16 != 0) { + if (anim->unk_16 >= OREG(24)) { + sp82 = anim->unk_16 - OREG(24); + spE2 = spC8.yaw; + OLib_Vec3fDiffToVecSphGeo(&spC8, at, eye); + spC8.yaw = BINANG_ROT180(spE2); + + t2 = 1.0f / OREG(23); + spE8 = (anim->unk_00 - spC8.r) * t2; + spE2 = BINANG_SUB(anim->unk_12, spC8.yaw) * t2; + spE0 = BINANG_SUB(anim->unk_14, spC8.pitch) * t2; + + spD8.r = Camera_LERPCeilF(spC8.r + (spE8 * sp82), spC0.r, PCT(OREG(28)), 1.0f); + spD8.yaw = Camera_LERPCeilS(spC8.yaw + (spE2 * sp82), spC0.yaw, PCT(OREG(28)), 0xA); + spD8.pitch = Camera_LERPCeilS(spC8.pitch + (spE0 * sp82), spC0.pitch, PCT(OREG(28)), 0xA); + } else { + sp88 = 1; + } + anim->unk_16--; + } else if (ABS(spE2) > DEGF_TO_BINANG(spEC)) { + spF4 = BINANG_TO_DEGF(spE2); + t2 = spEC + (spF0 - spEC) * (OLib_ClampMaxDist(spD0.r, spD8.r) / spD8.r); + temp_f12_2 = ((SQ(t2) - 2.0f) / (t2 - 360.0f)); + t1 = (temp_f12_2 * spF4) + (2.0f - (360.0f * temp_f12_2)); + temp_f14 = SQ(spF4) / t1; + spE0 = spE2 >= 0 ? (DEGF_TO_BINANG(temp_f14)) : (-DEGF_TO_BINANG(temp_f14)); + spD8.yaw = BINANG_ROT180((s16)(BINANG_ROT180(spB8.yaw) + spE0)); + } else { + spF4 = 0.02f; + spF4 = (1.0f - camera->speedRatio) * spF4; + spE0 = spE2 >= 0 ? DEGF_TO_BINANG(spEC) : -DEGF_TO_BINANG(spEC); + spD8.yaw = spB8.yaw - (s16)((spE0 - spE2) * spF4); + } + + if (sp88 == 0) { + spE2 = DEGF_TO_BINANG((f32)(keep1->unk_14 + ((keep1->unk_18 - keep1->unk_14) * sp84))); + spE2 -= (s16)(spC8.pitch * (.5f + (sp84 * .5f))); + + spE8 = spD0.pitch * keep1->unk_1C; + spE2 += (s16)spE8; + if (spE2 < -0x3200) { + spE2 = -0x3200; + } else if (spE2 > 0x3200) { + spE2 = 0x3200; + } + + spD8.pitch = Camera_LERPCeilS(spE2, spB8.pitch, PCT(OREG(12)), 0xA); + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &spD8); + sp8C.pos = *eyeNext; + if (camera->status == CAM_STAT_ACTIVE) { + if ((camera->globalCtx->envCtx.skyDisabled == 0) || keep1->interfaceFlags & 1) { + Camera_BGCheckInfo(camera, at, &sp8C); + } else if (keep1->interfaceFlags & 2) { + func_80043F94(camera, at, &sp8C); + } else { + OLib_Vec3fDistNormalize(&sp120, at, &sp8C.pos); + sp8C.pos.x -= sp120.x; + sp8C.pos.y -= sp120.y; + sp8C.pos.z -= sp120.z; + } + *eye = sp8C.pos; + } else { + *eye = *eyeNext; + } + OLib_Vec3fDistNormalize(&sp120, eye, at); + Camera_Vec3fTranslateByUnitVector(eye, eye, &sp120, OREG(1)); + } + camera->fov = Camera_LERPCeilF(keep1->unk_20, camera->fov, camera->fovUpdateRate, 1.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5f, 0xA); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, sp80 ? keep1->unk_2C : keep1->unk_24); + return 1; +} s32 Camera_KeepOn2(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_KeepOn3.s") +/** + * Talking to an NPC + */ +s32 Camera_KeepOn3(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f playerHeadPos; + Vec3f lineChkPointB; + f32 temp_f0; + f32 spBC; + f32 prevTargetPlayerDist; + f32 swingAngle; + Actor* colChkActors[2]; + VecSph targetToPlayerDir; + VecSph atToEyeAdj; + VecSph atToEyeDir; + VecSph atToEyeNextDir; + s32 i; + s32 angleCnt; + s16 sp82; + s16 sp80; + PosRot playerPosRot; + PosRot* camPlayerPosRot = &camera->playerPosRot; + KeepOn3* keep3 = (KeepOn3*)camera->paramData; + Keep3Anim* anim = &keep3->anim; + s32 pad; + f32 playerHeight; + playerHeight = Player_GetHeight(camera->player); + if (camera->target == NULL || camera->target->update == NULL) { + if (camera->target == NULL) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: warning: talk: target is not valid, change parallel\n" VT_RST); + } + camera->target = NULL; + Camera_ChangeMode(camera, CAM_MODE_TARGET); + return 1; + } + if (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14) { + if (camera->globalCtx->view.unk_124 == 0) { + camera->unk_14C |= 0x20; + camera->globalCtx->view.unk_124 = camera->thisIdx | 0x50; + return 1; + } + camera->unk_14C &= ~0x20; + } + camera->unk_14C &= ~0x10; + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(OREG(46))) - (PCT(OREG(46)) * (68.0f / playerHeight)); + keep3->yOffset = NEXTPCT * playerHeight * yNormal; + keep3->minDist = NEXTSETTING; + keep3->maxDist = NEXTSETTING; + keep3->swingYawInital = NEXTSETTING; + keep3->swingYawFinal = NEXTSETTING; + keep3->swingPitchInitial = NEXTSETTING; + keep3->swingPitchFinal = NEXTSETTING; + keep3->swingPitchAdj = NEXTPCT; + keep3->fovTarget = NEXTSETTING; + keep3->atLERPScaleMax = NEXTPCT; + keep3->initTimer = NEXTSETTING; + keep3->flags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + playerHeight += keep3->yOffset; + OLib_Vec3fDiffToVecSphGeo(&atToEyeDir, at, eye); + OLib_Vec3fDiffToVecSphGeo(&atToEyeNextDir, at, eyeNext); + func_8002EEE4(&camera->targetPosRot, camera->target); + func_8002EEE4(&playerPosRot, &camera->player->actor); + playerHeadPos = camPlayerPosRot->pos; + playerHeadPos.y += playerHeight; + OLib_Vec3fDiffToVecSphGeo(&targetToPlayerDir, &playerHeadPos, &camera->targetPosRot.pos); + sCameraInterfaceFlags = keep3->flags; + if (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14) { + colChkActors[0] = camera->target; + colChkActors[1] = camera->player; + camera->animState++; + anim->target = camera->target; + temp_f0 = (keep3->maxDist < targetToPlayerDir.r ? 1.0f : targetToPlayerDir.r / keep3->maxDist); + anim->animTimer = keep3->initTimer; + spBC = ((1.0f - temp_f0) * targetToPlayerDir.r) / anim->animTimer; + swingAngle = F32_LERPIMP(keep3->swingPitchInitial, keep3->swingPitchFinal, temp_f0); + atToEyeAdj.pitch = DEGF_TO_BINANG(swingAngle) + ((s16)(-(targetToPlayerDir.pitch * keep3->swingPitchAdj))); + swingAngle = F32_LERPIMP(keep3->swingYawInital, keep3->swingYawFinal, temp_f0); + if (keep3->flags & 0x10) { + if (BINANG_SUB(targetToPlayerDir.yaw, atToEyeNextDir.yaw) < 0) { + atToEyeAdj.yaw = targetToPlayerDir.yaw + DEGF_TO_BINANG(swingAngle); + } else { + atToEyeAdj.yaw = targetToPlayerDir.yaw - DEGF_TO_BINANG(swingAngle); + } + } else if (keep3->flags & 0x20) { + if (BINANG_SUB(targetToPlayerDir.yaw, atToEyeNextDir.yaw) < 0) { + atToEyeAdj.yaw = BINANG_ROT180(targetToPlayerDir.yaw) - DEGF_TO_BINANG(swingAngle); + } else { + atToEyeAdj.yaw = BINANG_ROT180(targetToPlayerDir.yaw) + DEGF_TO_BINANG(swingAngle); + } + } else if (ABS(BINANG_SUB(targetToPlayerDir.yaw, atToEyeNextDir.yaw)) < 0x3FFF) { + if (BINANG_SUB(targetToPlayerDir.yaw, atToEyeNextDir.yaw) < 0) { + atToEyeAdj.yaw = targetToPlayerDir.yaw + DEGF_TO_BINANG(swingAngle); + } else { + atToEyeAdj.yaw = targetToPlayerDir.yaw - DEGF_TO_BINANG(swingAngle); + } + } else { + if (BINANG_SUB(targetToPlayerDir.yaw, atToEyeNextDir.yaw) < 0) { + atToEyeAdj.yaw = BINANG_ROT180(targetToPlayerDir.yaw) - DEGF_TO_BINANG(swingAngle); + } else { + atToEyeAdj.yaw = BINANG_ROT180(targetToPlayerDir.yaw) + DEGF_TO_BINANG(swingAngle); + } + } + prevTargetPlayerDist = targetToPlayerDir.r; + temp_f0 = 0.6f; + targetToPlayerDir.r = (spBC * 0.6f) + (prevTargetPlayerDist * (1.0f - temp_f0)); + sp80 = atToEyeAdj.yaw; + sp82 = atToEyeAdj.pitch; + playerHeadPos = camPlayerPosRot->pos; + playerHeadPos.y += playerHeight; + if (!temp_f0) {} + Camera_Vec3fVecSphGeoAdd(&anim->atTarget, &playerHeadPos, &targetToPlayerDir); + angleCnt = ARRAY_COUNT(D_8011D3B0); + i = 0; + targetToPlayerDir.r = prevTargetPlayerDist; + atToEyeAdj.r = ((keep3->minDist + (targetToPlayerDir.r * (1 - 0.5f))) - atToEyeNextDir.r) + atToEyeNextDir.r; + Camera_Vec3fVecSphGeoAdd(&lineChkPointB, &anim->atTarget, &atToEyeAdj); + if (!(keep3->flags & 0x80)) { + while (i < angleCnt) { + if (!func_800626B0(camera->globalCtx, &camera->globalCtx->colChkCtx, &anim->atTarget, &lineChkPointB, + &colChkActors, 2) && + !Camera_BGCheck(camera, &anim->atTarget, &lineChkPointB)) { + break; + } + atToEyeAdj.yaw = sp80 + D_8011D3B0[i]; + atToEyeAdj.pitch = sp82 + D_8011D3CC[i]; + Camera_Vec3fVecSphGeoAdd(&lineChkPointB, &anim->atTarget, &atToEyeAdj); + i++; + } + } + osSyncPrintf("camera: talk: BG&collision check %d time(s)\n", i); + camera->unk_14C &= ~0xC; + pad = ((anim->animTimer + 1) * anim->animTimer) >> 1; + anim->eyeToAtTarget.y = (f32)BINANG_SUB(atToEyeAdj.yaw, atToEyeNextDir.yaw) / pad; + anim->eyeToAtTarget.z = (f32)BINANG_SUB(atToEyeAdj.pitch, atToEyeNextDir.pitch) / pad; + anim->eyeToAtTarget.x = (atToEyeAdj.r - atToEyeNextDir.r) / pad; + return 1; + } + + if (anim->animTimer != 0) { + at->x += (anim->atTarget.x - at->x) / anim->animTimer; + at->y += (anim->atTarget.y - at->y) / anim->animTimer; + at->z += (anim->atTarget.z - at->z) / anim->animTimer; + // needed to match + if (!prevTargetPlayerDist) {} + atToEyeAdj.r = ((anim->eyeToAtTarget.x * anim->animTimer) + atToEyeNextDir.r) + 1.0f; + atToEyeAdj.yaw = atToEyeNextDir.yaw + (s16)(anim->eyeToAtTarget.y * anim->animTimer); + atToEyeAdj.pitch = atToEyeNextDir.pitch + (s16)(anim->eyeToAtTarget.z * anim->animTimer); + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &atToEyeAdj); + *eye = *eyeNext; + camera->fov = Camera_LERPCeilF(keep3->fovTarget, camera->fov, 0.5, 1.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5, 0xA); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, keep3->atLERPScaleMax); + Camera_BGCheck(camera, at, eye); + anim->animTimer--; + } else { + camera->unk_14C |= 0x410; + } + + if (camera->unk_14C & 8) { + sCameraInterfaceFlags = 0; + func_80043B60(camera); + camera->atLERPStepScale = 0.0f; + + if (camera->xzSpeed > 0.001f || CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_A) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_B) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CLEFT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CDOWN) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CUP) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CRIGHT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_R) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_Z)) { + camera->unk_14C |= 4; + camera->unk_14C &= ~8; + } + } + return 1; +} + +#ifdef NON_MATCHING +s32 Camera_KeepOn4(Camera* camera) { + static Vec3f D_8015BD50; + static Vec3f D_8015BD60; + static Vec3f D_8015BD70; + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Actor* spCC[2]; + f32 t = -0.5f; + f32 temp_f0_2; + CollisionPoly* spC0; + VecSph spB8; + VecSph spB0; + VecSph spA8; + s16* temp_s0 = &camera->data2; + s16 spA2; + s16 spA0; + s16 sp9E; + s16 sp9C; + PosRot* playerPosRot = &camera->playerPosRot; + KeepOn4* keep4 = (KeepOn4*)camera->paramData; + KeepOn4_Unk20* unk20 = &keep4->unk_20; + s32 pad; + f32 playerHeight; + Player* player; + s16 angleCnt; + s32 i; + + player = (Player*)camera->globalCtx->actorCtx.actorList[ACTORTYPE_PLAYER].first; + + if (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14) { + if (camera->globalCtx->view.unk_124 == 0) { + camera->unk_14C |= 0x20; + camera->unk_14C &= ~(0x4 | 0x2); + camera->globalCtx->view.unk_124 = camera->thisIdx | 0x50; + return 1; + } + camera->unk_14C &= ~0x20; + unk20->unk_14 = *temp_s0; + } + + if (unk20->unk_14 != *temp_s0) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: item: item type changed %d -> %d\n" VT_RST, unk20->unk_14, + *temp_s0); + camera->unk_14C |= 0x20; + camera->animState = 0x14; + camera->unk_14C &= ~(0x4 | 0x2); + camera->globalCtx->view.unk_124 = camera->thisIdx | 0x50; + return 1; + } + + playerHeight = Player_GetHeight(camera->player); + camera->unk_14C &= ~0x10; + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + t) - ((68.0f / playerHeight) * t); + keep4->unk_00 = NEXTPCT * playerHeight * yNormal; + keep4->unk_04 = NEXTPCT * playerHeight * yNormal; + keep4->unk_08 = NEXTSETTING; + keep4->unk_0C = NEXTSETTING; + keep4->unk_10 = NEXTSETTING; + keep4->unk_18 = NEXTSETTING; + keep4->unk_1C = NEXTSETTING; + keep4->unk_14 = NEXTPCT; + keep4->unk_1E = NEXTSETTING; + osSyncPrintf("camera: item: type %d\n", *temp_s0); + switch (*temp_s0) { + case 1: + keep4->unk_00 = playerHeight * -0.6f * yNormal; + keep4->unk_04 = playerHeight * 2.0f * yNormal; + keep4->unk_08 = 10.0f; + break; + case 2: + case 3: + keep4->unk_08 = -20.0f; + keep4->unk_18 = 80.0f; + break; + case 4: + keep4->unk_00 = playerHeight * -0.2f * yNormal; + keep4->unk_08 = 25.0f; + break; + case 8: + keep4->unk_00 = playerHeight * -0.2f * yNormal; + keep4->unk_04 = playerHeight * 0.8f * yNormal; + keep4->unk_08 = 50.0f; + keep4->unk_18 = 70.0f; + break; + case 9: + keep4->unk_00 = playerHeight * 0.1f * yNormal; + keep4->unk_04 = playerHeight * 0.5f * yNormal; + keep4->unk_08 = -20.0f; + keep4->unk_0C = 0.0f; + keep4->unk_1C = 0x2540; + break; + case 5: + keep4->unk_00 = playerHeight * -0.4f * yNormal; + keep4->unk_08 = -10.0f; + keep4->unk_0C = 45.0f; + keep4->unk_1C = 0x2002; + break; + case 10: + keep4->unk_00 = playerHeight * -0.5f * yNormal; + keep4->unk_04 = playerHeight * 1.5f * yNormal; + keep4->unk_08 = -15.0f; + keep4->unk_0C = 175.0f; + keep4->unk_18 = 70.0f; + keep4->unk_1C = 0x2202; + keep4->unk_1E = 0x3C; + break; + case 12: + keep4->unk_00 = playerHeight * -0.6f * yNormal; + keep4->unk_04 = playerHeight * 1.6f * yNormal; + keep4->unk_08 = -2.0f; + keep4->unk_0C = 120.0f; + keep4->unk_10 = player->stateFlags1 & 0x8000000 ? 0.0f : 20.0f; + keep4->unk_1C = 0x3212; + keep4->unk_1E = 0x1E; + keep4->unk_18 = 50.0f; + break; + case 0x5A: + keep4->unk_00 = playerHeight * -0.3f * yNormal; + keep4->unk_18 = 45.0f; + keep4->unk_1C = 0x2F02; + break; + case 0x5B: + keep4->unk_00 = playerHeight * -0.1f * yNormal; + keep4->unk_04 = playerHeight * 1.5f * yNormal; + keep4->unk_08 = -3.0f; + keep4->unk_0C = 10.0f; + keep4->unk_18 = 55.0f; + keep4->unk_1C = 0x2F08; + break; + case 0x51: + keep4->unk_00 = playerHeight * -0.3f * yNormal; + keep4->unk_04 = playerHeight * 1.5f * yNormal; + keep4->unk_08 = 2.0f; + keep4->unk_0C = 20.0f; + keep4->unk_10 = 20.0f; + keep4->unk_1C = 0x2280; + keep4->unk_1E = 0x1E; + keep4->unk_18 = 45.0f; + break; + case 11: + keep4->unk_00 = playerHeight * -0.19f * yNormal; + keep4->unk_04 = playerHeight * 0.7f * yNormal; + keep4->unk_0C = 130.0f; + keep4->unk_10 = 10.0f; + keep4->unk_1C = 0x2522; + break; + default: + break; + } + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + sUpdateCameraDirection = 1; + sCameraInterfaceFlags = keep4->unk_1C; + OLib_Vec3fDiffToVecSphGeo(&spB0, at, eye); + OLib_Vec3fDiffToVecSphGeo(&spA8, at, eyeNext); + D_8015BD50 = playerPosRot->pos; + D_8015BD50.y += playerHeight; + temp_f0_2 = func_8003CCA4(&camera->globalCtx->colCtx, &spC0, &i, &D_8015BD50); + if (temp_f0_2 > (keep4->unk_00 + D_8015BD50.y)) { + D_8015BD50.y = temp_f0_2 + 10.0f; + } else { + D_8015BD50.y += keep4->unk_00; + } + + sp9C = 0; + switch (camera->animState) { + case 0: + case 0x14: + spCC[sp9C] = &camera->player->actor; + sp9C++; + func_80043ABC(camera); + camera->unk_14C &= ~(0x4 | 0x2); + unk20->unk_10 = keep4->unk_1E; + unk20->unk_08 = playerPosRot->pos.y - camera->playerPosDelta.y; + if (keep4->unk_1C & 2) { + spA2 = DEGF_TO_BINANG(keep4->unk_08); + spA0 = BINANG_SUB(BINANG_ROT180(playerPosRot->rot.y), spA8.yaw) > 0 + ? BINANG_ROT180(playerPosRot->rot.y) + DEGF_TO_BINANG(keep4->unk_0C) + : BINANG_ROT180(playerPosRot->rot.y) - DEGF_TO_BINANG(keep4->unk_0C); + } else if (keep4->unk_1C & 4) { + spA2 = DEGF_TO_BINANG(keep4->unk_08); + spA0 = DEGF_TO_BINANG(keep4->unk_0C); + } else if ((keep4->unk_1C & 8) && camera->target != NULL) { + PosRot sp60; + func_8002EF44(&sp60, camera->target); + spA2 = DEGF_TO_BINANG(keep4->unk_08) - sp60.rot.x; + spA0 = BINANG_SUB(BINANG_ROT180(sp60.rot.y), spA8.yaw) > 0 + ? BINANG_ROT180(sp60.rot.y) + DEGF_TO_BINANG(keep4->unk_0C) + : BINANG_ROT180(sp60.rot.y) - DEGF_TO_BINANG(keep4->unk_0C); + spCC[1] = camera->target; + sp9C++; + } else if ((keep4->unk_1C & 0x80) && camera->target != NULL) { + PosRot sp4C; + func_8002EF14(&sp4C, camera->target); + spA2 = ((s16)((keep4->unk_08) * (182.04167f) + .5f)); + if (1) { + sp9E = Camera_XZAngle(&sp4C.pos, &playerPosRot->pos); + spA0 = (BINANG_SUB(sp9E, spA8.yaw) > 0) ? sp9E + ((s16)((keep4->unk_0C) * (182.04167f) + .5f)) + : sp9E - ((s16)((keep4->unk_0C) * (182.04167f) + .5f)); + } + spCC[1] = camera->target; + sp9C++; + } else if (keep4->unk_1C & 0x40) { + spA2 = DEGF_TO_BINANG(keep4->unk_08); + spA0 = spA8.yaw; + } else { + spA2 = spA8.pitch; + spA0 = spA8.yaw; + } + + spB8.pitch = spA2; + spB8.yaw = spA0; + spB8.r = keep4->unk_04; + Camera_Vec3fVecSphGeoAdd(&D_8015BD70, &D_8015BD50, &spB8); + if (!(keep4->unk_1C & 1)) { + angleCnt = ARRAY_COUNT(D_8011D3B0); + for (i = 0; i < angleCnt; i++) { + if (!func_800626B0(camera->globalCtx, &camera->globalCtx->colChkCtx, &D_8015BD50, &D_8015BD70, spCC, + sp9C) && + !Camera_BGCheck(camera, &D_8015BD50, &D_8015BD70)) { + break; + } + spB8.yaw = D_8011D3B0[i] + spA0; + spB8.pitch = D_8011D3CC[i] + spA2; + Camera_Vec3fVecSphGeoAdd(&D_8015BD70, &D_8015BD50, &spB8); + } + osSyncPrintf("camera: item: BG&collision check %d time(s)\n", i); + } + temp_f0_2 = BINANG_SUB(spB8.pitch, spA8.pitch) / (f32)unk20->unk_10; + unk20->unk_04 = temp_f0_2; + unk20->unk_00 = BINANG_SUB(spB8.yaw, spA8.yaw) / (f32)unk20->unk_10; + unk20->unk_0C = spA8.yaw; + unk20->unk_0E = spA8.pitch; + camera->animState++; + unk20->unk_12 = 1; + break; + case 0xA: + unk20->unk_08 = playerPosRot->pos.y - camera->playerPosDelta.y; + default: + break; + } + camera->xzOffsetUpdateRate = 0.25f; + camera->yOffsetUpdateRate = 0.25f; + camera->atLERPStepScale = 0.75f; + Camera_LERPCeilVec3f(&D_8015BD50, at, 0.5f, 0.5f, 0.2f); + if (keep4->unk_10 != 0.0f) { + spB8.r = keep4->unk_10; + spB8.pitch = 0; + spB8.yaw = playerPosRot->rot.y; + Camera_Vec3fVecSphGeoAdd(at, at, &spB8); + } + camera->atLERPStepScale = 0.0f; + spB8.r = camera->dist = Camera_LERPCeilF(keep4->unk_04, camera->dist, 0.25f, 2.0f); + if (unk20->unk_10 != 0) { + camera->unk_14C |= 0x20; + unk20->unk_0C += (s16)unk20->unk_00; + unk20->unk_0E += (s16)unk20->unk_04; + unk20->unk_10--; + } else if (keep4->unk_1C & 0x10) { + camera->unk_14C |= (0x400 | 0x10); + camera->unk_14C |= (0x4 | 0x2); + camera->unk_14C &= ~8; + if (camera->timer > 0) { + camera->timer--; + } + } else { + camera->unk_14C |= (0x400 | 0x10); + if (camera->unk_14C & 8 || keep4->unk_1C & 0x80) { + sCameraInterfaceFlags = 0; + camera->unk_14C |= (0x4 | 0x2); + camera->unk_14C &= ~8; + if (camera->prevCamDataIdx < 0) { + Camera_ChangeSettingFlags(camera, camera->prevSetting, 2); + } else { + Camera_ChangeDataIdx(camera, camera->prevCamDataIdx); + camera->prevCamDataIdx = -1; + } + } + } + spB8.yaw = Camera_LERPCeilS(unk20->unk_0C, spA8.yaw, keep4->unk_14, 4); + spB8.pitch = Camera_LERPCeilS(unk20->unk_0E, spA8.pitch, keep4->unk_14, 4); + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &spB8); + *eye = *eyeNext; + Camera_BGCheck(camera, at, eye); + camera->fov = Camera_LERPCeilF(keep4->unk_18, camera->fov, camera->fovUpdateRate, 1.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5f, 0xA); +} +#else +Vec3f D_8015BD50; +Vec3f D_8015BD60; +Vec3f D_8015BD70; #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_KeepOn4.s") +#endif + +/** + * Talking in a pre-rendered room + */ +s32 Camera_KeepOn0(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f* at = &camera->at; + VecSph eyeTargetPosOffset; + VecSph eyeAtOffset; + KeepOn0* keep0 = (KeepOn0*)camera->paramData; + KeepOn0Anim* anim = &keep0->anim; + s32 pad; + Vec3s* sceneCamData; + Vec3s sceneCamRot; + s16 fov; + + camera->unk_14C &= ~0x10; + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + keep0->fovScale = NEXTPCT; + keep0->yawScale = NEXTPCT; + keep0->timerInit = NEXTSETTING; + keep0->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + sceneCamData = Camera_GetCamBGData(camera); + Camera_Vec3sToVec3f(eyeNext, &BGCAM_POS(sceneCamData)); + *eye = *eyeNext; + + sceneCamRot = BGCAM_ROT(sceneCamData); // unused + + fov = BGCAM_FOV(sceneCamData); + if (fov == -1) { + fov = 6000; + } + + if (camera->target == NULL || camera->target->update == NULL) { + if (camera->target == NULL) { + osSyncPrintf( + VT_COL(YELLOW, BLACK) "camera: warning: talk: target is not valid, change normal camera\n" VT_RST); + } + camera->target = NULL; + Camera_ChangeMode(camera, CAM_MODE_NORMAL); + return true; + } + + func_8002EEE4(&camera->targetPosRot, camera->target); + + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, eye, at); + OLib_Vec3fDiffToVecSphGeo(&eyeTargetPosOffset, eye, &camera->targetPosRot.pos); + + sCameraInterfaceFlags = keep0->interfaceFlags; + + if (camera->animState == 0) { + camera->animState++; + camera->fov = PCT(fov); + camera->roll = 0; + camera->atLERPStepScale = 0.0f; + anim->animTimer = keep0->timerInit; + anim->fovTarget = camera->fov - (camera->fov * keep0->fovScale); + } + + if (anim->animTimer != 0) { + eyeAtOffset.yaw += (BINANG_SUB(eyeTargetPosOffset.yaw, eyeAtOffset.yaw) / anim->animTimer) * keep0->yawScale; + Camera_Vec3fVecSphGeoAdd(at, eye, &eyeAtOffset); + anim->animTimer--; + } else { + camera->unk_14C |= (0x400 | 0x10); + } + camera->fov = Camera_LERPCeilF(anim->fovTarget, camera->fov, 0.5f, 10.0f); + return true; +} + +s32 Camera_Fixed1(Camera* camera) { + Fixed1* fixd1 = (Fixed1*)camera->paramData; + Fixed1Anim* anim = &fixd1->anim; + s32 pad; + VecSph eyeOffset; + VecSph eyeAtOffset; + s32 pad2; + Vec3f adjustedPos; + Vec3s* scenePosData; + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + PosRot* playerPosRot = &camera->playerPosRot; + f32 playerHeight; + + playerHeight = Player_GetHeight(camera->player); + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + scenePosData = Camera_GetCamBGData(camera); + Camera_Vec3sToVec3f(&anim->eyePosRotTarget.pos, &BGCAM_POS(scenePosData)); + anim->eyePosRotTarget.rot = BGCAM_ROT(scenePosData); + anim->fov = BGCAM_FOV(scenePosData); + fixd1->unk_00 = NEXTPCT * playerHeight; + fixd1->lerpStep = NEXTPCT; + fixd1->fov = NEXTSETTING; + fixd1->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + if (anim->fov == -1) { + anim->fov = fixd1->fov * 100.0f; + } else if (anim->fov < 361) { + anim->fov *= 100; + } + + sCameraInterfaceFlags = fixd1->interfaceFlags; + + if (camera->animState == 0) { + camera->animState++; + func_80043B60(camera); + if (anim->fov != -1) { + fixd1->fov = PCT(anim->fov); + } + } + + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, eye, at); + + Camera_LERPCeilVec3f(&anim->eyePosRotTarget.pos, eye, 0.1f, 0.1f, 0.2f); + adjustedPos = playerPosRot->pos; + adjustedPos.y += playerHeight; + camera->dist = OLib_Vec3fDist(&adjustedPos, eye); + + eyeOffset.r = camera->dist; + eyeOffset.pitch = Camera_LERPCeilS(-anim->eyePosRotTarget.rot.x, eyeAtOffset.pitch, fixd1->lerpStep, 5); + eyeOffset.yaw = Camera_LERPCeilS(anim->eyePosRotTarget.rot.y, eyeAtOffset.yaw, fixd1->lerpStep, 5); + + Camera_Vec3fVecSphGeoAdd(at, eye, &eyeOffset); + + camera->eyeNext = *eye; + + camera->fov = Camera_LERPCeilF(fixd1->fov, camera->fov, fixd1->lerpStep, 0.01f); + camera->roll = 0; + camera->atLERPStepScale = 0.0f; + + camera->posOffset.x = camera->at.x - playerPosRot->pos.x; + camera->posOffset.y = camera->at.y - playerPosRot->pos.y; + camera->posOffset.z = camera->at.z - playerPosRot->pos.z; + + return true; +} + +s32 Camera_Fixed2(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f atTarget; + Vec3f posOffsetTarget; + PosRot* playerPosRot = &camera->playerPosRot; + Vec3s* scenePosData; + Fixed2* fixd2 = (Fixed2*)camera->paramData; + Fixed2InitParams* initParams = &fixd2->initParams; + s32 pad; + f32 playerHeight; + + playerHeight = Player_GetHeight(camera->player); + + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight)); + fixd2->yOffset = (NEXTPCT * playerHeight) * yNormal; + fixd2->eyeStepScale = NEXTPCT; + fixd2->posStepScale = NEXTPCT; + fixd2->fov = NEXTSETTING; + fixd2->interfaceFlags = NEXTSETTING; + initParams->fov = fixd2->fov * 100.0f; + scenePosData = Camera_GetCamBGData(camera); + if (scenePosData != NULL) { + Camera_Vec3sToVec3f(&initParams->eye, &BGCAM_POS(scenePosData)); + if (BGCAM_FOV(scenePosData) != -1) { + initParams->fov = BGCAM_FOV(scenePosData); + } + } else { + initParams->eye = *eye; + } + if (initParams->fov < 361) { + initParams->fov *= 100; + } + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + sCameraInterfaceFlags = fixd2->interfaceFlags; + + posOffsetTarget.x = 0.0f; + posOffsetTarget.y = fixd2->yOffset + playerHeight; + posOffsetTarget.z = 0.0f; + + Camera_LERPCeilVec3f(&posOffsetTarget, &camera->posOffset, fixd2->posStepScale, fixd2->posStepScale, 0.1f); + atTarget.x = playerPosRot->pos.x + camera->posOffset.x; + atTarget.y = playerPosRot->pos.y + camera->posOffset.y; + atTarget.z = playerPosRot->pos.z + camera->posOffset.z; + if (camera->animState == 0) { + camera->animState++; + func_80043B60(camera); + if (!(fixd2->interfaceFlags & 1)) { + *eye = *eyeNext = initParams->eye; + camera->at = atTarget; + } + } + + Camera_LERPCeilVec3f(&atTarget, &camera->at, fixd2->posStepScale, fixd2->posStepScale, 10.0f); + Camera_LERPCeilVec3f(&initParams->eye, eyeNext, fixd2->eyeStepScale, fixd2->eyeStepScale, 0.1f); + + *eye = *eyeNext; + camera->dist = OLib_Vec3fDist(at, eye); + camera->roll = 0; + camera->xzSpeed = 0.0f; + camera->fov = PCT(initParams->fov); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, 1.0f); + camera->posOffset.x = camera->at.x - playerPosRot->pos.x; + camera->posOffset.y = camera->at.y - playerPosRot->pos.y; + camera->posOffset.z = camera->at.z - playerPosRot->pos.z; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_KeepOn0.s") +/** + * Camera's position is fixed, does not move, or rotate + */ +s32 Camera_Fixed3(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + VecSph atSph; + Vec3s* sceneCamData; + VecSph eyeAtOffset; + Fixed3* fixd3 = (Fixed3*)camera->paramData; + Fixed3Anim* anim = &fixd3->anim; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Fixed1.s") + sceneCamData = Camera_GetCamBGData(camera); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Fixed2.s") + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, eye, at); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Fixed3.s") + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + fixd3->interfaceFlags = NEXTSETTING; + Camera_Vec3sToVec3f(eyeNext, &BGCAM_POS(sceneCamData)); + *eye = *eyeNext; + anim->rot = BGCAM_ROT(sceneCamData); + anim->fov = BGCAM_FOV(sceneCamData); + anim->jfifId = BGCAM_JFIFID(sceneCamData); + if (anim->fov == -1) { + anim->fov = 6000; + } + if (anim->fov <= 360) { + anim->fov *= 100; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Fixed4.s") + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + if (camera->animState == 0) { + anim->updDirTimer = 5; + R_CAM_FIXED3_FOV = anim->fov; + camera->animState++; + } + + if (BGCAM_JFIFID(sceneCamData) != anim->jfifId) { + osSyncPrintf("camera: position change %d \n", anim->jfifId); + anim->jfifId = BGCAM_JFIFID(sceneCamData); + anim->updDirTimer = 5; + } + + if (anim->updDirTimer > 0) { + anim->updDirTimer--; + sUpdateCameraDirection = true; + } else { + sUpdateCameraDirection = false; + } + + atSph.r = 150.0f; + atSph.yaw = anim->rot.y; + atSph.pitch = -anim->rot.x; + + Camera_Vec3fVecSphGeoAdd(at, eye, &atSph); + sCameraInterfaceFlags = fixd3->interfaceFlags; + anim->fov = R_CAM_FIXED3_FOV; + camera->roll = 0; + camera->fov = anim->fov * 0.01f; + camera->atLERPStepScale = 0.0f; + return true; +} + +/** + * camera follow player, eye is in a fixed offset of the previous eye, and a value + * specified in the scene. + */ +s32 Camera_Fixed4(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f playerPosWithCamOffset; + Vec3f atTarget; + Vec3f posOffsetTarget; + VecSph atEyeNextOffset; + VecSph atTargetEyeNextOffset; + PosRot* playerPosRot = &camera->playerPosRot; + Vec3s* camPosData; + Vec3f* posOffset = &camera->posOffset; + Fixed4* fixed4 = (Fixed4*)camera->paramData; + Fixed4Anim* anim = &fixed4->anim; + f32 playerYOffset; + + playerYOffset = Player_GetHeight(camera->player); + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = ((1.0f + PCT(OREG(46))) - (PCT(OREG(46)) * (68.0f / playerYOffset))); + fixed4->yOffset = NEXTPCT * playerYOffset * yNormal; + fixed4->speedToEyePos = NEXTPCT; + fixed4->followSpeed = NEXTPCT; + fixed4->fov = NEXTSETTING; + fixed4->interfaceFlags = NEXTSETTING; + camPosData = Camera_GetCamBGData(camera); + if (camPosData != NULL) { + Camera_Vec3sToVec3f(&anim->eyeTarget, &BGCAM_POS(camPosData)); + } else { + anim->eyeTarget = *eye; + } + } + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + sCameraInterfaceFlags = fixed4->interfaceFlags; + if (camera->animState == 0) { + camera->animState++; + if (!(fixed4->interfaceFlags & 4)) { + func_80043B60(camera); + } + anim->followSpeed = fixed4->followSpeed; + } + + VEC3F_LERPIMPDST(eyeNext, eyeNext, &anim->eyeTarget, fixed4->speedToEyePos); + *eye = *eyeNext; + + posOffsetTarget.x = 0.0f; + posOffsetTarget.y = fixed4->yOffset + playerYOffset; + posOffsetTarget.z = 0.0f; + Camera_LERPCeilVec3f(&posOffsetTarget, &camera->posOffset, 0.1f, 0.1f, 0.1f); + + playerPosWithCamOffset.x = playerPosRot->pos.x + camera->posOffset.x; + playerPosWithCamOffset.y = playerPosRot->pos.y + camera->posOffset.y; + playerPosWithCamOffset.z = playerPosRot->pos.z + camera->posOffset.z; + VEC3F_LERPIMPDST(&atTarget, at, &playerPosWithCamOffset, 0.5f); + + OLib_Vec3fDiffToVecSphGeo(&atEyeNextOffset, eyeNext, at); + OLib_Vec3fDiffToVecSphGeo(&atTargetEyeNextOffset, eyeNext, &atTarget); + + atEyeNextOffset.r += (atTargetEyeNextOffset.r - atEyeNextOffset.r) * anim->followSpeed; + atEyeNextOffset.pitch = Camera_LERPCeilS(atTargetEyeNextOffset.pitch, atEyeNextOffset.pitch, + anim->followSpeed * camera->speedRatio, 0xA); + atEyeNextOffset.yaw = + Camera_LERPCeilS(atTargetEyeNextOffset.yaw, atEyeNextOffset.yaw, anim->followSpeed * camera->speedRatio, 0xA); + Camera_Vec3fVecSphGeoAdd(at, eyeNext, &atEyeNextOffset); + camera->dist = OLib_Vec3fDist(at, eye); + camera->roll = 0; + camera->fov = fixed4->fov; + camera->atLERPStepScale = Camera_ClampLERPScale(camera, 1.0f); + return true; +} s32 Camera_Fixed0(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Subj1(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Subj2(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Subj3.s") +/** + * First person view + */ +s32 Camera_Subj3(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f sp98; + Vec3f sp8C; + VecSph sp84; + VecSph sp7C; + VecSph tsph; + PosRot sp60; + PosRot* playerPosRot = &camera->playerPosRot; + f32 sp58; + f32 temp_f0_3; + s16 sp52; + s16 sp50; + Subj3* subj3 = (Subj3*)camera->paramData; + Subj3Anim* anim = &subj3->anim; + CameraModeValue* values; + Vec3f* pad2; + f32 playerHeight; + + func_8002EEE4(&sp60, &camera->player->actor); + playerHeight = Player_GetHeight(camera->player); + + if (camera->globalCtx->view.unk_124 == 0) { + camera->globalCtx->view.unk_124 = camera->thisIdx | 0x50; + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Subj4.s") + func_80043ABC(camera); + Camera_CopyPREGToModeValues(camera); + values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + subj3->eyeNextYOffset = NEXTPCT * playerHeight; + subj3->eyeDist = NEXTSETTING; + subj3->eyeNextDist = NEXTSETTING; + subj3->unk_0C = NEXTSETTING; + subj3->atOffset.x = NEXTSETTING * 0.1f; + subj3->atOffset.y = NEXTSETTING * 0.1f; + subj3->atOffset.z = NEXTSETTING * 0.1f; + subj3->fovTarget = NEXTSETTING; + subj3->interfaceFlags = NEXTSETTING; + sp84.r = subj3->eyeNextDist; + sp84.yaw = BINANG_ROT180(sp60.rot.y); + sp84.pitch = sp60.rot.x; + sp98 = sp60.pos; + sp98.y += subj3->eyeNextYOffset; + + Camera_Vec3fVecSphGeoAdd(&sp8C, &sp98, &sp84); + OLib_Vec3fDiffToVecSphGeo(&sp7C, at, eye); + + sCameraInterfaceFlags = subj3->interfaceFlags; + if (camera->animState == 0 || camera->animState == 0xA || camera->animState == 0x14) { + anim->r = sp7C.r; + anim->yaw = sp7C.yaw; + anim->pitch = sp7C.pitch; + anim->animTimer = OREG(23); + camera->dist = subj3->eyeNextDist; + camera->animState++; + camera->rUpdateRateInv = 1.0f; + camera->dist = subj3->eyeNextDist; + } + + tsph.r = anim->r; + tsph.yaw = anim->yaw; + tsph.pitch = anim->pitch; + if (anim->animTimer != 0) { + temp_f0_3 = (1.0f / anim->animTimer); + pad2 = at; + at->x = at->x + (sp98.x - pad2->x) * temp_f0_3; + at->y = at->y + (sp98.y - pad2->y) * temp_f0_3; + at->z = at->z + (sp98.z - pad2->z) * temp_f0_3; + + temp_f0_3 = (1.0f / OREG(23)); + sp58 = (tsph.r - sp84.r) * temp_f0_3; + sp52 = BINANG_SUB(tsph.yaw, sp84.yaw) * temp_f0_3; + sp50 = BINANG_SUB(tsph.pitch, sp84.pitch) * temp_f0_3; + + sp7C.r = Camera_LERPCeilF(sp84.r + (sp58 * anim->animTimer), sp7C.r, PCT(OREG(28)), 1.0f); + sp7C.yaw = Camera_LERPCeilS(sp84.yaw + (sp52 * anim->animTimer), sp7C.yaw, PCT(OREG(28)), 0xA); + sp7C.pitch = Camera_LERPCeilS(sp84.pitch + (sp50 * anim->animTimer), sp7C.pitch, PCT(OREG(28)), 0xA); + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &sp7C); + + *eye = *eyeNext; + anim->animTimer--; + + if (camera->globalCtx->envCtx.skyDisabled == 0) { + Camera_BGCheck(camera, at, eye); + } else { + func_80044340(camera, at, eye); + } + } else { + sp58 = Math_Sins(-sp60.rot.x); + temp_f0_3 = Math_Coss(-sp60.rot.x); + sp98.x = subj3->atOffset.x; + sp98.y = (subj3->atOffset.y * temp_f0_3) - (subj3->atOffset.z * sp58); + sp98.z = (subj3->atOffset.y * sp58) + (subj3->atOffset.z * temp_f0_3); + sp58 = Math_Sins(BINANG_ROT180(sp60.rot.y)); + temp_f0_3 = Math_Coss(BINANG_ROT180(sp60.rot.y)); + subj3->atOffset.x = (sp98.z * sp58) + (sp98.x * temp_f0_3); + subj3->atOffset.y = sp98.y; + subj3->atOffset.z = (sp98.z * temp_f0_3) - (sp98.x * sp58); + at->x = subj3->atOffset.x + sp60.pos.x; + at->y = subj3->atOffset.y + sp60.pos.y; + at->z = subj3->atOffset.z + sp60.pos.z; + sp7C.r = subj3->eyeNextDist; + sp7C.yaw = BINANG_ROT180(sp60.rot.y); + sp7C.pitch = sp60.rot.x; + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &sp7C); + sp7C.r = subj3->eyeDist; + Camera_Vec3fVecSphGeoAdd(eye, at, &sp7C); + } + + camera->posOffset.x = camera->at.x - playerPosRot->pos.x; + camera->posOffset.y = camera->at.y - playerPosRot->pos.y; + camera->posOffset.z = camera->at.z - playerPosRot->pos.z; + camera->fov = Camera_LERPCeilF(subj3->fovTarget, camera->fov, 0.25f, 1.0f); + camera->roll = 0; + camera->atLERPStepScale = 0.0f; + return 1; +} + +s32 Camera_Subj4(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f* at = &camera->at; + u16 spAA; + Vec3s* spA4; + Vec3f sp98; + Vec3f sp8C; + f32 sp88; + s16 pad2; + f32 temp_f16; + PosRot sp6C; + VecSph sp64; + VecSph sp5C; + s16 temp_a0; + f32 tx; + Player* player; + PosRot* playerPosRot = &camera->playerPosRot; + Subj4* subj4 = (Subj4*)camera->paramData; + Subj4Anim* anim = &subj4->anim; + + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + subj4->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + if (camera->globalCtx->view.unk_124 == 0) { + camera->globalCtx->view.unk_124 = (camera->thisIdx | 0x50); + anim->unk_24 = camera->xzSpeed; + return true; + } + + func_8002EF44(&sp6C, &camera->player->actor); + + OLib_Vec3fDiffToVecSphGeo(&sp5C, at, eye); + sCameraInterfaceFlags = subj4->interfaceFlags; + if (camera->animState == 0) { + spA4 = Camera_GetCamBgDataUnderPlayer(camera, &spAA); + Camera_Vec3sToVec3f(&anim->unk_00.a, &spA4[1]); + Camera_Vec3sToVec3f(&sp98, &spA4[spAA - 2]); + + sp64.r = 10.0f; + // 0x238C ~ 50 degrees + sp64.pitch = 0x238C; + sp64.yaw = Camera_XZAngle(&sp98, &anim->unk_00.a); + sp88 = OLib_Vec3fDist(&playerPosRot->pos, &anim->unk_00.a); + if (OLib_Vec3fDist(&playerPosRot->pos, &sp98) < sp88) { + anim->unk_00.b.x = anim->unk_00.a.x - sp98.x; + anim->unk_00.b.y = anim->unk_00.a.y - sp98.y; + anim->unk_00.b.z = anim->unk_00.a.z - sp98.z; + anim->unk_00.a = sp98; + } else { + anim->unk_00.b.x = sp98.x - anim->unk_00.a.x; + anim->unk_00.b.y = sp98.y - anim->unk_00.a.y; + anim->unk_00.b.z = sp98.z - anim->unk_00.a.z; + sp64.yaw = BINANG_ROT180(sp64.yaw); + } + anim->unk_30 = sp64.yaw; + anim->unk_32 = 0xA; + anim->unk_2C = 0; + anim->unk_2E = false; + anim->unk_28 = 0.0f; + camera->animState++; + } + + if (anim->unk_32 != 0) { + sp64.r = 10.0f; + sp64.pitch = 0x238C; + sp64.yaw = anim->unk_30; + Camera_Vec3fVecSphGeoAdd(&sp8C, &sp6C.pos, &sp64); + sp88 = (anim->unk_32 + 1.0f); + at->x += (sp8C.x - at->x) / sp88; + at->y += (sp8C.y - at->y) / sp88; + at->z += (sp8C.z - at->z) / sp88; + sp5C.r -= (sp5C.r / sp88); + sp5C.yaw = BINANG_LERPIMPINV(sp5C.yaw, BINANG_ROT180(sp6C.rot.y), anim->unk_32); + sp5C.pitch = BINANG_LERPIMPINV(sp5C.pitch, sp6C.rot.x, anim->unk_32); + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &sp5C); + *eye = *eyeNext; + anim->unk_32--; + return false; + } else if (anim->unk_24 < 0.5f) { + return false; + } + + func_8002EF44(&sp6C, &camera->player->actor); + Math3D_LineClosestToPoint(&anim->unk_00, &sp6C.pos, eyeNext); + at->x = eyeNext->x + anim->unk_00.b.x; + at->y = eyeNext->y + anim->unk_00.b.y; + at->z = eyeNext->z + anim->unk_00.b.z; + *eye = *eyeNext; + sp64.yaw = anim->unk_30; + sp64.r = 5.0f; + sp64.pitch = 0x238C; + Camera_Vec3fVecSphGeoAdd(&sp98, eyeNext, &sp64); + anim->unk_2C += 0xBB8; + temp_f16 = Math_Coss(anim->unk_2C); + eye->x += (sp98.x - eye->x) * fabsf(temp_f16); + eye->y += (sp98.y - eye->y) * fabsf(temp_f16); + eye->z += (sp98.z - eye->z) * fabsf(temp_f16); + + if ((anim->unk_28 < temp_f16) && !anim->unk_2E) { + player = camera->player; + anim->unk_2E = true; + func_800F4010(&player->actor.projectedPos, player->unk_89E + 0x8B0, 4.0f); + } else if (anim->unk_28 > temp_f16) { + anim->unk_2E = false; + } + + anim->unk_28 = temp_f16; + camera->player->actor.posRot.pos = *eyeNext; + camera->player->actor.posRot.pos.y = camera->playerGroundY; + camera->player->actor.shape.rot.y = sp64.yaw; + temp_f16 = ((240.0f * temp_f16) * (anim->unk_24 * 0.416667f)); + temp_a0 = temp_f16 + anim->unk_30; + at->x = eye->x + (Math_Sins(temp_a0) * 10.0f); + at->y = eye->y; + at->z = eye->z + (Math_Coss(temp_a0) * 10.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5f, 0xA); + return 1; +} s32 Camera_Subj0(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Data0(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Data1(Camera* camera) { @@ -2736,77 +4388,1082 @@ s32 Camera_Data1(Camera* camera) { } s32 Camera_Data2(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Data3(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); +} + +s32 Camera_Data4(Camera* camera) { + s32 pad2[2]; + Data4* data4 = (Data4*)camera->paramData; + VecSph eyeAtOffset; + VecSph atOffset; + VecSph eyeNextAtOffset; + f32 yNormal; + s16 fov; + Vec3f* eyeNext = &camera->eyeNext; + Vec3s* sceneCamData; + Vec3f lookAt; + CameraModeValue* values; + Data4InitParams* initParams = &data4->initParams; + Vec3f* eye = &camera->eye; + f32 playerHeight; + Vec3f* at = &camera->at; + s32 pad; + + playerHeight = Player_GetHeight(camera->player); + + if (RELOAD_PARAMS) { + values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight)); + data4->yOffset = NEXTPCT * playerHeight * yNormal; + data4->fov = NEXTSETTING; + data4->interfaceFlags = NEXTSETTING; + sceneCamData = Camera_GetCamBGData(camera); + Camera_Vec3sToVec3f(&initParams->eyePosRot.pos, &BGCAM_POS(sceneCamData)); + initParams->eyePosRot.rot = BGCAM_ROT(sceneCamData); + fov = BGCAM_FOV(sceneCamData); + initParams->fov = fov; + if (fov != -1) { + data4->fov = initParams->fov < 361 ? initParams->fov : PCT(initParams->fov); + } + + initParams->jfifId = BGCAM_JFIFID(sceneCamData); + *eye = initParams->eyePosRot.pos; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + sCameraInterfaceFlags = data4->interfaceFlags; + + if (camera->animState == 0) { + camera->animState++; + func_80043B60(camera); + } + + OLib_Vec3fDiffToVecSphGeo(&eyeNextAtOffset, at, eyeNext); + Camera_CalcAtDefault(camera, &eyeNextAtOffset, data4->yOffset, false); + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, eye, at); + + atOffset.r = eyeAtOffset.r; + atOffset.yaw = + (initParams->jfifId & 1) ? (DEGF_TO_BINANG(camera->data2) + initParams->eyePosRot.rot.y) : eyeAtOffset.yaw; + atOffset.pitch = + (initParams->jfifId & 2) ? (DEGF_TO_BINANG(camera->data3) + initParams->eyePosRot.rot.x) : eyeAtOffset.pitch; + + Camera_Vec3fVecSphGeoAdd(at, eye, &atOffset); + + lookAt = camera->playerPosRot.pos; + lookAt.y += playerHeight; + + camera->dist = OLib_Vec3fDist(&lookAt, eye); + camera->roll = 0; + camera->xzSpeed = 0.0f; + camera->fov = data4->fov; + camera->atLERPStepScale = 0; + return true; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Data4.s") +/** + * Hanging off of a ledge + */ +s32 Camera_Unique1(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f playerBodyPart0; + s16 phiTarget; + VecSph sp8C; + VecSph unk908PlayerPosOffset; + VecSph eyeAtOffset; + VecSph eyeNextAtOffset; + PosRot* playerPosRot = &camera->playerPosRot; + PosRot playerPosRot2; + Unique1* uniq1 = (Unique1*)camera->paramData; + Unique1Anim* anim = &uniq1->anim; + s32 pad; + f32 playerHeight; + s32 pad2; + + playerHeight = Player_GetHeight(camera->player); + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight)); + uniq1->yOffset = NEXTPCT * playerHeight * yNormal; + uniq1->distMin = NEXTPCT * playerHeight * yNormal; + uniq1->distMax = NEXTPCT * playerHeight * yNormal; + uniq1->pitchTarget = DEGF_TO_BINANG(NEXTSETTING); + uniq1->fovTarget = NEXTSETTING; + uniq1->atLERPScaleMax = NEXTPCT; + uniq1->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS != 0) { + Camera_CopyPREGToModeValues(camera); + } + + sUpdateCameraDirection = 1; + + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, at, eye); + OLib_Vec3fDiffToVecSphGeo(&eyeNextAtOffset, at, eyeNext); + + sCameraInterfaceFlags = uniq1->interfaceFlags; + + if (camera->animState == 0) { + camera->posOffset.y = camera->posOffset.y - camera->playerPosDelta.y; + anim->yawTarget = eyeNextAtOffset.yaw; + anim->unk_00 = 0.0f; + playerBodyPart0 = camera->player->bodyPartsPos[0]; + OLib_Vec3fDiffToVecSphGeo(&unk908PlayerPosOffset, &playerPosRot->pos, &playerBodyPart0); + anim->timer = R_DEFA_CAM_ANIM_TIME; + anim->yawTargetAdj = ABS(BINANG_SUB(unk908PlayerPosOffset.yaw, eyeAtOffset.yaw)) < 0x3A98 + ? 0 + : ((BINANG_SUB(unk908PlayerPosOffset.yaw, eyeAtOffset.yaw) / anim->timer) / 4) * 3; + camera->animState++; + } + + func_8002EEE4(&playerPosRot2, &camera->player->actor); // unused -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Unique1.s") + camera->yawUpdateRateInv = Camera_LERPCeilF(100.0f, camera->yawUpdateRateInv, OREG(25) * 0.01f, 0.1f); + camera->pitchUpdateRateInv = Camera_LERPCeilF(100.0f, camera->pitchUpdateRateInv, OREG(25) * 0.01f, 0.1f); + camera->xzOffsetUpdateRate = Camera_LERPCeilF(0.005f, camera->xzOffsetUpdateRate, OREG(25) * 0.01f, 0.01f); + camera->yOffsetUpdateRate = Camera_LERPCeilF(0.01f, camera->yOffsetUpdateRate, OREG(26) * 0.01f, 0.01f); + camera->fovUpdateRate = Camera_LERPCeilF(OREG(4) * 0.01f, camera->fovUpdateRate, 0.05f, 0.1f); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Unique2.s") + Camera_CalcAtDefault(camera, &eyeNextAtOffset, uniq1->yOffset, 1); + OLib_Vec3fDiffToVecSphGeo(&sp8C, at, eyeNext); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Unique3.s") + camera->dist = Camera_LERPClampDist(camera, sp8C.r, uniq1->distMin, uniq1->distMax); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Unique0.s") + phiTarget = uniq1->pitchTarget; + sp8C.pitch = Camera_LERPCeilS(phiTarget, eyeNextAtOffset.pitch, 1.0f / camera->pitchUpdateRateInv, 0xA); + + if (sp8C.pitch > OREG(5)) { + sp8C.pitch = OREG(5); + } + if (sp8C.pitch < -OREG(5)) { + sp8C.pitch = -OREG(5); + } + + if (anim->timer != 0) { + anim->yawTarget += anim->yawTargetAdj; + anim->timer--; + } + + sp8C.yaw = Camera_LERPFloorS(anim->yawTarget, eyeNextAtOffset.yaw, 0.5f, 0x2710); + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &sp8C); + *eye = *eyeNext; + Camera_BGCheck(camera, at, eye); + camera->fov = Camera_LERPCeilF(uniq1->fovTarget, camera->fov, camera->fovUpdateRate, 1.0f); + camera->roll = 0; + camera->atLERPStepScale = Camera_ClampLERPScale(camera, uniq1->atLERPScaleMax); + return true; +} + +s32 Camera_Unique2(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f playerPos; + VecSph eyeOffset; + VecSph eyeAtOffset; + s32 pad; + f32 lerpRateFactor; + Unique2* uniq2 = (Unique2*)camera->paramData; + Unique2Unk10* unk10 = &uniq2->unk_10; + s32 pad2; + f32 playerHeight; + + playerHeight = Player_GetHeight(camera->player); + + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, at, eye); + + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = ((1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight))); + uniq2->yOffset = NEXTPCT * playerHeight * yNormal; + uniq2->distTarget = NEXTSETTING; + uniq2->fovTarget = NEXTSETTING; + uniq2->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + sCameraInterfaceFlags = uniq2->interfaceFlags; + + if ((camera->animState == 0) || (unk10->unk_04 != uniq2->interfaceFlags)) { + unk10->unk_04 = uniq2->interfaceFlags; + } + + if (camera->animState == 0) { + camera->animState = 1; + func_80043B60(camera); + unk10->unk_00 = 200.0f; + if (uniq2->interfaceFlags & 0x10) { + camera->unk_14C &= ~4; + } + } + + playerPos = camera->playerPosRot.pos; + lerpRateFactor = (uniq2->interfaceFlags & 1 ? 1.0f : camera->speedRatio); + at->x = F32_LERPIMP(at->x, playerPos.x, lerpRateFactor * 0.6f); + at->y = F32_LERPIMP(at->y, playerPos.y + playerHeight + uniq2->yOffset, 0.4f); + at->z = F32_LERPIMP(at->z, playerPos.z, lerpRateFactor * 0.6f); + unk10->unk_00 = F32_LERPIMP(unk10->unk_00, 2.0f, 0.05f); // unused. + + if (uniq2->interfaceFlags & 1) { + OLib_Vec3fDiffToVecSphGeo(&eyeOffset, at, eyeNext); + eyeOffset.r = uniq2->distTarget; + Camera_Vec3fVecSphGeoAdd(&playerPos, at, &eyeOffset); + Camera_LERPCeilVec3f(&playerPos, eye, 0.25f, 0.25f, 0.2f); + } else if (uniq2->interfaceFlags & 2) { + if (OLib_Vec3fDistXZ(at, eyeNext) < uniq2->distTarget) { + OLib_Vec3fDiffToVecSphGeo(&eyeOffset, at, eyeNext); + eyeOffset.yaw = Camera_LERPCeilS(eyeOffset.yaw, eyeAtOffset.yaw, 0.1f, 0xA); + eyeOffset.r = uniq2->distTarget; + eyeOffset.pitch = 0; + Camera_Vec3fVecSphGeoAdd(eye, at, &eyeOffset); + eye->y = eyeNext->y; + } else { + Camera_LERPCeilVec3f(eyeNext, eye, 0.25f, 0.25f, 0.2f); + } + } + + Camera_BGCheck(camera, at, eye); + camera->dist = OLib_Vec3fDist(at, eye); + camera->roll = 0; + camera->fov = Camera_LERPCeilF(uniq2->fovTarget, camera->fov, 0.2f, 0.1f); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, 1.0f); + return true; +} + +s32 Camera_Unique3(Camera* camera) { + VecSph sp60; + f32 playerHeight; + Unique3* uniq3 = (Unique3*)camera->paramData; + Vec3s* temp_v0_2; + Vec3s sp4C; + Unique3Anim* anim = &uniq3->anim; + Unique3Params* params = &uniq3->params; + Vec3f* at = &camera->at; + PosRot* cameraPlayerPosRot = &camera->playerPosRot; + + playerHeight = Player_GetHeight(camera->player); + camera->unk_14C &= ~0x10; + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight)); + params->yOffset = NEXTPCT * playerHeight * yNormal; + params->fov = NEXTSETTING; + params->interfaceFlags = NEXTSETTING; + } + if (R_RELOAD_CAM_PARAMS != 0) { + Camera_CopyPREGToModeValues(camera); + } + sCameraInterfaceFlags = params->interfaceFlags; + switch (camera->animState) { + case 0: + func_80043B60(camera); + camera->unk_14C &= ~(0x8 | 0x4); + anim->initialFov = camera->fov; + anim->initialDist = OLib_Vec3fDist(at, &camera->eye); + camera->animState++; + case 1: + if (uniq3->doorParams.timer1-- > 0) { + break; + } + temp_v0_2 = Camera_GetCamBGData(camera); + Camera_Vec3sToVec3f(&camera->eyeNext, &BGCAM_POS(temp_v0_2)); + camera->eye = camera->eyeNext; + sp4C = BGCAM_ROT(temp_v0_2); + sp60.r = 100.0f; + sp60.yaw = sp4C.y; + sp60.pitch = -sp4C.x; + Camera_Vec3fVecSphGeoAdd(at, &camera->eye, &sp60); + camera->animState++; + + case 2: + if (params->interfaceFlags & 4) { + camera->at = cameraPlayerPosRot->pos; + camera->at.y += playerHeight + params->yOffset; + } + if (uniq3->doorParams.timer2-- > 0) { + break; + } + camera->animState++; + + case 3: + camera->unk_14C |= (0x400 | 0x10); + if ((camera->unk_14C & 8) != 0) { + camera->animState++; + } else { + break; + } + case 4: + if (params->interfaceFlags & 2) { + camera->unk_14C |= 4; + camera->unk_14C &= ~8; + Camera_ChangeSettingFlags(camera, CAM_SET_CIRCLE3, 2); + break; + } + uniq3->doorParams.timer3 = 5; + if (camera->xzSpeed > 0.001f || CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_A) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_B) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CLEFT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CDOWN) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CUP) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CRIGHT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_R) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_Z)) { + camera->animState++; + } else { + break; + } + case 5: + camera->fov = Camera_LERPCeilF(anim->initialFov, camera->fov, 0.4f, 0.1f); + OLib_Vec3fDiffToVecSphGeo(&sp60, at, &camera->eye); + sp60.r = Camera_LERPCeilF(100.0f, sp60.r, 0.4f, 0.1f); + Camera_Vec3fVecSphGeoAdd(&camera->eyeNext, at, &sp60); + camera->eye = camera->eyeNext; + if (uniq3->doorParams.timer3-- > 0) { + break; + } + camera->animState++; + default: + camera->unk_14C |= 4; + camera->unk_14C &= ~8; + camera->fov = params->fov; + Camera_ChangeSettingFlags(camera, camera->prevSetting, 2); + camera->atLERPStepScale = 0.0f; + camera->posOffset.x = camera->at.x - cameraPlayerPosRot->pos.x; + camera->posOffset.y = camera->at.y - cameraPlayerPosRot->pos.y; + camera->posOffset.z = camera->at.z - cameraPlayerPosRot->pos.z; + break; + } + + return true; +} + +/** + * Camera's eye is specified by scene camera data, at point is generated at the intersection + * of the eye to the player + */ +s32 Camera_Unique0(Camera* camera) { + f32 yOffset; + CameraModeValue* values; + Player* player; + Vec3f playerPosWithOffset; + VecSph atPlayerOffset; + Vec3s* sceneCamData; + Vec3s sceneCamRot; + PosRot* playerPosRot = &camera->playerPosRot; + Unique0* uniq0 = (Unique0*)camera->paramData; + Unique0Params* params = &uniq0->uniq0; + Unique0Anim* anim = ¶ms->anim; + Vec3f* eye = &camera->eye; + s16 fov; + + yOffset = Player_GetHeight(camera->player); + player = camera->player; + + if (RELOAD_PARAMS) { + values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + params->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + playerPosWithOffset = playerPosRot->pos; + playerPosWithOffset.y += yOffset; + + sCameraInterfaceFlags = params->interfaceFlags; + + if (camera->animState == 0) { + func_80043B60(camera); + camera->unk_14C &= ~4; + sceneCamData = Camera_GetCamBGData(camera); + Camera_Vec3sToVec3f(&anim->sceneCamPosPlayerLine.a, &BGCAM_POS(sceneCamData)); + + *eye = camera->eyeNext = anim->sceneCamPosPlayerLine.a; + sceneCamRot = BGCAM_ROT(sceneCamData); + fov = BGCAM_FOV(sceneCamData); + if (fov != -1) { + camera->fov = fov < 361 ? fov : PCT(fov); + } + anim->animTimer = BGCAM_JFIFID(sceneCamData); + if (anim->animTimer == -1) { + anim->animTimer = uniq0->doorParams.timer1 + uniq0->doorParams.timer2; + } + atPlayerOffset.r = OLib_Vec3fDist(&playerPosWithOffset, eye); + atPlayerOffset.yaw = sceneCamRot.y; + atPlayerOffset.pitch = -sceneCamRot.x; + OLib_VecSphGeoToVec3f(&anim->sceneCamPosPlayerLine.b, &atPlayerOffset); + Math3D_LineClosestToPoint(&anim->sceneCamPosPlayerLine, &playerPosRot->pos, &camera->at); + anim->initalPos = playerPosRot->pos; + camera->animState++; + } + + if (player->stateFlags1 & 0x20000000) { + anim->initalPos = playerPosRot->pos; + } + + if (params->interfaceFlags & 1) { + if (anim->animTimer > 0) { + anim->animTimer--; + anim->initalPos = playerPosRot->pos; + } else if ((!(player->stateFlags1 & 0x20000000)) && + ((OLib_Vec3fDistXZ(&playerPosRot->pos, &anim->initalPos) >= 10.0f) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_A) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_B) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CLEFT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CDOWN) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CUP) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CRIGHT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_R) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_Z))) { + camera->dist = OLib_Vec3fDist(&camera->at, eye); + camera->posOffset.x = camera->at.x - playerPosRot->pos.x; + camera->posOffset.y = camera->at.y - playerPosRot->pos.y; + camera->posOffset.z = camera->at.z - playerPosRot->pos.z; + camera->atLERPStepScale = 0.0f; + camera->unk_14C |= 4; + Camera_ChangeSettingFlags(camera, camera->prevSetting, 2); + } + } else { + if (anim->animTimer > 0) { + anim->animTimer--; + if (anim->animTimer == 0) { + sCameraInterfaceFlags = 0; + } + } else { + anim->initalPos = playerPosRot->pos; + } + + if ((!(player->stateFlags1 & 0x20000000)) && + ((0.001f < camera->xzSpeed) || CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_A) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_B) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CLEFT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CDOWN) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CUP) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CRIGHT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_R) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_Z))) { + camera->dist = OLib_Vec3fDist(&camera->at, &camera->eye); + camera->posOffset.x = camera->at.x - playerPosRot->pos.x; + camera->posOffset.y = camera->at.y - playerPosRot->pos.y; + camera->posOffset.z = camera->at.z - playerPosRot->pos.z; + camera->atLERPStepScale = 0.0f; + Camera_ChangeSettingFlags(camera, camera->prevSetting, 2); + camera->unk_14C |= 4; + } + } + return true; +} s32 Camera_Unique4(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Unique5(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } +/** + * This function doesn't really update much. + * Eye/at positions are updated via Camera_SetParam + */ s32 Camera_Unique6(Camera* camera) { - CameraModeValue* val; - s32 pad; + Unique6* uniq6 = (Unique6*)camera->paramData; + CameraModeValue* values; Vec3f sp2C; - Vec3f* playerPosRot; + PosRot* playerPosRot = &camera->playerPosRot; f32 offset; - if (camera->unk_15E == 0 || camera->unk_15E == 0xA || camera->unk_15E == 0x14 || QREG(0)) { - val = sCameraSettings[camera->setting].cameraModes[camera->mode].values; - camera->unk_00.sh[0] = val[0].val; + if (RELOAD_PARAMS) { + values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + uniq6->interfaceFlags = NEXTSETTING; } - if (QREG(0)) { + + if (R_RELOAD_CAM_PARAMS) { Camera_CopyPREGToModeValues(camera); } - D_8011D3A0.w = camera->unk_00.sh[0]; - if (camera->unk_15E == 0) { - camera->unk_15E++; + + sCameraInterfaceFlags = uniq6->interfaceFlags; + + if (camera->animState == 0) { + camera->animState++; func_80043ABC(camera); } + if (camera->player != NULL) { - offset = Player_GetCameraYOffset(camera->player); - playerPosRot = &camera->playerPosRot.pos; - sp2C = *playerPosRot; + offset = Player_GetHeight(camera->player); + sp2C = playerPosRot->pos; sp2C.y += offset; camera->dist = OLib_Vec3fDist(&sp2C, &camera->eye); - camera->unk_E4.x = camera->at.x - playerPosRot->x; - camera->unk_E4.y = camera->at.y - playerPosRot->y; - camera->unk_E4.z = camera->at.z - playerPosRot->z; + camera->posOffset.x = camera->at.x - playerPosRot->pos.x; + camera->posOffset.y = camera->at.y - playerPosRot->pos.y; + camera->posOffset.z = camera->at.z - playerPosRot->pos.z; } else { camera->dist = OLib_Vec3fDist(&camera->at, &camera->eye); } - if (camera->unk_00.sh[0] & 1) { - if (camera->unk_160 > 0) { - camera->unk_160--; - } + + if (uniq6->interfaceFlags & 1 && camera->timer > 0) { + camera->timer--; } - return 1; + + return true; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Unique7.s") +/** + * Camera is at a fixed point specified by the scene's camera data, + * camera rotates to follow player + */ +s32 Camera_Unique7(Camera* camera) { + s32 pad; + Unique7* uniq7 = (Unique7*)camera->paramData; + CameraModeValue* values; + VecSph playerPosEyeOffset; + s16 fov; + Vec3s* sceneCamData; + Vec3s sceneCamRot; + Vec3f* at = &camera->at; + PosRot* playerPosRot = &camera->playerPosRot; + Vec3f* eye = &camera->eye; + Vec3f* eyeNext = &camera->eyeNext; + Unique7Unk8* unk08 = &uniq7->unk_08; + + if (RELOAD_PARAMS) { + values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + uniq7->fov = NEXTSETTING; + uniq7->interfaceFlags = (s16)NEXTSETTING; + } + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + sceneCamData = Camera_GetCamBGData(camera); + + Camera_Vec3sToVec3f(eyeNext, &BGCAM_POS(sceneCamData)); + *eye = *eyeNext; + sceneCamRot = BGCAM_ROT(sceneCamData); + + OLib_Vec3fDiffToVecSphGeo(&playerPosEyeOffset, eye, &playerPosRot->pos); + + // fov actually goes unused since it's hard set later on. + fov = BGCAM_FOV(sceneCamData); + if (fov == -1) { + fov = uniq7->fov * 100.0f; + } + + if (fov < 361) { + fov *= 100; + } + + sCameraInterfaceFlags = uniq7->interfaceFlags; + + if (camera->animState == 0) { + camera->animState++; + camera->fov = PCT(fov); + camera->atLERPStepScale = 0.0f; + camera->roll = 0; + unk08->unk_00.x = playerPosEyeOffset.yaw; + } + + camera->fov = 60.0f; + + // 0x7D0 ~ 10.98 degres. + unk08->unk_00.x = Camera_LERPFloorS(playerPosEyeOffset.yaw, unk08->unk_00.x, 0.4f, 0x7D0); + playerPosEyeOffset.pitch = + -BGCAM_ROT(sceneCamData).x * Math_Coss(playerPosEyeOffset.yaw - BGCAM_ROT(sceneCamData).y); + Camera_Vec3fVecSphGeoAdd(at, eye, &playerPosEyeOffset); + camera->unk_14C |= 0x400; + return true; +} s32 Camera_Unique8(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Unique9.s") +s32 Camera_Unique9(Camera* camera) { + Vec3f atTarget; + Vec3f eyeTarget; + Unique9* uniq9 = &ONEPOINTDEMO->uniq9; + Unique9Anim* anim = &uniq9->anim; + f32 invKeyFrameTimer; + VecSph eyeNextAtOffset; + VecSph scratchSph; + VecSph playerTargetOffset; + s16 pad; + s16 atInitFlags; + s16 eyeInitFlags; + s16 pad2; + PosRot targetPosRot2; + PosRot playerPosRot2; + PosRot playerPosRot; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f* at = &camera->at; + s16 action; + Player* player; + Actor* focusActor; + f32 spB4; + PosRot atFocusPosRot; + Vec3f eyeLookAtPos; + Vec3f* eye = &camera->eye; + PosRot eyeFocusPosRot; + + player = camera->player; + + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + uniq9->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + sCameraInterfaceFlags = uniq9->interfaceFlags; + + func_8002EF14(&playerPosRot, &camera->player->actor); + + if (camera->animState == 0) { + camera->animState++; + anim->curKeyFrameIdx = -1; + anim->keyFrameTimer = 1; + anim->unk_38 = 0; + anim->playerPos.x = playerPosRot.pos.x; + anim->playerPos.y = playerPosRot.pos.y; + anim->playerPos.z = playerPosRot.pos.z; + camera->atLERPStepScale = 0.0f; + func_80043B60(camera); + } + + if (anim->unk_38 == 0 && anim->keyFrameTimer > 0) { + anim->keyFrameTimer--; + } + + if (anim->keyFrameTimer == 0) { + anim->isNewKeyFrame = true; + anim->curKeyFrameIdx++; + if (anim->curKeyFrameIdx < ONEPOINTDEMO->keyFrameCnt) { + anim->curKeyFrame = &ONEPOINTDEMO->keyFrames[anim->curKeyFrameIdx]; + anim->keyFrameTimer = anim->curKeyFrame->timerInit; + + if (anim->curKeyFrame->unk_01 != 0xFF) { + if ((anim->curKeyFrame->unk_01 & 0xF0) == 0x80) { + D_8011D3AC = anim->curKeyFrame->unk_01 & 0xF; + } else if ((anim->curKeyFrame->unk_01 & 0xF0) == 0xC0) { + Camera_UpdateInterface(0xF000 | ((anim->curKeyFrame->unk_01 & 0xF) << 8)); + } else if (camera->player->stateFlags1 & 0x8000000 && player->currentBoots != PLAYER_BOOTS_IRON) { + func_8002DF38(camera->globalCtx, camera->target, 8); + osSyncPrintf("camera: demo: player demo set WAIT\n"); + } else { + osSyncPrintf("camera: demo: player demo set %d\n", anim->curKeyFrame->unk_01); + func_8002DF38(camera->globalCtx, camera->target, anim->curKeyFrame->unk_01); + } + } + } else { + // We've gone through all the keyframes. + if (camera->thisIdx != 0) { + camera->timer = 0; + } + return true; + } + } else { + anim->isNewKeyFrame = false; + } + + atInitFlags = anim->curKeyFrame->initFlags & 0xFF; + if (atInitFlags == 1) { + anim->atTarget = anim->curKeyFrame->atTargetInit; + } else if (atInitFlags == 2) { + if (anim->isNewKeyFrame) { + anim->atTarget.x = camera->globalCtx->view.lookAt.x + anim->curKeyFrame->atTargetInit.x; + anim->atTarget.y = camera->globalCtx->view.lookAt.y + anim->curKeyFrame->atTargetInit.y; + anim->atTarget.z = camera->globalCtx->view.lookAt.z + anim->curKeyFrame->atTargetInit.z; + } + } else if (atInitFlags == 3) { + if (anim->isNewKeyFrame) { + anim->atTarget.x = camera->at.x + anim->curKeyFrame->atTargetInit.x; + anim->atTarget.y = camera->at.y + anim->curKeyFrame->atTargetInit.y; + anim->atTarget.z = camera->at.z + anim->curKeyFrame->atTargetInit.z; + } + } else if (atInitFlags == 4 || atInitFlags == 0x84) { + if (camera->target != NULL && camera->target->update != NULL) { + func_8002EEE4(&targetPosRot2, camera->target); + func_8002EEE4(&playerPosRot2, &camera->player->actor); + playerPosRot2.pos.x = playerPosRot.pos.x; + playerPosRot2.pos.z = playerPosRot.pos.z; + OLib_Vec3fDiffToVecSphGeo(&playerTargetOffset, &targetPosRot2.pos, &playerPosRot2.pos); + if (atInitFlags & (s16)0x8080) { + scratchSph.pitch = DEGF_TO_BINANG(anim->curKeyFrame->atTargetInit.x); + scratchSph.yaw = DEGF_TO_BINANG(anim->curKeyFrame->atTargetInit.y); + scratchSph.r = anim->curKeyFrame->atTargetInit.z; + } else { + OLib_Vec3fToVecSphGeo(&scratchSph, &anim->curKeyFrame->atTargetInit); + } + scratchSph.yaw += playerTargetOffset.yaw; + scratchSph.pitch += playerTargetOffset.pitch; + Camera_Vec3fVecSphGeoAdd(&anim->atTarget, &targetPosRot2.pos, &scratchSph); + } else { + if (camera->target == NULL) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: warning: demo C: actor is not valid\n" VT_RST); + } + + camera->target = NULL; + anim->atTarget = camera->at; + } + } else if (atInitFlags & 0x6060) { + if (!(atInitFlags & 4) || anim->isNewKeyFrame) { + if (atInitFlags & 0x2020) { + focusActor = &camera->player->actor; + } else if (camera->target != NULL && camera->target->update != NULL) { + focusActor = camera->target; + } else { + camera->target = NULL; + focusActor = NULL; + } + + if (focusActor != NULL) { + if ((atInitFlags & 0xF) == 1) { + // posRot2 + func_8002EEE4(&atFocusPosRot, focusActor); + } else if ((atInitFlags & 0xF) == 2) { + // posRot + func_8002EF14(&atFocusPosRot, focusActor); + } else { + // posRot, shape rot + func_8002EF44(&atFocusPosRot, focusActor); + } + + if (atInitFlags & (s16)0x8080) { + scratchSph.pitch = DEGF_TO_BINANG(anim->curKeyFrame->atTargetInit.x); + scratchSph.yaw = DEGF_TO_BINANG(anim->curKeyFrame->atTargetInit.y); + scratchSph.r = anim->curKeyFrame->atTargetInit.z; + } else { + OLib_Vec3fToVecSphGeo(&scratchSph, &anim->curKeyFrame->atTargetInit); + } + + scratchSph.yaw += atFocusPosRot.rot.y; + scratchSph.pitch -= atFocusPosRot.rot.x; + Camera_Vec3fVecSphGeoAdd(&anim->atTarget, &atFocusPosRot.pos, &scratchSph); + } else { + if (camera->target == NULL) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: warning: demo C: actor is not valid\n" VT_RST); + } + anim->atTarget = *at; + } + } + } else { + anim->atTarget = *at; + } + + eyeInitFlags = anim->curKeyFrame->initFlags & 0xFF00; + if (eyeInitFlags == 0x100) { + anim->eyeTarget = anim->curKeyFrame->eyeTargetInit; + } else if (eyeInitFlags == 0x200) { + if (anim->isNewKeyFrame) { + anim->eyeTarget.x = camera->globalCtx->view.eye.x + anim->curKeyFrame->eyeTargetInit.x; + anim->eyeTarget.y = camera->globalCtx->view.eye.y + anim->curKeyFrame->eyeTargetInit.y; + anim->eyeTarget.z = camera->globalCtx->view.eye.z + anim->curKeyFrame->eyeTargetInit.z; + } + } else if (eyeInitFlags == 0x300) { + if (anim->isNewKeyFrame) { + anim->eyeTarget.x = camera->eyeNext.x + anim->curKeyFrame->eyeTargetInit.x; + anim->eyeTarget.y = camera->eyeNext.y + anim->curKeyFrame->eyeTargetInit.y; + anim->eyeTarget.z = camera->eyeNext.z + anim->curKeyFrame->eyeTargetInit.z; + } + } else { + if (eyeInitFlags == 0x400 || eyeInitFlags == (s16)0x8400 || eyeInitFlags == 0x500 || + eyeInitFlags == (s16)0x8500) { + if (camera->target != NULL && camera->target->update != NULL) { + func_8002EEE4(&targetPosRot2, camera->target); + func_8002EEE4(&playerPosRot2, &camera->player->actor); + playerPosRot2.pos.x = playerPosRot.pos.x; + playerPosRot2.pos.z = playerPosRot.pos.z; + OLib_Vec3fDiffToVecSphGeo(&playerTargetOffset, &targetPosRot2.pos, &playerPosRot2.pos); + if (eyeInitFlags == 0x400 || eyeInitFlags == (s16)0x8400) { + eyeLookAtPos = targetPosRot2.pos; + } else { + eyeLookAtPos = anim->atTarget; + } + + if (eyeInitFlags & (s16)0x8080) { + scratchSph.pitch = DEGF_TO_BINANG(anim->curKeyFrame->eyeTargetInit.x); + scratchSph.yaw = DEGF_TO_BINANG(anim->curKeyFrame->eyeTargetInit.y); + scratchSph.r = anim->curKeyFrame->eyeTargetInit.z; + } else { + OLib_Vec3fToVecSphGeo(&scratchSph, &anim->curKeyFrame->eyeTargetInit); + } + + scratchSph.yaw += playerTargetOffset.yaw; + scratchSph.pitch += playerTargetOffset.pitch; + Camera_Vec3fVecSphGeoAdd(&anim->eyeTarget, &eyeLookAtPos, &scratchSph); + } else { + if (camera->target == NULL) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: warning: demo C: actor is not valid\n" VT_RST); + } + camera->target = NULL; + anim->eyeTarget = *eyeNext; + } + } else { + if (eyeInitFlags & 0x6060) { + if (!(eyeInitFlags & 0x400) || anim->isNewKeyFrame) { + if (eyeInitFlags & 0x2020) { + focusActor = &camera->player->actor; + } else if (camera->target != NULL && camera->target->update != NULL) { + focusActor = camera->target; + } else { + camera->target = NULL; + focusActor = NULL; + } + + if (focusActor != NULL) { + if ((eyeInitFlags & 0xF00) == 0x100) { + // posRot2 + func_8002EEE4(&eyeFocusPosRot, focusActor); + } else if ((eyeInitFlags & 0xF00) == 0x200) { + // posRot + func_8002EF14(&eyeFocusPosRot, focusActor); + } else { + // posRot, shapeRot + func_8002EF44(&eyeFocusPosRot, focusActor); + } + + if (eyeInitFlags & (s16)0x8080) { + scratchSph.pitch = DEGF_TO_BINANG(anim->curKeyFrame->eyeTargetInit.x); + scratchSph.yaw = DEGF_TO_BINANG(anim->curKeyFrame->eyeTargetInit.y); + scratchSph.r = anim->curKeyFrame->eyeTargetInit.z; + } else { + OLib_Vec3fToVecSphGeo(&scratchSph, &anim->curKeyFrame->eyeTargetInit); + } + + scratchSph.yaw += eyeFocusPosRot.rot.y; + scratchSph.pitch -= eyeFocusPosRot.rot.x; + Camera_Vec3fVecSphGeoAdd(&anim->eyeTarget, &eyeFocusPosRot.pos, &scratchSph); + } else { + if (camera->target == NULL) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: warning: demo C: actor is not valid\n" VT_RST); + } + camera->target = NULL; + anim->eyeTarget = *eyeNext; + } + } + } else { + anim->eyeTarget = *eyeNext; + } + } + } + + if (anim->curKeyFrame->initFlags == 2) { + anim->fovTarget = camera->globalCtx->view.fovy; + anim->rollTarget = 0; + } else if (anim->curKeyFrame->initFlags == 0) { + anim->fovTarget = camera->fov; + anim->rollTarget = camera->roll; + } else { + anim->fovTarget = anim->curKeyFrame->fovTargetInit; + anim->rollTarget = DEGF_TO_BINANG(anim->curKeyFrame->rollTargetInit); + } + + action = anim->curKeyFrame->actionFlags & 0x1F; + switch (action) { + case 15: + // static copy to at/eye/fov/roll + *at = anim->atTarget; + *eyeNext = anim->eyeTarget; + camera->fov = anim->fovTarget; + camera->roll = anim->rollTarget; + camera->unk_14C |= 0x400; + break; + case 21: + // same as 15, but with unk_38 ? + if (anim->unk_38 == 0) { + anim->unk_38 = 1; + } else if (camera->unk_14C & 8) { + anim->unk_38 = 0; + camera->unk_14C &= ~8; + } + *at = anim->atTarget; + *eyeNext = anim->eyeTarget; + camera->fov = anim->fovTarget; + camera->roll = anim->rollTarget; + break; + case 16: + // same as 16, but don't unset bit 0x8 on unk_14C + if (anim->unk_38 == 0) { + anim->unk_38 = 1; + } else if (camera->unk_14C & 8) { + anim->unk_38 = 0; + } + + *at = anim->atTarget; + *eyeNext = anim->eyeTarget; + camera->fov = anim->fovTarget; + camera->roll = anim->rollTarget; + break; + case 1: + // linear interpolation of eye/at using the spherical coordinates + OLib_Vec3fDiffToVecSphGeo(&eyeNextAtOffset, at, eyeNext); + OLib_Vec3fDiffToVecSphGeo(&anim->atEyeOffsetTarget, &anim->atTarget, &anim->eyeTarget); + invKeyFrameTimer = 1.0f / anim->keyFrameTimer; + scratchSph.r = F32_LERPIMP(eyeNextAtOffset.r, anim->atEyeOffsetTarget.r, invKeyFrameTimer); + scratchSph.pitch = eyeNextAtOffset.pitch + + (BINANG_SUB(anim->atEyeOffsetTarget.pitch, eyeNextAtOffset.pitch) * invKeyFrameTimer); + scratchSph.yaw = + eyeNextAtOffset.yaw + (BINANG_SUB(anim->atEyeOffsetTarget.yaw, eyeNextAtOffset.yaw) * invKeyFrameTimer); + Camera_Vec3fVecSphGeoAdd(&eyeTarget, at, &scratchSph); + goto setEyeNext; + case 2: + // linear interpolation of eye/at using the eyeTarget + invKeyFrameTimer = 1.0f / anim->keyFrameTimer; + eyeTarget.x = F32_LERPIMP(camera->eyeNext.x, anim->eyeTarget.x, invKeyFrameTimer); + eyeTarget.y = F32_LERPIMP(camera->eyeNext.y, anim->eyeTarget.y, invKeyFrameTimer); + eyeTarget.z = F32_LERPIMP(camera->eyeNext.z, anim->eyeTarget.z, invKeyFrameTimer); + + setEyeNext: + camera->eyeNext.x = + Camera_LERPFloorF(eyeTarget.x, camera->eyeNext.x, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->eyeNext.y = + Camera_LERPFloorF(eyeTarget.y, camera->eyeNext.y, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->eyeNext.z = + Camera_LERPFloorF(eyeTarget.z, camera->eyeNext.z, anim->curKeyFrame->lerpStepScale, 1.0f); + case 9: + case 10: + // linear interpolation of at/fov/roll + invKeyFrameTimer = 1.0f / anim->keyFrameTimer; + atTarget.x = F32_LERPIMP(camera->at.x, anim->atTarget.x, invKeyFrameTimer); + atTarget.y = F32_LERPIMP(camera->at.y, anim->atTarget.y, invKeyFrameTimer); + atTarget.z = F32_LERPIMP(camera->at.z, anim->atTarget.z, invKeyFrameTimer); + camera->at.x = Camera_LERPFloorF(atTarget.x, camera->at.x, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->at.y = Camera_LERPFloorF(atTarget.y, camera->at.y, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->at.z = Camera_LERPFloorF(atTarget.z, camera->at.z, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->fov = Camera_LERPFloorF(F32_LERPIMP(camera->fov, anim->fovTarget, invKeyFrameTimer), camera->fov, + anim->curKeyFrame->lerpStepScale, 0.01f); + camera->roll = Camera_LERPFloorS(BINANG_LERPIMPINV(camera->roll, anim->rollTarget, anim->keyFrameTimer), + camera->roll, anim->curKeyFrame->lerpStepScale, 0xA); + break; + case 4: + // linear interpolation of eye/at/fov/roll using the step scale, and spherical coordinates + OLib_Vec3fDiffToVecSphGeo(&eyeNextAtOffset, at, eyeNext); + OLib_Vec3fDiffToVecSphGeo(&anim->atEyeOffsetTarget, &anim->atTarget, &anim->eyeTarget); + scratchSph.r = + Camera_LERPCeilF(anim->atEyeOffsetTarget.r, eyeNextAtOffset.r, anim->curKeyFrame->lerpStepScale, 0.1f); + scratchSph.pitch = Camera_LERPCeilS(anim->atEyeOffsetTarget.pitch, eyeNextAtOffset.pitch, + anim->curKeyFrame->lerpStepScale, 1); + scratchSph.yaw = + Camera_LERPCeilS(anim->atEyeOffsetTarget.yaw, eyeNextAtOffset.yaw, anim->curKeyFrame->lerpStepScale, 1); + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &scratchSph); + goto setAtFOVRoll; + case 3: + // linear interplation of eye/at/fov/roll using the step scale using eyeTarget + camera->eyeNext.x = + Camera_LERPCeilF(anim->eyeTarget.x, camera->eyeNext.x, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->eyeNext.y = + Camera_LERPCeilF(anim->eyeTarget.y, camera->eyeNext.y, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->eyeNext.z = + Camera_LERPCeilF(anim->eyeTarget.z, camera->eyeNext.z, anim->curKeyFrame->lerpStepScale, 1.0f); + case 11: + case 12: + setAtFOVRoll: + // linear interpolation of at/fov/roll using the step scale. + camera->at.x = Camera_LERPCeilF(anim->atTarget.x, camera->at.x, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->at.y = Camera_LERPCeilF(anim->atTarget.y, camera->at.y, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->at.z = Camera_LERPCeilF(anim->atTarget.z, camera->at.z, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->fov = Camera_LERPCeilF(anim->fovTarget, camera->fov, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->roll = Camera_LERPCeilS(anim->rollTarget, camera->roll, anim->curKeyFrame->lerpStepScale, 1); + break; + case 13: + // linear interpolation of at, with rotation around eyeTargetInit.y + camera->at.x = Camera_LERPCeilF(anim->atTarget.x, camera->at.x, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->at.y += camera->playerPosDelta.y * anim->curKeyFrame->lerpStepScale; + camera->at.z = Camera_LERPCeilF(anim->atTarget.z, camera->at.z, anim->curKeyFrame->lerpStepScale, 1.0f); + OLib_Vec3fDiffToVecSphGeo(&scratchSph, at, eyeNext); + scratchSph.yaw += DEGF_TO_BINANG(anim->curKeyFrame->eyeTargetInit.y); + + // 3A98 ~ 82.40 degrees + if (scratchSph.pitch >= 0x3A99) { + scratchSph.pitch = 0x3A98; + } + + if (scratchSph.pitch < -0x3A98) { + scratchSph.pitch = -0x3A98; + } + + spB4 = scratchSph.r; + if (1) {} + scratchSph.r = + !(spB4 < anim->curKeyFrame->eyeTargetInit.z) + ? Camera_LERPCeilF(anim->curKeyFrame->eyeTargetInit.z, spB4, anim->curKeyFrame->lerpStepScale, 1.0f) + : scratchSph.r; + + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &scratchSph); + camera->fov = + Camera_LERPCeilF(F32_LERPIMPINV(camera->fov, anim->curKeyFrame->fovTargetInit, anim->keyFrameTimer), + camera->fov, anim->curKeyFrame->lerpStepScale, 1.0f); + camera->roll = Camera_LERPCeilS(anim->rollTarget, camera->roll, anim->curKeyFrame->lerpStepScale, 1); + break; + case 24: + // Set current keyframe to the roll target? + anim->curKeyFrameIdx = anim->rollTarget; + break; + case 19: + // Change the parent camera (or default)'s mode to normal + Camera_ChangeModeFlags(camera->globalCtx->cameraPtrs[camera->parentCamIdx < 0 ? 0 : camera->parentCamIdx], + CAM_MODE_NORMAL, 1); + case 18: + // copy the current camera to the parent (or default)'s camera. + { + Camera* cam = camera->globalCtx->cameraPtrs[camera->parentCamIdx < 0 ? 0 : camera->parentCamIdx]; + *eye = *eyeNext; + Camera_Copy(cam, camera); + } + default: + if (camera->thisIdx != 0) { + camera->timer = 0; + } + } + + *eye = *eyeNext; + + if (anim->curKeyFrame->actionFlags & 0x80) { + Camera_BGCheck(camera, at, eye); + } + + if (anim->curKeyFrame->actionFlags & 0x40) { + // Set the player's position + camera->player->actor.posRot.pos.x = anim->playerPos.x; + camera->player->actor.posRot.pos.z = anim->playerPos.z; + if (camera->player->stateFlags1 & 0x8000000 && player->currentBoots != PLAYER_BOOTS_IRON) { + camera->player->actor.posRot.pos.y = anim->playerPos.y; + } + } else { + anim->playerPos.x = playerPosRot.pos.x; + anim->playerPos.y = playerPosRot.pos.y; + anim->playerPos.z = playerPosRot.pos.z; + } + + if (anim->unk_38 == 0 && camera->timer > 0) { + camera->timer--; + } + + if (camera->player != NULL) { + camera->posOffset.x = camera->at.x - camera->playerPosRot.pos.x; + camera->posOffset.y = camera->at.y - camera->playerPosRot.pos.y; + camera->posOffset.z = camera->at.z - camera->playerPosRot.pos.z; + } + + camera->dist = OLib_Vec3fDist(at, eye); + return true; +} void Camera_DebugPrintSplineArray(char* name, s16 length, CutsceneCameraPoint cameraPoints[]) { s32 i; @@ -2825,149 +5482,817 @@ void Camera_DebugPrintSplineArray(char* name, s16 length, CutsceneCameraPoint ca osSyncPrintf("};\n\n"); } +/** + * Copies `src` to `dst`, used in Camera_Demo1 + * Name from AC map: Camera2_SetPos_Demo + */ void Camera_Vec3fCopy(Vec3f* src, Vec3f* dst) { dst->x = src->x; dst->y = src->y; dst->z = src->z; } -void func_80054478(PosRot* arg0, Vec3f* arg1, Vec3f* arg2) { - VecSph sp28; - Vec3f sp1C; - - Camera_Vec3fCopy(arg1, &sp1C); - OLib_Vec3fToVecSphGeo(&sp28, &sp1C); - sp28.yaw += arg0->rot.y; - func_80043C28(arg2, &arg0->pos, &sp28); +/** + * Calculates new position from `at` to `pos`, outputs to `dst + * Name from AC map: Camera2_CalcPos_Demo + */ +void Camera_RotateAroundPoint(PosRot* at, Vec3f* pos, Vec3f* dst) { + VecSph posSph; + Vec3f posCopy; + + Camera_Vec3fCopy(pos, &posCopy); + OLib_Vec3fToVecSphGeo(&posSph, &posCopy); + posSph.yaw += at->rot.y; + Camera_Vec3fVecSphGeoAdd(dst, &at->pos, &posSph); } -s32 func_800BB2B4(Vec3f*, f32*, f32*, CutsceneCameraPoint*, s16*, Demo1_unk_04*); - -#ifdef NON_MATCHING +/** + * Camera follows points specified at pointers to CutsceneCameraPoints, + * camera->data0 for camera at positions, and camera->data1 for camera eye positions + * until all keyFrames have been exhausted. + */ s32 Camera_Demo1(Camera* camera) { - Vec3f* at; - Vec3f* eyeNext; - Vec3f* eye; - char* t; - CutsceneCameraPoint* sp84; - CutsceneCameraPoint* sp80; - PosRot sp68; - Vec3f sp5C; - Vec3f sp50; - f32 sp4C; - s16* relativeToPlayer; - CameraModeValue* values; - Demo1_unk_04* unk_04; s32 pad; - - sp84 = camera->atPoints; - sp80 = camera->eyePoints; - if (camera->unk_15E == 0 || camera->unk_15E == 0xA || camera->unk_15E == 0x14 || QREG(0)) { + Demo1* demo1 = (Demo1*)camera->paramData; + CameraModeValue* values; + Vec3f* at = &camera->at; + CutsceneCameraPoint* csAtPoints = (CutsceneCameraPoint*)camera->data0; + CutsceneCameraPoint* csEyePoints = (CutsceneCameraPoint*)camera->data1; + Vec3f* eye = &camera->eye; + PosRot curPlayerPosRot; + Vec3f csEyeUpdate; + Vec3f csAtUpdate; + f32 newRoll; + Vec3f* eyeNext = &camera->eyeNext; + f32* cameraFOV = &camera->fov; + s16* relativeToPlayer = &camera->data2; + Demo1Anim* anim = &demo1->anim; + + if (RELOAD_PARAMS) { values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; - camera->unk_00.demo1.unk_00 = values->val; + demo1->interfaceFlags = NEXTSETTING; } - D_8011D3A0.w = camera->unk_00.demo1.unk_00; - unk_04 = &camera->unk_00.demo1.unk_04; - relativeToPlayer = &camera->relativeToPlayer; - eyeNext = &camera->eyeNext; - at = &camera->at; - eye = &camera->eye; - switch (camera->unk_15E) { + sCameraInterfaceFlags = demo1->interfaceFlags; + + switch (camera->animState) { case 0: - unk_04->unk_04 = 0; - unk_04->unk_00 = 0.0f; - camera->unk_15E++; + // initalize camera state + anim->keyframe = 0; + anim->curFrame = 0.0f; + camera->animState++; // absolute / relative - t = *relativeToPlayer == 0 ? "絶対" : "相対"; - osSyncPrintf("\x1b[1m%06u:\x1b[m camera: spline demo: start %s \n", camera->globalCtx->state.frames, t); + osSyncPrintf(VT_SGR("1") "%06u:" VT_RST " camera: spline demo: start %s \n", + camera->globalCtx->state.frames, *relativeToPlayer == 0 ? "絶対" : "相対"); + if (PREG(93)) { - Camera_DebugPrintSplineArray("CENTER", 5, sp84); - Camera_DebugPrintSplineArray(" EYE", 5, sp80); + Camera_DebugPrintSplineArray("CENTER", 5, csAtPoints); + Camera_DebugPrintSplineArray(" EYE", 5, csEyePoints); } case 1: // follow CutsceneCameraPoints. function returns 1 if at the end. - // unk_15E appears to be some kind of state of the cutscene? 0 is init, 1 is update, anything else is stop. - if (func_800BB2B4(&sp5C, &sp4C, &camera->fov, sp80, &unk_04->unk_04, unk_04) || - func_800BB2B4(&sp50, &sp4C, &camera->fov, sp84, &unk_04->unk_04, unk_04)) { - camera->unk_15E++; + if (func_800BB2B4(&csEyeUpdate, &newRoll, cameraFOV, csEyePoints, &anim->keyframe, &anim->curFrame) || + func_800BB2B4(&csAtUpdate, &newRoll, cameraFOV, csAtPoints, &anim->keyframe, &anim->curFrame)) { + camera->animState++; } if (*relativeToPlayer) { + // if the camera is set to be relative to the player, move the interpolated points + // relative to the player's position if (camera->player != NULL && camera->player->actor.update != NULL) { - func_8002EF14(&sp68, &camera->player->actor); - func_80054478(&sp68, &sp5C, eyeNext); - func_80054478(&sp68, &sp50, at); + func_8002EF14(&curPlayerPosRot, &camera->player->actor); + Camera_RotateAroundPoint(&curPlayerPosRot, &csEyeUpdate, eyeNext); + Camera_RotateAroundPoint(&curPlayerPosRot, &csAtUpdate, at); } else { - osSyncPrintf("\x1b[41;37mcamera: spline demo: owner dead\n\x1b[m"); + osSyncPrintf(VT_COL(RED, WHITE) "camera: spline demo: owner dead\n" VT_RST); } } else { - Camera_Vec3fCopy(&sp5C, eyeNext); - Camera_Vec3fCopy(&sp50, at); + // simply copy the interpolated values to the eye and at + Camera_Vec3fCopy(&csEyeUpdate, eyeNext); + Camera_Vec3fCopy(&csAtUpdate, at); } *eye = *eyeNext; - camera->roll = sp4C * 256.0f; + camera->roll = newRoll * 256.0f; camera->dist = OLib_Vec3fDist(at, eye); break; } - return 1; + return true; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Demo1.s") -#endif s32 Camera_Demo2(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Demo3.s") +/** + * Opening large chests. + * The camera position will be at a fixed point, and rotate around at different intervals. + * The direction, and initial position is dependent on when the camera was started. + */ +s32 Camera_Demo3(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + PosRot* camPlayerPosRot = &camera->playerPosRot; + VecSph eyeAtOffset; + VecSph eyeOffset; + VecSph atOffset; + Vec3f sp74; + Vec3f sp68; + Vec3f sp5C; + f32 temp_f0; + s32 pad; + u8 skipUpdateEye; + f32 yOffset; + s16 angle; + Demo3* demo3 = (Demo3*)camera->paramData; + Demo3Anim* anim = &demo3->anim; + s32 pad2; + + skipUpdateEye = false; + yOffset = Player_GetHeight(camera->player); + camera->unk_14C &= ~0x10; + + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + demo3->fov = NEXTSETTING; + demo3->unk_04 = NEXTSETTING; // unused. + demo3->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, at, eye); + + sCameraInterfaceFlags = demo3->interfaceFlags; + + switch (camera->animState) { + case 0: + camera->unk_14C &= ~(0x8 | 0x4); + func_80043B60(camera); + camera->fov = demo3->fov; + camera->roll = anim->animFrame = 0; + anim->initialAt = camPlayerPosRot->pos; + if (camera->playerGroundY != BGCHECK_Y_MIN) { + anim->initialAt.y = camera->playerGroundY; + } + angle = camPlayerPosRot->rot.y; + sp68.x = anim->initialAt.x + (Math_Sins(angle) * 40.0f); + sp68.y = anim->initialAt.y + 40.0f; + sp68.z = anim->initialAt.z + (Math_Coss(angle) * 40.0f); + if (camera->globalCtx->state.frames & 1) { + angle -= 0x3FFF; + anim->yawDir = 1; + } else { + angle += 0x3FFF; + anim->yawDir = -1; + } + sp74.x = sp68.x + (D_8011D658[1].r * Math_Sins(angle)); + sp74.y = anim->initialAt.y + 5.0f; + sp74.z = sp68.z + (D_8011D658[1].r * Math_Coss(angle)); + if (Camera_BGCheck(camera, &sp68, &sp74)) { + anim->yawDir = -anim->yawDir; + } + OLib_Vec3fToVecSphGeo(&atOffset, &D_8011D678[0]); + atOffset.yaw += camPlayerPosRot->rot.y; + Camera_Vec3fVecSphGeoAdd(at, &anim->initialAt, &atOffset); + eyeOffset.r = D_8011D658[0].r; + eyeOffset.pitch = D_8011D658[0].pitch; + eyeOffset.yaw = (D_8011D658[0].yaw * anim->yawDir) + camPlayerPosRot->rot.y; + anim->unk_0C = 1.0f; + break; + case 1: + temp_f0 = (anim->animFrame - 2) * (1.0f / 146.0f); + + sp5C.x = F32_LERPIMP(D_8011D678[0].x, D_8011D678[1].x, temp_f0); + sp5C.y = F32_LERPIMP(D_8011D678[0].y, D_8011D678[1].y, temp_f0); + sp5C.z = F32_LERPIMP(D_8011D678[0].z, D_8011D678[1].z, temp_f0); + + OLib_Vec3fToVecSphGeo(&atOffset, &sp5C); + atOffset.yaw = (atOffset.yaw * anim->yawDir) + camPlayerPosRot->rot.y; + Camera_Vec3fVecSphGeoAdd(at, &anim->initialAt, &atOffset); + + atOffset.r = F32_LERPIMP(D_8011D658[0].r, D_8011D658[1].r, temp_f0); + atOffset.pitch = BINANG_LERPIMP(D_8011D658[0].pitch, D_8011D658[1].pitch, temp_f0); + atOffset.yaw = BINANG_LERPIMP(D_8011D658[0].yaw, D_8011D658[1].yaw, temp_f0); + + eyeOffset.r = atOffset.r; + eyeOffset.pitch = atOffset.pitch; + eyeOffset.yaw = (atOffset.yaw * anim->yawDir) + camPlayerPosRot->rot.y; + + anim->unk_0C -= (1.0f / 365.0f); + break; + case 2: + temp_f0 = (anim->animFrame - 0x94) * 0.1f; + + sp5C.x = F32_LERPIMP(D_8011D678[1].x, D_8011D678[2].x, temp_f0); + sp5C.y = F32_LERPIMP((D_8011D678[1].y - yOffset), D_8011D678[2].y, temp_f0); + sp5C.y += yOffset; + sp5C.z = F32_LERPIMP(D_8011D678[1].z, D_8011D678[2].z, temp_f0); + + OLib_Vec3fToVecSphGeo(&atOffset, &sp5C); + atOffset.yaw = (atOffset.yaw * anim->yawDir) + camPlayerPosRot->rot.y; + Camera_Vec3fVecSphGeoAdd(at, &anim->initialAt, &atOffset); + + atOffset.r = F32_LERPIMP(D_8011D658[1].r, D_8011D658[2].r, temp_f0); + atOffset.pitch = BINANG_LERPIMP(D_8011D658[1].pitch, D_8011D658[2].pitch, temp_f0); + atOffset.yaw = BINANG_LERPIMP(D_8011D658[1].yaw, D_8011D658[2].yaw, temp_f0); + + eyeOffset.r = atOffset.r; + eyeOffset.pitch = atOffset.pitch; + eyeOffset.yaw = (atOffset.yaw * anim->yawDir) + camPlayerPosRot->rot.y; + anim->unk_0C -= 0.04f; + break; + case 3: + temp_f0 = (anim->animFrame - 0x9F) * (1.0f / 9.0f); + + sp5C.x = F32_LERPIMP(D_8011D678[2].x, D_8011D678[3].x, temp_f0); + sp5C.y = F32_LERPIMP(D_8011D678[2].y, D_8011D678[3].y, temp_f0); + sp5C.y += yOffset; + sp5C.z = F32_LERPIMP(D_8011D678[2].z, D_8011D678[3].z, temp_f0); + + OLib_Vec3fToVecSphGeo(&atOffset, &sp5C); + atOffset.yaw = (atOffset.yaw * anim->yawDir) + camPlayerPosRot->rot.y; + Camera_Vec3fVecSphGeoAdd(at, &anim->initialAt, &atOffset); + + atOffset.r = F32_LERPIMP(D_8011D658[2].r, D_8011D658[3].r, temp_f0); + atOffset.pitch = BINANG_LERPIMP(D_8011D658[2].pitch, D_8011D658[3].pitch, temp_f0); + atOffset.yaw = BINANG_LERPIMP(D_8011D658[2].yaw, D_8011D658[3].yaw, temp_f0); + + eyeOffset.r = atOffset.r; + eyeOffset.pitch = atOffset.pitch; + eyeOffset.yaw = (atOffset.yaw * anim->yawDir) + camPlayerPosRot->rot.y; + anim->unk_0C += (4.0f / 45.0f); + break; + case 30: + camera->unk_14C |= 0x400; + if (camera->unk_14C & 8) { + camera->animState = 4; + } + case 10: + case 20: + skipUpdateEye = true; + break; + case 4: + eyeOffset.r = 80.0f; + eyeOffset.pitch = 0; + eyeOffset.yaw = eyeAtOffset.yaw; + anim->unk_0C = 0.1f; + sCameraInterfaceFlags = 0x3400; + + if (!((anim->animFrame < 0 || camera->xzSpeed > 0.001f || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_A) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_B) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CLEFT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CDOWN) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CUP) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CRIGHT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_R) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_Z)) && + camera->unk_14C & 8)) { + goto skipeyeUpdate; + } + + default: + camera->unk_14C |= 0x14; + camera->unk_14C &= ~8; + if (camera->prevCamDataIdx < 0) { + Camera_ChangeSettingFlags(camera, camera->prevSetting, 2); + } else { + Camera_ChangeDataIdx(camera, camera->prevCamDataIdx); + camera->prevCamDataIdx = -1; + } + sCameraInterfaceFlags = 0; + skipeyeUpdate: + skipUpdateEye = 1; + break; + } + + anim->animFrame++; + + if (anim->animFrame == 1) { + camera->animState = 0xA; + } else if (anim->animFrame == 2) { + camera->animState = 0x1; + } else if (anim->animFrame == 0x94) { + camera->animState = 2; + } else if (anim->animFrame == 0x9E) { + camera->animState = 0x14; + } else if (anim->animFrame == 0x9F) { + camera->animState = 3; + } else if (anim->animFrame == 0xA8) { + camera->animState = 0x1E; + } else if (anim->animFrame == 0xE4) { + camera->animState = 4; + } + + if (!skipUpdateEye) { + eyeOffset.r = Camera_LERPCeilF(eyeOffset.r, eyeAtOffset.r, anim->unk_0C, 2.0f); + eyeOffset.pitch = Camera_LERPCeilS(eyeOffset.pitch, eyeAtOffset.pitch, anim->unk_0C, 0xA); + eyeOffset.yaw = Camera_LERPCeilS(eyeOffset.yaw, eyeAtOffset.yaw, anim->unk_0C, 0xA); + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeOffset); + *eye = *eyeNext; + } + + camera->dist = OLib_Vec3fDist(at, eye); + camera->atLERPStepScale = 0.1f; + camera->posOffset.x = camera->at.x - camPlayerPosRot->pos.x; + camera->posOffset.y = camera->at.y - camPlayerPosRot->pos.y; + camera->posOffset.z = camera->at.z - camPlayerPosRot->pos.z; + return true; +} s32 Camera_Demo4(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); +} + +/** + * Sets up a cutscene for Camera_Uniq9 + */ +s32 Camera_Demo5(Camera* camera) { + f32 eyeTargetDist; + f32 sp90; + VecSph playerTargetGeo; + VecSph eyePlayerGeo; + VecSph sp78; + PosRot playerPosRot2; + PosRot targetPosRot2; + Player* player; + s16 sp4A; + s32 pad; + s32 temp_v0; + s16 t; + s32 pad2; + + func_8002EEE4(&playerPosRot2, &camera->player->actor); + player = camera->player; + sCameraInterfaceFlags = 0x3200; + if ((camera->target == NULL) || (camera->target->update == NULL)) { + if (camera->target == NULL) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: warning: attention: target is not valid, stop!\n" VT_RST); + } + camera->target = NULL; + return true; + } + func_8002EEE4(&camera->targetPosRot, camera->target); + OLib_Vec3fDiffToVecSphGeo(&playerTargetGeo, &camera->targetPosRot.pos, &camera->playerPosRot.pos); + D_8011D3AC = camera->target->type; + func_8002F374(camera->globalCtx, camera->target, &sp78.yaw, &sp78.pitch); + eyeTargetDist = OLib_Vec3fDist(&camera->targetPosRot.pos, &camera->eye); + OLib_Vec3fDiffToVecSphGeo(&eyePlayerGeo, &playerPosRot2.pos, &camera->eyeNext); + sp4A = eyePlayerGeo.yaw - playerTargetGeo.yaw; + if (camera->target->type == ACTORTYPE_PLAYER) { + // camera is targeting a(the) player actor + if (eyePlayerGeo.r > 30.0f) { + D_8011D6AC[1].timerInit = camera->timer - 1; + D_8011D6AC[1].atTargetInit.z = Math_Rand_ZeroOne() * 10.0f; + D_8011D6AC[1].eyeTargetInit.x = Math_Rand_ZeroOne() * 10.0f; + ONEPOINTDEMO->keyFrames = D_8011D6AC; + ONEPOINTDEMO->keyFrameCnt = ARRAY_COUNT(D_8011D6AC); + if (camera->parentCamIdx != 0) { + ONEPOINTDEMO->keyFrameCnt--; + } else { + camera->timer += D_8011D6AC[2].timerInit; + } + } else { + D_8011D724[1].eyeTargetInit.x = Math_Rand_ZeroOne() * 10.0f; + D_8011D724[1].timerInit = camera->timer - 1; + ONEPOINTDEMO->keyFrames = D_8011D724; + ONEPOINTDEMO->keyFrameCnt = ARRAY_COUNT(D_8011D724); + if (camera->parentCamIdx != 0) { + ONEPOINTDEMO->keyFrameCnt--; + } else { + camera->timer += D_8011D724[2].timerInit; + } + } + } else if (playerTargetGeo.r < 30.0f) { + // distance between player and target is less than 30 units. + ONEPOINTDEMO->keyFrames = D_8011D79C; + ONEPOINTDEMO->keyFrameCnt = ARRAY_COUNT(D_8011D79C); + if ((sp78.yaw < 0x15) || (sp78.yaw >= 0x12C) || (sp78.pitch < 0x29) || (sp78.pitch >= 0xC8)) { + D_8011D79C[0].actionFlags = 0x41; + D_8011D79C[0].atTargetInit.y = -30.0f; + D_8011D79C[0].atTargetInit.x = 0.0f; + D_8011D79C[0].atTargetInit.z = 0.0f; + D_8011D79C[0].eyeTargetInit.y = 0.0f; + D_8011D79C[0].eyeTargetInit.x = 10.0f; + D_8011D79C[0].eyeTargetInit.z = -50.0f; + } + + D_8011D79C[1].timerInit = camera->timer - 1; + + if (camera->parentCamIdx != 0) { + ONEPOINTDEMO->keyFrameCnt -= 2; + } else { + camera->timer += D_8011D79C[2].timerInit + D_8011D79C[3].timerInit; + } + } else if (eyeTargetDist < 300.0f && eyePlayerGeo.r < 30.0f) { + // distance from the camera's current positon and the target is less than 300 units + // and the distance fromthe camera's current position to the player is less than 30 units + D_8011D83C[0].timerInit = camera->timer; + ONEPOINTDEMO->keyFrames = D_8011D83C; + ONEPOINTDEMO->keyFrameCnt = ARRAY_COUNT(D_8011D83C); + if (camera->parentCamIdx != 0) { + ONEPOINTDEMO->keyFrameCnt--; + } else { + camera->timer += D_8011D83C[1].timerInit; + } + } else if (eyeTargetDist < 700.0f && ABS(sp4A) < 0x36B0) { + // The distance between the camera's current position and the target is less than 700 units + // and the angle between the camera's position and the player, and the player to the target + // is less than ~76.9 degrees + if (sp78.yaw >= 0x15 && sp78.yaw < 0x12C && sp78.pitch >= 0x29 && sp78.pitch < 0xC8 && eyePlayerGeo.r > 30.0f) { + D_8011D88C[0].timerInit = camera->timer; + ONEPOINTDEMO->keyFrames = D_8011D88C; + ONEPOINTDEMO->keyFrameCnt = ARRAY_COUNT(D_8011D88C); + if (camera->parentCamIdx != 0) { + ONEPOINTDEMO->keyFrameCnt--; + } else { + camera->timer += D_8011D88C[1].timerInit; + } + } else { + D_8011D8DC[0].atTargetInit.z = eyeTargetDist * 0.6f; + D_8011D8DC[0].eyeTargetInit.z = eyeTargetDist + 50.0f; + D_8011D8DC[0].eyeTargetInit.x = Math_Rand_ZeroOne() * 10.0f; + if (BINANG_SUB(eyePlayerGeo.yaw, playerTargetGeo.yaw) > 0) { + D_8011D8DC[0].atTargetInit.x = -D_8011D8DC[0].atTargetInit.x; + D_8011D8DC[0].eyeTargetInit.x = -D_8011D8DC[0].eyeTargetInit.x; + D_8011D8DC[0].rollTargetInit = -D_8011D8DC[0].rollTargetInit; + } + D_8011D8DC[0].timerInit = camera->timer; + D_8011D8DC[1].timerInit = (s16)(eyeTargetDist * 0.005f) + 8; + ONEPOINTDEMO->keyFrames = D_8011D8DC; + ONEPOINTDEMO->keyFrameCnt = ARRAY_COUNT(D_8011D8DC); + if (camera->parentCamIdx != 0) { + ONEPOINTDEMO->keyFrameCnt -= 2; + } else { + camera->timer += D_8011D8DC[1].timerInit + D_8011D8DC[2].timerInit; + } + } + } else if (camera->target->type == ACTORTYPE_DOOR) { + // the target is a door. + D_8011D954[0].timerInit = camera->timer - 5; + sp4A = 0; + if (!func_800C0D34(camera->globalCtx, camera->target, &sp4A)) { + osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: attention demo: this door is dummy door!\n" VT_RST); + if (ABS(playerTargetGeo.yaw - camera->target->shape.rot.y) >= 0x4000) { + sp4A = camera->target->shape.rot.y; + } else { + sp4A = BINANG_ROT180(camera->target->shape.rot.y); + } + } + + D_8011D954[0].atTargetInit.y = D_8011D954[0].eyeTargetInit.y = D_8011D954[1].atTargetInit.y = + camera->target->shape.rot.y == sp4A ? 180.0f : 0.0f; + sp90 = (BINANG_SUB(playerTargetGeo.yaw, sp4A) < 0 ? 20.0f : -20.0f) * Math_Rand_ZeroOne(); + D_8011D954[0].eyeTargetInit.y = D_8011D954->eyeTargetInit.y + sp90; + temp_v0 = Math_Rand_ZeroOne() * (sp90 * -0.2f); + D_8011D954[1].rollTargetInit = temp_v0; + D_8011D954[0].rollTargetInit = temp_v0; + func_8002EEE4(&targetPosRot2, camera->target); + targetPosRot2.pos.x += 50.0f * Math_Sins(BINANG_ROT180(sp4A)); + targetPosRot2.pos.z += 50.0f * Math_Coss(BINANG_ROT180(sp4A)); + if (Camera_BGCheck(camera, &playerPosRot2.pos, &targetPosRot2.pos)) { + D_8011D954[1].actionFlags = 0xC1; + D_8011D954[2].actionFlags = 0x8F; + } else { + D_8011D954[2].timerInit = (s16)(eyeTargetDist * 0.004f) + 6; + } + ONEPOINTDEMO->keyFrames = D_8011D954; + ONEPOINTDEMO->keyFrameCnt = ARRAY_COUNT(D_8011D954); + if (camera->parentCamIdx != 0) { + ONEPOINTDEMO->keyFrameCnt -= 2; + } else { + camera->timer += D_8011D954[2].timerInit + D_8011D954[3].timerInit; + } + } else { + if (playerTargetGeo.r < 200.0f) { + D_8011D9F4[0].eyeTargetInit.z = playerTargetGeo.r; + D_8011D9F4[0].atTargetInit.z = playerTargetGeo.r * 0.25f; + } + if (playerTargetGeo.r < 400.0f) { + D_8011D9F4[0].eyeTargetInit.x = Math_Rand_ZeroOne() * 25.0f; + } + Player_GetHeight(camera->player); + D_8011D9F4[0].timerInit = camera->timer; + func_8002EEE4(&targetPosRot2, camera->target); + if (Camera_BGCheck(camera, &playerPosRot2.pos, &targetPosRot2.pos)) { + D_8011D9F4[1].timerInit = 4; + D_8011D9F4[1].actionFlags = 0x8F; + } else { + t = eyeTargetDist * 0.005f; + D_8011D9F4[1].timerInit = t + 8; + } + ONEPOINTDEMO->keyFrames = D_8011D9F4; + ONEPOINTDEMO->keyFrameCnt = ARRAY_COUNT(D_8011D9F4); + if (camera->parentCamIdx != 0) { + if (camera->globalCtx->state.frames & 1) { + D_8011D9F4[0].rollTargetInit = -D_8011D9F4[0].rollTargetInit; + D_8011D9F4[1].rollTargetInit = -D_8011D9F4[1].rollTargetInit; + } + ONEPOINTDEMO->keyFrameCnt -= 2; + } else { + camera->timer += D_8011D9F4[1].timerInit + D_8011D9F4[2].timerInit; + D_8011D9F4[0].rollTargetInit = D_8011D9F4[1].rollTargetInit = 0; + } + } + + pad = sDemo5PrevSfxFrame - camera->globalCtx->state.frames; + if ((pad >= 0x33) || (pad < -0x32)) { + func_80078884(camera->data1); + } + + sDemo5PrevSfxFrame = camera->globalCtx->state.frames; + + if (camera->player->stateFlags1 & 0x8000000 && (player->currentBoots != PLAYER_BOOTS_IRON)) { + // swimming, and not iron boots + player->stateFlags1 |= 0x20000000; + // env frozen + player->actor.freezeTimer = camera->timer; + } else { + sp4A = playerPosRot2.rot.y - playerTargetGeo.yaw; + if (camera->target->type == ACTORTYPE_PLAYER) { + pad = camera->globalCtx->state.frames - sDemo5PrevAction12Frame; + if (player->stateFlags1 & 0x800) { + // holding object over head. + func_8002DF54(camera->globalCtx, camera->target, 8); + } else if (ABS(pad) > 3000) { + func_8002DF54(camera->globalCtx, camera->target, 12); + } else { + func_8002DF54(camera->globalCtx, camera->target, 69); + } + } else { + func_8002DF54(camera->globalCtx, camera->target, 1); + } + } + + sDemo5PrevAction12Frame = camera->globalCtx->state.frames; + Camera_ChangeSettingFlags(camera, CAM_SET_DEMOC, (4 | 1)); + Camera_Unique9(camera); + return true; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Demo5.s") +/** + * Used in Forest Temple when poes are defeated, follows the flames to the torches. + * Fixed position, rotates to follow the target + */ +s32 Camera_Demo6(Camera* camera) { + Camera* cam0; + Demo6Anim* anim = (Demo6Anim*)&((Demo6*)camera->paramData)->anim; + Vec3f* eyeNext = &camera->eyeNext; + CameraModeValue* values; + VecSph eyeOffset; + Actor* camFocus; + PosRot focusPosRot; + s16 stateTimers[4]; + Vec3f* at = &camera->at; + + cam0 = Gameplay_GetCamera(camera->globalCtx, 0); + camFocus = camera->target; + stateTimers[1] = 0x37; + stateTimers[2] = 0x46; + stateTimers[3] = 0x5A; + + if (RELOAD_PARAMS) { + values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + ((Demo6*)camera->paramData)->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + switch (camera->animState) { + case 0: + // initalizes the camera state. + anim->animTimer = 0; + camera->fov = 60.0f; + func_8002EF14(&focusPosRot, camFocus); + camera->at.x = focusPosRot.pos.x; + camera->at.y = focusPosRot.pos.y + 20.0f; + camera->at.z = focusPosRot.pos.z; + eyeOffset.r = 200.0f; + // 0x7D0 ~10.99 degrees + eyeOffset.yaw = Camera_XZAngle(&focusPosRot.pos, &cam0->playerPosRot.pos) + 0x7D0; + // -0x3E8 ~5.49 degrees + eyeOffset.pitch = -0x3E8; + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeOffset); + camera->eye = *eyeNext; + camera->animState++; + case 1: + if (stateTimers[camera->animState] < anim->animTimer) { + func_8002DF54(camera->globalCtx, &camera->player->actor, 8); + func_8002EF14(&focusPosRot, camFocus); + anim->atTarget.x = focusPosRot.pos.x; + anim->atTarget.y = focusPosRot.pos.y - 20.0f; + anim->atTarget.z = focusPosRot.pos.z; + camera->animState++; + } else { + break; + } + case 2: + Camera_LERPCeilVec3f(&anim->atTarget, at, 0.1f, 0.1f, 8.0f); + if (stateTimers[camera->animState] < anim->animTimer) { + camera->animState++; + } else { + break; + } + case 3: + camera->fov = Camera_LERPCeilF(50.0f, camera->fov, 0.2f, 0.01f); + if (stateTimers[camera->animState] < anim->animTimer) { + camera->timer = 0; + return true; + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Demo6.s") + anim->animTimer++; + func_8002EF14(&focusPosRot, camFocus); -void Camera_Demo7(Camera* camera) { - if (camera->unk_15E == 0) { + return true; +} + +s32 Camera_Demo7(Camera* camera) { + if (camera->animState == 0) { camera->unk_14C &= ~4; camera->unk_14C |= 0x1000; - camera->unk_15E++; + camera->animState++; } + // @bug doesn't return } s32 Camera_Demo8(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Demo9.s") +/** + * Camera follows points specified by demo9.atPoints and demo9.eyePoints, allows finer control + * over the final eye and at points than Camera_Demo1, by allowing the interpolated at and eye points + * to be relative to the main camera's player, the current camera's player, or the main camera's target + */ +s32 Camera_Demo9(Camera* camera) { + s32 pad; + s32 finishAction; + s16 onePointParam; + Demo9OnePointDemo* demo9OnePoint = (Demo9OnePointDemo*)camera->paramData; + Vec3f csEyeUpdate; + Vec3f csAtUpdate; + Vec3f newEye; + Vec3f newAt; + f32 newRoll; + CameraModeValue* values; + Camera* cam0; + Vec3f* eye = &camera->eye; + PosRot* cam0PlayerPosRot; + PosRot focusPosRot; + s32 pad3; + Vec3f* eyeNext = &camera->eyeNext; + Demo9* demo9 = &demo9OnePoint->demo9; + Vec3f* at = &camera->at; + f32* camFOV = &camera->fov; + Demo9Anim* anim = &demo9->anim; + + cam0 = Gameplay_GetCamera(camera->globalCtx, 0); + cam0PlayerPosRot = &cam0->playerPosRot; + if (RELOAD_PARAMS) { + values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + demo9->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + sCameraInterfaceFlags = demo9->interfaceFlags; + + switch (camera->animState) { + case 0: + // initalize the camera state + anim->keyframe = 0; + anim->finishAction = 0; + anim->curFrame = 0.0f; + camera->animState++; + anim->doLERPAt = false; + finishAction = demo9OnePoint->onePointDemo.actionParameters & 0xF000; + if (finishAction != 0) { + anim->finishAction = finishAction; + + // Clear finish parameters + demo9OnePoint->onePointDemo.actionParameters &= 0xFFF; + } + anim->animTimer = demo9OnePoint->onePointDemo.initTimer; + case 1: + // Run the camera state + if (anim->animTimer > 0) { + // if the animation timer is still running, run the demo logic + // if it is not, then the case will fallthrough to the finish logic. + + // Run the at and eye cs interpoloation functions, if either of them return 1 (that no more points + // exist) change the animation state to 2 (standby) + if (func_800BB2B4(&csEyeUpdate, &newRoll, camFOV, demo9OnePoint->onePointDemo.eyePoints, + &anim->keyframe, &anim->curFrame) != 0 || + func_800BB2B4(&csAtUpdate, &newRoll, camFOV, demo9OnePoint->onePointDemo.atPoints, &anim->keyframe, + &anim->curFrame) != 0) { + camera->animState = 2; + } + + if (demo9OnePoint->onePointDemo.actionParameters == 1) { + // rotate around cam0's player + Camera_RotateAroundPoint(cam0PlayerPosRot, &csEyeUpdate, &newEye); + Camera_RotateAroundPoint(cam0PlayerPosRot, &csAtUpdate, &newAt); + } else if (demo9OnePoint->onePointDemo.actionParameters == 4) { + // rotate around the current camera's player + func_8002EF14(&focusPosRot, &camera->player->actor); + Camera_RotateAroundPoint(&focusPosRot, &csEyeUpdate, &newEye); + Camera_RotateAroundPoint(&focusPosRot, &csAtUpdate, &newAt); + } else if (demo9OnePoint->onePointDemo.actionParameters == 8) { + // rotate around the current camera's target + if (camera->target != NULL && camera->target->update != NULL) { + func_8002EF14(&focusPosRot, camera->target); + Camera_RotateAroundPoint(&focusPosRot, &csEyeUpdate, &newEye); + Camera_RotateAroundPoint(&focusPosRot, &csAtUpdate, &newAt); + } else { + camera->target = NULL; + newEye = *eye; + newAt = *at; + } + } else { + // simple copy + Camera_Vec3fCopy(&csEyeUpdate, &newEye); + Camera_Vec3fCopy(&csAtUpdate, &newAt); + } + + *eyeNext = newEye; + *eye = *eyeNext; + if (anim->doLERPAt) { + Camera_LERPCeilVec3f(&newAt, at, 0.5f, 0.5f, 0.1f); + } else { + *at = newAt; + anim->doLERPAt = true; + } + camera->roll = newRoll * 256.0f; + anim->animTimer--; + break; + } + case 3: + // the cs is finished, decide the next action + camera->timer = 0; + if (anim->finishAction != 0) { + if (anim->finishAction != 0x1000) { + if (anim->finishAction == 0x2000) { + // finish action = 0x2000, run OnePointDemo 0x3FC (Dramatic Return to Link) + onePointParam = demo9OnePoint->onePointDemo.initTimer < 0x32 + ? 5 + : demo9OnePoint->onePointDemo.initTimer / 5; + func_800800F8(camera->globalCtx, 0x3FC, onePointParam, NULL, camera->parentCamIdx); + } + } else { + // finish action = 0x1000, copy the current camera's values to the + // default camera. + Camera_Copy(cam0, camera); + } + } + break; + case 2: + // standby while the timer finishes, change the animState to finish when + // the timer runs out. + anim->animTimer--; + if (anim->animTimer < 0) { + camera->animState++; + } + break; + case 4: + // do nothing. + break; + } + + return true; +} s32 Camera_Demo0(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Special0(Camera* camera) { - s32 pad; - CameraModeValue* val; - Vec3f* playerPosRot; + PosRot* playerPosRot = &camera->playerPosRot; + Special0* spec0 = (Special0*)camera->paramData; - if (camera->unk_15E == 0 || camera->unk_15E == 0xA || camera->unk_15E == 0x14 || QREG(0)) { - val = sCameraSettings[camera->setting].cameraModes[camera->mode].values; - camera->unk_00.spec0.unk_00 = val->val * 0.01f; - val++; - camera->unk_00.spec0.unk_04 = val->val; + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + spec0->lerpAtScale = NEXTPCT; + spec0->interfaceFlags = NEXTSETTING; } - if (QREG(0)) { + if (R_RELOAD_CAM_PARAMS) { Camera_CopyPREGToModeValues(camera); } - D_8011D3A0.w = camera->unk_00.spec0.unk_04; + sCameraInterfaceFlags = spec0->interfaceFlags; - if (camera->unk_15E == 0) { - camera->unk_15E++; + if (camera->animState == 0) { + camera->animState++; } + if ((camera->target == NULL) || (camera->target->update == NULL)) { if (camera->target == NULL) { osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: warning: circle: target is not valid, stop!\n" VT_RST); @@ -2977,23 +6302,22 @@ s32 Camera_Special0(Camera* camera) { } func_8002EEE4(&camera->targetPosRot, camera->target); - func_80043A3C(&camera->targetPosRot, &camera->at, camera->unk_00.f, camera->unk_00.f, 0.1f); - if (1) { - playerPosRot = &camera->playerPosRot.pos; - } - camera->unk_E4.x = camera->at.x - playerPosRot->x; - camera->unk_E4.y = camera->at.y - playerPosRot->y; - camera->unk_E4.z = camera->at.z - playerPosRot->z; + Camera_LERPCeilVec3f(&camera->targetPosRot.pos, &camera->at, spec0->lerpAtScale, spec0->lerpAtScale, 0.1f); + + camera->posOffset.x = camera->at.x - playerPosRot->pos.x; + camera->posOffset.y = camera->at.y - playerPosRot->pos.y; + camera->posOffset.z = camera->at.z - playerPosRot->pos.z; + camera->dist = OLib_Vec3fDist(&camera->at, &camera->eye); - camera->unk_D8 = 0.0f; - if (camera->unk_160 > 0) { - camera->unk_160--; + camera->xzSpeed = 0.0f; + if (camera->timer > 0) { + camera->timer--; } return true; } s32 Camera_Special1(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } s32 Camera_Special2(Camera* camera) { @@ -3001,69 +6325,450 @@ s32 Camera_Special2(Camera* camera) { } s32 Camera_Special3(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#ifdef NON_MATCHING s32 Camera_Special4(Camera* camera) { - PosRot sp3C; - s32 temp_v0; + PosRot curTargetPosRot; s16 sp3A; - s16* unk_160 = &camera->unk_160; + s16* timer = &camera->timer; + Special4* spec4 = (Special4*)camera->paramData; - if (camera->unk_15E == 0) { - D_8011D3A0.w = 0x3200; - camera->unk_15E++; + if (camera->animState == 0) { + sCameraInterfaceFlags = 0x3200; camera->fov = 40.0f; - camera->unk_00.sh[0] = *unk_160; + camera->animState++; + spec4->initalTimer = camera->timer; } - camera->fov = func_8004389C(80.0f, camera->fov, 1.0f / *unk_160, 0.1f); - if ((camera->unk_00.sh[0] - *unk_160) < 0xF) { - *unk_160 = *unk_160 - 1; - return 0; + + camera->fov = Camera_LERPCeilF(80.0f, camera->fov, 1.0f / *timer, 0.1f); + if ((spec4->initalTimer - *timer) < 0xF) { + (*timer)--; + return false; + } else { + camera->roll = -0x1F4; + func_8002EF14(&curTargetPosRot, camera->target); + + camera->at = curTargetPosRot.pos; + camera->at.y -= 150.0f; + + // 0x3E8 ~ 5.49 degrees + sp3A = BINANG_ROT180(curTargetPosRot.rot.y) + 0x3E8; + camera->eye.x = camera->eyeNext.x = (Math_Sins(sp3A) * 780.0f) + camera->at.x; + camera->eyeNext.y = camera->at.y; + camera->eye.z = camera->eyeNext.z = (Math_Coss(sp3A) * 780.0f) + camera->at.z; + camera->eye.y = curTargetPosRot.pos.y; + camera->eye.y = Camera_GetFloorY(camera, &camera->eye) + 20.0f; + (*timer)--; + return true; } - camera->roll = -0x1F4; - func_8002EF14(&sp3C, camera->target); - camera->at = sp3C.pos; - camera->at.y -= 150.0f; - temp_v0 = (s16)(sp3C.rot.y - 0x7FFF) + 0x3E8; - sp3A = temp_v0; - camera->eyeNext.y = (f32)camera->at.y; - camera->eye.x = camera->eyeNext.x = (Math_Sins(temp_v0) * 780.0f) + camera->at.x; - camera->eye.z = camera->eyeNext.z = (Math_Coss(sp3A) * 780.0f) + camera->at.z; - camera->eye.y = sp3C.pos.y; - camera->eye.y = func_80044510(camera, &camera->eye) + 20.0f; - camera->unk_160--; - return 1; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Special4.s") -#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Special5.s") +/** + * Flying with hookshot + */ +s32 Camera_Special5(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + PosRot spA8; + s16 pad; + s16 spA4; + CamColChk sp7C; + VecSph sp74; + VecSph sp6C; + VecSph sp64; + VecSph sp5C; + PosRot* playerPosRot = &camera->playerPosRot; + Special5* spec5 = (Special5*)camera->paramData; + Special5Anim* anim = &spec5->anim; + f32 temp_f0_2; + f32 yOffset; + + yOffset = Player_GetHeight(camera->player); + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / yOffset)); + spec5->yOffset = (NEXTPCT * yOffset) * yNormal; + spec5->eyeDist = NEXTSETTING; + spec5->minDistForRot = NEXTSETTING; + spec5->timerInit = NEXTSETTING; + spec5->pitch = DEGF_TO_BINANG(NEXTSETTING); + spec5->fovTarget = NEXTSETTING; + spec5->atMaxLERPScale = NEXTPCT; + spec5->interfaceFlags = NEXTSETTING; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Special7.s") + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + OLib_Vec3fDiffToVecSphGeo(&sp64, at, eye); + OLib_Vec3fDiffToVecSphGeo(&sp5C, at, eyeNext); + func_8002EF14(&spA8, camera->target); + + sCameraInterfaceFlags = spec5->interfaceFlags; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Special6.s") + if (camera->animState == 0) { + camera->animState++; + anim->animTimer = spec5->timerInit; + } + + if (anim->animTimer > 0) { + anim->animTimer--; + } else if (anim->animTimer == 0) { + if (camera->target == NULL || camera->target->update == NULL) { + camera->target = NULL; + return true; + } + + anim->animTimer--; + if (spec5->minDistForRot < OLib_Vec3fDist(&spA8.pos, &playerPosRot->pos)) { + sp6C.yaw = playerPosRot->rot.y; + sp6C.pitch = -playerPosRot->rot.x; + sp6C.r = 20.0f; + Camera_Vec3fVecSphGeoAdd(&sp7C.pos, &spA8.pos, &sp6C); + Camera_BGCheckInfo(camera, at, &sp7C); + OLib_Vec3fToVecSphGeo(&sp6C, &sp7C.norm); + spA4 = BINANG_SUB(playerPosRot->rot.y, sp6C.yaw); + sp74.r = spec5->eyeDist; + temp_f0_2 = Math_Rand_ZeroOne(); + sp74.yaw = + BINANG_ROT180(playerPosRot->rot.y) + (s16)(spA4 < 0 ? -(s16)(0x1553 + (s16)(temp_f0_2 * 2730.0f)) + : (s16)(0x1553 + (s16)(temp_f0_2 * 2730.0f))); + sp74.pitch = spec5->pitch; + Camera_Vec3fVecSphGeoAdd(eyeNext, &spA8.pos, &sp74); + *eye = *eyeNext; + Camera_BGCheck(camera, &spA8.pos, eye); + } + } + + Camera_CalcAtDefault(camera, &sp5C, spec5->yOffset, 0); + camera->fov = Camera_LERPCeilF(spec5->fovTarget, camera->fov, camera->atLERPStepScale * PCT(OREG(4)), 1.0f); + camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5f, 0xA); + camera->atLERPStepScale = Camera_ClampLERPScale(camera, spec5->atMaxLERPScale); + return true; +} + +/** + * Camera's eye is fixed at points specified at D_8011DA6C / D_8011DA9C + * depending on the player's position + */ +s32 Camera_Special7(Camera* camera) { + Special7* spec7 = (Special7*)camera->paramData; + PosRot* playerPosRot = &camera->playerPosRot; + Vec3f atTarget; + f32 yOffset; + f32 temp_f0; + + yOffset = Player_GetHeight(camera->player); + if (camera->animState == 0) { + if (camera->globalCtx->sceneNum == SCENE_JYASINZOU) { + // Spirit Temple + spec7->idx = 3; + } else if (playerPosRot->pos.x < 1500.0f) { + spec7->idx = 2; + } else if (playerPosRot->pos.y < 3000.0f) { + spec7->idx = 0; + } else { + spec7->idx = 1; + } + camera->animState++; + camera->roll = 0; + } + + if (camera->at.y < D_8011DACC[spec7->idx]) { + atTarget = playerPosRot->pos; + atTarget.y -= 20.0f; + Camera_LERPCeilVec3f(&atTarget, &camera->at, 0.4f, 0.4f, 0.10f); + camera->eye = camera->eyeNext = D_8011DA6C[spec7->idx]; + temp_f0 = (playerPosRot->pos.y - D_8011DADC[spec7->idx]) / (D_8011DACC[spec7->idx] - D_8011DADC[spec7->idx]); + camera->roll = D_8011DAEC[spec7->idx] * temp_f0; + camera->fov = (20.0f * temp_f0) + 60.0f; + } else { + atTarget = playerPosRot->pos; + atTarget.y += yOffset; + Camera_LERPCeilVec3f(&atTarget, &camera->at, 0.4f, 0.4f, 0.1f); + camera->roll = 0; + camera->eye = camera->eyeNext = D_8011DA9C[spec7->idx]; + camera->fov = 70.0f; + } + + camera->dist = OLib_Vec3fDist(&camera->at, &camera->eye); + camera->atLERPStepScale = 0.0f; + camera->posOffset.x = camera->at.x - playerPosRot->pos.x; + camera->posOffset.y = camera->at.y - playerPosRot->pos.y; + camera->posOffset.z = camera->at.z - playerPosRot->pos.z; + return true; +} + +/** + * Courtyard. + * Camera's eye is fixed on the z plane, slides on the xy plane with link + * When the camera's scene data changes the animation to the next "screen" + * happens for 12 frames. The camera's eyeNext is the scene's camera data's position + */ +s32 Camera_Special6(Camera* camera) { + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + VecSph atOffset; + Vec3f sceneCamPos; + Vec3f eyePosCalc; + Vec3f eyeAnim; + Vec3f atAnim; + VecSph eyeAtOffset; + PosRot* playerPosRot = &camera->playerPosRot; + Vec3s* sceneCamData; + Vec3s sceneCamRot; + s16 fov; + f32 sp54; + f32 timerF; + f32 timerDivisor; + Special6* spec6 = (Special6*)camera->paramData; + Special6Anim* anim = &spec6->anim; + s32 pad; + + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + spec6->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + OLib_Vec3fDiffToVecSphGeo(&eyeAtOffset, eye, at); + + sceneCamData = Camera_GetCamBGData(camera); + Camera_Vec3sToVec3f(&sceneCamPos, &BGCAM_POS(sceneCamData)); + sceneCamRot = BGCAM_ROT(sceneCamData); + fov = BGCAM_FOV(sceneCamData); + if (fov == -1) { + fov = 6000; + } + + if (fov < 361) { + fov *= 100; + } + + sCameraInterfaceFlags = spec6->interfaceFlags; + + if (eyeNext->x != sceneCamPos.x || eyeNext->y != sceneCamPos.y || eyeNext->z != sceneCamPos.z || + camera->animState == 0) { + // A change in the current scene's camera positon has been detected, + // Change "screens" + camera->player->actor.freezeTimer = 12; + sCameraInterfaceFlags = (sCameraInterfaceFlags & 0xF0FF) | 0x300; + anim->initalPlayerY = playerPosRot->pos.y; + anim->animTimer = 12; + *eyeNext = sceneCamPos; + if (camera->animState == 0) { + camera->animState++; + } + } + + if (anim->animTimer > 0) { + // In transition between "screens" + timerF = anim->animTimer; + eyePosCalc = *eyeNext; + eyePosCalc.x += (playerPosRot->pos.x - eyePosCalc.x) * 0.5f; + eyePosCalc.y += (playerPosRot->pos.y - anim->initalPlayerY) * 0.2f; + eyeAnim = eyePosCalc; + eyeAnim.y = Camera_LERPCeilF(eyePosCalc.y, eye->y, 0.5f, 0.01f); + + // set the at point to be 100 units from the eye looking at the + // direction specified in the scene's camera data. + atOffset.r = 100.0f; + atOffset.yaw = sceneCamRot.y; + atOffset.pitch = -sceneCamRot.x; + Camera_Vec3fVecSphGeoAdd(&atAnim, &eyeAnim, &atOffset); + timerDivisor = 1.0f / timerF; + eye->x += (eyeAnim.x - eye->x) * timerDivisor; + eye->y += (eyeAnim.y - eye->y) * timerDivisor; + eye->z += (eyeAnim.z - eye->z) * timerDivisor; + at->x += (atAnim.x - at->x) * timerDivisor; + at->y += (atAnim.y - at->y) * timerDivisor; + at->z += (atAnim.z - at->z) * timerDivisor; + camera->fov += (PCT(fov) - camera->fov) / anim->animTimer; + anim->animTimer--; + } else { + // Camera following link on the x axis. + sCameraInterfaceFlags &= 0xF0FF; + eyePosCalc = *eyeNext; + eyePosCalc.x += (playerPosRot->pos.x - eyePosCalc.x) * 0.5f; + eyePosCalc.y += (playerPosRot->pos.y - anim->initalPlayerY) * 0.2f; + *eye = eyePosCalc; + eye->y = Camera_LERPCeilF(eyePosCalc.y, eye->y, 0.5f, 0.01f); + + // set the at point to be 100 units from the eye looking at the + // direction specified in the scene's camera data. + atOffset.r = 100.0f; + atOffset.yaw = sceneCamRot.y; + atOffset.pitch = -sceneCamRot.x; + Camera_Vec3fVecSphGeoAdd(at, eye, &atOffset); + } + return true; +} s32 Camera_Special8(Camera* camera) { - return func_80047394(camera); + return Camera_Noop(camera); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_Special9.s") +s32 Camera_Special9(Camera* camera) { + s32 pad; + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + Vec3f spAC; + VecSph eyeAdjustment; + VecSph atEyeOffsetGeo; + f32 playerYOffset; + s32 pad3; + PosRot* playerPosRot = &camera->playerPosRot; + PosRot adjustedPlayerPosRot; + f32 yNormal; + Special9* spec9 = (Special9*)camera->paramData; + Special9Params* params = &spec9->params; + Special9Anim* anim = ¶ms->anim; + s32 pad4; + Vec3s* camPosData; + + playerYOffset = Player_GetHeight(camera->player); + camera->unk_14C &= ~0x10; + yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM)) - (PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerYOffset)); + + if (RELOAD_PARAMS) { + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + + params->yOffset = NEXTPCT * playerYOffset * yNormal; + params->unk_04 = NEXTSETTING; + params->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + if (spec9->doorParams.doorActor != NULL) { + func_8002EF44(&adjustedPlayerPosRot, spec9->doorParams.doorActor); + } else { + adjustedPlayerPosRot = *playerPosRot; + adjustedPlayerPosRot.pos.y += playerYOffset + params->yOffset; + adjustedPlayerPosRot.rot.x = 0; + } + + OLib_Vec3fDiffToVecSphGeo(&atEyeOffsetGeo, at, eye); + + sCameraInterfaceFlags = params->interfaceFlags; + + switch (camera->animState) { + do { + } while (0); + case 0: + camera->unk_14C &= ~(0x4 | 0x2); + camera->animState++; + anim->targetYaw = ABS(playerPosRot->rot.y - adjustedPlayerPosRot.rot.y) >= 0x4000 + ? BINANG_ROT180(adjustedPlayerPosRot.rot.y) + : adjustedPlayerPosRot.rot.y; + case 1: + spec9->doorParams.timer1--; + if (spec9->doorParams.timer1 <= 0) { + camera->animState++; + if (params->interfaceFlags & 1) { + camPosData = Camera_GetCamBGData(camera); + Camera_Vec3sToVec3f(eyeNext, &BGCAM_POS(camPosData)); + spAC = *eye = *eyeNext; + } else { + s16 yaw; + // 0xE38 ~ 20 degrees + eyeAdjustment.pitch = 0xE38; + // 0xAAA ~ 15 degrees. + yaw = 0xAAA * ((camera->globalCtx->state.frames & 1) ? 1 : -1); + eyeAdjustment.yaw = anim->targetYaw + yaw; + eyeAdjustment.r = 200.0f * yNormal; + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeAdjustment); + spAC = *eye = *eyeNext; + if (Camera_CheckOOB(camera, &spAC, &playerPosRot->pos)) { + yaw = -yaw; + eyeAdjustment.yaw = anim->targetYaw + yaw; + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeAdjustment); + *eye = *eyeNext; + } + } + } else { + break; + } + case 2: + spAC = playerPosRot->pos; + spAC.y += playerYOffset + params->yOffset; + + Camera_LERPCeilVec3f(&spAC, at, 0.25f, 0.25f, 0.1f); + spec9->doorParams.timer2--; + if (spec9->doorParams.timer2 <= 0) { + camera->animState++; + anim->targetYaw = BINANG_ROT180(anim->targetYaw); + } else { + break; + } + case 3: + spAC = playerPosRot->pos; + spAC.y += (playerYOffset + params->yOffset); + Camera_LERPCeilVec3f(&spAC, at, 0.5f, 0.5f, 0.1f); + eyeAdjustment.pitch = Camera_LERPCeilS(0xAAA, atEyeOffsetGeo.pitch, 0.3f, 0xA); + eyeAdjustment.yaw = Camera_LERPCeilS(anim->targetYaw, atEyeOffsetGeo.yaw, 0.3f, 0xA); + eyeAdjustment.r = Camera_LERPCeilF(60.0f, atEyeOffsetGeo.r, 0.3f, 1.0f); + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeAdjustment); + *eye = *eyeNext; + spec9->doorParams.timer3--; + if (spec9->doorParams.timer3 <= 0) { + camera->animState++; + } else { + break; + } + case 4: + camera->animState++; + default: + camera->unk_14C |= (0x400 | 0x10); + sCameraInterfaceFlags = 0; + + if (camera->xzSpeed > 0.001f || CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_A) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_B) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CLEFT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CDOWN) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CUP) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_CRIGHT) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_R) || + CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_Z) || params->interfaceFlags & 0x8) { + + Camera_ChangeSettingFlags(camera, camera->prevSetting, 2); + camera->unk_14C |= (0x4 | 0x2); + } + break; + } + if (!camera->globalCtx->state.frames) {} + spAC = playerPosRot->pos; + spAC.y += playerYOffset; + camera->dist = OLib_Vec3fDist(&spAC, eye); + camera->posOffset.x = camera->at.x - playerPosRot->pos.x; + camera->posOffset.y = camera->at.y - playerPosRot->pos.y; + camera->posOffset.z = camera->at.z - playerPosRot->pos.z; + return true; +} -Camera* func_80057B98(View* view, CollisionContext* colCtx, GlobalContext* globalCtx) { +Camera* Camera_Create(View* view, CollisionContext* colCtx, GlobalContext* globalCtx) { Camera* newCamera = ZeldaArena_MallocDebug(sizeof(*newCamera), "../z_camera.c", 9370); + if (newCamera != NULL) { osSyncPrintf(VT_FGCOL(BLUE) "camera: create --- allocate %d byte" VT_RST "\n", sizeof(*newCamera) * 4); - func_80057C6C(newCamera, view, colCtx, globalCtx); + Camera_Init(newCamera, view, colCtx, globalCtx); } else { osSyncPrintf(VT_COL(RED, WHITE) "camera: create: not enough memory\n" VT_RST); } return newCamera; } -void func_80057C14(Camera* camera) { +void Camera_Destroy(Camera* camera) { if (camera != NULL) { osSyncPrintf(VT_FGCOL(BLUE) "camera: destroy ---" VT_RST "\n"); ZeldaArena_FreeDebug(camera, "../z_camera.c", 9391); @@ -3072,30 +6777,13 @@ void func_80057C14(Camera* camera) { } } -#ifdef NON_MATCHING -void func_80057C6C(Camera* camera, View* view, CollisionContext* colCtx, GlobalContext* globalCtx) { - Camera* temp_v0; - s16 temp_a1; - s32 temp_a1_2; - s32 temp_v1; - s32 temp_v1_2; - s32 temp_v1_3; - s16* phi_a0; - s32 phi_v0; - s32 phi_v1; - s16* phi_a0_2; - s32 phi_v0_2; - s32 phi_v1_2; - s32 phi_a1; - s16 phi_v1_3; - s32 phi_v1_4; - s16 phi_a1_2; +void Camera_Init(Camera* camera, View* view, CollisionContext* colCtx, GlobalContext* globalCtx) { + Camera* camP; s32 i; - s32 j; - Camera* cam; - s16 t; + s16 curUID; + s16 j; - func_80106860((void*)camera, 0, 0x16CU); + func_80106860(camera, 0, sizeof(*camera)); if (sInitRegs) { for (i = 0; i < sOREGInitCnt; i++) { OREG(i) = sOREGInit[i]; @@ -3105,99 +6793,93 @@ void func_80057C6C(Camera* camera, View* view, CollisionContext* colCtx, GlobalC PREG(i) = sPREGInit[i]; } - func_800B958C(camera, &D_8015BD80, &gGameInfo); + DbgCamera_FirstInit(camera, &D_8015BD80); sInitRegs = false; PREG(88) = -1; } camera->globalCtx = D_8015BD7C = globalCtx; - func_800B4D58(&D_8015BD80, camera); - temp_a1 = D_8011D39C; - D_8011D39C++; - for (temp_a1 = D_8011D39C, D_8011D39C++; temp_a1 != 0; temp_a1 = D_8011D39C, D_8011D39C++) { - if (temp_a1 == 0) { - D_8011D39C++; - } - for (phi_v1_3 = 0; phi_v1_3 < 4; phi_v1_3++) { - temp_v0 = camera->globalCtx->cameraPtrs[phi_v1_3]; - if (temp_v0 != NULL && temp_a1 == temp_v0->uid) { + DbgCamera_Init(&D_8015BD80, camera); + curUID = sNextUID; + sNextUID++; + while (curUID != 0) { + if (curUID == 0) { + sNextUID++; + } + + for (j = 0; j < 4; j++) { + camP = camera->globalCtx->cameraPtrs[j]; + if (camP != NULL && curUID == camP->uid) { break; } } - if (phi_v1_3 == 4) { + if (j == 4) { break; } + + curUID = sNextUID++; } - camera->unk_134.y = 0x3FFF; - camera->unk_13A = camera->unk_134; - camera->uid = temp_a1; - camera->unk_C0.x = 10.0f; - camera->unk_C0.z = 10.0f; - camera->unk_68.y = 1.0f; - camera->unk_68.x = 0.0f; - camera->unk_68.z = 0.0f; + // ~ 90 degrees + camera->inputDir.y = 0x3FFF; + camera->uid = curUID; + camera->camDir = camera->inputDir; + camera->rUpdateRateInv = 10.0f; + camera->yawUpdateRateInv = 10.0f; + camera->up.x = 0.0f; + camera->up.y = 1.0f; + camera->up.z = 0.0f; camera->fov = 60.0f; - D_8011D3A8 = 0x20; - D_8011D3A4 = 0; - camera->unk_C0.y = OREG(7); - camera->unk_CC.x = OREG(2) * 0.01f; - camera->unk_CC.y = OREG(3) * 0.01f; - camera->unk_CC.z = OREG(4) * 0.01f; - + camera->pitchUpdateRateInv = R_CAM_DEFA_PHI_UPDRATE; + camera->xzOffsetUpdateRate = PCT(OREG(2)); + camera->yOffsetUpdateRate = PCT(OREG(3)); + camera->fovUpdateRate = PCT(OREG(4)); + sCameraShrinkWindowVal = 0x20; + sCameraInterfaceAlpha = 0; camera->unk_14C = 0; - camera->unk_154 = 0x21U; - camera->unk_166 = -1; + camera->setting = camera->prevSetting = 0x21; + camera->camDataIdx = camera->prevCamDataIdx = -1; camera->mode = 0; - camera->unk_146 = 0x32; + camera->bgCheckId = 0x32; camera->unk_168 = 0x7FFF; - camera->unk_160 = -1; + camera->timer = -1; camera->unk_14C |= 0x4000; - camera->unk_68.y = 1.0f; - camera->unk_68.z = 0.0f; - camera->unk_68.x = 0.0f; - camera->unk_80.x = 0.0f; - camera->unk_80.y = 0.0f; - camera->unk_80.z = 0.0f; - camera->setting = camera->unk_154; - camera->unk_148 = camera->unk_166; - camera->unk_100 = 1.0f; - D_8011D3A0.w = 0xFF00; - D_8011D398 = -1; + + camera->up.y = 1.0f; + camera->up.z = camera->up.x = 0.0f; + camera->skyboxOffset.x = camera->skyboxOffset.y = camera->skyboxOffset.z = 0; + camera->atLERPStepScale = 1; + sCameraInterfaceFlags = 0xFF00; + sDbgModeIdx = -1; D_8011D3F0 = 3; osSyncPrintf(VT_FGCOL(BLUE) "camera: initialize --- " VT_RST " UID %d\n", camera->uid); } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80057C6C.s") -#endif - -s32 func_8005AD40(Camera* camera, Actor* doorActor, s16 arg2, f32 arg3, s16 arg4, s16 arg5, s16 arg6); void func_80057FC4(Camera* camera) { if (camera != &camera->globalCtx->mainCamera) { - camera->unk_154 = camera->setting = CAM_SET_FREE0; + camera->prevSetting = camera->setting = CAM_SET_FREE0; camera->unk_14C &= ~0x4; } else if (camera->globalCtx->roomCtx.curRoom.mesh->polygon.type != 1) { switch (camera->globalCtx->roomCtx.curRoom.unk_03) { case 1: - func_8005AD40(camera, 0, -99, 0, 0, 18, 10); - camera->unk_154 = camera->setting = CAM_SET_DUNGEON0; + Camera_ChangeDoorCam(camera, NULL, -99, 0, 0, 18, 10); + camera->prevSetting = camera->setting = CAM_SET_DUNGEON0; break; case 0: osSyncPrintf("camera: room type: default set field\n"); - func_8005AD40(camera, 0, -99, 0, 0, 18, 10); - camera->unk_154 = camera->setting = CAM_SET_NORMAL0; + Camera_ChangeDoorCam(camera, NULL, -99, 0, 0, 18, 10); + camera->prevSetting = camera->setting = CAM_SET_NORMAL0; break; default: osSyncPrintf("camera: room type: default set etc (%d)\n", camera->globalCtx->roomCtx.curRoom.unk_03); - func_8005AD40(camera, 0, -99, 0, 0, 18, 10); - camera->unk_154 = camera->setting = CAM_SET_NORMAL0; + Camera_ChangeDoorCam(camera, NULL, -99, 0, 0, 18, 10); + camera->prevSetting = camera->setting = CAM_SET_NORMAL0; camera->unk_14C |= 4; break; } } else { osSyncPrintf("camera: room type: prerender\n"); - camera->unk_154 = camera->setting = CAM_SET_FREE0; + camera->prevSetting = camera->setting = CAM_SET_FREE0; camera->unk_14C &= ~0x4; } } @@ -3205,116 +6887,318 @@ void func_80057FC4(Camera* camera) { void Camera_Stub80058140(Camera* camera) { } -#ifdef NON_MATCHING -void func_80058148(Camera* camera, Player* player) { - s32 pad; - PosRot sp54; - VecSph sp4C; - s32 sp48; - Vec3f sp3C; - f32 temp_f0; - - func_8002EF44(&sp54, &player->actor); - temp_f0 = Player_GetCameraYOffset(player); +void Camera_InitPlayerSettings(Camera* camera, Player* player) { + PosRot playerPosShape; + VecSph eyeNextAtOffset; + s32 bgId; + Vec3f floorPos; + s32 upXZ; + f32 playerYOffset; + Vec3f* eye = &camera->eye; + Vec3f* at = &camera->at; + Vec3f* eyeNext = &camera->eyeNext; + + func_8002EF44(&playerPosShape, &player->actor); + playerYOffset = Player_GetHeight(player); camera->player = player; - camera->playerPosRot = sp54; - sp4C.r = 180.0f; - camera->dist = 180.0f; - camera->unk_134.y = sp54.rot.y; - sp4C.pitch = 0x71C; - sp4C.yaw = camera->unk_134.y - 0x7FFF; - camera->unk_134.x = 0x71C; - camera->unk_134.z = 0; - camera->unk_13A = camera->unk_134; - camera->unk_D8 = 0.0f; - camera->unk_F0.y = 0.0f; - camera->at = sp54.pos; - camera->unk_E4.y = temp_f0; - camera->unk_E4.x = 0.0f; - camera->unk_E4.z = 0.0f; - camera->at.y += temp_f0; - func_80043C28(&camera->eyeNext, &camera->at, &sp4C); - camera->eye = camera->eyeNext; + camera->playerPosRot = playerPosShape; + camera->dist = eyeNextAtOffset.r = 180.0f; + camera->inputDir.y = playerPosShape.rot.y; + eyeNextAtOffset.yaw = BINANG_ROT180(camera->inputDir.y); + camera->inputDir.x = eyeNextAtOffset.pitch = 0x71C; + camera->inputDir.z = 0; + camera->camDir = camera->inputDir; + camera->xzSpeed = 0.0f; + camera->playerPosDelta.y = 0.0f; + camera->at = playerPosShape.pos; + camera->at.y += playerYOffset; + + camera->posOffset.x = 0; + camera->posOffset.y = playerYOffset; + camera->posOffset.z = 0; + + Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeNextAtOffset); + *eye = *eyeNext; camera->roll = 0; - camera->unk_68.z = 0.0f; - camera->unk_68.x = 0.0f; - camera->unk_68.y = 1.0f; - if (func_80044434(camera, &sp3C, &camera->at, &sp48) != -32000.0f) { - camera->unk_146 = sp48; - } - camera->unk_118 = -1; - camera->unk_11C = -1; + + upXZ = 0; + camera->up.z = upXZ; + camera->up.y = 1.0f; + camera->up.x = upXZ; + + if (Camera_GetFloorYNorm(camera, &floorPos, at, &bgId) != BGCHECK_Y_MIN) { + camera->bgCheckId = bgId; + } + + camera->waterPrevCamIdx = -1; + camera->waterPrevCamSetting = -1; camera->unk_14C |= 4; + if (camera == &camera->globalCtx->mainCamera) { - D_8011D3A0.w = 0xB200; + sCameraInterfaceFlags = 0xB200; } else { - D_8011D3A0.w = 0; + sCameraInterfaceFlags = 0; } + func_80057FC4(camera); camera->unk_14A = 0; - camera->unk_15C = 0; - camera->unk_156 = -1; - camera->unk_100 = 1.0f; + camera->paramFlags = 0; + camera->nextCamDataIdx = -1; + camera->atLERPStepScale = 1.0f; Camera_CopyModeValuesToPREG(camera, camera->mode); - func_8005B044(); + Camera_QRegInit(); osSyncPrintf(VT_FGCOL(BLUE) "camera: personalize ---" VT_RST "\n"); - if (camera->unk_164 == 0) { - func_800588B4(camera); + + if (camera->thisIdx == 0) { + Camera_CheckWater(camera); } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80058148.s") -#endif -#ifdef NON_MATCHING -void Camera_ChangeStatus(Camera* camera, s16 status) { - s32 temp_s1; - CameraMode* temp_v0; - s32 phi_a1; - s32 phi_a2; - s16 phi_v0; - CameraModeValue* phi_s0; - s32 phi_s1; +s16 Camera_ChangeStatus(Camera* camera, s16 status) { + CameraModeValue* values; + CameraModeValue* valueP; + s32 i; if (PREG(82)) { - phi_a1 = status == 7 ? 0x6F : 0x78; - phi_a2 = camera->status != 7 ? 0x6F : 0x78; - osSyncPrintf("camera: change camera status: cond %c%c\n", phi_a1, phi_a2); + osSyncPrintf("camera: change camera status: cond %c%c\n", status == 7 ? 'o' : 'x', + camera->status != 7 ? 'o' : 'x'); } + if (PREG(82)) { - osSyncPrintf("camera: res: stat (%d/%d/%d)\n", camera->unk_164, camera->setting, camera->mode); + osSyncPrintf("camera: res: stat (%d/%d/%d)\n", camera->thisIdx, camera->setting, camera->mode); } - if (status == 7 && camera->status != 7) { - temp_v0 = &sCameraSettings[camera->setting].cameraModes[camera->mode]; - if (temp_v0->valueCnt > 0) { - phi_s0 = temp_v0->values; - phi_s1 = 0; - loop_12: - PREG(phi_s0->param) = phi_s0->val; - if (PREG(82) != 0) { - osSyncPrintf("camera: change camera status: PREG(%02d) = %d\n", phi_s0->param, phi_s0->val); - } - temp_s1 = phi_s1 + 1; - phi_s0 = phi_s0 + 4; - phi_s1 = temp_s1; - if (temp_s1 < sCameraSettings[camera->setting].cameraModes[camera->mode].valueCnt) { - goto loop_12; + + if (status == CAM_STAT_ACTIVE && camera->status != CAM_STAT_ACTIVE) { + values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + for (i = 0; i < sCameraSettings[camera->setting].cameraModes[camera->mode].valueCnt; i++) { + valueP = &values[i]; + PREG(valueP->param) = valueP->val; + if (PREG(82)) { + osSyncPrintf("camera: change camera status: PREG(%02d) = %d\n", valueP->param, valueP->val); } } } camera->status = status; + return camera->status; +} + +#ifdef NON_MATCHING +void Camera_PrintSettings(Camera* camera) { + char sp58[8]; + char sp50[8]; + char sp48[8]; + s16 temp_v0; + s32 temp_v0_2; + s8* temp_t6; + s8* temp_t7; + s8* temp_t8; + s8* temp_t9; + Camera* temp_a0; + s32 phi_a1; + char* phi_v1; + char* phi_t0; + s32 phi_v0; + s32 phi_v0_2; + + if (OREG(0) & 1 && camera->thisIdx == camera->globalCtx->activeCamera && !gDbgCamEnabled) { + for (phi_a1 = 0, phi_v1 = sp58, phi_t0 = sp48; phi_v1 < &sp58[4]; phi_v1++, phi_t0++, phi_a1++) { + temp_a0 = camera->globalCtx->cameraPtrs[phi_a1]; + if (temp_a0 == NULL) { + *phi_v1 = '-'; + *phi_t0 = ' '; + } else { + switch (temp_a0->status) { + case 0: + *phi_v1 = 'c'; + *phi_t0 = ' '; + break; + case 1: + *phi_v1 = 'w'; + *phi_t0 = ' '; + break; + case 3: + *phi_v1 = 's'; + *phi_t0 = ' '; + break; + case 7: + *phi_v1 = 'a'; + *phi_t0 = ' '; + break; + case 0x100: + *phi_v1 = 'd'; + *phi_t0 = ' '; + break; + default: + *phi_v1 = '*'; + *phi_t0 = ' '; + break; + } + } + } + *phi_v1++ = '\0'; + *phi_t0++ = '\0'; + + sp48[camera->globalCtx->activeCamera] = 'a'; + func_8006376C(3, 0x16, 5, sp58); + func_8006376C(3, 0x16, 1, sp48); + func_8006376C(3, 0x17, 5, "S:"); + func_8006376C(5, 0x17, 4, sCameraSettingNames[camera->setting]); + func_8006376C(3, 0x18, 5, "M:"); + func_8006376C(5, 0x18, 4, sCameraModeNames[camera->mode]); + func_8006376C(3, 0x19, 5, "F:"); + func_8006376C(5, 0x19, 4, + sCameraFunctionNames[sCameraSettings[camera->setting].cameraModes[camera->mode].funcIdx]); + + phi_v0 = 0; + if (camera->camDataIdx < 0) { + sp50[phi_v0++] = '-'; + } + phi_v0_2 = camera->camDataIdx / 0xA; + if (phi_v0_2 != 0) { + sp50[phi_v0++] = phi_v0 / 0xA + '0'; + } + sp50[phi_v0++] = phi_v0 % 10 + '0'; + sp50[phi_v0++] = ' '; + sp50[phi_v0++] = ' '; + sp50[phi_v0++] = ' '; + sp50[phi_v0++] = ' '; + sp50[phi_v0] = '\0'; + func_8006376C(3, 26, 5, "I:"); + func_8006376C(5, 26, 4, sp50); + } } #else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_ChangeStatus.s") +void Camera_PrintSettings(Camera* camera); +#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_PrintSettings.s") #endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800584E8.s") +s32 Camera_CheckWater(Camera* camera) { + f32 waterY; + s16 newQuakeId; + s32 waterBoxProp; + s32* waterPrevCamSetting = &camera->waterPrevCamSetting; + s16 waterCamIdx; + s16* quakeId = (s16*)&camera->waterQuakeId; + Player* player = camera->player; + s16 prevBgId; + + if (!(camera->unk_14C & 2) || sCameraSettings[camera->setting].unk_00 & 0x40000000) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800588B4.s") + if (camera->unk_14C & 0x200) { + if (player->stateFlags2 & 0x800) { + Camera_ChangeSettingFlags(camera, CAM_SET_CIRCLE5, 6); + camera->unk_14C |= (s16)0x8000; + } else if (camera->unk_14C & (s16)0x8000) { + Camera_ChangeSettingFlags(camera, *waterPrevCamSetting, 6); + camera->unk_14C &= ~((s16)0x8000); + } + } + if (!(camera->unk_14C & (s16)0x8000)) { + if (waterCamIdx = Camera_GetWaterBoxDataIdx(camera, &waterY), waterCamIdx == -2) { + // No camera data idx + if (!(camera->unk_14C & 0x200)) { + camera->unk_14C |= 0x200; + camera->waterYPos = waterY; + camera->waterPrevCamIdx = camera->camDataIdx; + *quakeId = -1; + } + if (camera->playerGroundY != camera->playerPosRot.pos.y) { + prevBgId = camera->bgCheckId; + camera->bgCheckId = 50; + Camera_ChangeSettingFlags(camera, CAM_SET_NORMAL3, 2); + *waterPrevCamSetting = camera->setting; + camera->bgCheckId = prevBgId; + camera->camDataIdx = -2; + } + } else if (waterCamIdx != -1) { + // player is in a water box + if (!(camera->unk_14C & 0x200)) { + camera->unk_14C |= 0x200; + camera->waterYPos = waterY; + camera->waterPrevCamIdx = camera->camDataIdx; + *quakeId = -1; + } + if (camera->playerGroundY != camera->playerPosRot.pos.y) { + prevBgId = camera->bgCheckId; + camera->bgCheckId = 50; + Camera_ChangeDataIdx(camera, waterCamIdx); + *waterPrevCamSetting = camera->setting; + camera->bgCheckId = prevBgId; + } + } else if (camera->unk_14C & 0x200) { + // player is out of a water box. + osSyncPrintf("camera: water: off\n"); + camera->unk_14C &= ~0x200; + prevBgId = camera->bgCheckId; + camera->bgCheckId = 50; + if (camera->waterPrevCamIdx < 0) { + func_80057FC4(camera); + camera->camDataIdx = -1; + } else { + Camera_ChangeDataIdx(camera, camera->waterPrevCamIdx); + } + camera->bgCheckId = prevBgId; + } + } -s32 func_80058CF8(Camera* camera) { - camera->unk_152 &= ~1; + if (waterY = Camera_GetWaterSurface(camera, &camera->eye, &waterBoxProp), waterY != BGCHECK_Y_MIN) { + camera->waterYPos = waterY; + if (!(camera->unk_14C & 0x100)) { + camera->unk_14C |= 0x100; + osSyncPrintf("kankyo changed water, sound on\n"); + func_80070600(camera->globalCtx, waterBoxProp); + camera->unk_150 = 0x50; + } + + func_800F6828(0x20); + + if (PREG(81)) { + Quake_RemoveFromIdx(*quakeId); + *quakeId = -1; + PREG(81) = 0; + } + + if ((*quakeId == -1) || (Quake_GetCountdown(*quakeId) == 0xA)) { + if (*quakeId = newQuakeId = Quake_Add(camera, 5U), newQuakeId != 0) { + Quake_SetSpeed(*quakeId, 550); + Quake_SetQuakeValues(*quakeId, 1, 1, 180, 0); + Quake_SetCountdown(*quakeId, 1000); + } + } + if (camera->unk_150 > 0) { + camera->unk_150--; + camera->unk_152 |= 8; + return; + } else if (camera->globalCtx->sceneNum == 0x49) { + camera->unk_152 |= 0x10; + return; + } else { + camera->unk_152 |= 2; + return; + } + } + if (camera->unk_14C & 0x100) { + camera->unk_14C &= ~0x100; + osSyncPrintf("kankyo changed water off, sound off\n"); + func_800706A0(camera->globalCtx); + if (*quakeId != 0) { + Quake_RemoveFromIdx(*quakeId); + } + camera->unk_150 = 0; + camera->unk_152 = 0; + } + func_800F6828(0); + // @BUG: doesn't always return a value, but sometimes does. +} + +/** + * Sets the room to be hot camera quake flag + */ +s32 Camera_SetRoomHotFlag(Camera* camera) { + camera->unk_152 &= ~1; if (camera->globalCtx->roomCtx.curRoom.unk_02 == 3) { camera->unk_152 |= 1; } @@ -3322,49 +7206,377 @@ s32 func_80058CF8(Camera* camera) { return 1; } -s32 func_80058D34(Camera* camera) { - s32 phi_a2 = 0; +s32 Camera_DbgChangeMode(Camera* camera) { + s32 changeDir = 0; - if (D_8011D394 == 0) { - if (camera->globalCtx->activeCamera == 0) { - if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CUP)) { - osSyncPrintf("attention sound URGENCY\n"); - func_80078884(NA_SE_SY_ATTENTION_URGENCY); - } - if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CDOWN)) { - osSyncPrintf("attention sound NORMAL\n"); - func_80078884(NA_SE_SY_ATTENTION_ON); + if (gDbgCamEnabled == 0 && camera->globalCtx->activeCamera == 0) { + if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CUP)) { + osSyncPrintf("attention sound URGENCY\n"); + func_80078884(NA_SE_SY_ATTENTION_URGENCY); + } + if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CDOWN)) { + osSyncPrintf("attention sound NORMAL\n"); + func_80078884(NA_SE_SY_ATTENTION_ON); + } + + if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CRIGHT)) { + changeDir = 1; + } + if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CLEFT)) { + changeDir = -1; + } + if (changeDir != 0) { + sDbgModeIdx = (sDbgModeIdx + changeDir) % 6; + if (Camera_ChangeSetting(camera, D_8011DAFC[sDbgModeIdx]) > 0) { + osSyncPrintf("camera: force change SET to %s!\n", sCameraSettingNames[D_8011DAFC[sDbgModeIdx]]); } + } + } + return true; +} + +void func_80058E8C(Camera* camera) { + static s16 D_8011DB08 = 0x3F0; + static s16 D_8011DB0C = 0x156; + s32 pad3; + f32 sp60; + s32 pad; + s32 pad1; + s32 pad4; + f32 phi_f2; + s32 pad2; + f32 phi_f0; + f32 phi_f20; + f32 sp40; + f32 sp3C; + f32 sp38; + f32 sp34; + + if (camera->unk_152 != 0) { + if (camera->unk_152 & 4) { + phi_f0 = 0.0f; + phi_f2 = 170.0f; + sp3C = 0.01f; + sp40 = -0.01f; + sp38 = 0.0f; + sp34 = 0.6f; + phi_f20 = camera->unk_150 / 60.0f; + sp60 = 1.0f; + } else if (camera->unk_152 & 8) { + phi_f0 = 248.0f; + phi_f2 = -90.0f; + sp38 = 0.2f; + sp34 = 0.2f; + sp40 = -0.3f; + sp3C = 0.3f; + phi_f20 = camera->unk_150 / 80.0f; + sp60 = 1.0f; + } else if (camera->unk_152 & 2) { + phi_f0 = 359.2f; + phi_f2 = -18.5f; + sp40 = 0.09f; + sp38 = 0.01f; + sp3C = 0.09f; + sp34 = 0.08f; + phi_f20 = + (((camera->waterYPos - camera->eye.y) > 150.0f ? 1.0f : (camera->waterYPos - camera->eye.y) / 150.0f) * + 0.45f) + + (camera->speedRatio * 0.45f); + sp60 = phi_f20; + } else if (camera->unk_152 & 1) { + // hot room flag + phi_f2 = 150.0f; + phi_f0 = 0.0f; + sp3C = 0.01f; + sp38 = 0.01f; + sp40 = -0.01f; + sp34 = 0.6f; + sp60 = 1.0f; + phi_f20 = 1.0f; + + } else { + return; + } + D_8011DB08 += DEGF_TO_BINANG(phi_f0); + D_8011DB0C += DEGF_TO_BINANG(phi_f2); + Math_Coss(D_8011DB08); + Math_Sins(D_8011DB08); + Math_Sins(D_8011DB0C); + func_800AA76C(&camera->globalCtx->view, 0.0f, 0.0f, 0.0f); + func_800AA78C(&camera->globalCtx->view, Math_Sins(D_8011DB0C) * (sp40 * phi_f20) + 1.0f, + Math_Coss(D_8011DB0C) * (sp3C * phi_f20) + 1.0f, Math_Coss(D_8011DB08) * (sp38 * phi_f20) + 1.0f); + func_800AA7AC(&camera->globalCtx->view, sp34 * sp60); + camera->unk_14C |= 0x40; + } else if (camera->unk_14C & 0x40) { + func_800AA814(&camera->globalCtx->view); + camera->unk_14C &= ~0x40; + } +} + +Vec3s* Camera_Update(Vec3s* outVec, Camera* camera) { + static s32 sOOBTimer = 0; + Vec3f viewAt; + Vec3f viewEye; + Vec3f viewUp; + f32 viewFov; + Vec3f spAC; + u32 bgCheckId; + f32 playerGroundY; + f32 playerXZSpeed; + VecSph eyeAtAngle; + s16 camDataIdx; + PosRot curPlayerPosRot; + QuakeCamCalc quake; + Player* player; + + player = camera->globalCtx->cameraPtrs[0]->player; + + if (R_DBG_CAM_UPDATE) { + osSyncPrintf("camera: in %x\n", camera); + } + + if (camera->status == CAM_STAT_CUT) { + if (R_DBG_CAM_UPDATE) { + osSyncPrintf("camera: cut out %x\n", camera); + } + *outVec = camera->inputDir; + return outVec; + } + + sUpdateCameraDirection = false; + + if (camera->player != NULL) { + func_8002EF44(&curPlayerPosRot, &camera->player->actor); + camera->xzSpeed = playerXZSpeed = OLib_Vec3fDistXZ(&curPlayerPosRot.pos, &camera->playerPosRot.pos); + + camera->speedRatio = OLib_ClampMaxDist(playerXZSpeed / (func_8002DCE4(camera->player) * PCT(OREG(8))), 1.0f); + camera->playerPosDelta.x = curPlayerPosRot.pos.x - camera->playerPosRot.pos.x; + camera->playerPosDelta.y = curPlayerPosRot.pos.y - camera->playerPosRot.pos.y; + camera->playerPosDelta.z = curPlayerPosRot.pos.z - camera->playerPosRot.pos.z; + spAC = curPlayerPosRot.pos; + spAC.y += Player_GetHeight(camera->player); + + playerGroundY = func_8003CA0C(camera->globalCtx, &camera->globalCtx->colCtx, &playerFloorPoly, &bgCheckId, + &camera->player->actor, &spAC); + if (playerGroundY != BGCHECK_Y_MIN) { + // player is above ground. + sOOBTimer = 0; + camera->floorNorm.x = playerFloorPoly->norm.x * COLPOLY_NORM_FRAC; + camera->floorNorm.y = playerFloorPoly->norm.y * COLPOLY_NORM_FRAC; + camera->floorNorm.z = playerFloorPoly->norm.z * COLPOLY_NORM_FRAC; + camera->bgCheckId = bgCheckId; + camera->playerGroundY = playerGroundY; + } else { + // player is not above ground. + sOOBTimer++; + camera->floorNorm.x = 0.0; + camera->floorNorm.y = 1.0f; + camera->floorNorm.z = 0.0; + } + + camera->playerPosRot = curPlayerPosRot; - if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CRIGHT)) { - phi_a2 = 1; + if (sOOBTimer < 200) { + if (camera->status == CAM_STAT_ACTIVE) { + Camera_CheckWater(camera); + Camera_SetRoomHotFlag(camera); } - if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CLEFT)) { - phi_a2 = -1; + + if (!(camera->unk_14C & 4)) { + camera->nextCamDataIdx = -1; } - if (phi_a2 != 0) { - D_8011D398 = (D_8011D398 + phi_a2) % 6; - if (func_8005A77C(camera, D_8011DAFC[D_8011D398]) > 0) { - osSyncPrintf("camera: force change SET to %s!\n", sCameraSettingNames[D_8011DAFC[D_8011D398]]); + + if ((camera->unk_14C & 1) && (camera->unk_14C & 4) && (!(camera->unk_14C & 0x400)) && + (!(camera->unk_14C & 0x200) || (player->currentBoots == PLAYER_BOOTS_IRON)) && + (!(camera->unk_14C & (s16)0x8000)) && (playerGroundY != BGCHECK_Y_MIN)) { + camDataIdx = Camera_GetDataIdxForPoly(camera, &bgCheckId, playerFloorPoly); + if (camDataIdx != -1) { + camera->nextBGCheckId = bgCheckId; + if (bgCheckId == 50) { + camera->nextCamDataIdx = camDataIdx; + } } } + + if (camera->nextCamDataIdx != -1 && (fabsf(curPlayerPosRot.pos.y - playerGroundY) < 2.0f) && + (!(camera->unk_14C & 0x200) || (player->currentBoots == PLAYER_BOOTS_IRON))) { + camera->bgCheckId = camera->nextBGCheckId; + Camera_ChangeDataIdx(camera, camera->nextCamDataIdx); + camera->nextCamDataIdx = -1; + } } } - return 1; -} + Camera_PrintSettings(camera); + Camera_DbgChangeMode(camera); + + if (camera->status == CAM_STAT_WAIT) { + if (R_DBG_CAM_UPDATE) { + osSyncPrintf("camera: wait out %x\n", camera); + } + *outVec = camera->inputDir; + return outVec; + } + + camera->unk_14A = 0; + camera->unk_14C &= ~(0x400 | 0x20); + camera->unk_14C |= 0x10; + + if (R_DBG_CAM_UPDATE) { + osSyncPrintf("camera: engine (%d %d %d) %04x \n", camera->setting, camera->mode, + sCameraSettings[camera->setting].cameraModes[camera->mode].funcIdx, camera->unk_14C); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_80058E8C.s") + if (sOOBTimer < 200) { + sCameraFunctions[sCameraSettings[camera->setting].cameraModes[camera->mode].funcIdx](camera); + } else if (camera->player != NULL) { + OLib_Vec3fDiffToVecSphGeo(&eyeAtAngle, &camera->at, &camera->eye); + Camera_CalcAtDefault(camera, &eyeAtAngle, 0.0f, 0); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800591EC.s") + if (camera->status == CAM_STAT_ACTIVE) { + if ((gSaveContext.gameMode != 0) && (gSaveContext.gameMode != 3)) { + sCameraInterfaceFlags = 0; + Camera_UpdateInterface(sCameraInterfaceFlags); + } else if ((D_8011D3F0 != 0) && (camera->thisIdx == 0)) { + D_8011D3F0--; + sCameraInterfaceFlags = 0x3200; + Camera_UpdateInterface(sCameraInterfaceFlags); + } else if (camera->globalCtx->transitionMode != 0) { + sCameraInterfaceFlags = 0xF200; + Camera_UpdateInterface(sCameraInterfaceFlags); + } else if (camera->globalCtx->csCtx.state != 0) { + sCameraInterfaceFlags = 0x3200; + Camera_UpdateInterface(sCameraInterfaceFlags); + } else { + Camera_UpdateInterface(sCameraInterfaceFlags); + } + } -void func_80059EC8(Camera* camera) { - Camera* sp24 = camera->globalCtx->cameraPtrs[0]; + if (R_DBG_CAM_UPDATE) { + osSyncPrintf("camera: shrink_and_bitem %x(%d)\n", sCameraInterfaceFlags, camera->globalCtx->transitionMode); + } + + if (R_DBG_CAM_UPDATE) { + osSyncPrintf("camera: engine (%s(%d) %s(%d) %s(%d)) ok!\n", &sCameraSettingNames[camera->setting], + camera->setting, &sCameraModeNames[camera->mode], camera->mode, + &sCameraFunctionNames[sCameraSettings[camera->setting].cameraModes[camera->mode].funcIdx], + sCameraSettings[camera->setting].cameraModes[camera->mode].funcIdx); + } + + // enable/disable debug cam + if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_START)) { + gDbgCamEnabled ^= 1; + if (gDbgCamEnabled) { + DbgCamera_Enable(&D_8015BD80, camera); + } else if (camera->globalCtx->csCtx.state != 0) { + func_80064534(camera->globalCtx, &camera->globalCtx->csCtx); + } + } + + // Debug cam update + if (gDbgCamEnabled) { + camera->globalCtx->view.fovy = D_8015BD80.fov; + DbgCamera_Update(&D_8015BD80, camera); + func_800AA358(&camera->globalCtx->view, &D_8015BD80.eye, &D_8015BD80.at, &D_8015BD80.up); + if (R_DBG_CAM_UPDATE) { + osSyncPrintf("camera: debug out\n"); + } + *outVec = D_8015BD80.unk_10C6; + return outVec; + } + + OREG(0) &= ~8; + + if (camera->status == 3) { + *outVec = camera->inputDir; + return outVec; + } + + // setting bgCheckId to the ret of Quake_Calc, and checking that + // is required, it doesn't make too much sense though. + if ((bgCheckId = Quake_Calc(camera, &quake), bgCheckId != 0) && (camera->setting != CAM_SET_ITEM2)) { + viewAt.x = camera->at.x + quake.atOffset.x; + viewAt.y = camera->at.y + quake.atOffset.y; + viewAt.z = camera->at.z + quake.atOffset.z; + viewEye.x = camera->eye.x + quake.eyeOffset.x; + viewEye.y = camera->eye.y + quake.eyeOffset.y; + viewEye.z = camera->eye.z + quake.eyeOffset.z; + OLib_Vec3fDiffToVecSphGeo(&eyeAtAngle, &viewEye, &viewAt); + Camera_CalcUpFromPitchYawRoll(&viewUp, eyeAtAngle.pitch + quake.rotZ, eyeAtAngle.yaw + quake.unk_1A, + camera->roll); + viewFov = camera->fov + BINANG_TO_DEGF(quake.zoom); + } else { + viewAt = camera->at; + viewEye = camera->eye; + OLib_Vec3fDiffToVecSphGeo(&eyeAtAngle, &viewEye, &viewAt); + Camera_CalcUpFromPitchYawRoll(&viewUp, eyeAtAngle.pitch, eyeAtAngle.yaw, camera->roll); + viewFov = camera->fov; + } + + if (camera->paramFlags & 4) { + camera->paramFlags &= ~4; + viewUp = camera->up; + } else { + camera->up = viewUp; + } + + camera->skyboxOffset = quake.eyeOffset; + + func_80058E8C(camera); + if ((camera->globalCtx->sceneNum == SCENE_SPOT00) && (camera->fov < 59.0f)) { + View_SetScale(&camera->globalCtx->view, 0.79f); + } else { + View_SetScale(&camera->globalCtx->view, 1.0f); + } + camera->globalCtx->view.fovy = viewFov; + func_800AA358(&camera->globalCtx->view, &viewEye, &viewAt, &viewUp); + camera->camDir.x = eyeAtAngle.pitch; + camera->camDir.y = eyeAtAngle.yaw; + camera->camDir.z = 0; + + if (sUpdateCameraDirection == 0) { + camera->inputDir.x = eyeAtAngle.pitch; + camera->inputDir.y = eyeAtAngle.yaw; + camera->inputDir.z = 0; + } + + if (PREG(81)) { + osSyncPrintf("dir (%d) %d(%f) %d(%f) 0(0) \n", sUpdateCameraDirection, camera->inputDir.x, + BINANG_TO_DEGF(camera->inputDir.x), camera->inputDir.y, BINANG_TO_DEGF(camera->inputDir.y)); + osSyncPrintf("real (%d) %d(%f) %d(%f) 0(0) \n", sUpdateCameraDirection, camera->camDir.x, + BINANG_TO_DEGF(camera->camDir.x), camera->camDir.y, BINANG_TO_DEGF(camera->camDir.y)); + } + + if (camera->timer != -1 && CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_DRIGHT)) { + camera->timer = 0; + } + + if (R_DBG_CAM_UPDATE) { + osSyncPrintf("camera: out (%f %f %f) (%f %f %f)\n", camera->at.x, camera->at.y, camera->at.z, camera->eye.x, + camera->eye.y, camera->eye.z); + osSyncPrintf("camera: dir (%f %d(%f) %d(%f)) (%f)\n", eyeAtAngle.r, eyeAtAngle.pitch, + BINANG_TO_DEGF(eyeAtAngle.pitch), eyeAtAngle.yaw, BINANG_TO_DEGF(eyeAtAngle.yaw), camera->fov); + if (camera->player != NULL) { + osSyncPrintf("camera: foot(%f %f %f) dist (%f)\n", curPlayerPosRot.pos.x, curPlayerPosRot.pos.y, + curPlayerPosRot.pos.z, camera->dist); + } + } + + *outVec = camera->inputDir; + return outVec; +} + +/** + * When the camera's timer is 0, change the camera to it's parent + */ +void Camera_Finish(Camera* camera) { + Camera* defaultCam = camera->globalCtx->cameraPtrs[0]; Player* player = (Player*)camera->globalCtx->actorCtx.actorList[2].first; - if (camera->unk_160 == 0) { - Gameplay_ChangeCameraStatus(camera->globalCtx, camera->unk_162, 7); + if (camera->timer == 0) { + Gameplay_ChangeCameraStatus(camera->globalCtx, camera->parentCamIdx, 7); - if ((camera->unk_162 == 0) && (camera->unk_168 != 0)) { + if ((camera->parentCamIdx == 0) && (camera->unk_168 != 0)) { player->actor.freezeTimer = 0; player->stateFlags1 &= ~0x20000000; @@ -3373,154 +7585,143 @@ void func_80059EC8(Camera* camera) { osSyncPrintf("camera: player demo end!!\n"); } - sp24->unk_14C |= 8; + defaultCam->unk_14C |= 8; } - if (camera->globalCtx->cameraPtrs[camera->unk_14E]->unk_162 == camera->unk_164) { - camera->globalCtx->cameraPtrs[camera->unk_14E]->unk_162 = camera->unk_162; + if (camera->globalCtx->cameraPtrs[camera->childCamIdx]->parentCamIdx == camera->thisIdx) { + camera->globalCtx->cameraPtrs[camera->childCamIdx]->parentCamIdx = camera->parentCamIdx; } - if (camera->globalCtx->cameraPtrs[camera->unk_162]->unk_14E == camera->unk_164) { - camera->globalCtx->cameraPtrs[camera->unk_162]->unk_14E = camera->unk_14E; + if (camera->globalCtx->cameraPtrs[camera->parentCamIdx]->childCamIdx == camera->thisIdx) { + camera->globalCtx->cameraPtrs[camera->parentCamIdx]->childCamIdx = camera->childCamIdx; } - if (camera->globalCtx->cameraPtrs[camera->unk_162]->unk_164 == 0) { - camera->globalCtx->cameraPtrs[camera->unk_162]->unk_15E = 0; + if (camera->globalCtx->cameraPtrs[camera->parentCamIdx]->thisIdx == 0) { + camera->globalCtx->cameraPtrs[camera->parentCamIdx]->animState = 0; } - camera->unk_162 = 0; - camera->unk_14E = camera->unk_162; - camera->unk_160 = -1; + camera->parentCamIdx = 0; + camera->childCamIdx = camera->parentCamIdx; + camera->timer = -1; camera->globalCtx->envCtx.unk_E1 = 0; - Gameplay_ClearCamera(camera->globalCtx, camera->unk_164); + Gameplay_ClearCamera(camera->globalCtx, camera->thisIdx); } } s32 func_8005A02C(Camera* camera) { camera->unk_14C |= 0xC; camera->unk_14C &= ~(0x1000 | 0x8); - return 1; + return true; } -#ifdef NON_MATCHING -extern s32 D_8011DB14; -s32 Camera_ChangeMode(Camera* camera, s16 mode, u8 arg2) { - s32 phi_v0; - u32 temp_t8; - s32 phi_at; +s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags) { + static s32 modeChangeFlags = 0; if (QREG(89)) { osSyncPrintf("+=+(%d)+=+ recive request -> %s\n", camera->globalCtx->state.frames, sCameraModeNames[mode]); } - if ((camera->unk_14C & 0x20) && (arg2 == 0)) { + if (camera->unk_14C & 0x20 && flags == 0) { camera->unk_14A |= 0x20; return -1; - } else if (!(sCameraSettings[camera->setting].validModes & (1 << mode))) { - if (mode == CAM_MODE_SUBJECT) { + } + + if (!((sCameraSettings[camera->setting].unk_00 & 0x3FFFFFFF) & (1 << mode))) { + if (mode == CAM_MODE_FIRSTPERSON) { osSyncPrintf("camera: error sound\n"); func_80078884(NA_SE_SY_ERROR); } + if (camera->mode != CAM_MODE_NORMAL) { osSyncPrintf(VT_COL(YELLOW, BLACK) "camera: change camera mode: force NORMAL: %s %s refused\n" VT_RST, sCameraSettingNames[camera->setting], sCameraModeNames[mode]); camera->mode = CAM_MODE_NORMAL; Camera_CopyModeValuesToPREG(camera, camera->mode); func_8005A02C(camera); - phi_at = 0xC0000000; + return 0xC0000000 | mode; } else { - camera->unk_14A = (s16)(camera->unk_14A | 0x20); - camera->unk_14A = (s16)(camera->unk_14A | 2); + camera->unk_14A |= 0x20; + camera->unk_14A |= 2; return 0; } - } else if ((mode == camera->mode) && (arg2 == 0)) { - camera->unk_14A |= 0x20; - camera->unk_14A |= 2; - return -1; } else { + if (mode == camera->mode && flags == 0) { + camera->unk_14A |= 0x20; + camera->unk_14A |= 2; + return -1; + } camera->unk_14A |= 0x20; camera->unk_14A |= 2; - camera = camera; Camera_CopyModeValuesToPREG(camera, mode); - temp_t8 = mode - 1; - phi_v0 = 0; + modeChangeFlags = 0; switch (mode) { - default: - break; - case 5: // switch 1 - phi_v0 = 0x20; + case CAM_MODE_FIRSTPERSON: + modeChangeFlags = 0x20; break; - case 3: // switch 1 - phi_v0 = 4; + case CAM_MODE_BATTLE: + modeChangeFlags = 4; break; - case 1: // switch 1 - phi_v0 = 0; - if (camera->target != NULL) { - phi_v0 = 0; - if (camera->target->id != ACTOR_EN_BOOM) { - phi_v0 = 8; - } + case CAM_MODE_FOLLOWTARGET: + if (camera->target != NULL && camera->target->id != ACTOR_EN_BOOM) { + modeChangeFlags = 8; } break; - case 0: // switch 1 - case 2: // switch 1 - case 7: // switch 1 - case 14: // switch 1 - case 18: // switch 1 - phi_v0 = 2; + case CAM_MODE_TARGET: + case CAM_MODE_TALK: + case CAM_MODE_BOWARROWZ: + case CAM_MODE_HANGZ: + case CAM_MODE_PUSHPULL: + modeChangeFlags = 2; break; } switch (camera->mode) { - default: - break; - case 6: // switch 2 - if ((phi_v0 & 0x20) != 0) { - camera->unk_15E = (u16)0xAU; + case CAM_MODE_FIRSTPERSON: + if (modeChangeFlags & 0x20) { + camera->animState = 0xA; } break; - case 1: // switch 2 - if ((phi_v0 & 0x10) != 0) { - camera->unk_15E = (u16)0xAU; + case CAM_MODE_TARGET: + if (modeChangeFlags & 0x10) { + camera->animState = 0xA; } - phi_v0 |= 1; + modeChangeFlags |= 1; break; - case 17: // switch 2 - phi_v0 |= 1; + case CAM_MODE_CHARGE: + modeChangeFlags |= 1; break; - case 2: // switch 2 - if ((phi_v0 & 8) != 0) { - camera->unk_15E = (u16)0xAU; + case CAM_MODE_FOLLOWTARGET: + if (modeChangeFlags & 8) { + camera->animState = 0xA; } - phi_v0 |= 1; + modeChangeFlags |= 1; break; - case 4: // switch 2 - if ((phi_v0 & 4) != 0) { - camera->unk_15E = (u16)0xAU; + case CAM_MODE_BATTLE: + if (modeChangeFlags & 4) { + camera->animState = 0xA; } - phi_v0 |= 1; + modeChangeFlags |= 1; break; - case 8: // switch 2 - case 15: // switch 2 - case 19: // switch 2 - phi_v0 |= 1; + case CAM_MODE_BOWARROWZ: + case CAM_MODE_HANGZ: + case CAM_MODE_PUSHPULL: + modeChangeFlags |= 1; break; - case 0: // switch 2 - if ((phi_v0 & 0x10) != 0) { - camera->unk_15E = (u16)0xAU; + case CAM_MODE_NORMAL: + if (modeChangeFlags & 0x10) { + camera->animState = 0xA; } break; } - phi_v0 &= ~0x10; - D_8011DB14 = phi_v0; - if (camera->status == 7) { - switch (phi_v0) { + modeChangeFlags &= ~0x10; + if (camera->status == CAM_STAT_ACTIVE) { + switch (modeChangeFlags) { case 1: - func_80078884(NA_SE_PL_WALK_GROUND - SFX_FLAG); + func_80078884(0); break; case 2: - if (1 == camera->globalCtx->roomCtx.curRoom.unk_03) { + if (camera->globalCtx->roomCtx.curRoom.unk_03 == 1) { func_80078884(NA_SE_SY_ATTENTION_URGENCY); } else { func_80078884(NA_SE_SY_ATTENTION_ON); @@ -3536,47 +7737,38 @@ s32 Camera_ChangeMode(Camera* camera, s16 mode, u8 arg2) { } func_8005A02C(camera); camera->mode = mode; - phi_at = 0x80000000; + return 0x80000000 | mode; } - return mode | phi_at; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_ChangeMode.s") -#endif -s32 func_8005A444(Camera* camera, s16 arg1) { - return Camera_ChangeMode(camera, arg1, 0); +s32 Camera_ChangeMode(Camera* camera, s16 mode) { + return Camera_ChangeModeFlags(camera, mode, 0); } -s32 func_8005A470(Camera* camera, s16 arg1) { - s32 phi_return; - +s32 Camera_CheckValidMode(Camera* camera, s16 mode) { if (QREG(89) != 0) { - osSyncPrintf("+=+=+=+ recive asking -> %s (%s)\n", sCameraModeNames[arg1], + osSyncPrintf("+=+=+=+ recive asking -> %s (%s)\n", sCameraModeNames[mode], sCameraSettingNames[camera->setting]); } - if (!(sCameraSettings[camera->setting].validModes & (1 << arg1))) { + if (!(sCameraSettings[camera->setting].validModes & (1 << mode))) { return 0; - } else if (arg1 == camera->mode) { + } else if (mode == camera->mode) { return -1; } else { - return arg1 | 0x80000000; + return mode | 0x80000000; } } -#ifdef NON_MATCHING -s16 Camera_ChangeSetting(Camera* camera, s16 setting, s16 arg2) { - s16 temp_t1; - s32 t; - - if ((camera->unk_14A & 1) && (((sCameraSettings[camera->setting].unk_00 & 0xF000000) >> 0x18) >= - (sCameraSettings[setting].unk_00 & 0xF000000) >> 0x18)) { - camera->unk_14A |= 0x10; - return -2; +s16 Camera_ChangeSettingFlags(Camera* camera, s16 setting, s16 flags) { + if ((camera->unk_14A & 1) != 0) { + if ((u32)((u32)(sCameraSettings[camera->setting].unk_00 & 0xF000000) >> 0x18) >= + (u32)((u32)(sCameraSettings[setting].unk_00 & 0xF000000) >> 0x18)) { + camera->unk_14A |= 0x10; + return -2; + } } - - if ((setting == CAM_SET_SPOT05A || setting == CAM_SET_SPOT05B) && LINK_IS_ADULT && - (camera->globalCtx->sceneNum == 0x56)) { + if (((setting == CAM_SET_SPOT05A) || (setting == CAM_SET_SPOT05B)) && (gSaveContext.linkAge == 0) && + (camera->globalCtx->sceneNum == SCENE_SPOT05)) { camera->unk_14A |= 0x10; return -5; } @@ -3586,135 +7778,128 @@ s16 Camera_ChangeSetting(Camera* camera, s16 setting, s16 arg2) { return -0x63; } - if (setting == camera->setting && !(arg2 & 1)) { + if ((setting == camera->setting) && (!(flags & 1))) { camera->unk_14A |= 0x10; - if (!(arg2 & 2)) { + if (!(flags & 2)) { camera->unk_14A |= 1; } return -1; } camera->unk_14A |= 0x10; - - if (1 && !(arg2 & 2)) { + if ((flags & 2) == 0) { camera->unk_14A |= 1; } - camera->unk_14C |= (0x8 | 0x4); - camera->unk_14C &= ~(0x1000 | 0x8); - if (!(sCameraSettings[camera->setting].unk_bit1)) { - camera->unk_154 = camera->setting; + camera->unk_14C |= 0xC; + camera->unk_14C &= ~0x1008; + + if (!(sCameraSettings[camera->setting].unk_00 & 0x40000000)) { + camera->prevSetting = camera->setting; } - t = sCameraSettings[camera->setting].unk_00 & 0x40000000; - if (arg2 & 8) { - camera->unk_148 = camera->unk_166; - camera->unk_166 = -1; - } else if (!(arg2 & 4)) { - if (!t) { - camera->unk_166 = camera->unk_148; + if (flags & 8) { + if (1) {} + camera->camDataIdx = camera->prevCamDataIdx; + camera->prevCamDataIdx = -1; + } else if (!(flags & 4)) { + if (!(sCameraSettings[camera->setting].unk_00 & 0x40000000)) { + camera->prevCamDataIdx = camera->camDataIdx; } - camera->unk_148 = -1; + camera->camDataIdx = -1; } camera->setting = setting; - if (Camera_ChangeMode(camera, camera->mode, 1) >= 0) { + if (Camera_ChangeModeFlags(camera, camera->mode, 1) >= 0) { Camera_CopyModeValuesToPREG(camera, camera->mode); } osSyncPrintf(VT_SGR("1") "%06u:" VT_RST " camera: change camera[%d] set %s\n", camera->globalCtx->state.frames, - camera->unk_164, sCameraSettingNames[camera->setting]); + camera->thisIdx, sCameraSettingNames[camera->setting]); return setting; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_ChangeSetting.s") -#endif -s32 func_8005A77C(Camera* camera, s16 setting) { - return Camera_ChangeSetting(camera, setting, 0); +s32 Camera_ChangeSetting(Camera* camera, s16 setting) { + return Camera_ChangeSettingFlags(camera, setting, 0); } -#ifdef NON_MATCHING -s16 func_8005A7A8(Camera* arg0, s32 arg1) { - s16 temp_v0; - s16 temp_v1; +s32 Camera_ChangeDataIdx(Camera* camera, s32 camDataIdx) { + s16 newCameraSetting; + s16 settingChangeSuccessful; - if (arg1 == -1 || arg1 == arg0->unk_148) { - arg0->unk_14A |= 0x40; + if (camDataIdx == -1 || camDataIdx == camera->camDataIdx) { + camera->unk_14A |= 0x40; return -1; - } else if (!(arg0->unk_14A & 0x40)) { - temp_v0 = func_80044740(arg0, arg1); - arg0->unk_14A |= 0x40; - temp_v1 = (Camera_ChangeSetting(arg0, temp_v0, 5) < 0) ^ 1; - if ((temp_v1 != 0) || sCameraSettings[arg0->setting].unk_00 & 0x80000000) { - arg0->unk_148 = arg1; - arg0->unk_14A |= 4; - Camera_CopyModeValuesToPREG(arg0, arg0->mode); - } else if (temp_v1 < -1) { - osSyncPrintf(VT_COL(RED, WHITE) "camera: error: illegal camera ID (%d) !! (%d|%d|%d)\n" VT_RST, arg1, - arg0->unk_164, 0x32, temp_v0); + } + + if (!(camera->unk_14A & 0x40)) { + newCameraSetting = Camera_GetCamDataSetting(camera, camDataIdx); + camera->unk_14A |= 0x40; + settingChangeSuccessful = Camera_ChangeSettingFlags(camera, newCameraSetting, 5) >= 0; + if (settingChangeSuccessful || sCameraSettings[camera->setting].unk_00 & 0x80000000) { + camera->camDataIdx = camDataIdx; + camera->unk_14A |= 4; + Camera_CopyModeValuesToPREG(camera, camera->mode); + } else if (settingChangeSuccessful < -1) { + // @bug: This condition can never happen since settingChangeSuccesful is only ever 0 or 1. + osSyncPrintf(VT_COL(RED, WHITE) "camera: error: illegal camera ID (%d) !! (%d|%d|%d)\n" VT_RST, camDataIdx, + camera->thisIdx, 0x32, newCameraSetting); } - return temp_v1; + return 0x80000000 | camDataIdx; } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_8005A7A8.s") -#endif -#ifdef NON_MATCHING -// this code uses lw, then lhu. D_8015CD46 is probably part of a struct. -Vec3s* func_8005A8C4(Vec3s* arg0, Camera* camera) { - if (D_8011D394 != 0) { - *arg0 = D_8015CE46; - return arg0; +Vec3s* Camera_GetInputDir(Vec3s* dst, Camera* camera) { + if (gDbgCamEnabled != 0) { + *dst = D_8015BD80.unk_10C6; + return dst; } else { - *arg0 = camera->unk_134; - return arg0; + *dst = camera->inputDir; + return dst; } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_8005A8C4.s") -#endif -s16 func_8005A948(Camera* camera) { - Vec3s sp18; +s16 Camera_GetInputDirPitch(Camera* camera) { + Vec3s dir; - func_8005A8C4(&sp18, camera); - return sp18.y; + Camera_GetInputDir(&dir, camera); + return dir.x; } -#ifdef NON_MATCHING -// Same issue as func_8005A8C4 -Vec3s* func_8005A970(Vec3s* arg0, Camera* arg1) { - if (D_8011D394 != 0) { - *arg0 = D_8015CE46; - return arg0; +s16 Camera_GetInputDirYaw(Camera* camera) { + Vec3s dir; + + Camera_GetInputDir(&dir, camera); + return dir.y; +} + +Vec3s* Camera_GetCamDir(Vec3s* dst, Camera* camera) { + if (gDbgCamEnabled != 0) { + *dst = D_8015BD80.unk_10C6; + return dst; } else { - *arg0 = arg1->unk_13A; - return arg0; + *dst = camera->camDir; + return dst; } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_8005A970.s") -#endif -s16 func_8005A9CC(s32 arg0) { - Vec3s sp18; +s16 Camera_GetCamDirPitch(Camera* camera) { + Vec3s camDir; - func_8005A970(&sp18, arg0); - return sp18.x; + Camera_GetCamDir(&camDir, camera); + return camDir.x; } -s16 func_8005A9F4(Camera* camera) { - Vec3s sp18; +s16 Camera_GetCamDirYaw(Camera* camera) { + Vec3s camDir; - func_8005A970(&sp18, camera); - return sp18.y; + Camera_GetCamDir(&camDir, camera); + return camDir.y; } -s32 func_8005AA1C(Camera* camera, s32 arg1, s16 y, s32 countdown) { +s32 Camera_AddQuake(Camera* camera, s32 arg1, s16 y, s32 countdown) { s16 quakeIdx; quakeIdx = Quake_Add(camera, 3); @@ -3727,20 +7912,17 @@ s32 func_8005AA1C(Camera* camera, s32 arg1, s16 y, s32 countdown) { return 1; } -#ifdef NON_MATCHING -// additional move v0, zero added. s32 Camera_SetParam(Camera* camera, s32 param, void* value) { - s32 pad; - Vec3f sp4; + s32 pad[3]; if (value != NULL) { switch (param) { case 1: - camera->unk_15C &= ~(0x10 | 0x8 | 0x1); + camera->paramFlags &= ~(0x10 | 0x8 | 0x1); camera->at = *(Vec3f*)value; break; case 16: - camera->unk_15C &= ~(0x10 | 0x8 | 0x1); + camera->paramFlags &= ~(0x10 | 0x8 | 0x1); camera->targetPosRot.pos = *(Vec3f*)value; break; case 8: @@ -3748,93 +7930,61 @@ s32 Camera_SetParam(Camera* camera, s32 param, void* value) { break; } camera->target = (Actor*)value; - camera->unk_15C &= ~(0x10 | 0x8 | 0x1); + camera->paramFlags &= ~(0x10 | 0x8 | 0x1); break; case 2: - sp4 = *(Vec3f*)value; - camera->eyeNext = sp4; - camera->eye = sp4; + camera->eye = camera->eyeNext = *(Vec3f*)value; break; case 4: - camera->unk_68 = *(Vec3f*)value; + camera->up = *(Vec3f*)value; break; case 0x40: - camera->roll = *(f32*)value * (M_PI / 180.0f) + 0.5f; + camera->roll = DEGF_TO_BINANG(*(f32*)value); break; - case 32: + case 0x20: camera->fov = *(f32*)value; break; - case 3: - case 5: - case 6: - case 7: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - case 27: - case 28: - case 29: - case 30: - case 31: - return false; default: return false; } - camera->unk_15C |= param; - return true; + camera->paramFlags |= param; } else { return false; } + return true; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_SetParam.s") -#endif -s32 func_8005AC24(Camera* camera, s16 arg1) { - camera->unk_15C &= ~arg1; +s32 Camera_UnsetParam(Camera* camera, s16 param) { + camera->paramFlags &= ~param; return true; } s32 func_8005AC48(Camera* camera, s16 arg1) { camera->unk_14C = arg1; - return 1; + return true; } -s32 func_8005AC60(Camera* camera) { - camera->unk_15E = 0; +s32 Camera_ResetAnim(Camera* camera) { + camera->animState = 0; return 1; } -s32 func_8005AC6C(Camera* camera, CutsceneCameraPoint* atPoints, CutsceneCameraPoint* eyePoints, Player* player, - s16 relativeToPlayer) { - PosRot sp24; +s32 Camera_SetCSParams(Camera* camera, CutsceneCameraPoint* atPoints, CutsceneCameraPoint* eyePoints, Player* player, + s16 relativeToPlayer) { + PosRot playerPosRot; - camera->atPoints = atPoints; - camera->eyePoints = eyePoints; - camera->relativeToPlayer = relativeToPlayer; + camera->data0 = atPoints; + camera->data1 = eyePoints; + camera->data2 = relativeToPlayer; - if (camera->relativeToPlayer != 0) { + if (camera->data2 != 0) { camera->player = player; - func_8002EF44(&sp24, &player->actor); - camera->playerPosRot = sp24; + func_8002EF44(&playerPosRot, &player->actor); + camera->playerPosRot = playerPosRot; - camera->unk_156 = -1; - camera->unk_D8 = 0.0f; - camera->unk_E0 = 0.0f; + camera->nextCamDataIdx = -1; + camera->xzSpeed = 0.0f; + camera->speedRatio = 0.0f; } return 1; @@ -3850,106 +8000,106 @@ s16 func_8005AD1C(Camera* camera, s16 arg1) { return camera->unk_14C; } -s32 func_8005AD40(Camera* camera, Actor* doorActor, s16 arg2, f32 arg3, s16 arg4, s16 arg5, s16 arg6) { +s32 Camera_ChangeDoorCam(Camera* camera, Actor* doorActor, s16 camDataIdx, f32 arg3, s16 timer1, s16 timer2, + s16 timer3) { + DoorParams* doorParams = (DoorParams*)camera->paramData; + if ((camera->setting == CAM_SET_DEMO4) || (camera->setting == CAM_SET_DOORC)) { return 0; } - camera->unk_00.doorCam.door = doorActor; - camera->unk_00.doorCam.unk_06 = arg4; - camera->unk_00.doorCam.unk_08 = arg5; - camera->unk_00.doorCam.unk_0A = arg6; - camera->unk_00.doorCam.unk_04 = arg2; + doorParams->doorActor = doorActor; + doorParams->timer1 = timer1; + doorParams->timer2 = timer2; + doorParams->timer3 = timer3; + doorParams->camDataIdx = camDataIdx; - if (arg2 == -99) { + if (camDataIdx == -99) { Camera_CopyModeValuesToPREG(camera, camera->mode); return -99; } - if (arg2 == -1) { - func_8005A77C(camera, CAM_SET_DOORC); + if (camDataIdx == -1) { + Camera_ChangeSetting(camera, CAM_SET_DOORC); osSyncPrintf(".... change default door camera (set %d)\n", CAM_SET_DOORC); } else { - s32 ret = func_80044740(camera, arg2); + s32 setting = Camera_GetCamDataSetting(camera, camDataIdx); camera->unk_14A |= 0x40; - if (func_8005A77C(camera, ret) >= 0) { - camera->unk_148 = arg2; + if (Camera_ChangeSetting(camera, setting) >= 0) { + camera->camDataIdx = camDataIdx; camera->unk_14A |= 4; } - osSyncPrintf("....change door camera ID %d (set %d)\n", camera->unk_148, camera->setting); + osSyncPrintf("....change door camera ID %d (set %d)\n", camera->camDataIdx, camera->setting); } Camera_CopyModeValuesToPREG(camera, camera->mode); return -1; } -s32 func_8005AE64(Camera* camera, Camera* otherCamera) { - s32 unused; - Vec3f sp30; - - camera->unk_E4.x = 0.0f; - camera->unk_E4.y = 0.0f; - camera->unk_E4.z = 0.0f; - camera->unk_100 = 0.1f; - camera->at = otherCamera->at; - - sp30 = otherCamera->eye; - camera->eyeNext = sp30; - camera->eye = sp30; - - camera->dist = OLib_Vec3fDist(&camera->at, &camera->eye); - camera->fov = otherCamera->fov; - camera->roll = otherCamera->roll; - func_80043B60(camera); +s32 Camera_Copy(Camera* dstCamera, Camera* srcCamera) { + s32 pad; - if (camera->player != NULL) { - func_8002EF14(&camera->playerPosRot, &camera->player->actor); - camera->unk_E4.x = camera->at.x - camera->playerPosRot.pos.x; - camera->unk_E4.y = camera->at.y - camera->playerPosRot.pos.y; - camera->unk_E4.z = camera->at.z - camera->playerPosRot.pos.z; - camera->dist = OLib_Vec3fDist(&camera->playerPosRot.pos, &camera->eye); - camera->unk_CC.x = 1.0f; - camera->unk_CC.y = 1.0f; + dstCamera->posOffset.x = 0.0f; + dstCamera->posOffset.y = 0.0f; + dstCamera->posOffset.z = 0.0f; + dstCamera->atLERPStepScale = 0.1f; + dstCamera->at = srcCamera->at; + + dstCamera->eye = dstCamera->eyeNext = srcCamera->eye; + + dstCamera->dist = OLib_Vec3fDist(&dstCamera->at, &dstCamera->eye); + dstCamera->fov = srcCamera->fov; + dstCamera->roll = srcCamera->roll; + func_80043B60(dstCamera); + + if (dstCamera->player != NULL) { + func_8002EF14(&dstCamera->playerPosRot, &dstCamera->player->actor); + dstCamera->posOffset.x = dstCamera->at.x - dstCamera->playerPosRot.pos.x; + dstCamera->posOffset.y = dstCamera->at.y - dstCamera->playerPosRot.pos.y; + dstCamera->posOffset.z = dstCamera->at.z - dstCamera->playerPosRot.pos.z; + dstCamera->dist = OLib_Vec3fDist(&dstCamera->playerPosRot.pos, &dstCamera->eye); + dstCamera->xzOffsetUpdateRate = 1.0f; + dstCamera->yOffsetUpdateRate = 1.0f; } - return 1; + return true; } -s32 func_8005AFA8() { - return D_8011D394; +s32 Camera_GetDbgCamEnabled() { + return gDbgCamEnabled; } -Vec3f* func_8005AFB4(Vec3f* dst, Camera* camera) { - *dst = camera->unk_80; +Vec3f* Camera_GetSkyboxOffset(Vec3f* dst, Camera* camera) { + *dst = camera->skyboxOffset; return dst; } -void Camera_SetCameraData(Camera* camera, s16 arg1, CutsceneCameraPoint* atPoints, CutsceneCameraPoint* eyePoints, - s16 relativeToPlayer, s16 arg5, s32 arg6) { - if (arg1 & 0x1) { - camera->atPoints = atPoints; +void Camera_SetCameraData(Camera* camera, s16 setDataFlags, void* data0, void* data1, s16 data2, s16 data3, + UNK_TYPE arg6) { + if (setDataFlags & 0x1) { + camera->data0 = data0; } - if (arg1 & 0x2) { - camera->eyePoints = eyePoints; + if (setDataFlags & 0x2) { + camera->data1 = data1; } - if (arg1 & 0x4) { - camera->relativeToPlayer = relativeToPlayer; + if (setDataFlags & 0x4) { + camera->data2 = data2; } - if (arg1 & 0x8) { - camera->unk_12E = arg5; + if (setDataFlags & 0x8) { + camera->data3 = data3; } - if (arg1 & 0x10) { + if (setDataFlags & 0x10) { osSyncPrintf(VT_COL(RED, WHITE) "camera: setCameraData: last argument not alive!\n" VT_RST); } } -s32 func_8005B044() { - if (QREG(0) == 0) { +s32 Camera_QRegInit() { + if (!R_RELOAD_CAM_PARAMS) { QREG(2) = 1; QREG(10) = -1; QREG(11) = 100; @@ -3980,7 +8130,7 @@ s32 func_8005B044() { } QREG(65) = 50; - return 1; + return true; } s32 func_8005B198() { @@ -3990,10 +8140,10 @@ s32 func_8005B198() { s16 func_8005B1A4(Camera* camera) { camera->unk_14C |= 0x8; - if ((camera->unk_164 == 0) && (camera->globalCtx->activeCamera != 0)) { + if ((camera->thisIdx == 0) && (camera->globalCtx->activeCamera != 0)) { camera->globalCtx->cameraPtrs[camera->globalCtx->activeCamera]->unk_14C |= 0x8; return camera->globalCtx->activeCamera; } - return camera->unk_164; + return camera->thisIdx; } diff --git a/src/code/z_camera_data.c b/src/code/z_camera_data.c new file mode 100644 index 000000000..4ec44ff3d --- /dev/null +++ b/src/code/z_camera_data.c @@ -0,0 +1,3573 @@ +#include <ultra64.h> +#include <global.h> + +typedef struct { + s16 val; + s16 param; +} CameraModeValue; + +typedef struct { + s16 funcIdx; + s16 valueCnt; + CameraModeValue* values; +} CameraMode; + +typedef struct { + union { + u32 unk_00; + struct { + u32 unk_bit0 : 1; + u32 unk_bit1 : 1; + u32 validModes : 30; + }; + }; + CameraMode* cameraModes; +} CameraSetting; + +/*==================================================================*/ +// Data +s16 sOREGInit[] = { + 0, 1, 5, 5, 5, 14500, 20, 16, 150, 25, 150, 6, 10, 10, 0, 0, 1, 100, + 250, 120, 80, 30, 120, 4, 1, 50, 20, 1800, 50, 50, 50, 20, 20, -10, -5460, -9100, + -6, 8, 15, 75, 60, 12, 110, 40, 50, 250, -10, 30, 30, 70, 20, 20, 20, +}; + +s16 sOREGInitCnt = 53; + +s16 sPREGInit[] = { + -20, 200, 300, 10, 12, 10, 35, 60, 60, 3, 0, -40, 20, 25, 45, -5, 15, 15, 20, 0, 0, 0, 6, 60, 30, 0, 5, +}; + +s16 sPREGInitCnt = 27; + +char sCameraSettingNames[][12] = { + "NONE ", "NORMAL0 ", "NORMAL1 ", "DUNGEON0 ", "DUNGEON1 ", "NORMAL3 ", "HORSE0 ", + "BOSS_GOMA ", "BOSS_DODO ", "BOSS_BARI ", "BOSS_FGANON", "BOSS_BAL ", "BOSS_SHADES", "BOSS_MOFA ", + "BOSS_TWIN0 ", "BOSS_TWIN1 ", "BOSS_GANON1", "BOSS_GANON2", "TOWER0 ", "TOWER1 ", "FIXED0 ", + "FIXED1 ", "CIRCLE0 ", "CIRCLE2 ", "CIRCLE3 ", "PREREND0 ", "PREREND1 ", "PREREND3 ", + "DOOR0 ", "DOORC ", "RAIL3 ", "START0 ", "START1 ", "FREE0 ", "FREE2 ", + "CIRCLE4 ", "CIRCLE5 ", "DEMO0 ", "DEMO1 ", "MORI1 ", "ITEM0 ", "ITEM1 ", + "DEMO3 ", "DEMO4 ", "UFOBEAN ", "LIFTBEAN ", "SCENE0 ", "SCENE1 ", "HIDAN1 ", + "HIDAN2 ", "MORI2 ", "MORI3 ", "TAKO ", "SPOT05A ", "SPOT05B ", "HIDAN3 ", + "ITEM2 ", "CIRCLE6 ", "NORMAL2 ", "FISHING ", "DEMOC ", "UO_FIBER ", "DUNGEON2 ", + "TEPPEN ", "CIRCLE7 ", "NORMAL4 ", +}; + +char sCameraModeNames[][12] = { + "NORMAL ", "PARALLEL ", "KEEPON ", "TALK ", "BATTLE ", "CLIMB ", "SUBJECT ", + "BOWARROW ", "BOWARROWZ ", "FOOKSHOT ", "BOOMERANG ", "PACHINCO ", "CLIMBZ ", "JUMP ", + "HANG ", "HANGZ ", "FREEFALL ", "CHARGE ", "STILL ", "PUSHPULL ", "BOOKEEPON ", +}; + +CameraModeValue D_8011A3A0[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { 10, 3 }, // pitchtarget + { 12, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 35, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 60, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011A3C8[] = { + /* CAM_FUNC_PARA1 */ + { -20, 0 }, // unk_00 + { 250, 1 }, // distTarget + { 0, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 45, 7 }, // fovTarget + { 50, 8 }, // unk_14 + { 0x200A, 9 }, // flags + { -40, 11 }, // unk_18 + { 20, 12 } // unk_1C +}; + +CameraModeValue D_8011A3F4[] = { + /* CAM_FUNC_KEEP1 */ + { -20, 0 }, // unk_00 + { 120, 1 }, // unk_04 + { 140, 2 }, // unk_08 + { 25, 13 }, // unk_0C + { 45, 14 }, // unk_10 + { -5, 15 }, // unk_14 + { 15, 16 }, // unk_18 + { 15, 17 }, // unk_1C + { 45, 7 }, // unk_20 + { 50, 8 }, // unk_24 + { 0x2001, 9 }, // flags + { -50, 11 }, // unk_28 + { 30, 12 }, // unk_2C +}; + +CameraModeValue D_8011A428[] = { + /* CAM_FUNC_KEEP3 */ + { -30, 0 }, // yOffset + { 70, 1 }, // minDist + { 200, 2 }, // maxDist + { 40, 13 }, // swingYawInitial + { 10, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 5, 16 }, // swingPitchFinal + { 70, 17 }, // swingPitchAdj + { 45, 7 }, // fovTarget + { 50, 8 }, // atLERPScaleMax + { 10, 4 }, // initTimer + { 0x3500, 9 }, // flags +}; + +CameraModeValue D_8011A458[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 180, 1 }, // distance + { 10, 13 }, // swingYawInitial + { 80, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 10, 16 }, // swingPitchFinal + { 25, 17 }, // swingPitchAdj (PCT) + { 50, 7 }, // fov + { 80, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 25, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011A488[] = { + /* CAM_FUNC_JUMP2 */ + { -20, 0 }, // atYOffset + { 200, 1 }, // minDist + { 300, 2 }, // maxDist + { 20, 18 }, // minMaxDistFactor + { 5, 4 }, // yawUpdRateTarget + { 5, 5 }, // xzUpdRateTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPStepScale + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A4AC[] = { + /* CAM_FUNC_SUBJ3 */ + { 0, 0 }, // eyeNextYOffset + { 5, 1 }, // eyeDist + { 50, 2 }, // eyeNextDist + { 10, 4 }, // unk_0C + { 0, 19 }, // atOffset.x + { 0, 20 }, // atOffset.y + { 0, 21 }, // atOffset.z + { 45, 7 }, // fovTarget + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A4D0[] = { + /* CAM_FUNC_SUBJ3 */ + { -7, 0 }, // eyeNextYOffset + { 14, 1 }, // eyeDist + { 50, 2 }, // eyeNextDist + { 10, 4 }, // unk_0C + { 0, 19 }, // atOffset.x + { -30, 20 }, // atOffset.y + { -5, 21 }, // atOffset.z + { 45, 7 }, // fovTarget + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011A4F4[] = { + /* CAM_FUNC_SUBJ3 */ + { 20, 0 }, // eyeNextYOffset + { 70, 1 }, // eyeDist + { 70, 2 }, // eyeNextDist + { 10, 4 }, // unk_0C + { -120, 19 }, // atOffset.x + { 20, 20 }, // atOffset.y + { 0, 21 }, // atOffset.z + { 45, 7 }, // fovTarget + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011A518[] = { + /* CAM_FUNC_SPEC5 */ + { -20, 0 }, // yOffset + { 80, 1 }, // eyeDist + { 250, 2 }, // minDistForRot + { 45, 3 }, // timerInit + { 60, 7 }, // pitch + { 40, 8 }, // fovTarget + { 6, 22 }, // atMaxLERPScale + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011A538[] = { + /* CAM_FUNC_SUBJ3 */ + { 5, 0 }, // eyeNextYOffset + { 50, 1 }, // eyeDist + { 50, 2 }, // eyeNextDist + { 10, 4 }, // unk_0C + { 0, 19 }, // atOffset.x + { 0, 20 }, // atOffset.y + { 0, 21 }, // atOffset.z + { 45, 7 }, // fovTarget + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011A55C[] = { + /* CAM_FUNC_SUBJ3 */ + { -7, 0 }, // eyeNextYOffset + { 14, 1 }, // eyeDist + { 50, 2 }, // eyeNextDist + { 10, 4 }, // unk_0C + { -9, 19 }, // atOffset.x + { -63, 20 }, // atOffset.y + { -30, 21 }, // atOffset.z + { 45, 7 }, // fovTarget + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011A580[] = { + /* CAM_FUNC_JUMP2 */ + { -20, 0 }, // atYOffset + { 200, 1 }, // minDist + { 300, 2 }, // maxDist + { 20, 18 }, // minMaxDistFactor + { 999, 4 }, // yawUpdRateTarget + { 5, 5 }, // xzUpdRateTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPStepScale + { 0x2006, 9 }, // flags +}; + +CameraModeValue D_8011A5A4[] = { + /* CAM_FUNC_JUMP1 */ + { -20, 0 }, // atYOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { 12, 4 }, // yawUpdateRateTarget + { 35, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 40, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A5C4[] = { + /* CAM_FUNC_UNIQ1 */ + { -80, 0 }, // yOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { 40, 3 }, // pitchTarget + { 60, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A5E0[] = { + /* CAM_FUNC_UNIQ1 */ + { -120, 0 }, // yOffset + { 300, 1 }, // distMin + { 300, 2 }, // distMax + { 70, 3 }, // pitchTarget + { 45, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011A5FC[] = { + /* CAM_FUNC_JUMP1 */ + { -20, 0 }, // atYOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { 15, 4 }, // yawUpdateRateTarget + { 80, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 20, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A61C[] = { + /* CAM_FUNC_BATT4 */ + { -20, 0 }, // yOffset + { 300, 1 }, // rTarget + { 50, 3 }, // pitchTarget + { 2, 4 }, // lerpUpdateRate + { 80, 7 }, // fovTarget + { 20, 8 }, // atLERPTarget + { 0xF000, 9 }, // flags +}; + +CameraModeValue D_8011A638[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { 10, 3 }, // pitchTarget + { 100, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 100, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 5, 8 }, // atLERPScaleMax + { 0xF003, 9 }, // flags +}; + +CameraModeValue D_8011A660[] = { + /* CAM_FUNC_PARA1 */ + { 0, 0 }, // unk_00 + { 250, 1 }, // distTarget + { 25, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 70, 7 }, // fovTarget + { 30, 8 }, // unk_14 + { 0x206A, 9 }, // flags + { -20, 11 }, // unk_18 + { 30, 12 }, // unk_1C +}; + +CameraModeValue D_8011A68C[] = { + /* CAM_FUNC_KEEP1 */ + { -5, 0 }, // unk_00 + { 120, 1 }, // unk_04 + { 140, 2 }, // unk_08 + { 5, 13 }, // unk_0C + { 85, 14 }, // unk_10 + { 10, 15 }, // unk_14 + { 5, 16 }, // unk_18 + { 25, 17 }, // unk_1C + { 45, 7 }, // unk_20 + { 50, 8 }, // unk_24 + { 0x2001, 9 }, // flags + { -15, 11 }, // unk_28 + { 30, 12 }, // unk_2C +}; + +CameraModeValue sSetNorm1ModeNormVals[] = { + /* CAM_FUNC_NORM1 */ + { 0, 0 }, // yOffset + { 200, 1 }, // distMin + { 400, 2 }, // distMax + { 10, 3 }, // pitchTarget + { 12, 4 }, // unk_0C + { 20, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 60, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue sSetNorm1ModeParaVals[] = { + /* CAM_FUNC_PARA1 */ + { 0, 0 }, // unk_00 + { 250, 1 }, // distTarget + { 0, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 45, 7 }, // fovTarget + { 50, 8 }, // unk_14 + { 0x2002, 9 }, // flags + { -40, 11 }, // unk_18 + { 20, 12 }, // unk_1C +}; + +CameraModeValue D_8011A714[] = { + /* CAM_FUNC_KEEP1 */ + { -20, 0 }, // unk_00 + { 120, 1 }, // unk_04 + { 140, 2 }, // unk_08 + { 25, 13 }, // unk_0C + { 45, 14 }, // unk_10 + { -5, 15 }, // unk_14 + { 15, 16 }, // unk_18 + { 15, 17 }, // unk_1C + { 45, 7 }, // unk_20 + { 50, 8 }, // unk_24 + { 0x2001, 9 }, // flags + { -50, 11 }, // unk_28 + { 20, 12 }, // unk_2C +}; + +CameraModeValue D_8011A748[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 250, 1 }, // distance + { 10, 13 }, // swingYawInitial + { 80, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 10, 16 }, // swingPitchFinal + { 25, 17 }, // swingPitchAdj (PCT) + { 50, 7 }, // fov + { 65, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 25, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011A778[] = { + /* CAM_FUNC_SPEC5 */ + { -20, 0 }, // yOffset + { 80, 1 }, // eyeDist + { 250, 2 }, // minDistForRot + { 6, 22 }, // timerInit + { 45, 3 }, // pitch + { 60, 7 }, // fovTarget + { 40, 8 }, // atMaxLERPScale + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011A798[] = { + /* CAM_FUNC_JUMP1 */ + { 0, 0 }, // atYOffset + { 250, 1 }, // distMin + { 400, 2 }, // distMax + { 15, 4 }, // yawUpdateRateTarget + { 50, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 30, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A7B8[] = { + /* CAM_FUNC_JUMP1 */ + { 0, 0 }, // atYOffset + { 200, 1 }, // distMin + { 400, 2 }, // distMax + { 30, 4 }, // yawUpdateRateTarget + { 80, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 20, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A7D8[] = { + /* CAM_FUNC_JUMP2 */ + { -20, 0 }, // atYOffset + { 200, 1 }, // minDist + { 400, 2 }, // maxDist + { 20, 18 }, // minMaxDistFactor + { 5, 4 }, // yawUpdRateTarget + { 5, 5 }, // xzUpdRateTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPStepScale + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A7FC[] = { + /* CAM_FUNC_JUMP2 */ + { -20, 0 }, // atYOffset + { 250, 1 }, // minDist + { 400, 2 }, // maxDist + { 20, 18 }, // minMaxDistFactor + { 999, 4 }, // yawUpdRateTarget + { 5, 5 }, // xzUpdRateTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPStepScale + { 0x2006, 9 }, // flags +}; + +CameraModeValue D_8011A820[] = { + /* CAM_FUNC_BATT4 */ + { 0, 0 }, // yOffset + { 300, 1 }, // rTarget + { 50, 3 }, // pitchTarget + { 2, 4 }, // lerpUpdateRate + { 80, 7 }, // fovTarget + { 20, 8 }, // atLERPTarget + { 0xF000, 9 }, // flags +}; + +CameraModeValue D_8011A83C[] = { + /* CAM_FUNC_UNIQ1 */ + { -80, 0 }, // yOffset + { 200, 1 }, // distMin + { 400, 2 }, // distMax + { 40, 3 }, // pitchTarget + { 60, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A858[] = { + /* CAM_FUNC_UNIQ1 */ + { -120, 0 }, // yOffset + { 400, 1 }, // distMin + { 400, 2 }, // distMax + { 70, 3 }, // pitchTarget + { 45, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011A874[] = { + /* CAM_FUNC_NORM1 */ + { 0, 0 }, // yOffset + { 200, 1 }, // distMin + { 400, 2 }, // distMax + { 10, 3 }, // pitchTarget + { 100, 4 }, // unk_0C + { 20, 5 }, // unk_10 + { 100, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 5, 8 }, // atLERPScaleMax + { 0xF003, 9 }, // flags +}; + +CameraModeValue D_8011A89C[] = { + /* CAM_FUNC_NORM1 */ + { -10, 0 }, // yOffset + { 150, 1 }, // distMin + { 250, 2 }, // distMax + { 5, 3 }, // pitchTarget + { 10, 4 }, // unk_0C + { 5, 5 }, // unk_10 + { 30, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 60, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011A8C4[] = { + /* CAM_FUNC_PARA1 */ + { -20, 0 }, // unk_00 + { 150, 1 }, // distTarget + { 0, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 45, 7 }, // fovTarget + { 50, 8 }, // unk_14 + { 0x200A, 9 }, // flags + { -40, 11 }, // unk_18 + { 20, 12 }, // unk_1C +}; + +CameraModeValue D_8011A8F0[] = { + /* CAM_FUNC_KEEP1 */ + { -20, 0 }, // unk_00 + { 120, 1 }, // unk_04 + { 140, 2 }, // unk_08 + { 25, 13 }, // unk_0C + { 45, 14 }, // unk_10 + { -5, 15 }, // unk_14 + { 15, 16 }, // unk_18 + { 15, 17 }, // unk_1C + { 45, 7 }, // unk_20 + { 50, 8 }, // unk_24 + { 0x2001, 9 }, // flags + { -40, 11 }, // unk_28 + { 20, 12 }, // unk_2C +}; + +CameraModeValue D_8011A924[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 180, 1 }, // distance + { 10, 13 }, // swingYawInitial + { 80, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 10, 16 }, // swingPitchFinal + { 25, 17 }, // swingPitchAdj (PCT) + { 45, 7 }, // fov + { 80, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 25, 12 }, // atLERPScaleOnGround (PCT) +}; + +CameraModeValue D_8011A954[] = { + /* CAM_FUNC_JUMP1 */ + { -10, 0 }, // atYOffset + { 150, 1 }, // distMin + { 250, 2 }, // distMax + { 10, 4 }, // yawUpdateRateTarget + { 50, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 40, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A974[] = { + /* CAM_FUNC_JUMP1 */ + { -10, 0 }, // atYOffset + { 150, 1 }, // distMin + { 250, 2 }, // distMax + { 10, 4 }, // yawUpdateRateTarget + { 80, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 20, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A994[] = { + /* CAM_FUNC_JUMP2 */ + { -40, 0 }, // atYOffset + { 150, 1 }, // minDist + { 250, 2 }, // maxDist + { 20, 18 }, // minMaxDistFactor + { 5, 4 }, // yawUpdRateTarget + { 5, 5 }, // xzUpdRateTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPStepScale + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011A9B8[] = { + /* CAM_FUNC_JUMP2 */ + { -40, 0 }, // atYOffset + { 250, 1 }, // minDist + { 250, 2 }, // maxDist + { 20, 18 }, // minMaxDistFactor + { 999, 4 }, // yawUpdRateTarget + { 5, 5 }, // xzUpdRateTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPStepScale + { 0x2006, 9 }, // flags +}; + +CameraModeValue D_8011A9DC[] = { + /* CAM_FUNC_BATT4 */ + { -10, 0 }, // yOffset + { 300, 1 }, // rTarget + { 50, 3 }, // pitchTarget + { 2, 4 }, // lerpUpdateRate + { 80, 7 }, // fovTarget + { 20, 8 }, // atLERPTarget + { 0xF000, 9 }, // flags +}; + +CameraModeValue D_8011A9F8[] = { + /* CAM_FUNC_UNIQ1 */ + { -80, 0 }, // yOffset + { 150, 1 }, // distMin + { 250, 2 }, // distMax + { 40, 3 }, // pitchTarget + { 60, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011AA14[] = { + /* CAM_FUNC_UNIQ1 */ + { -120, 0 }, // yOffset */ + { 250, 1 }, // distMin */ + { 250, 2 }, // distMax */ + { 70, 3 }, // pitchTarget */ + { 45, 7 }, // fovTarget */ + { 10, 8 }, // atLERPScaleMax */ + { 0x2000, 9 }, // flags */ +}; + +CameraModeValue D_8011AA30[] = { + /* CAM_FUNC_NORM1 */ + { -10, 0 }, // yOffset + { 150, 1 }, // distMin + { 250, 2 }, // distMax + { 5, 3 }, // pitchTarget + { 100, 4 }, // unk_0C + { 5, 5 }, // unk_10 + { 100, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 5, 8 }, // atLERPScaleMax + { 0xF003, 9 }, // flags +}; + +CameraModeValue D_8011AA58[] = { + /* CAM_FUNC_NORM1 */ + { -40, 0 }, // yOffset + { 150, 1 }, // distMin + { 150, 2 }, // distMax + { 0, 3 }, // pitchTarget + { 10, 4 }, // unk_0C + { 5, 5 }, // unk_10 + { 30, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 60, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011AA80[] = { + /* CAM_FUNC_KEEP3 */ + { -20, 0 }, // yOffset + { 70, 1 }, // minDist + { 200, 2 }, // maxDist + { 40, 13 }, // swingYawInitial + { 10, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 5, 16 }, // swingPitchFinal + { 70, 17 }, // swingPitchAdj + { 45, 7 }, // fovTarget + { 50, 8 }, // atLERPScaleMax + { 10, 4 }, // initTimer + { 0x3500, 9 }, // flags +}; + +CameraModeValue D_8011AAB0[] = { + /* CAM_FUNC_JUMP1 */ + { -40, 0 }, // atYOffset + { 150, 1 }, // distMin + { 150, 2 }, // distMax + { 10, 4 }, // yawUpdateRateTarget + { 50, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 40, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011AAD0[] = { + /* CAM_FUNC_JUMP1 */ + { -40, 0 }, // atYOffset + { 150, 1 }, // distMin + { 180, 2 }, // distMax + { 12, 4 }, // yawUpdateRateTarget + { 80, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 20, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011AAF0[] = { + /* CAM_FUNC_JUMP2 */ + { -40, 0 }, // atYOffset + { 150, 1 }, // minDist + { 150, 2 }, // maxDist + { 20, 18 }, // minMaxDistFactor + { 5, 4 }, // yawUpdRateTarget + { 5, 5 }, // xzUpdRateTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPStepScale + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011AB14[] = { + /* CAM_FUNC_JUMP2 */ + { -40, 0 }, // atYOffset + { 150, 1 }, // minDist + { 150, 2 }, // maxDist + { 20, 18 }, // minMaxDistFactor + { 999, 4 }, // yawUpdRateTarget + { 5, 5 }, // xzUpdRateTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPStepScale + { 0x2006, 9 }, // flags +}; + +CameraModeValue D_8011AB38[] = { + /* CAM_FUNC_BATT4 */ + { -40, 0 }, // yOffset + { 200, 1 }, // rTarget + { 50, 3 }, // pitchTarget + { 2, 4 }, // lerpUpdateRate + { 80, 7 }, // fovTarget + { 20, 8 }, // atLERPTarget + { 0xF000, 9 }, // flags +}; + +CameraModeValue D_8011AB54[] = { + /* CAM_FUNC_UNIQ1 */ + { -80, 0 }, // yOffset */ + { 150, 1 }, // distMin */ + { 150, 2 }, // distMax */ + { 40, 3 }, // pitchTarget */ + { 60, 7 }, // fovTarget */ + { 10, 8 }, // atLERPScaleMax */ + { 0x0000, 9 }, // flags */ +}; + +CameraModeValue D_8011AB70[] = { + /* CAM_FUNC_UNIQ1 */ + { -120, 0 }, // yOffset + { 150, 1 }, // distMin + { 150, 2 }, // distMax + { 70, 3 }, // pitchTarget + { 45, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011AB8C[] = { + /* CAM_FUNC_NORM1 */ + { -40, 0 }, // yOffset + { 150, 1 }, // distMin + { 150, 2 }, // distMax + { 0, 3 }, // pitchTarget + { 100, 4 }, // unk_0C + { 5, 5 }, // unk_10 + { 100, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 5, 8 }, // atLERPScaleMax + { 0xF003, 9 }, // flags +}; + +CameraModeValue D_8011ABB4[] = { + /* CAM_FUNC_PARA1 */ + { -40, 0 }, // unk_00 + { 180, 1 }, // distTarget + { 25, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 60, 7 }, // fovTarget + { 50, 8 }, // unk_14 + { 0x206A, 9 }, // flags + { -20, 11 }, // unk_18 + { 30, 12 }, // unk_1C +}; + +CameraModeValue sSetNorm3ModeNormVals[] = { + /* CAM_FUNC_JUMP3 */ + { -20, 0 }, // yOffset + { 280, 1 }, // distMin + { 300, 2 }, // distMax + { 20, 3 }, // pitchTarget + { 15, 4 }, // swingUpdateRate + { 5, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 100, 8 }, // unk_1C + { 0x0004, 9 }, // flags +}; + +CameraModeValue D_8011AC08[] = { + /* CAM_FUNC_PARA1 */ + { -50, 0 }, // unk_00 + { 250, 1 }, // distTarget + { 70, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 15, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 60, 7 }, // fovTarget + { 100, 8 }, // unk_14 + { 0x200A, 9 }, // flags + { -50, 11 }, // unk_18 + { 20, 12 }, // unk_1C +}; + +CameraModeValue D_8011AC34[] = { + /* CAM_FUNC_KEEP3 */ + { -30, 0 }, // yOffset + { 70, 1 }, // minDist + { 200, 2 }, // maxDist + { 40, 13 }, // swingYawInitial + { 10, 14 }, // swingYawFinal + { 10, 15 }, // swingPitchInitial + { 20, 16 }, // swingPitchFinal + { 70, 17 }, // swingPitchAdj + { 45, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 10, 4 }, // initTimer + { 0x3500, 9 }, // flags +}; + +CameraModeValue sSetNorm3ModeBoomVals[] = { + /* CAM_FUNC_JUMP3 */ + /* mode is BOOMERANG, but these values are for when the eye + * >= OREG(45) units below the surface of the water. + */ + { -40, 0 }, // yOffset + { 150, 1 }, // distMin + { 250, 2 }, // distMax + { -5, 3 }, // pitchTarget + { 18, 4 }, // swingUpdateRate + { 5, 5 }, // unk_10 + { 60, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 40, 8 }, // unk_1C + { 0x0005, 9 }, // flags +}; + +CameraModeValue sSetHrse0ModeNormVals[] = { + /* CAM_FUNC_NORM3 */ + { -50, 0 }, // yOffset */ + { 220, 1 }, // distMin */ + { 250, 2 }, // distMax */ + { 10, 3 }, // pitchTarget */ + { 16, 4 }, // yawUpdateSpeed */ + { 20, 5 }, // unk_10 */ + { 60, 7 }, // fovTarget */ + { 100, 8 }, // maxAtLERPScale */ + { 0x0600, 9 }, // flags */ +}; + +CameraModeValue sSetHrse0ModeParaVals[] = { + /* CAM_FUNC_NORM3 */ + { -40, 0 }, // yOffset + { 180, 1 }, // distMin + { 220, 2 }, // distMax + { -2, 3 }, // pitchTarget + { 12, 4 }, // yawUpdateSpeed + { 100, 5 }, // unk_10 + { 45, 7 }, // fovTarget + { 100, 8 }, // maxAtLERPScale + { 0x2600, 9 }, // flags +}; + +CameraModeValue D_8011ACD4[] = { + /* CAM_FUNC_SUBJ3 */ + { -7, 0 }, // eyeNextYOffset + { 14, 1 }, // eyeDist + { 100, 2 }, // eyeNextDist + { 10, 4 }, // unk_0C + { 0, 19 }, // atOffset.x + { -30, 20 }, // atOffset.y + { -5, 21 }, // atOffset.z + { 40, 7 }, // fovTarget + { 0x2600, 9 }, // flags +}; + +CameraModeValue D_8011ACF8[] = { + /* CAM_FUNC_KEEP1 */ + { -60, 0 }, // unk_00 + { 180, 1 }, // unk_04 + { 220, 2 }, // unk_08 + { 25, 13 }, // unk_0C + { 45, 14 }, // unk_10 + { -5, 15 }, // unk_14 + { 15, 16 }, // unk_18 + { 15, 17 }, // unk_1C + { 45, 7 }, // unk_20 + { 50, 8 }, // unk_24 + { 0x2601, 9 }, // flags + { -60, 11 }, // unk_28 + { 20, 12 }, // unk_2C +}; + +CameraModeValue D_8011AD2C[] = { + /* CAM_FUNC_KEEP3 */ + { -60, 0 }, // yOffset + { 140, 1 }, // minDist + { 200, 2 }, // maxDist + { 40, 13 }, // swingYawInitial + { 10, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 5, 16 }, // swingPitchFinal + { 70, 17 }, // swingPitchAdj + { 45, 7 }, // fovTarget + { 50, 8 }, // atLERPScaleMax + { 10, 4 }, // initTimer + { 0x3500, 9 }, // flags +}; + +CameraModeValue D_8011AD5C[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 150, 1 }, // distMin + { 250, 2 }, // distMax + { 0, 3 }, // pitchTarget + { 15, 4 }, // unk_0C + { 5, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 60, 8 }, // atLERPScaleMax + { 0x0001, 9 }, // flags +}; + +CameraModeValue D_8011AD84[] = { + /* CAM_FUNC_BATT1 */ + { -30, 0 }, // yOffset (PCT) */ + { 150, 1 }, // distance */ + { 10, 13 }, // swingYawInitial */ + { 40, 14 }, // swingYawFinal */ + { -10, 15 }, // swingPitchInitial */ + { 0, 16 }, // swingPitchFinal */ + { 25, 17 }, // swingPitchAdj (PCT) */ + { 60, 7 }, // fov */ + { 40, 8 }, // atLERPScaleOnGround (PCT) */ + { 0x2002, 9 }, // flags */ + { -50, 11 }, // yOffsetOffGround (PCT) */ + { 20, 12 }, // atLERPScaleOffGround (PCT) */ +}; + +CameraModeValue D_8011ADB4[] = { + /* CAM_FUNC_NORM1 */ + { 0, 0 }, // yOffset + { 150, 1 }, // distMin + { 300, 2 }, // distMax + { 0, 3 }, // pitchTarget + { 12, 4 }, // unk_0C + { 5, 5 }, // unk_10 + { 70, 6 }, // unk_14 + { 70, 7 }, // fovTarget + { 40, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011ADDC[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 160, 1 }, // distance + { 10, 13 }, // swingYawInitial + { 60, 14 }, // swingYawFinal + { -5, 15 }, // swingPitchInitial + { 0, 16 }, // swingPitchFinal + { 25, 17 }, // swingPitchAdj (PCT) + { 70, 7 }, // fov + { 50, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 20, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011AE0C[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 150, 1 }, // distMin + { 300, 2 }, // distMax + { -5, 3 }, // pitchTarget + { 15, 4 }, // unk_0C + { 5, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 70, 7 }, // fovTarget + { 70, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011AE34[] = { + /* CAM_FUNC_BATT1 */ + { -30, 0 }, // yOffset (PCT) + { 125, 1 }, // distance + { 10, 13 }, // swingYawInitial + { 10, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 0, 16 }, // swingPitchFinal + { 50, 17 }, // swingPitchAdj (PCT) + { 60, 7 }, // fov + { 50, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -50, 11 }, // yOffsetOffGround (PCT) + { 20, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011AE64[] = { + /* CAM_FUNC_NORM1 */ + { 10, 0 }, // yOffset + { 150, 1 }, // distMin + { 250, 2 }, // distMax + { 0, 3 }, // pitchTarget + { 15, 4 }, // unk_0C + { 15, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 100, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011AE8C[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 200, 1 }, // distance + { 45, 13 }, // swingYawInitial + { 40, 14 }, // swingYawFinal + { 5, 15 }, // swingPitchInitial + { -5, 16 }, // swingPitchFinal + { 35, 17 }, // swingPitchAdj (PCT) + { 60, 7 }, // fov + { 100, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 60, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011AEBC[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 500, 1 }, // distMin + { 500, 2 }, // distMax + { 10, 3 }, // pitchTarget + { 16, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 80, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011AEE4[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 200, 1 }, // distance + { 20, 13 }, // swingYawInitial + { 60, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 10, 16 }, // swingPitchFinal + { 15, 17 }, // swingPitchAdj (PCT) + { 45, 7 }, // fov + { 50, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 20, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011AF14[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 500, 1 }, // distMin + { 500, 2 }, // distMax + { 10, 3 }, // pitchTarget + { 20, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 80, 8 }, // atLERPScaleMax + { 0x0083, 9 }, // flags +}; + +CameraModeValue D_8011AF3C[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 200, 1 }, // distance + { 20, 13 }, // swingYawInitial + { 60, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 10, 16 }, // swingPitchFinal + { 15, 17 }, // swingPitchAdj (PCT) + { 45, 7 }, // fov + { 50, 8 }, // atLERPScaleOnGround (PCT) + { 0x2082, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 20, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011AF6C[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 500, 1 }, // distMin + { 500, 2 }, // distMax + { 10, 3 }, // pitchTarget + { 20, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 80, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 80, 8 }, // atLERPScaleMax + { 0x0083, 9 }, // flags +}; + +CameraModeValue D_8011AF94[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 100, 1 }, // distMin + { 150, 2 }, // distMax + { -10, 3 }, // pitchTarget + { 15, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 80, 7 }, // fovTarget + { 60, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011AFBC[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 200, 1 }, // distance + { 10, 13 }, // swingYawInitial + { 80, 14 }, // swingYawFinal + { -10, 15 }, // swingPitchInitial + { 10, 16 }, // swingPitchFinal + { 25, 17 }, // swingPitchAdj (PCT) + { 70, 7 }, // fov + { 40, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 20, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011AFEC[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 150, 1 }, // distMin + { 300, 2 }, // distMax + { 0, 3 }, // pitchTarget + { 20, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 80, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011B014[] = { + /* CAM_FUNC_BATT1 */ + { 0, 0 }, // yOffset (PCT) + { 400, 1 }, // distance + { 0, 13 }, // swingYawInitial + { 60, 14 }, // swingYawFinal + { -10, 15 }, // swingPitchInitial + { 5, 16 }, // swingPitchFinal + { 25, 17 }, // swingPitchAdj (PCT) + { 45, 7 }, // fov + { 40, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -20, 11 }, // yOffsetOffGround (PCT) + { 20, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011B044[] = { + /* CAM_FUNC_NORM1 */ + { -10, 0 }, // yOffset + { 150, 1 }, // distMin + { 200, 2 }, // distMax + { -10, 3 }, // pitchTarget + { 12, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 50, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011B06C[] = { + /* CAM_FUNC_NORM1 */ + { 40, 0 }, // yOffset + { 330, 1 }, // distMin + { 330, 2 }, // distMax + { -5, 3 }, // pitchTarget + { 15, 4 }, // unk_0C + { 15, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 100, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B094[] = { + /* CAM_FUNC_BATT4 */ + { -40, 0 }, // yOffset + { 250, 1 }, // rTarget + { 0, 3 }, // pitchTarget + { 2, 4 }, // lerpUpdateRate + { 80, 7 }, // fovTarget + { 20, 8 }, // atLERPTarget + { 0xF000, 9 }, // flags +}; + +CameraModeValue D_8011B0B0[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 500, 1 }, // distMin + { 500, 2 }, // distMax + { 10, 3 }, // pitchTarget + { 20, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 40, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 80, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011B0D8[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 180, 1 }, // distance + { 20, 13 }, // swingYawInitial + { 60, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 10, 16 }, // swingPitchFinal + { 25, 17 }, // swingPitchAdj (PCT) + { 45, 7 }, // fov + { 50, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 20, 12 }, // atLERPScaleOffGround (PCT) +}; +/*start here */ +CameraModeValue D_8011B108[] = { + /* CAM_FUNC_NORM2 */ + { 0, 0 }, // unk_00 + { 120, 1 }, // unk_04 + { 280, 2 }, // unk_08 + { 60, 23 }, // unk_1C + { 8, 4 }, // unk_0C + { 40, 6 }, // unk_10 + { 60, 7 }, // unk_14 + { 50, 8 }, // unk_18 + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B12C[] = { + /* CAM_FUNC_NORM2 */ + { 0, 0 }, // unk_00 + { 120, 1 }, // unk_04 + { 280, 2 }, // unk_08 + { 60, 23 }, // unk_1C + { 8, 4 }, // unk_0C + { 40, 6 }, // unk_10 + { 60, 7 }, // unk_14 + { 50, 8 }, // unk_18 + { 0x0080, 9 }, // flags +}; + +CameraModeValue D_8011B150[] = { + /* CAM_FUNC_NORM2 */ + { 0, 0 }, // unk_00 + { 270, 1 }, // unk_04 + { 300, 2 }, // unk_08 + { 120, 23 }, // unk_1C + { 8, 4 }, // unk_0C + { 60, 6 }, // unk_10 + { 60, 7 }, // unk_14 + { 100, 8 }, // unk_18 + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B174[] = { + /* CAM_FUNC_NORM2 */ + { 0, 0 }, // unk_00 + { 270, 1 }, // unk_04 + { 300, 2 }, // unk_08 + { 120, 23 }, // unk_1C + { 6, 4 }, // unk_0C + { 60, 6 }, // unk_10 + { 60, 7 }, // unk_14 + { 100, 8 }, // unk_18 + { 0x0000, 9 }, // flags +}; + +CameraModeValue sSetFixd0ModeNormVals[] = { + /* CAM_FUNC_FIXD1 */ + { -40, 0 }, // yOffset + { 100, 4 }, // lerpStep + { 60, 7 }, // fov + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B1A8[] = { + /* CAM_FUNC_FIXD1 */ + { -40, 0 }, // yOffset + { 100, 4 }, // lerpStep + { 60, 7 }, // fov + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011B1B8[] = { + /* CAM_FUNC_FIXD1 */ + { -40, 0 }, // yOffset + { 100, 4 }, // lerpStep + { 60, 7 }, // fov + { 0x3500, 9 }, // flags +}; + +CameraModeValue D_8011B1C8[] = { + /* CAM_FUNC_FIXD1 */ + { -40, 0 }, // yOffset + { 25, 4 }, // lerpStep + { 60, 7 }, // fov + { 0x0000, 9 }, // flags +}; + +CameraModeValue sSetCirc0ModeNormVals[] = { + /* CAM_FUNC_FIXD2 */ + { -40, 0 }, // yOffset + { 50, 4 }, // eyeStepScale + { 80, 5 }, // posStepScale + { 60, 7 }, // fov + { 0x0001, 9 }, // flags +}; + +CameraModeValue sSetCirc2ModeNormVals[] = { + /* CAM_FUNC_DATA4 */ + { -40, 0 }, // yOffset + { 60, 7 }, // fov + { 0x3F00, 9 }, // flags +}; + +CameraModeValue D_8011B1F8[] = { + /* CAM_FUNC_FIXD4 */ + { -40, 0 }, // yOffset + { 50, 4 }, // speedToEyePos + { 80, 5 }, // followSpeed + { 60, 7 }, // fov + { 0x0004, 9 }, // flags +}; + +CameraModeValue D_8011B20C[] = { + /* CAM_FUNC_UNIQ0 + CAM_FUNC_FIXD3 + CAM_FUNC_SPEC6 + CAM_FUNC_SPEC7 */ + { 0x0000, 9 }, // flags +}; + +CameraModeValue sSetPR0ModeKeepTalkVals[] = { + /* CAM_FUNC_FIXD3 */ + { 0x2000, 9 }, // flags +}; + +CameraModeValue sSetPR1ModeNormVals[] = { + /* CAM_FUNC_UNIQ7 */ + { 60, 7 }, // fov + { 0x0000, 9 }, // flags +}; + +CameraModeValue sSetPR1ModeKeepVals[] = { + /* CAM_FUNC_UNIQ7 */ + { 60, 7 }, // fov + { 0x2000, 9 }, // flags +}; + +CameraModeValue sSetPreRend1ModeTalkVals[] = { + /* CAM_FUNC_KEEP0 */ + { 30, 24 }, // fovScale + { 0, 25 }, // yawScale + { 4, 4 }, // timerInit + { 0x3500, 9 }, // flags +}; + +CameraModeValue sSetDoor0ModeNormVals[] = { + /* CAM_FUNC_UNIQ3 */ + { -40, 0 }, // yOffset + { 60, 7 }, // fov + { 0x3200, 9 }, // flags +}; + +CameraModeValue sSetDoorCModeNormVals[] = { + /* CAM_FUNC_SPEC9 */ + { -5, 0 }, // yOffset + { 60, 7 }, // unk_04 (unused) + { 0x3202, 9 }, // flags +}; + +CameraModeValue sSetDoorCModeParaVals[] = { + /* CAM_FUNC_SPEC9 */ + { -5, 0 }, // yOffset + { 60, 7 }, // unk_04 (unused) + { 0x320A, 9 }, // flags +}; + +CameraModeValue sSetRail3ModeNormVals[] = { + /* CAM_FUNC_SUBJ4 + Camera_Subj4 only reads one setting which is used for flags. */ + { 0, 0 }, // flags + { 2, 1 }, // unused + { 30, 2 }, // unused + { 10, 4 }, // unused + { 45, 7 }, // unused + { 0x3200, 9 }, // unused +}; + +CameraModeValue D_8011B270[] = { + /* CAM_FUNC_UNIQ0 */ + { 0x0001, 9 }, // flags +}; + +CameraModeValue sSetFree0ModeNormVals[] = { + /* CAM_FUNC_UNIQ6 */ + { 0xFF00, 9 }, // flags +}; + +CameraModeValue sSetFree1ModeNormVals[] = { + /* CAM_FUNC_UNIQ6 */ + { 0xFF01, 9 }, // flags +}; + +CameraModeValue sSetCirc4ModeNormVals[] = { + /* CAM_FUNC_FIXD2 */ + { -40, 0 }, // yOffset + { 100, 4 }, // eyeStepScale + { 80, 5 }, // posStepScale + { 60, 7 }, // fov + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B290[] = { + /* CAM_FUNC_UNIQ2 */ + { -40, 0 }, // yOffset + { 60, 1 }, // distTarget + { 60, 7 }, // fovTarget + { 0x0002, 9 }, // flags +}; + +CameraModeValue D_8011B2A0[] = { + /* CAM_FUNC_UNIQ2 */ + { -30, 0 }, // yOffset + { 45, 1 }, // distTarget + { 100, 7 }, // fovTarget + { 0x2001, 9 }, // flags +}; + +CameraModeValue D_8011B2B0[] = { + /* CAM_FUNC_DEMO1 + CAM_FUNC_DEMO4 (Not actually used in Camera_Demo4) + CAM_FUNC_DEMO6 + CAM_FUNC_SPEC4 */ + { 0x3200, 9 }, // flags +}; + +CameraModeValue sSetMori1ModeNormVals[] = { + /* CAM_FUNC_PARA1 */ + { -50, 0 }, // unk_00 + { 450, 1 }, // distTarget + { 40, 3 }, // pitchTarget3 + { 180, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 70, 7 }, // fovTarget + { 30, 8 }, // unk_14 + { 0x000C, 9 }, // flags + { -50, 11 }, // unk_18 + { 20, 12 }, // unk_1C +}; + +CameraModeValue D_8011B2E0[] = { + /* CAM_FUNC_PARA3 */ + { 0x3501, 9 }, // flags +}; + +CameraModeValue D_8011B2E4[] = { + /* CAM_FUNC_DEMO3 + CAM_FUNC_DEMO4 (not actually used in Camera_Demo4) */ + { 60, 7 }, // fov + { 30, 8 }, // unk_04 + { 0x3200, 9 }, // flags +}; + +CameraModeValue sSetDemo3ModeNormVals[] = { + /* CAM_FUNC_DEMO9 */ + { 0x3212, 9 }, // flags +}; + +CameraModeValue D_8011B2F4[] = { + /* CAM_FUNC_NORM1 */ + { -50, 0 }, // yOffset + { 300, 1 }, // distMin + { 300, 2 }, // distMax + { 50, 3 }, // pitchTarget + { 20, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 50, 6 }, // unk_14 + { 70, 7 }, // fovTarget + { 40, 8 }, // atLERPScaleMax + { 0x0002, 9 }, // flags +}; + +CameraModeValue D_8011B31C[] = { + /* CAM_FUNC_PARA1 */ + { -50, 0 }, // unk_00 + { 300, 1 }, // distTarget + { 10, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 45, 7 }, // fovTarget + { 50, 8 }, // unk_14 + { 0x200A, 9 }, // flags + { -40, 11 }, // unk_18 + { 20, 12 }, // unk_1C +}; + +CameraModeValue D_8011B348[] = { + /* CAM_FUNC_JUMP1 */ + { -50, 0 }, // atYOffset + { 300, 1 }, // distMin + { 300, 2 }, // distMax + { 12, 4 }, // yawUpdateRateTarget + { 35, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 40, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B368[] = { + /* CAM_FUNC_UNIQ1 */ + { -80, 0 }, // yOffset + { 300, 1 }, // distMin + { 300, 2 }, // distMax + { 60, 3 }, // fovTarget + { 70, 7 }, // pitchTarget + { 30, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B384[] = { + /* CAM_FUNC_UNIQ1 */ + { -120, 0 }, // yOffset + { 300, 1 }, // distMin + { 300, 2 }, // distMax + { 70, 3 }, // pitchTarget + { 50, 7 }, // fovTarget + { 30, 8 }, // atLERPScaleMax + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011B3A0[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 300, 1 }, // distMin + { 350, 2 }, // distMax + { 50, 3 }, // pitchTarget + { 100, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 100, 6 }, // unk_14 + { 70, 7 }, // fovTarget + { 30, 8 }, // atLERPScaleMax + { 0xF002, 9 }, // flags +}; + +CameraModeValue D_8011B3C8[] = { + /* CAM_FUNC_NORM1 */ + { -50, 0 }, // yOffset + { 200, 1 }, // distMin + { 200, 2 }, // distMax + { 20, 3 }, // pitchTarget + { 16, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 50, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 50, 8 }, // atLERPScaleMax + { 0x0002, 9 }, // flags +}; + +CameraModeValue D_8011B3F0[] = { + /* CAM_FUNC_PARA1 */ + { -50, 0 }, // unk_00 + { 200, 1 }, // distTarget + { 40, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 45, 7 }, // fovTarget + { 50, 8 }, // unk_14 + { 0x200A, 9 }, // flags + { -40, 11 }, // unk_18 + { 20, 12 }, // unk_1C +}; + +CameraModeValue D_8011B41C[] = { + /* CAM_FUNC_JUMP1 */ + { -50, 0 }, // atYOffset + { 150, 1 }, // distMin + { 250, 2 }, // distMax + { 12, 4 }, // yawUpdateRateTarget + { 35, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 40, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B43C[] = { + /* CAM_FUNC_UNIQ1 */ + { -80, 0 }, // yOffset + { 200, 1 }, // distMin + { 200, 2 }, // distMax + { 40, 3 }, // pitchTarget + { 60, 7 }, // fovTarget + { 30, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B458[] = { + /* CAM_FUNC_UNIQ1 */ + { -120, 0 }, // yOffset + { 200, 1 }, // distMin + { 200, 2 }, // distMax + { 60, 3 }, // pitchtarget + { 50, 7 }, // fovTarget + { 30, 8 }, // atLERPScaleMax + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011B474[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 200, 1 }, // distMin + { 250, 2 }, // distMax + { 20, 3 }, // unk_0C + { 100, 4 }, // unk_10 + { 10, 5 }, // unk_14 + { 100, 6 }, // pitchTarget + { 60, 7 }, // fovTarget + { 30, 8 }, // atLERPScaleMax + { 0xF002, 9 }, // flags +}; + +CameraModeValue sSetScn0ModeNormVals[] = { + /* CAM_FUNC_SPEC9 */ + { -30, 0 }, // yOffset + { 60, 7 }, // unk_04 (unused) + { 0x10A, 9 }, // flags +}; + +CameraModeValue D_8011B4A8[] = { + /* CAM_FUNC_UNIQ2 */ + { -20, 0 }, // yOffset + { 150, 1 }, // distTarget + { 60, 7 }, // fovTarget + { 0x0210, 9 }, // flags +}; + +CameraModeValue D_8011B4B8[] = { + /* CAM_FUNC_NORM1 */ + { 0, 0 }, // yOffset + { 400, 1 }, // distMin + { 500, 2 }, // distMax + { 35, 3 }, // unk_0C + { 14, 4 }, // unk_10 + { 5, 5 }, // unk_14 + { 20, 6 }, // pitchTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPScaleMax + { 0x0012, 9 }, // flags +}; + +CameraModeValue D_8011B4E0[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 250, 1 }, // distance + { 5, 13 }, // swingYawInitial + { 10, 14 }, // swingYawFinal + { 30, 15 }, // swingPitchInitial + { 20, 16 }, // swingPitchFinal + { 25, 17 }, // swingPitchAdj (PCT) + { 45, 7 }, // fov + { 60, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 25, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011B510[] = { + /* CAM_FUNC_NORM1 */ + { 0, 0 }, // yOffset + { 300, 1 }, // distMin + { 500, 2 }, // distMax + { 60, 3 }, // unk_0C + { 8, 4 }, // unk_10 + { 5, 5 }, // unk_14 + { 60, 6 }, // pitchTarget + { 60, 7 }, // fovTarget + { 30, 8 }, // atLERPScaleMax + { 0x0012, 9 }, // flags +}; + +CameraModeValue D_8011B538[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 500, 1 }, // distMin + { 500, 2 }, // distMax + { 80, 3 }, // unk_0C + { 20, 4 }, // unk_10 + { 10, 5 }, // unk_14 + { 70, 6 }, // pitchTarget + { 70, 7 }, // fovTarget + { 80, 8 }, // atLERPScaleMax + { 0x0012, 9 }, // flags +}; + +CameraModeValue D_8011B560[] = { + /* CAM_FUNC_PARA1 */ + { -20, 0 }, // unk_00 + { 500, 1 }, // distTarget + { 80, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 70, 7 }, // fovTarget + { 80, 8 }, // unk_14 + { 0x201A, 9 }, // flags + { -40, 11 }, // unk_18 + { 40, 12 }, // unk_1C +}; + +CameraModeValue D_8011B58C[] = { + /* CAM_FUNC_PARA1 */ + { -20, 0 }, // unk_00 + { 500, 1 }, // distTarget + { 80, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 60, 7 }, // fovTarget + { 80, 8 }, // unk_14 + { 0x201A, 9 }, // flags + { -40, 11 }, // unk_18 + { 40, 12 }, // unk_1C +}; + +CameraModeValue D_8011B5B8[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 500, 1 }, // distMin + { 500, 2 }, // distMax + { 80, 3 }, // unk_0C + { 20, 4 }, // unk_10 + { 10, 5 }, // unk_14 + { 80, 6 }, // pitchTarget + { 60, 7 }, // fovTarget + { 20, 8 }, // atLERPScaleMax + { 0x0012, 9 }, // flags +}; + +CameraModeValue D_8011B5E0[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 750, 1 }, // distMin + { 750, 2 }, // distMax + { 80, 3 }, // unk_0C + { 20, 4 }, // unk_10 + { 10, 5 }, // unk_14 + { 70, 6 }, // pitchTarget + { 70, 7 }, // fovTarget + { 80, 8 }, // atLERPScaleMax + { 0x0012, 9 }, // flags +}; + +CameraModeValue D_8011B608[] = { + /* CAM_FUNC_PARA1 */ + { -20, 0 }, // unk_00 + { 750, 1 }, // distTarget + { 80, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 70, 7 }, // fovTarget + { 80, 8 }, // unk_14 + { 0x201A, 9 }, // flags + { -40, 11 }, // unk_18 + { 40, 12 }, // unk_1C +}; + +CameraModeValue D_8011B634[] = { + /* CAM_FUNC_PARA1 */ + { -20, 0 }, // unk_00 + { 750, 1 }, // distTarget + { 80, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 70, 7 }, // fovTarget + { 80, 8 }, // unk_14 + { 0x200A, 9 }, // flags + { -40, 11 }, // unk_18 + { 40, 12 }, // unk_1C +}; + +CameraModeValue D_8011B660[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 750, 1 }, // distMin + { 750, 2 }, // distMax + { 80, 3 }, // unk_0C + { 20, 4 }, // unk_10 + { 10, 5 }, // unk_14 + { 80, 6 }, // pitchTarget + { 70, 7 }, // fovTarget + { 20, 8 }, // atLERPScaleMax + { 0x0012, 9 }, // flags +}; + +CameraModeValue D_8011B688[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 500, 1 }, // distMin + { 500, 2 }, // distMax + { 80, 3 }, // unk_0C + { 20, 4 }, // unk_10 + { 10, 5 }, // unk_14 + { 70, 6 }, // pitchTarget + { 70, 7 }, // fovTarget + { 80, 8 }, // atLERPScaleMax + { 0x0002, 9 }, // flags +}; + +CameraModeValue D_8011B6B0[] = { + /* CAM_FUNC_PARA1 */ + { -20, 0 }, // unk_00 + { 500, 1 }, // distTarget + { 80, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 70, 7 }, // fovTarget + { 80, 8 }, // unk_14 + { 0x200A, 9 }, // flags + { -40, 11 }, // unk_18 + { 40, 12 }, // unk_1C +}; + +CameraModeValue D_8011B6DC[] = { + /* CAM_FUNC_PARA1 */ + { -20, 0 }, // unk_00 + { 500, 1 }, // distTarget + { 80, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 60, 7 }, // fovTarget + { 80, 8 }, // unk_14 + { 0x200A, 9 }, // flags + { -40, 11 }, // unk_18 + { 40, 12 }, // unk_1C +}; + +CameraModeValue D_8011B708[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 500, 1 }, // distMin + { 500, 2 }, // distMax + { 80, 3 }, // unk_0C + { 20, 4 }, // unk_10 + { 10, 5 }, // unk_14 + { 80, 6 }, // pitchTarget + { 60, 7 }, // fovTarget + { 20, 8 }, // atLERPScaleMax + { 0x0002, 9 }, // flags +}; + +CameraModeValue D_8011B730[] = { + /* CAM_FUNC_KEEP4 */ + { -30, 0 }, // unk_00 + { 120, 1 }, // unk_04 + { -10, 3 }, // unk_08 + { 170, 10 }, // unk_0C + { 0, 21 }, // unk_10 + { 60, 7 }, // unk_18 + { 0x2502, 9 }, // flags + { 25, 4 }, // unk_14 + { 6, 22 }, // unk_1E +}; + +CameraModeValue sSetCirc6ModeNormVals[] = { + /* CAM_FUNC_SPEC0 */ + { 20, 4 }, // lerpATScale + { 0x3200, 9 }, // flags +}; + +CameraModeValue D_8011B75C[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { 10, 3 }, // pitchTarget + { 12, 4 }, // unk_0C + { 10, 5 }, // unk_10 + { 35, 6 }, // unk_14 + { 60, 7 }, // fovTarget + { 60, 8 }, // atLERPScaleMax + { 0x0002, 9 }, // flags +}; + +CameraModeValue D_8011B784[] = { + /* CAM_FUNC_NORM1 */ + { 0, 0 }, // yOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { 20, 3 }, // unk_0C + { 12, 4 }, // unk_10 + { 10, 5 }, // unk_14 + { 35, 6 }, // pitchTarget + { 55, 7 }, // fovTarget + { 60, 8 }, // atLERPScaleMax + { 0x0F02, 9 }, // flags +}; + +CameraModeValue D_8011B7AC[] = { + /* CAM_FUNC_PARA1 */ + { -20, 0 }, // unk_00 + { 250, 1 }, // distTarget + { 0, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 45, 7 }, // fovTarget + { 50, 8 }, // unk_14 + { 0x2F0A, 9 }, // flags + { -40, 11 }, // unk_18 + { 20, 12 }, // unk_1C +}; + +CameraModeValue D_8011B7D8[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 250, 1 }, // distance + { 0, 13 }, // swingYawInitial + { 80, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 0, 16 }, // swingPitchFinal + { 25, 17 }, // swingPitchAdj (PCT) + { 55, 7 }, // fov + { 80, 8 }, // atLERPScaleOnGround (PCT) + { 0x2F02, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 25, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011B808[] = { + /* CAM_FUNC_KEEP3 */ + { -30, 0 }, // yOffset + { 70, 1 }, // minDist + { 200, 2 }, // maxDist + { 40, 13 }, // swingYawInitial + { 10, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 5, 16 }, // swingPitchFinal + { 70, 17 }, // swingPitchAdj + { 45, 7 }, // fovTarget + { 50, 8 }, // atLERPScaleMax + { 10, 4 }, // initTimer + { 0x3F20, 9 }, // flags +}; + +CameraModeValue D_8011B838[] = { + /* CAM_FUNC_SUBJ3 */ + { 0, 0 }, // eyeNextYOffset + { 5, 1 }, // eyeDist + { 50, 2 }, // eyeNextDist + { 10, 4 }, // unk_0C + { 0, 19 }, // atOffset.x + { 0, 20 }, // atOffset.y + { 0, 21 }, // atOffset.z + { 45, 7 }, // fovTarget + { 0x0F00, 9 }, // flags +}; + +CameraModeValue D_8011B85C[] = { + /* CAM_FUNC_JUMP1 */ + { -20, 0 }, // atYOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { 12, 4 }, // yawUpdateRateTarget + { 35, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 40, 8 }, // atLERPScaleMax + { 0x0F00, 9 }, // flags +}; + +CameraModeValue D_8011B87C[] = { + /* CAM_FUNC_JUMP1 */ + { -20, 0 }, // atYOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { 15, 4 }, // yawUpdateRateTarget + { 80, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 20, 8 }, // atLERPScaleMax + { 0x0F00, 9 }, // flags +}; + +CameraModeValue D_8011B89C[] = { + /* CAM_FUNC_UNIQ1 */ + { -80, 0 }, // yOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { 40, 3 }, // pitchTarget + { 60, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 0x0F00, 9 }, // flags +}; + +CameraModeValue D_8011B8B8[] = { + /* CAM_FUNC_UNIQ1 */ + { -120, 0 }, // yOffset + { 300, 1 }, // distMin + { 300, 2 }, // distMax + { 70, 3 }, // pitchTarget + { 45, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 0x2F00, 9 }, // flags +}; + +CameraModeValue sSetDemoCModeNormVals[] = { + /* CAM_FUNC_UNIQ9 */ + { 0x3F00, 9 }, /* flags */ +}; + +CameraModeValue D_8011B8D8[] = { + /* CAM_FUNC_NORM1 */ + { 30, 0 }, // yOffset + { 200, 1 }, // distMin + { 300, 2 }, // distMax + { -20, 3 }, // unk_0C + { 15, 4 }, // unk_10 + { 5, 26 }, // unk_14 + { 50, 6 }, // pitchTarget + { 70, 7 }, // fovTarget + { 70, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011B900[] = { + /* CAM_FUNC_BATT1 */ + { -30, 0 }, // yOffset (PCT) + { 160, 1 }, // distance + { 10, 13 }, // swingYawInitial + { 10, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 0, 16 }, // swingPitchFinal + { 70, 17 }, // swingPitchAdj (PCT) + { 60, 7 }, // fov + { 40, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -50, 11 }, // yOffsetOffGround (PCT) + { 20, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011B930[] = { + /* CAM_FUNC_NORM1 */ + { -20, 0 }, // yOffset + { 350, 1 }, // distMin + { 350, 2 }, // distMax + { 20, 3 }, // unk_0C + { 15, 4 }, // unk_10 + { 5, 5 }, // unk_14 + { 30, 6 }, // pitchTarget + { 60, 7 }, // fovTarget + { 60, 8 }, // atLERPScaleMax + { 0x0003, 9 }, // flags +}; + +CameraModeValue D_8011B958[] = { + /* CAM_FUNC_PARA1 */ + { -20, 0 }, // unk_00 + { 200, 1 }, // distTarget + { 0, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 45, 7 }, // fovTarget + { 50, 8 }, // unk_14 + { 0x200A, 9 }, // flags + { -40, 11 }, // unk_18 + { 20, 12 }, // unk_1C +}; + +CameraModeValue sSetDung2ModeBattVals[] = { + /* CAM_FUNC_BATT1 */ + { -20, 0 }, // yOffset (PCT) + { 180, 1 }, // distance + { 10, 13 }, // swingYawInitial + { 80, 14 }, // swingYawFinal + { -10, 15 }, // swingPitchInitial + { 10, 16 }, // swingPitchFinal + { 25, 17 }, // swingPitchAdj (PCT) + { 45, 7 }, // fov + { 80, 8 }, // atLERPScaleOnGround (PCT) + { 0x2002, 9 }, // flags + { -40, 11 }, // yOffsetOffGround (PCT) + { 25, 12 }, // atLERPScaleOffGround (PCT) +}; + +CameraModeValue D_8011B9B4[] = { + /* CAM_FUNC_JUMP1 */ + { -20, 0 }, // atYOffset + { 350, 1 }, // distMin + { 350, 2 }, // distMax + { 10, 4 }, // yawUpdateRateTarget + { 50, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 40, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B9D4[] = { + /* CAM_FUNC_JUMP1 */ + { -20, 0 }, // atYOffset + { 350, 1 }, // distMin + { 350, 2 }, // distMax + { 15, 4 }, // yawUpdateRateTarget + { 80, 6 }, // maxYawUpdate + { 60, 7 }, // unk_14 + { 20, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011B9F4[] = { + /* CAM_FUNC_JUMP2 */ + { -40, 0 }, // atYOffset + { 350, 1 }, // minDist + { 350, 2 }, // maxDist + { 20, 18 }, // minMaxDistFactor + { 5, 4 }, // yawUpdRateTarget + { 5, 5 }, // xzUpdRateTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPStepScale + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011BA18[] = { + /* CAM_FUNC_JUMP2 */ + { -40, 0 }, // atYOffset + { 350, 1 }, // minDist + { 350, 2 }, // maxDist + { 20, 18 }, // minMaxDistFactor + { 999, 4 }, // yawUpdRateTarget + { 5, 5 }, // xzUpdRateTarget + { 60, 7 }, // fovTarget + { 40, 8 }, // atLERPStepScale + { 0x2006, 9 }, // flags +}; + +CameraModeValue D_8011BA3C[] = { + /* CAM_FUNC_UNIQ1 */ + { -50, 0 }, // yOffset + { 350, 1 }, // distMin + { 350, 2 }, // distMax + { 40, 3 }, // pitchTarget + { 60, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 0x0000, 9 }, // flags +}; + +CameraModeValue D_8011BA58[] = { + /* CAM_FUNC_UNIQ1 */ + { -100, 0 }, // yOffset + { 350, 1 }, // distMin + { 350, 2 }, // distMax + { 70, 3 }, // pitchTarget + { 45, 7 }, // fovTarget + { 10, 8 }, // atLERPScaleMax + { 0x2000, 9 }, // flags +}; + +CameraModeValue D_8011BA74[] = { + /* CAM_FUNC_NORM1 */ + { -10, 0 }, // yOffset + { 350, 1 }, // distMin + { 350, 2 }, // distMax + { 20, 3 }, // unk_0C + { 100, 4 }, // unk_10 + { 5, 5 }, // unk_14 + { 100, 6 }, // pitchTarget + { 60, 7 }, // fovTarget + { 5, 8 }, // atLERPScaleMax + { 0xF003, 9 }, // flags +}; + +CameraModeValue D_8011BA9C[] = { + /* CAM_FUNC_PARA1 */ + { 0, 0 }, // unk_00 + { 280, 1 }, // distTarget + { 25, 3 }, // pitchTarget + { 0, 10 }, // yawTarget + { 5, 4 }, // unk_08 + { 5, 5 }, // unk_0C + { 70, 7 }, // fovTarget + { 30, 8 }, // unk_14 + { 0x206A, 9 }, // flags + { -20, 11 }, // unk_18 + { 30, 12 }, // unk_1C +}; + +CameraModeValue D_8011BAC8[] = { + /* CAM_FUNC_NORM1 */ + { -10, 0 }, // yOffset + { 280, 1 }, // distMin + { 320, 2 }, // distMax + { -8, 3 }, // unk_0C + { 20, 4 }, // unk_10 + { 10, 5 }, // unk_14 + { 80, 6 }, // pitchTarget + { 60, 7 }, // fovTarget + { 80, 8 }, // atLERPScaleMax + { 0x0002, 9 }, // flags +}; + +CameraModeValue D_8011BAF0[] = { + /* CAM_FUNC_KEEP1 */ + { -20, 0 }, // unk_00 + { 180, 1 }, // unk_04 + { 200, 2 }, // unk_08 + { 35, 13 }, // unk_0C + { 45, 14 }, // unk_10 + { 0, 15 }, // unk_14 + { -5, 16 }, // unk_18 + { 20, 17 }, // unk_1C + { 50, 7 }, // unk_20 + { 50, 8 }, // unk_24 + { 0x2001, 9 }, // flags + { -50, 11 }, // unk_28 + { 30, 12 }, // unk_2C +}; + +CameraModeValue D_8011BB24[] = { + /* CAM_FUNC_KEEP3 */ + { -80, 0 }, // yOffset + { 200, 1 }, // minDist + { 250, 2 }, // maxDist + { 30, 13 }, // swingYawInitial + { 10, 14 }, // swingYawFinal + { -8, 15 }, // swingPitchInitial + { -8, 16 }, // swingPitchFinal + { 30, 17 }, // swingPitchAdj + { 50, 7 }, // fovTarget + { 50, 8 }, // atLERPScaleMax + { 10, 4 }, // initTimer + { 0x3520, 9 }, // flags +}; + +CameraModeValue D_8011BB54[] = { + /* CAM_FUNC_KEEP3 */ + { -30, 0 }, // yOffset + { 70, 1 }, // minDist + { 200, 2 }, // maxDist + { 40, 13 }, // swingYawInitial + { 10, 14 }, // swingYawFinal + { 0, 15 }, // swingPitchInitial + { 5, 16 }, // swingPitchFinal + { 70, 17 }, // swingPitchAdj + { 45, 7 }, // fovTarget + { 50, 8 }, // atLERPScaleMax + { 10, 4 }, // initTimer + { 0x35A0, 9 }, // flags +}; + +CameraMode sCamSetNorm0Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011A3A0 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A458 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5FC }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetNorm1Modes[] = { + { CAM_FUNC_NORM1, 10, sSetNorm1ModeNormVals }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, sSetNorm1ModeParaVals }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A714 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A748 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A7D8 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A778 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A7FC }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A798 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A83C }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A858 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A7B8 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A820 }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A874 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetDungeon0Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011A89C }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A8C4 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A8F0 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A924 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A994 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A778 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A9B8 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A954 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A9F8 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011AA14 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A974 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A9DC }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011AA30 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetDungeon1Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011AA58 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A8C4 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A714 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011AA80 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A924 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011AAF0 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A778 }, // CAM_MODE_FOOKSHOT, + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011AB14 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011AAB0 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011AB54 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011AB70 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011AAD0 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011AB38 }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011AB8C }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011ABB4 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetNorm3Modes[] = { + { CAM_FUNC_JUMP3, 10, sSetNorm3ModeNormVals }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011AC08 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011AC34 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A458 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_JUMP3, 10, sSetNorm3ModeBoomVals }, // CAM_MODE_BOOMERANG + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL +}; + +CameraMode sCamSetHorse0Modes[] = { + { CAM_FUNC_NORM3, 9, sSetHrse0ModeNormVals }, // CAM_MODE_NORMAL + { CAM_FUNC_NORM3, 9, sSetHrse0ModeParaVals }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011ACF8 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011AD2C }, // CAM_MODE_TALK + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_BATTLE + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_CLIMB + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011ACD4 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ +}; + +CameraMode sCamSetBossGomaModes[] = { + { CAM_FUNC_NORM1, 10, D_8011AD5C }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011AD84 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT, + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A9DC }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetBossDodoModes[] = { + { CAM_FUNC_NORM1, 10, D_8011ADB4 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011ADDC }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT, + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetBossBariModes[] = { + { CAM_FUNC_NORM1, 10, D_8011AE0C }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011AE34 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT, + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetBossFGanonModes[] = { + { CAM_FUNC_NORM1, 10, D_8011AE64 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011AE8C }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetBossBalModes[] = { + { CAM_FUNC_NORM1, 10, D_8011AEBC }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011AEE4 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetBossShadesModes[] = { + { CAM_FUNC_NORM1, 10, D_8011AF14 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011AF3C }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT, + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_NORM1, 10, D_8011AF6C }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_NORM1, 10, D_8011AF6C }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetBossMofaModes[] = { + { CAM_FUNC_NORM1, 10, D_8011AF94 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011AFBC }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFAL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetBossTwin0Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011AFEC }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011B014 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT, + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFAL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetBossTwin1Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011B044 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011B014 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT, + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFAL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetBossGanon1Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011B06C }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011AE8C }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT, + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFAL + { CAM_FUNC_BATT4, 7, D_8011B094 }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetBossGanon2Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011B0B0 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011B0D8 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT, + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFAL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetTower0Modes[] = { + { CAM_FUNC_NORM2, 9, D_8011B108 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A458 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_NORM2, 9, D_8011B12C }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetTower1Modes[] = { + { CAM_FUNC_NORM2, 9, D_8011B150 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A458 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_NORM2, 9, D_8011B174 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetFixed0Modes[] = { + { CAM_FUNC_FIXD1, 4, sSetFixd0ModeNormVals }, // CAM_MODE_NORMAL + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_TARGET + { CAM_FUNC_FIXD1, 4, D_8011B1A8 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_FIXD1, 4, D_8011B1B8 }, // CAM_MODE_TALK +}; + +CameraMode sCamSetFixed1Modes[] = { + { CAM_FUNC_FIXD1, 4, D_8011B1C8 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetCirc0Modes[] = { + { CAM_FUNC_FIXD2, 5, sSetCirc0ModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetCirc2Modes[] = { + { CAM_FUNC_DATA4, 3, sSetCirc2ModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetCirc3Modes[] = { + { CAM_FUNC_FIXD4, 5, D_8011B1F8 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A748 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_JUMP + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_HANG + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_HANGZ + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetPreRend0Modes[] = { + { CAM_FUNC_FIXD3, 1, D_8011B20C }, // CAM_MODE_NORMAL + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_TARGET + { CAM_FUNC_FIXD3, 1, sSetPR0ModeKeepTalkVals }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_FIXD3, 1, sSetPR0ModeKeepTalkVals }, // CAM_MODE_TALK +}; + +CameraMode sCamSetPreRend1Modes[] = { + { CAM_FUNC_UNIQ7, 2, sSetPR1ModeNormVals }, // CAM_MODE_NORMAL + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_TARGET + { CAM_FUNC_UNIQ7, 2, sSetPR1ModeKeepVals }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP0, 4, sSetPreRend1ModeTalkVals }, // CAM_MODE_TALK +}; + +CameraMode sCamSetPreRend3Modes[] = { + { CAM_FUNC_SPEC6, 1, D_8011B20C }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetDoor0Modes[] = { + { CAM_FUNC_UNIQ3, 3, sSetDoor0ModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetDoorCModes[] = { + { CAM_FUNC_SPEC9, 3, sSetDoorCModeNormVals }, // CAM_MODE_NORMAL + { CAM_FUNC_SPEC9, 3, sSetDoorCModeParaVals }, // CAM_MODE_TARGET +}; + +CameraMode sCamSetRail3Modes[] = { + { CAM_FUNC_SUBJ4, 6, sSetRail3ModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetStart0Modes[] = { + { CAM_FUNC_UNIQ0, 1, D_8011B20C }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetStart1Modes[] = { + { CAM_FUNC_UNIQ0, 1, D_8011B270 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetFree0Modes[] = { + { CAM_FUNC_UNIQ6, 1, sSetFree0ModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetFree1Modes[] = { + { CAM_FUNC_UNIQ6, 1, sSetFree1ModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetCirc4Modes[] = { + { CAM_FUNC_FIXD2, 5, sSetCirc4ModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetCirc5Modes[] = { + { CAM_FUNC_UNIQ2, 4, D_8011B290 }, // CAM_MODE_NORMAL + { CAM_FUNC_UNIQ2, 4, D_8011B2A0 }, // CAM_MODE_TARGET +}; + +CameraMode sCamSetDemo0Modes[] = { + { CAM_FUNC_DEMO1, 1, D_8011B2B0 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetDemo1Modes[] = { + { CAM_FUNC_DEMO2, 1, D_8011B2B0 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetMori1Modes[] = { + { CAM_FUNC_PARA1, 11, sSetMori1ModeNormVals }, // CAM_MODE_NORMAL + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_TARGET + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_PARA3, 1, D_8011B2E0 }, // CAM_MODE_TALK +}; + +CameraMode sCamSetItem0Modes[] = { + { CAM_FUNC_DEMO3, 3, D_8011B2E4 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetItem1Modes[] = { + { CAM_FUNC_DEMO4, 3, D_8011B2E4 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetDemo3Modes[] = { + { CAM_FUNC_DEMO9, 1, sSetDemo3ModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetDemo4Modes[] = { + { CAM_FUNC_DEMO5, 1, D_8011B2B0 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetUFOBeanModes[] = { + { CAM_FUNC_NORM1, 10, D_8011B2F4 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011B31C }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A748 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011B348 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011B368 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011B384 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011B3A0 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetLiftBeanModes[] = { + { CAM_FUNC_NORM1, 10, D_8011B3C8 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011B3F0 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A748 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011B41C }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011B43C }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011B458 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011B474 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetScene0Modes[] = { + { CAM_FUNC_SPEC9, 3, sSetScn0ModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetScene1Modes[] = { + { CAM_FUNC_UNIQ2, 4, D_8011B4A8 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetHidan1Modes[] = { + { CAM_FUNC_SPEC7, 1, D_8011B20C }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetHidan2Modes[] = { + { CAM_FUNC_SPEC4, 1, D_8011B2B0 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetMori2Modes[] = { + { CAM_FUNC_UNIQ5, 1, D_8011B2B0 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetMori3Modes[] = { + { CAM_FUNC_DEMO6, 1, D_8011B2B0 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetTakoModes[] = { + { CAM_FUNC_NORM1, 10, D_8011B4B8 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A8C4 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A8F0 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011B4E0 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A994 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A778 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A9B8 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A954 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A9F8 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011AA14 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A974 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A9DC }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011B510 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetSpot05AModes[] = { + { CAM_FUNC_NORM1, 10, D_8011B538 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011B560 }, // CAM_MODE_TARGET + { 0, 0, NULL }, // CAM_MODE_FOLLOWTARGET + { 0, 0, NULL }, // CAM_MODE_TALK + { CAM_FUNC_PARA1, 11, D_8011B58C }, // CAM_MODE_BATTLE + { CAM_FUNC_NORM1, 10, D_8011B5B8 }, // CAM_MODE_CLIMB +}; + +CameraMode sCamSetSpot05BModes[] = { + { CAM_FUNC_NORM1, 10, D_8011B5E0 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011B608 }, // CAM_MODE_TARGET + { 0, 0, NULL }, // CAM_MODE_FOLLOWTARGET + { 0, 0, NULL }, // CAM_MODE_TALK + { CAM_FUNC_PARA1, 11, D_8011B634 }, // CAM_MODE_BATTLE + { CAM_FUNC_NORM1, 10, D_8011B660 }, // CAM_MODE_CLIMB +}; + +CameraMode sCamSetHidan3Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011B688 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011B6B0 }, // CAM_MODE_TARGET + { 0, 0, NULL }, // CAM_MODE_FOLLOWTARGET + { 0, 0, NULL }, // CAM_MODE_TALK + { CAM_FUNC_PARA1, 11, D_8011B6DC }, // CAM_MODE_BATTLE + { CAM_FUNC_NORM1, 10, D_8011B708 }, // CAM_MODE_CLIMB +}; + +CameraMode sCamSetItem2Modes[] = { + { CAM_FUNC_KEEP4, 9, D_8011B730 }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetCirc6Modes[] = { + { CAM_FUNC_SPEC0, 2, sSetCirc6ModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetNorm2Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011B75C }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A748 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetFishingModes[] = { + { CAM_FUNC_NORM1, 10, D_8011B784 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011B7AC }, // CAM_MODE_TARGET + { CAM_FUNC_BATT1, 12, D_8011B7D8 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011B808 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011B7D8 }, // CAM_MODE_BATTLE + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011B838 }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_BOWARROW + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_BOOMERANG + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011B85C }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011B89C }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011B8B8 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011B87C }, // CAM_MODE_FREEFALL +}; + +CameraMode sCamSetDemoCModes[] = { + { CAM_FUNC_UNIQ9, 1, sSetDemoCModeNormVals }, // CAM_MODE_NORMAL +}; + +CameraMode sCamSetUOFiberModes[] = { + { CAM_FUNC_NORM1, 10, D_8011B8D8 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011B900 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetDungeon2Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011B930 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011B958 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A8F0 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, sSetDung2ModeBattVals }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011B9F4 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A778 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011BA18 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011B9B4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011BA3C }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011BA58 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011B9D4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011BA74 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011BA9C }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetTeppenModes[] = { + { CAM_FUNC_NORM1, 10, D_8011BAC8 }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011BAF0 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011BB24 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A458 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraMode sCamSetCirc7Modes[] = { + { CAM_FUNC_FIXD4, 5, D_8011B1F8 }, // CAM_MODE_NORMAL + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_TARGET + { CAM_FUNC_FIXD4, 5, D_8011B1F8 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011A428 }, // CAM_MODE_TALK + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_BATTLE + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_NONE, 0, NULL }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT +}; + +CameraMode sCamSetNorm4Modes[] = { + { CAM_FUNC_NORM1, 10, D_8011B75C }, // CAM_MODE_NORMAL + { CAM_FUNC_PARA1, 11, D_8011A3C8 }, // CAM_MODE_TARGET + { CAM_FUNC_KEEP1, 13, D_8011A3F4 }, // CAM_MODE_FOLLOWTARGET + { CAM_FUNC_KEEP3, 12, D_8011BB54 }, // CAM_MODE_TALK + { CAM_FUNC_BATT1, 12, D_8011A748 }, // CAM_MODE_BATTLE + { CAM_FUNC_JUMP2, 9, D_8011A488 }, // CAM_MODE_CLIMB + { CAM_FUNC_SUBJ3, 9, D_8011A4AC }, // CAM_MODE_FIRSTPERSON + { CAM_FUNC_SUBJ3, 9, D_8011A4D0 }, // CAM_MODE_BOWARROW + { CAM_FUNC_SUBJ3, 9, D_8011A4F4 }, // CAM_MODE_BOWARROWZ + { CAM_FUNC_SPEC5, 8, D_8011A518 }, // CAM_MODE_FOOKSHOT + { CAM_FUNC_SUBJ3, 9, D_8011A538 }, // CAM_MODE_BOOMERANG + { CAM_FUNC_SUBJ3, 9, D_8011A55C }, // CAM_MODE_SLINGSHOT + { CAM_FUNC_JUMP2, 9, D_8011A580 }, // CAM_MODE_CLIMBZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_JUMP + { CAM_FUNC_UNIQ1, 7, D_8011A5C4 }, // CAM_MODE_HANG + { CAM_FUNC_UNIQ1, 7, D_8011A5E0 }, // CAM_MODE_HANGZ + { CAM_FUNC_JUMP1, 8, D_8011A5A4 }, // CAM_MODE_FREEFALL + { CAM_FUNC_BATT4, 7, D_8011A61C }, // CAM_MODE_CHARGE + { CAM_FUNC_NORM1, 10, D_8011A638 }, // CAM_MODE_STILL + { CAM_FUNC_PARA1, 11, D_8011A660 }, // CAM_MODE_PUSHPULL + { CAM_FUNC_KEEP1, 13, D_8011A68C }, // CAM_MODE_BOOMFOLLLOW +}; + +CameraSetting sCameraSettings[] = { + { { 0x00000000 }, NULL }, // CAM_SET_NONE + { { 0x051FFFFF }, sCamSetNorm0Modes }, // CAM_SET_NORMAL0 + { { 0x051FFFFF }, sCamSetNorm1Modes }, // CAM_SET_NORMAL1 + { { 0x051FFFFF }, sCamSetDungeon0Modes }, // CAM_SET_DUNGEON0 + { { 0x051FFFFF }, sCamSetDungeon1Modes }, // CAM_SET_DUNGEON1 + { { 0x050FF7FF }, sCamSetNorm3Modes }, // CAM_SET_NORMAL3 + { { 0x8500018F }, sCamSetHorse0Modes }, // CAM_SET_HORSE0 + { { 0x051FFFFF }, sCamSetBossGomaModes }, // CAM_SET_BOSS_GOMA + { { 0x051FFFFF }, sCamSetBossDodoModes }, // CAM_SET_BOSS_DODO + { { 0x051FFFFF }, sCamSetBossBariModes }, // CAM_SET_BOSS_BARI + { { 0x051FFFFF }, sCamSetBossFGanonModes }, // CAM_SET_BOSS_FGANON + { { 0x051FFFFF }, sCamSetBossBalModes }, // CAM_SET_BOSS_BAL + { { 0x051FFFFF }, sCamSetBossShadesModes }, // CAM_SET_BOSS_SHADES + { { 0x051FFFFF }, sCamSetBossMofaModes }, // CAM_SET_BOSS_MOFA + { { 0x051FFFFF }, sCamSetBossTwin0Modes }, // CAM_SET_TWIN0 + { { 0x051FFFFF }, sCamSetBossTwin1Modes }, // CAM_SET_TWIN1 + { { 0x051FFFFF }, sCamSetBossGanon1Modes }, // CAM_SET_BOSS_GANON1 + { { 0x051FFFFF }, sCamSetBossGanon2Modes }, // CAM_SET_BOSS_GANON2 + { { 0x851FFFFF }, sCamSetTower0Modes }, // CAM_SET_TOWER0 + { { 0x851FFFFF }, sCamSetTower1Modes }, // CAM_SET_TOWER1 + { { 0x8500000D }, sCamSetFixed0Modes }, // CAM_SET_FIXED0 + { { 0x85000001 }, sCamSetFixed1Modes }, // CAM_SET_FIXED1 + { { 0x85000001 }, sCamSetCirc0Modes }, // CAM_SET_CIRCLE0 + { { 0x85000001 }, sCamSetCirc2Modes }, // CAM_SET_CIRCLE2 + { { 0x851E1FFF }, sCamSetCirc3Modes }, // CAM_SET_CIRCLE3 + { { 0x8C00000D }, sCamSetPreRend0Modes }, // CAM_SET_PREREND0 + { { 0x8C00000D }, sCamSetPreRend1Modes }, // CAM_SET_PREREND1 + { { 0x8C000001 }, sCamSetPreRend3Modes }, // CAM_SET_PREREND3 + { { 0xC5000001 }, sCamSetDoor0Modes }, // CAM_SET_DOOR0 + { { 0xC5000003 }, sCamSetDoorCModes }, // CAM_SET_DOORC + { { 0xC5000001 }, sCamSetRail3Modes }, // CAM_SET_RAIL3 + { { 0xC5000001 }, sCamSetStart0Modes }, // CAM_SET_START0 + { { 0xC5000001 }, sCamSetStart1Modes }, // CAM_SET_START1 + { { 0x05000001 }, sCamSetFree0Modes }, // CAM_SET_FREE0 + { { 0x05000001 }, sCamSetFree1Modes }, // CAM_SET_FREE2 + { { 0x85000001 }, sCamSetCirc4Modes }, // CAM_SET_CIRCLE4 + { { 0x05000003 }, sCamSetCirc5Modes }, // CAM_SET_CIRCLE5 + { { 0xCE000001 }, sCamSetDemo0Modes }, // CAM_SET_DEMO0 + { { 0x4E000001 }, sCamSetDemo1Modes }, // CAM_SET_DEMO1 + { { 0x05000009 }, sCamSetMori1Modes }, // CAM_SET_MORI1 + { { 0x45000001 }, sCamSetItem0Modes }, // CAM_SET_ITEM0 + { { 0x45000001 }, sCamSetItem1Modes }, // CAM_SET_ITEM1 + { { 0x45000001 }, sCamSetDemo3Modes }, // CAM_SET_DEMO3 + { { 0x45000001 }, sCamSetDemo4Modes }, // CAM_SET_DEMO4 + { { 0x451FFFFF }, sCamSetUFOBeanModes }, // CAM_SET_UFOBEAN + { { 0x451FFFFF }, sCamSetLiftBeanModes }, // CAM_SET_LIFTBEAN + { { 0xC5000001 }, sCamSetScene0Modes }, // CAM_SET_SCENE0 + { { 0x45000001 }, sCamSetScene1Modes }, // CAM_SET_SCENE1 + { { 0x05000001 }, sCamSetHidan1Modes }, // CAM_SET_HIDAN1 + { { 0x45000001 }, sCamSetHidan2Modes }, // CAM_SET_HIDAN2 + { { 0x45000001 }, sCamSetMori2Modes }, // CAM_SET_MORI2 + { { 0x45000001 }, sCamSetMori3Modes }, // CAM_SET_MORI3 + { { 0x451FFFFF }, sCamSetTakoModes }, // CAM_SET_TAKO + { { 0x05000033 }, sCamSetSpot05AModes }, // CAM_SET_SPOT05A + { { 0x05000033 }, sCamSetSpot05BModes }, // CAM_SET_SPOT05B + { { 0x05000033 }, sCamSetHidan3Modes }, // CAM_SET_HIDAN3 + { { 0x4A000001 }, sCamSetItem2Modes }, // CAM_SET_ITEM2 + { { 0x05000001 }, sCamSetCirc6Modes }, // CAM_SET_CIRCLE6 + { { 0x051FFFFF }, sCamSetNorm2Modes }, // CAM_SET_NORMAL2 + { { 0x0501E05F }, sCamSetFishingModes }, // CAM_SET_FISHING + { { 0x45000001 }, sCamSetDemoCModes }, // CAM_SET_DEMOC + { { 0x051FFFFF }, sCamSetUOFiberModes }, // CAM_SET_UO_FIBER + { { 0x051FFFFF }, sCamSetDungeon2Modes }, // CAM_SET_DUNGEON2 + { { 0x051FFFFF }, sCamSetTeppenModes }, // CAM_SET_TEPPEN + { { 0xC5000ECD }, sCamSetCirc7Modes }, // CAM_SET_CIRCLE7 + { { 0x051FFFFF }, sCamSetNorm4Modes }, // CAM_SET_NORMAL4 +}; + +s32 Camera_Normal0(Camera* camera); +s32 Camera_Normal1(Camera* camera); +s32 Camera_Normal2(Camera* camera); +s32 Camera_Normal3(Camera* camera); +s32 Camera_Normal4(Camera* camera); +s32 Camera_Parallel0(Camera* camera); +s32 Camera_Parallel1(Camera* camera); +s32 Camera_Parallel2(Camera* camera); +s32 Camera_Parallel3(Camera* camera); +s32 Camera_Parallel4(Camera* camera); +s32 Camera_KeepOn0(Camera* camera); +s32 Camera_KeepOn1(Camera* camera); +s32 Camera_KeepOn2(Camera* camera); +s32 Camera_KeepOn3(Camera* camera); +s32 Camera_KeepOn4(Camera* camera); +s32 Camera_Subj0(Camera* camera); +s32 Camera_Subj1(Camera* camera); +s32 Camera_Subj2(Camera* camera); +s32 Camera_Subj3(Camera* camera); +s32 Camera_Subj4(Camera* camera); +s32 Camera_Jump0(Camera* camera); +s32 Camera_Jump1(Camera* camera); +s32 Camera_Jump2(Camera* camera); +s32 Camera_Jump3(Camera* camera); +s32 Camera_Jump4(Camera* camera); +s32 Camera_Battle0(Camera* camera); +s32 Camera_Battle1(Camera* camera); +s32 Camera_Battle2(Camera* camera); +s32 Camera_Battle3(Camera* camera); +s32 Camera_Battle4(Camera* camera); +s32 Camera_Fixed0(Camera* camera); +s32 Camera_Fixed1(Camera* camera); +s32 Camera_Fixed2(Camera* camera); +s32 Camera_Fixed3(Camera* camera); +s32 Camera_Fixed4(Camera* camera); +s32 Camera_Data0(Camera* camera); +s32 Camera_Data1(Camera* camera); +s32 Camera_Data2(Camera* camera); +s32 Camera_Data3(Camera* camera); +s32 Camera_Data4(Camera* camera); +s32 Camera_Unique0(Camera* camera); +s32 Camera_Unique1(Camera* camera); +s32 Camera_Unique2(Camera* camera); +s32 Camera_Unique3(Camera* camera); +s32 Camera_Unique4(Camera* camera); +s32 Camera_Unique5(Camera* camera); +s32 Camera_Unique6(Camera* camera); +s32 Camera_Unique7(Camera* camera); +s32 Camera_Unique8(Camera* camera); +s32 Camera_Unique9(Camera* camera); +s32 Camera_Demo0(Camera* camera); +s32 Camera_Demo1(Camera* camera); +s32 Camera_Demo2(Camera* camera); +s32 Camera_Demo3(Camera* camera); +s32 Camera_Demo4(Camera* camera); +s32 Camera_Demo5(Camera* camera); +s32 Camera_Demo6(Camera* camera); +s32 Camera_Demo7(Camera* camera); +s32 Camera_Demo8(Camera* camera); +s32 Camera_Demo9(Camera* camera); +s32 Camera_Special0(Camera* camera); +s32 Camera_Special1(Camera* camera); +s32 Camera_Special2(Camera* camera); +s32 Camera_Special3(Camera* camera); +s32 Camera_Special4(Camera* camera); +s32 Camera_Special5(Camera* camera); +s32 Camera_Special6(Camera* camera); +s32 Camera_Special7(Camera* camera); +s32 Camera_Special8(Camera* camera); +s32 Camera_Special9(Camera* camera); + +s32 (*sCameraFunctions[])(Camera*) = { + NULL, + Camera_Normal0, + Camera_Normal1, + Camera_Normal2, + Camera_Normal3, + Camera_Normal4, + Camera_Parallel0, + Camera_Parallel1, + Camera_Parallel2, + Camera_Parallel3, + Camera_Parallel4, + Camera_KeepOn0, + Camera_KeepOn1, + Camera_KeepOn2, + Camera_KeepOn3, + Camera_KeepOn4, + Camera_Subj0, + Camera_Subj1, + Camera_Subj2, + Camera_Subj3, + Camera_Subj4, + Camera_Jump0, + Camera_Jump1, + Camera_Jump2, + Camera_Jump3, + Camera_Jump4, + Camera_Battle0, + Camera_Battle1, + Camera_Battle2, + Camera_Battle3, + Camera_Battle4, + Camera_Fixed0, + Camera_Fixed1, + Camera_Fixed2, + Camera_Fixed3, + Camera_Fixed4, + Camera_Data0, + Camera_Data1, + Camera_Data2, + Camera_Data3, + Camera_Data4, + Camera_Unique0, + Camera_Unique1, + Camera_Unique2, + Camera_Unique3, + Camera_Unique4, + Camera_Unique5, + Camera_Unique6, + Camera_Unique7, + Camera_Unique8, + Camera_Unique9, + Camera_Demo0, + Camera_Demo1, + Camera_Demo2, + Camera_Demo3, + Camera_Demo4, + Camera_Demo5, + Camera_Demo6, + Camera_Demo7, + Camera_Demo8, + Camera_Demo9, + Camera_Special0, + Camera_Special1, + Camera_Special2, + Camera_Special3, + Camera_Special4, + Camera_Special5, + Camera_Special6, + Camera_Special7, + Camera_Special8, + Camera_Special9, +}; + +s32 sInitRegs = 1; + +s32 gDbgCamEnabled = 0; +s32 sDbgModeIdx = -1; +s16 sNextUID = 0; + +s32 sCameraInterfaceFlags = 1; + +s32 sCameraInterfaceAlpha = 0x02; +s32 sCameraShrinkWindowVal = 0x20; +s32 D_8011D3AC = -1; + +s16 D_8011D3B0[] = { + 0x0AAA, 0xF556, 0x1555, 0xEAAB, 0x2AAA, 0xD556, 0x3FFF, 0xC001, 0x5555, 0xAAAB, 0x6AAA, 0x9556, 0x7FFF, 0x0000, +}; + +s16 D_8011D3CC[] = { + 0x0000, 0x02C6, 0x058C, 0x0000, 0x0000, 0xFD3A, 0x0000, 0x0852, 0x0000, 0x0000, 0x0B18, 0x02C6, 0xFA74, 0x0000, +}; + +s32 sUpdateCameraDirection = 0; +s32 D_8011D3EC = 0; +s32 D_8011D3F0 = 0; + +s32 sDemo5PrevAction12Frame = -16; + +char sCameraFunctionNames[][8] = { + "NONE ", "NORM0()", "NORM1()", "NORM2()", "NORM3()", "NORM4()", "PARA0()", "PARA1()", "PARA2()", "PARA3()", + "PARA4()", "KEEP0()", "KEEP1()", "KEEP2()", "KEEP3()", "KEEP4()", "SUBJ0()", "SUBJ1()", "SUBJ2()", "SUBJ3()", + "SUBJ4()", "JUMP0()", "JUMP1()", "JUMP2()", "JUMP3()", "JUMP4()", "BATT0()", "BATT1()", "BATT2()", "BATT3()", + "BATT4()", "FIXD0()", "FIXD1()", "FIXD2()", "FIXD3()", "FIXD4()", "DATA0()", "DATA1()", "DATA2()", "DATA3()", + "DATA4()", "UNIQ0()", "UNIQ1()", "UNIQ2()", "UNIQ3()", "UNIQ4()", "UNIQ5()", "UNIQ6()", "UNIQ7()", "UNIQ8()", + "UNIQ9()", "DEMO0()", "DEMO1()", "DEMO2()", "DEMO3()", "DEMO4()", "DEMO5()", "DEMO6()", "DEMO7()", "DEMO8()", + "DEMO9()", "SPEC0()", "SPEC1()", "SPEC2()", "SPEC3()", "SPEC4()", "SPEC5()", "SPEC6()", "SPEC7()", "SPEC8()", + "SPEC9()", "", "", "", "", "", +}; + +VecSph D_8011D658[] = { + { 50.0f, 0xEE3A, 0xD558 }, + { 75.0f, 0x0000, 0x8008 }, + { 80.0f, 0xEE3A, 0x8008 }, + { 15.0f, 0xEE3A, 0x8008 }, +}; + +Vec3f D_8011D678[] = { + { 0.0f, 40.0f, 20.0f }, + { 0.0f, 40.0f, 0.0f }, + { 0.0f, 3.0f, -3.0f }, + { 0.0f, 3.0f, -3.0 }, +}; + +/******************************************************* + * OnePoint initalization values for Demo5 + ********************************************************/ +s32 sDemo5PrevSfxFrame = -200; + +// target is player, far from eye +OnePointDemoFull D_8011D6AC[] = { + { // initflags & 0x00FF (at): 2, atTarget is view lookAt + atInit + // initFlags & 0xFF00 (eye): none + // action: 15, copy at, eye, roll, fov to camera + // result: eye remains in the same locaiton, at is View's lookAt + 0x8F, + 0xFF, + 0x0002, + 0x0001, + 0x0000, + 60.0f, + 1.0f, + { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f } }, + { // initFlags & 0x00FF (at): 3, atTarget is camera's current at + atInit + // initFlags & 0xFF00 (eye): 3, eyeTarget is the camera's current eye + eyeInit + // action: interplate eye and at. + // result: eye and at's y interpolate to become +20 from their current location. + 0x81, + 0xFF, + 0x0303, + 0x0013, + 0x0000, + 45.0f, + 1.0f, + { 0.0f, 20.0f, 0.0f }, + { 0.0f, 20.0f, 0.0f } }, + { // initFlags & 0x00FF (at): 0 none + // initFlags & 0xFF00 (eye): 0 none + // action: 18, copy this camera to default camera. + 0x12, + 0xFF, + 0x0000, + 0x0001, + 0x0000, + 60.0f, + 1.0f, + { -1.0f, -1.0f, -1.0f }, + { -1.0f, -1.0f, -1.0f } }, +}; + +// target is player close to current eye +OnePointDemoFull D_8011D724[] = { + { 0x8F, 0xFF, 0x2424, 0x0001, 0x0000, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 10.0f, -20.0f } }, + { 0x81, 0xFF, 0x2121, 0x0013, 0x0000, 50.0f, 1.0f, { 0.0f, -10.0f, 0.0f }, { 0.0f, 0.0f, 60.0f } }, + { 0x12, 0xFF, 0x0000, 0x0001, 0x0000, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } }, +}; + +// target is close to player +OnePointDemoFull D_8011D79C[] = { + { 0xCF, 0xFF, 0x0002, 0x0001, 0x0000, 60.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }, + { 0xC1, 0xFF, 0x0303, 0x0013, 0x0000, 45.0f, 1.0f, { 0.0f, -20.0f, 0.0f }, { 0.0f, -10.0f, 5.0f } }, + { + 0xC1, + 0xFF, + 0x0303, + 0x0009, + 0x0000, + 60.0f, + 1.0f, + { 0.0f, 10.0f, 0.0f }, + { 0.0f, 10.0f, 0.0f }, + }, + { 0x12, 0xFF, 0x0000, 0x0001, 0x0000, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } }, +}; + +// target is within 300 units of eye, and player is within 30 units of eye +OnePointDemoFull D_8011D83C[] = { + { 0x83, 0xFF, 0x2141, 0x0014, 0x0000, 45.0f, 0.2f, { 0.0f, 0.0f, 10.0f }, { 0.0f, 0.0f, 10.0f } }, + { 0x12, 0xFF, 0x0000, 0x0001, 0x0000, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } }, +}; + +// target is within 700 units of eye, angle between player/eye and target/eye is less than +// 76.9 degrees. The x/y coordinates of the target on screen is between (21, 41) and (300, 200), +// and the player is farther than 30 units of the eye +OnePointDemoFull D_8011D88C[] = { + { 0x81, 0xFF, 0x0303, 0x0014, 0x0000, 45.0f, 1.0f, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }, + { 0x12, 0xFF, 0x0000, 0x0001, 0x0000, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } }, +}; + +// same as above, but the target is NOT within the screen area. +OnePointDemoFull D_8011D8DC[] = { + { 0x8F, 0xFF, 0x0404, 0x0014, 0x0001, 50.0f, 1.0f, { 0.0f, 5.0f, 10.0f }, { 0.0f, 10.0f, -80.0f } }, + { 0x82, 0xFF, 0x2121, 0x0005, 0x0000, 60.0f, 1.0f, { 0.0f, 5.0f, 0.0f }, { 5.0f, 5.0f, -200.0f } }, + { 0x12, 0xFF, 0x0000, 0x0001, 0x0000, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } }, +}; + +// target is a door. +OnePointDemoFull D_8011D954[] = { + { 0x0F, 0xFF, 0xC1C1, 0x0014, 0x0000, 60.0f, 1.0f, { 0.0f, 0.0f, 50.0f }, { 0.0f, 0.0f, 250.0f } }, + { 0x83, 0xFF, 0x05B1, 0x0005, 0x0000, 60.0f, 0.1f, { 0.0f, 10.0f, 50.0f }, { 0.0f, 10.0f, 100.0f } }, + { 0x82, 0xFF, 0x2121, 0x0005, 0x0002, 60.0f, 1.0f, { 0.0f, 10.0f, 0.0f }, { 0.0f, 20.0f, -150.0f } }, + { 0x12, 0xFF, 0x0000, 0x0001, 0x0000, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } }, +}; + +// otherwise +OnePointDemoFull D_8011D9F4[] = { + { 0x8F, 0xFF, 0x0504, 0x0014, 0x0002, 60.0f, 1.0f, { 0.0f, 5.0f, 50.0f }, { 0.0f, 20.0f, 300.0f } }, + { 0x82, 0xFF, 0x2121, 0x0005, 0x0002, 60.0f, 1.0f, { 0.0f, 10.0f, 0.0f }, { 0.0f, 20.0f, -150.0f } }, + { 0x12, 0xFF, 0x0000, 0x0001, 0x0000, 60.0f, 1.0f, { -1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f } }, +}; + +Vec3f D_8011DA6C[] = { + { 3050.0f, 700.0f, 0.0f }, { 1755.0f, 3415.0f, -380.0f }, { -3120.0f, 3160.0f, 245.0f }, { 0.0f, -10.0f, 240.0f } +}; + +Vec3f D_8011DA9C[] = { + { 3160.0f, 2150.0f, 0.0f }, + { 1515.0f, 4130.0f, -835.0f }, + { -3040.0f, 4135.0f, 230.0f }, + { -50.0f, 600.0f, -75.0f }, +}; + +f32 D_8011DACC[] = { 1570.0f, 3680.0f, 3700.0f, 395.0f }; + +f32 D_8011DADC[] = { 320.0f, 320.0f, 320.0f, 0.0f }; + +s16 D_8011DAEC[] = { -2000, -1000, 0, 0, 0, 0, 0, 0 }; + +s16 D_8011DAFC[] = { + CAM_SET_NORMAL0, CAM_SET_NORMAL1, CAM_SET_NORMAL2, CAM_SET_DUNGEON0, CAM_SET_DUNGEON1, CAM_SET_DUNGEON2, +}; + +GlobalContext* D_8015BD7C; +DBCamera D_8015BD80; +CollisionPoly* playerFloorPoly; diff --git a/src/code/z_demo.c b/src/code/z_demo.c index 944203ffb..93b2bf85b 100644 --- a/src/code/z_demo.c +++ b/src/code/z_demo.c @@ -1,4 +1,5 @@ #include "global.h" +#include "z64camera.h" u16 D_8011E1C0 = 0; u16 D_8011E1C4 = 0; @@ -104,7 +105,7 @@ void func_800645A0(GlobalContext* globalCtx, CutsceneContext* csCtx) { } if (CHECK_BTN_ALL(pad1->press.button, BTN_DUP) && (csCtx->state == CS_STATE_IDLE) && - (gSaveContext.sceneSetupIndex >= 4) && (D_8011D394 == 0)) { + (gSaveContext.sceneSetupIndex >= 4) && (gDbgCamEnabled == 0)) { D_8015FCC8 = 1; gSaveContext.cutsceneIndex = 0xFFFD; gSaveContext.cutsceneTrigger = 1; @@ -1288,12 +1289,12 @@ s32 Cutscene_Command_CameraPositions(GlobalContext* globalCtx, CutsceneContext* if (csCtx->unk_1A != 0) { csCtx->unk_18 = cmdBase->startFrame; if (D_8015FCC8 != 0) { - func_800C0874(globalCtx, csCtx->unk_14, 0x25); - Gameplay_ChangeCameraStatus(globalCtx, D_8015FCC6, 1); - Gameplay_ChangeCameraStatus(globalCtx, csCtx->unk_14, 7); - func_8005AC60(Gameplay_GetCamera(globalCtx, csCtx->unk_14)); - func_8005AC6C(Gameplay_GetCamera(globalCtx, csCtx->unk_14), csCtx->cameraFocus, csCtx->cameraPosition, - PLAYER, relativeToLink); + Gameplay_CameraChangeSetting(globalCtx, csCtx->unk_14, CAM_SET_DEMO0); + Gameplay_ChangeCameraStatus(globalCtx, D_8015FCC6, CAM_STAT_WAIT); + Gameplay_ChangeCameraStatus(globalCtx, csCtx->unk_14, CAM_STAT_ACTIVE); + Camera_ResetAnim(Gameplay_GetCamera(globalCtx, csCtx->unk_14)); + Camera_SetCSParams(Gameplay_GetCamera(globalCtx, csCtx->unk_14), csCtx->cameraFocus, + csCtx->cameraPosition, PLAYER, relativeToLink); } } } @@ -1325,12 +1326,12 @@ s32 Cutscene_Command_CameraFocus(GlobalContext* globalCtx, CutsceneContext* csCt if (csCtx->unk_1B != 0) { D_8015FCC0 = cmdBase->startFrame; if (D_8015FCC8 != 0) { - func_800C0874(globalCtx, csCtx->unk_14, 0x25); - Gameplay_ChangeCameraStatus(globalCtx, D_8015FCC6, 1); - Gameplay_ChangeCameraStatus(globalCtx, csCtx->unk_14, 7); - func_8005AC60(Gameplay_GetCamera(globalCtx, csCtx->unk_14)); - func_8005AC6C(Gameplay_GetCamera(globalCtx, csCtx->unk_14), csCtx->cameraFocus, csCtx->cameraPosition, - PLAYER, relativeToLink); + Gameplay_CameraChangeSetting(globalCtx, csCtx->unk_14, CAM_SET_DEMO0); + Gameplay_ChangeCameraStatus(globalCtx, D_8015FCC6, CAM_STAT_WAIT); + Gameplay_ChangeCameraStatus(globalCtx, csCtx->unk_14, CAM_STAT_ACTIVE); + Camera_ResetAnim(Gameplay_GetCamera(globalCtx, csCtx->unk_14)); + Camera_SetCSParams(Gameplay_GetCamera(globalCtx, csCtx->unk_14), csCtx->cameraFocus, + csCtx->cameraPosition, PLAYER, relativeToLink); } } } @@ -1367,9 +1368,9 @@ s32 Cutscene_Command_07(GlobalContext* globalCtx, CutsceneContext* csCtx, u8* cm if (D_8015FCC8 != 0) { sp2C = Gameplay_GetCamera(globalCtx, csCtx->unk_14); sp2C->player = NULL; - Gameplay_ChangeCameraStatus(globalCtx, 0, 1); - Gameplay_ChangeCameraStatus(globalCtx, csCtx->unk_14, 7); - func_800C0874(globalCtx, csCtx->unk_14, 0x21); + Gameplay_ChangeCameraStatus(globalCtx, 0, CAM_STAT_WAIT); + Gameplay_ChangeCameraStatus(globalCtx, csCtx->unk_14, CAM_STAT_ACTIVE); + Gameplay_CameraChangeSetting(globalCtx, csCtx->unk_14, CAM_SET_FREE0); sp28 = csCtx->cameraFocus->cameraRoll * 1.40625f; Camera_SetParam(sp2C, 64, &sp28); sp3C.x = csCtx->cameraFocus->pos.x; @@ -1378,8 +1379,8 @@ s32 Cutscene_Command_07(GlobalContext* globalCtx, CutsceneContext* csCtx, u8* cm sp30.x = csCtx->cameraPosition->pos.x; sp30.y = csCtx->cameraPosition->pos.y; sp30.z = csCtx->cameraPosition->pos.z; - func_800C04D8(globalCtx, csCtx->unk_14, &sp3C, &sp30); - func_800C0704(globalCtx, csCtx->unk_14, csCtx->cameraPosition->viewAngle); + Gameplay_CameraSetAtEye(globalCtx, csCtx->unk_14, &sp3C, &sp30); + Gameplay_CameraSetFov(globalCtx, csCtx->unk_14, csCtx->cameraPosition->viewAngle); } } } @@ -1410,17 +1411,17 @@ s32 Cutscene_Command_08(GlobalContext* globalCtx, CutsceneContext* csCtx, u8* cm if (D_8015FCC8 != 0) { sp2C = Gameplay_GetCamera(globalCtx, csCtx->unk_14); sp2C->player = NULL; - Gameplay_ChangeCameraStatus(globalCtx, 0, 1); - Gameplay_ChangeCameraStatus(globalCtx, csCtx->unk_14, 7); - func_800C0874(globalCtx, csCtx->unk_14, 0x21); + Gameplay_ChangeCameraStatus(globalCtx, 0, CAM_STAT_WAIT); + Gameplay_ChangeCameraStatus(globalCtx, csCtx->unk_14, CAM_STAT_ACTIVE); + Gameplay_CameraChangeSetting(globalCtx, csCtx->unk_14, CAM_SET_FREE0); sp3C.x = csCtx->cameraFocus->pos.x; sp3C.y = csCtx->cameraFocus->pos.y; sp3C.z = csCtx->cameraFocus->pos.z; sp30.x = csCtx->cameraPosition->pos.x; sp30.y = csCtx->cameraPosition->pos.y; sp30.z = csCtx->cameraPosition->pos.z; - func_800C04D8(globalCtx, csCtx->unk_14, &sp3C, &sp30); - func_800C0704(globalCtx, csCtx->unk_14, csCtx->cameraPosition->viewAngle); + Gameplay_CameraSetAtEye(globalCtx, csCtx->unk_14, &sp3C, &sp30); + Gameplay_CameraSetFov(globalCtx, csCtx->unk_14, csCtx->cameraPosition->viewAngle); } } } @@ -1909,7 +1910,7 @@ void func_80068DC0(GlobalContext* globalCtx, CutsceneContext* csCtx) { case 0x028E: case 0x0292: case 0x0476: - func_800C078C(globalCtx, D_8015FCC6, csCtx->unk_14); + Gameplay_CopyCamera(globalCtx, D_8015FCC6, csCtx->unk_14); } Gameplay_ChangeCameraStatus(globalCtx, D_8015FCC6, 7); diff --git a/src/code/z_horse.c b/src/code/z_horse.c index 3d02e175e..076d69d2b 100644 --- a/src/code/z_horse.c +++ b/src/code/z_horse.c @@ -246,7 +246,7 @@ void func_8006D684(GlobalContext* globalCtx, Player* player) { sp54.y = player->actor.posRot.pos.y + 100.0f; sp54.z = player->actor.posRot.pos.z; - func_800C04D8(globalCtx, globalCtx->activeCamera, &player->actor.posRot.pos, &sp54); + Gameplay_CameraSetAtEye(globalCtx, globalCtx->activeCamera, &player->actor.posRot.pos, &sp54); } else { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HORSE, D_8011F9B8[i].pos.x, D_8011F9B8[i].pos.y, D_8011F9B8[i].pos.z, 0, D_8011F9B8[i].angle, 0, diff --git a/src/code/z_olib.c b/src/code/z_olib.c index b4b989929..92d66a2d3 100644 --- a/src/code/z_olib.c +++ b/src/code/z_olib.c @@ -75,19 +75,19 @@ Vec3f* OLib_Vec3fDistNormalize(Vec3f* dest, Vec3f* a, Vec3f* b) { */ Vec3f* OLib_VecSphToVec3f(Vec3f* dest, VecSph* sph) { Vec3f v; - f32 sinPhi; - f32 cosPhi; - f32 sinTheta; - f32 cosTheta; - - cosPhi = Math_Coss(sph->pitch); - cosTheta = Math_Coss(sph->yaw); - sinPhi = Math_Sins(sph->pitch); - sinTheta = Math_Sins(sph->yaw); - - v.x = sph->r * sinPhi * sinTheta; - v.y = sph->r * cosPhi; - v.z = sph->r * sinPhi * cosTheta; + f32 sinPitch; + f32 cosPitch; + f32 sinYaw; + f32 cosYaw; + + cosPitch = Math_Coss(sph->pitch); + cosYaw = Math_Coss(sph->yaw); + sinPitch = Math_Sins(sph->pitch); + sinYaw = Math_Sins(sph->yaw); + + v.x = sph->r * sinPitch * sinYaw; + v.y = sph->r * cosPitch; + v.z = sph->r * sinPitch * cosYaw; *dest = v; diff --git a/src/code/z_onepointdemo.c b/src/code/z_onepointdemo.c index 176a11f7a..6ba2334d6 100644 --- a/src/code/z_onepointdemo.c +++ b/src/code/z_onepointdemo.c @@ -1,36 +1,30 @@ #include "global.h" -typedef struct { - /* 0x00 */ u32 unk_00; - /* 0x04 */ u32 unk_04; - /* 0x08 */ s16 unk_08; - /* 0x0A */ s16 unk_0A; -} struct_8007C820; - #pragma GLOBAL_ASM("asm/non_matchings/code/z_onepointdemo/func_8007C680.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_onepointdemo/func_8007C704.s") -void func_8007C76C(f32* pfParm1, s16* puParm2) { - puParm2[0] = pfParm1[0]; - puParm2[1] = pfParm1[1]; - puParm2[2] = pfParm1[2]; +void func_8007C76C(Vec3f* src, Vec3s* dst) { + dst->x = src->x; + dst->y = src->y; + dst->z = src->z; } #pragma GLOBAL_ASM("asm/non_matchings/code/z_onepointdemo/func_8007C7A8.s") -void func_8007C7F8(u32 uParm1, u32 uParm2) { - u8 auStack4[4]; - u8 auStack8[4]; +void func_8007C7F8(CollisionContext* colCtx, Vec3f* arg1) { + CollisionPoly* poly; + s32 bgId; - func_8003C940(uParm1, auStack4, auStack8, uParm2); + func_8003C940(colCtx, &poly, &bgId, arg1); } -void func_8007C820(struct_8007C820* puParm1, s16 uParm2, s16 uParm3, u32 uParm4, u32 param_5) { - puParm1->unk_00 = uParm4; - puParm1->unk_04 = param_5; - puParm1->unk_08 = uParm2; - puParm1->unk_0A = uParm3; +void func_8007C820(OnePointDemoCamera* onePointCamera, s16 actionParameters, s16 initTimer, + CutsceneCameraPoint* atPoints, CutsceneCameraPoint* eyePoints) { + onePointCamera->atPoints = atPoints; + onePointCamera->eyePoints = eyePoints; + onePointCamera->actionParameters = actionParameters; + onePointCamera->initTimer = initTimer; } #pragma GLOBAL_ASM("asm/non_matchings/code/z_onepointdemo/func_8007C850.s") diff --git a/src/code/z_play.c b/src/code/z_play.c index 2be93f95c..95d973dff 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -14,7 +14,7 @@ s16 D_801614C8; u64 D_801614D0[0xA00]; void func_800BC450(GlobalContext* globalCtx) { - func_8005A7A8(ACTIVE_CAM, globalCtx->unk_1242B - 1); + Camera_ChangeDataIdx(ACTIVE_CAM, globalCtx->unk_1242B - 1); } void func_800BC490(GlobalContext* globalCtx, s16 point) { @@ -223,12 +223,12 @@ void Gameplay_Init(GameState* thisx) { globalCtx->cameraPtrs[i] = NULL; } - func_80057C6C(&globalCtx->mainCamera, &globalCtx->view, &globalCtx->colCtx, globalCtx); - Camera_ChangeStatus(&globalCtx->mainCamera, 7); + Camera_Init(&globalCtx->mainCamera, &globalCtx->view, &globalCtx->colCtx, globalCtx); + Camera_ChangeStatus(&globalCtx->mainCamera, CAM_STAT_ACTIVE); for (i = 0; i < 3; i++) { - func_80057C6C(&globalCtx->subCameras[i], &globalCtx->view, &globalCtx->colCtx, globalCtx); - Camera_ChangeStatus(&globalCtx->subCameras[i], 0x100); + Camera_Init(&globalCtx->subCameras[i + 1], &globalCtx->view, &globalCtx->colCtx, globalCtx); + Camera_ChangeStatus(&globalCtx->subCameras[i + 1], 0x100); } globalCtx->cameraPtrs[0] = &globalCtx->mainCamera; @@ -385,13 +385,13 @@ void Gameplay_Init(GameState* thisx) { } player = PLAYER; - func_80058148(&globalCtx->mainCamera, player); - func_8005A444(&globalCtx->mainCamera, 0); + Camera_InitPlayerSettings(&globalCtx->mainCamera, player); + Camera_ChangeMode(&globalCtx->mainCamera, CAM_MODE_NORMAL); playerStartCamId = player->actor.params & 0xFF; if (playerStartCamId != 0xFF) { osSyncPrintf("player has start camera ID (" VT_FGCOL(BLUE) "%d" VT_RST ")\n", playerStartCamId); - func_8005A7A8(&globalCtx->mainCamera, playerStartCamId); + Camera_ChangeDataIdx(&globalCtx->mainCamera, playerStartCamId); } if (YREG(15) == 0x20) { @@ -1011,7 +1011,7 @@ void Gameplay_Update(GlobalContext* globalCtx) { LOG_NUM("1", 1, "../z_play.c", 3801); } - if ((sp80 == 0) || (D_8011D394 != 0)) { + if ((sp80 == 0) || (gDbgCamEnabled != 0)) { s32 i; // 0x54 s32 camIdx; Vec3s sp48; @@ -1028,12 +1028,12 @@ void Gameplay_Update(GlobalContext* globalCtx) { LOG_NUM("1", 1, "../z_play.c", 3809); } - func_800591EC(&sp48, globalCtx->cameraPtrs[i]); + Camera_Update(&sp48, globalCtx->cameraPtrs[i]); camIdx = globalCtx->nextCamera; } } - func_800591EC(&sp48, globalCtx->cameraPtrs[camIdx]); + Camera_Update(&sp48, globalCtx->cameraPtrs[camIdx]); if (1 && HREG(63)) { LOG_NUM("1", 1, "../z_play.c", 3814); @@ -1231,7 +1231,7 @@ void Gameplay_Draw(GlobalContext* globalCtx) { if (globalCtx->skyboxCtx.unk_140 != 0) { if (ACTIVE_CAM->setting != 0x19) { Vec3f sp74; - func_8005AFB4(&sp74, ACTIVE_CAM); + Camera_GetSkyboxOffset(&sp74, ACTIVE_CAM); SkyboxDraw_Draw(&globalCtx->skyboxCtx, gfxCtx, globalCtx->skyboxId, 0, globalCtx->view.eye.x + sp74.x, globalCtx->view.eye.y + sp74.y, globalCtx->view.eye.z + sp74.z); @@ -1313,7 +1313,7 @@ void Gameplay_Draw(GlobalContext* globalCtx) { if (globalCtx->view.unk_124 != 0) { Vec3s sp50; - func_800591EC(&sp50, ACTIVE_CAM); + Camera_Update(&sp50, ACTIVE_CAM); func_800AB944(&globalCtx->view); globalCtx->view.unk_124 = 0; if ((globalCtx->skyboxId != 0) && (globalCtx->skyboxId != 0x1D) && !globalCtx->envCtx.skyDisabled) { @@ -1322,7 +1322,7 @@ void Gameplay_Draw(GlobalContext* globalCtx) { } } - func_80059EC8(ACTIVE_CAM); + Camera_Finish(ACTIVE_CAM); CLOSE_DISPS(gfxCtx, "../z_play.c", 4508); } @@ -1533,8 +1533,8 @@ s16 Gameplay_CreateSubCamera(GlobalContext* globalCtx) { i); globalCtx->cameraPtrs[i] = &globalCtx->subCameras[i - 1]; - func_80057C6C(globalCtx->cameraPtrs[i], &globalCtx->view, &globalCtx->colCtx, globalCtx); - globalCtx->cameraPtrs[i]->unk_164 = i; + Camera_Init(globalCtx->cameraPtrs[i], &globalCtx->view, &globalCtx->colCtx, globalCtx); + globalCtx->cameraPtrs[i]->thisIdx = i; return i; } @@ -1589,94 +1589,94 @@ Camera* Gameplay_GetCamera(GlobalContext* globalCtx, s16 camId) { return globalCtx->cameraPtrs[camIdx]; } -s32 func_800C04D8(GlobalContext* globalCtx, s16 camId, Vec3f* arg2, Vec3f* arg3) { +s32 Gameplay_CameraSetAtEye(GlobalContext* globalCtx, s16 camId, Vec3f* at, Vec3f* eye) { s32 ret = 0; s16 camIdx = (camId == -1) ? globalCtx->activeCamera : camId; Camera* camera = globalCtx->cameraPtrs[camIdx]; Player* player; - ret |= Camera_SetParam(camera, 1, arg2); + ret |= Camera_SetParam(camera, 1, at); ret <<= 1; - ret |= Camera_SetParam(camera, 2, arg3); + ret |= Camera_SetParam(camera, 2, eye); - camera->dist = Math3D_Vec3f_DistXYZ(arg2, arg3); + camera->dist = Math3D_Vec3f_DistXYZ(at, eye); player = camera->player; if (player != NULL) { - camera->unk_E4.x = arg2->x - player->actor.posRot.pos.x; - camera->unk_E4.y = arg2->y - player->actor.posRot.pos.y; - camera->unk_E4.z = arg2->z - player->actor.posRot.pos.z; + camera->posOffset.x = at->x - player->actor.posRot.pos.x; + camera->posOffset.y = at->y - player->actor.posRot.pos.y; + camera->posOffset.z = at->z - player->actor.posRot.pos.z; } else { - camera->unk_E4.x = camera->unk_E4.y = camera->unk_E4.z = 0.0f; + camera->posOffset.x = camera->posOffset.y = camera->posOffset.z = 0.0f; } - camera->unk_100 = 0.01f; + camera->atLERPStepScale = 0.01f; return ret; } -s32 func_800C05E4(GlobalContext* globalCtx, s16 camId, Vec3f* arg2, Vec3f* arg3, Vec3f* arg4) { +s32 Gameplay_CameraSetAtEyeUp(GlobalContext* globalCtx, s16 camId, Vec3f* at, Vec3f* eye, Vec3f* up) { s32 ret = 0; s16 camIdx = (camId == -1) ? globalCtx->activeCamera : camId; Camera* camera = globalCtx->cameraPtrs[camIdx]; Player* player; - ret |= Camera_SetParam(camera, 1, arg2); + ret |= Camera_SetParam(camera, 1, at); ret <<= 1; - ret |= Camera_SetParam(camera, 2, arg3); + ret |= Camera_SetParam(camera, 2, eye); ret <<= 1; - ret |= Camera_SetParam(camera, 4, arg4); + ret |= Camera_SetParam(camera, 4, up); - camera->dist = Math3D_Vec3f_DistXYZ(arg2, arg3); + camera->dist = Math3D_Vec3f_DistXYZ(at, eye); player = camera->player; if (player != NULL) { - camera->unk_E4.x = arg2->x - player->actor.posRot.pos.x; - camera->unk_E4.y = arg2->y - player->actor.posRot.pos.y; - camera->unk_E4.z = arg2->z - player->actor.posRot.pos.z; + camera->posOffset.x = at->x - player->actor.posRot.pos.x; + camera->posOffset.y = at->y - player->actor.posRot.pos.y; + camera->posOffset.z = at->z - player->actor.posRot.pos.z; } else { - camera->unk_E4.x = camera->unk_E4.y = camera->unk_E4.z = 0.0f; + camera->posOffset.x = camera->posOffset.y = camera->posOffset.z = 0.0f; } - camera->unk_100 = 0.01f; + camera->atLERPStepScale = 0.01f; return ret; } -s32 func_800C0704(GlobalContext* globalCtx, s16 camId, f32 arg2) { - s32 ret = Camera_SetParam(globalCtx->cameraPtrs[camId], 32, &arg2) & 1; +s32 Gameplay_CameraSetFov(GlobalContext* globalCtx, s16 camId, f32 fov) { + s32 ret = Camera_SetParam(globalCtx->cameraPtrs[camId], 0x20, &fov) & 1; if (1) {} return ret; } -s32 func_800C0744(GlobalContext* globalCtx, s16 camId, s16 arg2) { +s32 Gameplay_SetCameraRoll(GlobalContext* globalCtx, s16 camId, s16 roll) { s16 camIdx = (camId == -1) ? globalCtx->activeCamera : camId; Camera* camera; camera = globalCtx->cameraPtrs[camIdx]; - camera->roll = arg2; + camera->roll = roll; return 1; } -void func_800C078C(GlobalContext* globalCtx, s16 camId1, s16 camId2) { +void Gameplay_CopyCamera(GlobalContext* globalCtx, s16 camId1, s16 camId2) { s16 camIdx2 = (camId2 == -1) ? globalCtx->activeCamera : camId2; s16 camIdx1 = (camId1 == -1) ? globalCtx->activeCamera : camId1; - func_8005AE64(globalCtx->cameraPtrs[camIdx1], globalCtx->cameraPtrs[camIdx2]); + Camera_Copy(globalCtx->cameraPtrs[camIdx1], globalCtx->cameraPtrs[camIdx2]); } -s32 func_800C0808(GlobalContext* globalCtx, s16 camId, Player* player, s16 arg3) { +s32 func_800C0808(GlobalContext* globalCtx, s16 camId, Player* player, s16 setting) { Camera* camera; s16 camIdx = (camId == -1) ? globalCtx->activeCamera : camId; camera = globalCtx->cameraPtrs[camIdx]; - func_80058148(camera, player); - return func_8005A77C(camera, arg3); + Camera_InitPlayerSettings(camera, player); + return Camera_ChangeSetting(camera, setting); } -void func_800C0874(GlobalContext* globalCtx, s16 camId, s16 arg2) { - func_8005A77C(Gameplay_GetCamera(globalCtx, camId), arg2); +s32 Gameplay_CameraChangeSetting(GlobalContext* globalCtx, s16 camId, s16 setting) { + return Camera_ChangeSetting(Gameplay_GetCamera(globalCtx, camId), setting); } void func_800C08AC(GlobalContext* globalCtx, s16 camId, s16 arg2) { @@ -1695,14 +1695,14 @@ void func_800C08AC(GlobalContext* globalCtx, s16 camId, s16 arg2) { } if (arg2 <= 0) { - Gameplay_ChangeCameraStatus(globalCtx, 0, 7); - globalCtx->cameraPtrs[0]->unk_14E = globalCtx->cameraPtrs[0]->unk_162 = 0; + Gameplay_ChangeCameraStatus(globalCtx, 0, CAM_STAT_ACTIVE); + globalCtx->cameraPtrs[0]->childCamIdx = globalCtx->cameraPtrs[0]->parentCamIdx = 0; } else { func_800800F8(globalCtx, 1020, arg2, NULL, 0); } } -s16 func_800C09A4(GlobalContext* globalCtx, s16 camId) { +s16 Gameplay_CameraGetUID(GlobalContext* globalCtx, s16 camId) { Camera* camera = globalCtx->cameraPtrs[camId]; if (camera != NULL) { @@ -1827,7 +1827,7 @@ s32 func_800C0D34(GlobalContext* globalCtx, Actor* actor, s16* yaw) { } s32 func_800C0DB4(GlobalContext* globalCtx, Vec3f* arg1) { - UNK_TYPE sp3C; + WaterBox* sp3C; CollisionPoly* sp38; Vec3f sp2C; s32 sp28; diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index f8ee4e7a0..fd77f9057 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -406,7 +406,7 @@ void func_8008EEAC(GlobalContext* globalCtx, Actor* actor) { this->unk_684 = actor; this->stateFlags1 |= 0x10000; Camera_SetParam(Gameplay_GetCamera(globalCtx, 0), 8, actor); - func_8005A444(Gameplay_GetCamera(globalCtx, 0), 2); + Camera_ChangeMode(Gameplay_GetCamera(globalCtx, 0), 2); } s32 func_8008EF30(GlobalContext* globalCtx) { diff --git a/src/code/z_quake.c b/src/code/z_quake.c index 9869fa6fb..3638e3a76 100644 --- a/src/code/z_quake.c +++ b/src/code/z_quake.c @@ -148,7 +148,7 @@ QuakeRequest* Quake_AddImpl(Camera* cam, u32 callbackIdx) { func_80106860(req, 0, sizeof(QuakeRequest)); // memset req->cam = cam; - req->camPtrIdx = cam->unk_164; + req->camPtrIdx = cam->thisIdx; req->callbackIdx = callbackIdx; req->unk_1C = 1; req->randIdx = ((s16)(Math_Rand_ZeroOne() * (f32)0x10000) & ~3) + idx; @@ -293,7 +293,7 @@ u32 Quake_RemoveFromIdx(s16 idx) { return false; } -s16 Quake_Calc(Camera* camera, UnkQuakeCalcStruct* camData) { +s16 Quake_Calc(Camera* camera, QuakeCamCalc* camData) { f32 max; f32 max2; QuakeRequest* req; @@ -314,12 +314,12 @@ s16 Quake_Calc(Camera* camera, UnkQuakeCalcStruct* camData) { camData->rotZ = 0; camData->unk_1A = 0; camData->zoom = 0; - camData->vec1.x = 0.0f; - camData->vec1.y = 0.0f; - camData->vec1.z = 0.0f; - camData->vec2.x = 0.0f; - camData->vec2.y = 0.0f; - camData->vec2.z = 0.0f; + camData->atOffset.x = 0.0f; + camData->atOffset.y = 0.0f; + camData->atOffset.z = 0.0f; + camData->eyeOffset.x = 0.0f; + camData->eyeOffset.y = 0.0f; + camData->eyeOffset.z = 0.0f; camData->unk_20 = 0.0f; if (sQuakeRequestCount == 0) { @@ -335,29 +335,29 @@ s16 Quake_Calc(Camera* camera, UnkQuakeCalcStruct* camData) { req->camPtrIdx); Quake_Remove(req); } else { - temp = &camera->unk_164; - eq = req->cam->unk_164 != *temp; + temp = &camera->thisIdx; + eq = req->cam->thisIdx != *temp; absSpeedDiv = ABS(req->speed) / (f32)0x8000; if (sQuakeCallbacks[req->callbackIdx](req, &shake) == 0) { Quake_Remove(req); } else if (eq == 0) { - if (fabsf(camData->vec1.x) < fabsf(shake.vec1.x)) { - camData->vec1.x = shake.vec1.x; + if (fabsf(camData->atOffset.x) < fabsf(shake.vec1.x)) { + camData->atOffset.x = shake.vec1.x; } - if (fabsf(camData->vec1.y) < fabsf(shake.vec1.y)) { - camData->vec1.y = shake.vec1.y; + if (fabsf(camData->atOffset.y) < fabsf(shake.vec1.y)) { + camData->atOffset.y = shake.vec1.y; } - if (fabsf(camData->vec1.z) < fabsf(shake.vec1.z)) { - camData->vec1.z = shake.vec1.z; + if (fabsf(camData->atOffset.z) < fabsf(shake.vec1.z)) { + camData->atOffset.z = shake.vec1.z; } - if (fabsf(camData->vec2.x) < fabsf(shake.vec2.x)) { - camData->vec2.x = shake.vec2.x; + if (fabsf(camData->eyeOffset.x) < fabsf(shake.vec2.x)) { + camData->eyeOffset.x = shake.vec2.x; } - if (fabsf(camData->vec2.y) < fabsf(shake.vec2.y)) { - camData->vec2.y = shake.vec2.y; + if (fabsf(camData->eyeOffset.y) < fabsf(shake.vec2.y)) { + camData->eyeOffset.y = shake.vec2.y; } - if (fabsf(camData->vec2.z) < fabsf(shake.vec2.z)) { - camData->vec2.z = shake.vec2.z; + if (fabsf(camData->eyeOffset.z) < fabsf(shake.vec2.z)) { + camData->eyeOffset.z = shake.vec2.z; } if (camData->rotZ < shake.rotZ) { camData->rotZ = shake.rotZ; diff --git a/src/code/z_room.c b/src/code/z_room.c index 2a18f9b9c..e5a61ca71 100644 --- a/src/code/z_room.c +++ b/src/code/z_room.c @@ -358,7 +358,7 @@ void func_80096680(GlobalContext* globalCtx, Room* room, u32 flags) { { Vec3f sp60; spA8 = POLY_OPA_DISP; - func_8005AFB4(&sp60, camera); + Camera_GetSkyboxOffset(&sp60, camera); func_8009638C(&spA8, polygon1->single.source, polygon1->single.tlut, polygon1->single.width, polygon1->single.height, polygon1->single.fmt, polygon1->single.siz, polygon1->single.mode0, polygon1->single.tlutCount, @@ -390,8 +390,9 @@ BgImage* func_80096A74(PolygonType1* polygon1, GlobalContext* globalCtx) { s32 i; camera = ACTIVE_CAM; - camId = camera->unk_148; - camId2 = func_80041C10(&globalCtx->colCtx, camId, 50)->unk_0E; + camId = camera->camDataIdx; + // jfifid + camId2 = func_80041C10(&globalCtx->colCtx, camId, 50)[2].y; if (camId2 >= 0) { camId = camId2; } @@ -453,7 +454,7 @@ void func_80096B6C(GlobalContext* globalCtx, Room* room, u32 flags) { { Vec3f sp5C; spA8 = POLY_OPA_DISP; - func_8005AFB4(&sp5C, camera); + Camera_GetSkyboxOffset(&sp5C, camera); func_8009638C(&spA8, bgImage->source, bgImage->tlut, bgImage->width, bgImage->height, bgImage->fmt, bgImage->siz, bgImage->mode0, bgImage->tlutCount, (sp5C.x + sp5C.z) * 1.2f + sp5C.y * 0.6f, sp5C.y * 2.4f + (sp5C.x + sp5C.z) * 0.3f); |
