summaryrefslogtreecommitdiff
path: root/src/code/cutscene_camera.c
diff options
context:
space:
mode:
authorengineer124 <47598039+engineer124@users.noreply.github.com>2023-04-20 03:52:00 +1000
committerGitHub <noreply@github.com>2023-04-19 13:52:00 -0400
commit9d25fad40743fe259867bc81c152591683c8fe73 (patch)
treed580e92942742b3acff5067aedb1de1204c211eb /src/code/cutscene_camera.c
parent543c38ae06d68ce2aa603144dbbe76262d00ddb6 (diff)
Cutscene Documentation (z_eventmgr.c OK) (#1164)
* begin cutscene docs * more docs * more docs * z_eventmgr.c OK Co-authored-by: Thar0 <Thar0@users.noreply.github.com> * cutscene camera * commands WIP * more docs * merge master * csId, oof * more cleanup * more docs, csCam * more cleanup * more docs * more * cleanup functions.h * better misc cmd docs * apply discord discussions * small adjustment * more cleanup * more docs * more cleanup * more cs cam docs * small fix * cmd cleanup * small cleanup * better match, thanks anon * remove last return * PR suggestions, small cleanup * next PR review * rm internal funcs from functions.h * more PR * add comment * csCam interp typedef handler * cleanup, scene cmd * missed an enum use * ActorCutscene -> CutsceneManager, PR Suggestions * more PR Suggestions * more actorCutscene cleanup * R_USE_DEBUG_CUTSCENE * more small docs * move functions to cutscene.h * PlayerCsId * fix bss * missed some function headers * more scene cleanup * more scene cleanup * missed one * CS_SPAWN_FLAGS * wrong usage of macro * more cleanup * name last cs transition types * IsNext bool * update namefixer * fix namefixer * more cleanup * add comment * fixed enums for motion blur * consistent cutscene lists * cutscene entry func consistent * PR Suggestion * fig review * fix additionalCsId name in actor * more pr review * bss --------- Co-authored-by: Thar0 <Thar0@users.noreply.github.com> Co-authored-by: angie <angheloalf95@gmail.com>
Diffstat (limited to 'src/code/cutscene_camera.c')
-rw-r--r--src/code/cutscene_camera.c380
1 files changed, 380 insertions, 0 deletions
diff --git a/src/code/cutscene_camera.c b/src/code/cutscene_camera.c
new file mode 100644
index 000000000..d5f028b94
--- /dev/null
+++ b/src/code/cutscene_camera.c
@@ -0,0 +1,380 @@
+#include "global.h"
+
+extern CutsceneCamera* sCurCsCamera;
+
+typedef s16 (*CsCamInterpolateCallback)(Vec3f*, f32*, s16*, CsCmdCamPoint*, CsCmdCamMisc*, CutsceneCameraInterp*);
+
+// function declarations
+s16 func_80161180(Vec3f* pos, f32* fov, s16* roll, CsCmdCamPoint* point, CsCmdCamMisc* misc,
+ CutsceneCameraInterp* interp);
+s16 func_8016237C(Vec3f* pos, f32* fov, s16* roll, CsCmdCamPoint* point, CsCmdCamMisc* misc,
+ CutsceneCameraInterp* interp);
+s16 func_8016253C(Vec3f* pos, f32* fov, s16* roll, CsCmdCamPoint* point, CsCmdCamMisc* misc,
+ CutsceneCameraInterp* interp);
+s16 func_80162A50(Vec3f* pos, f32* fov, s16* roll, CsCmdCamPoint* point, CsCmdCamMisc* misc,
+ CutsceneCameraInterp* interp);
+s16 func_801623E4(Vec3f* pos, f32* fov, s16* roll, CsCmdCamPoint* point, CsCmdCamMisc* misc,
+ CutsceneCameraInterp* interp);
+s16 func_80161C20(Vec3f* pos, f32* fov, s16* roll, CsCmdCamPoint* point, CsCmdCamMisc* misc,
+ CutsceneCameraInterp* interp);
+s16 func_80161E4C(Vec3f* pos, f32* fov, s16* roll, CsCmdCamPoint* point, CsCmdCamMisc* misc,
+ CutsceneCameraInterp* interp);
+s16 func_801620CC(Vec3f* pos, f32* fov, s16* roll, CsCmdCamPoint* point, CsCmdCamMisc* misc,
+ CutsceneCameraInterp* interp);
+s16 func_80163334(Vec3f* pos, f32* fov, s16* roll, CsCmdCamPoint* point, CsCmdCamMisc* misc,
+ CutsceneCameraInterp* interp);
+f32 func_80163660(Actor* actor);
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_80161180.s")
+
+/**
+ * Initializes Cutscene Camera Info
+ */
+s32 CutsceneCamera_Init(Camera* camera, CutsceneCamera* csCamera) {
+ csCamera->camera = camera;
+
+ csCamera->nextSplineTimer = csCamera->updateSplineTimer = 0;
+ csCamera->cmdIndex = 0;
+ csCamera->splineIndex = 0xFFFF;
+ csCamera->splineNeedsInit = true;
+ csCamera->state = CS_CAM_STATE_UPDATE_ALL;
+
+ sCurCsCamera = csCamera;
+
+ __osMemset(&csCamera->eyeInterp, 0, sizeof(CutsceneCameraInterp));
+ __osMemset(&csCamera->atInterp, 0, sizeof(CutsceneCameraInterp));
+
+ csCamera->eyeInterp.unk_2D = csCamera->atInterp.unk_2D = 7;
+
+ return 1;
+}
+
+CsCamInterpolateCallback CutsceneCamera_Interpolate(u8 interpType) {
+ switch (interpType) {
+ case CS_CAM_INTERP_7:
+ default:
+ return func_80161180;
+
+ case CS_CAM_INTERP_0:
+ return func_8016237C;
+
+ case CS_CAM_INTERP_5:
+ return func_8016253C;
+
+ case CS_CAM_INTERP_4:
+ return func_80162A50;
+
+ case CS_CAM_INTERP_1:
+ return func_801623E4;
+
+ case CS_CAM_INTERP_2:
+ return func_80161C20;
+
+ case CS_CAM_INTERP_3:
+ return func_80161E4C;
+
+ case CS_CAM_INTERP_6:
+ return func_801620CC;
+ }
+}
+
+u8 CutsceneCamera_ProcessSpline(CutsceneCamera* csCamera) {
+ s32 sp5C;
+ f32* fov;
+ s16* roll;
+ CsCamInterpolateCallback interpHandler;
+ Player* player;
+ Actor* target;
+ s16 numPoints;
+
+ sp5C = true;
+ if (csCamera->state == CS_CAM_STATE_DONE_SPLINE) {
+ return false;
+ }
+
+ player = GET_PLAYER(csCamera->camera->play);
+ target = csCamera->camera->target;
+
+ if (csCamera->eyeCmd[csCamera->atInterp.curPoint].interpType <
+ csCamera->atCmd[csCamera->eyeInterp.curPoint].interpType) {
+ sp5C = false;
+ }
+
+ csCamera->eyeInterp.unk_00 = csCamera->camera->eye;
+ csCamera->atInterp.unk_00 = csCamera->camera->at;
+
+ if (sp5C) {
+ fov = NULL;
+ } else {
+ fov = &csCamera->camera->fov;
+ }
+
+ if (sp5C) {
+ roll = NULL;
+ } else {
+ roll = &csCamera->camera->roll;
+ }
+
+ interpHandler = CutsceneCamera_Interpolate(csCamera->atCmd[csCamera->eyeInterp.curPoint].interpType);
+
+ switch (csCamera->atCmd[csCamera->eyeInterp.curPoint].relativeTo) {
+ case CS_CAM_REL_2:
+ OLib_DbCameraVec3fDiff(&player->actor.world, &csCamera->camera->at, &csCamera->camera->at, 2);
+ break;
+
+ case CS_CAM_REL_3:
+ OLib_DbCameraVec3fDiff(&player->actor.world, &csCamera->camera->at, &csCamera->camera->at, 1);
+ break;
+
+ case CS_CAM_REL_1:
+ OLib_DbCameraVec3fDiff(&player->actor.world, &csCamera->camera->at, &csCamera->camera->at, 1);
+ break;
+
+ case CS_CAM_REL_4:
+ OLib_DbCameraVec3fDiff(&target->world, &csCamera->camera->at, &csCamera->camera->at, 1);
+ break;
+
+ case CS_CAM_REL_5:
+ OLib_DbCameraVec3fDiff(&target->world, &csCamera->camera->at, &csCamera->camera->at, 2);
+ break;
+
+ default: // CS_CAM_REL_0
+ break;
+ }
+
+ numPoints = interpHandler(&csCamera->camera->at, fov, roll, &csCamera->atCmd[csCamera->eyeInterp.curPoint],
+ &csCamera->miscCmd[csCamera->eyeInterp.curPoint], &csCamera->eyeInterp);
+
+ switch (csCamera->atCmd[csCamera->eyeInterp.curPoint].relativeTo) {
+ case CS_CAM_REL_2:
+ OLib_DbCameraVec3fSum(&player->actor.world, &csCamera->camera->at, &csCamera->camera->at, 2);
+ break;
+
+ case CS_CAM_REL_3:
+ OLib_DbCameraVec3fSum(&player->actor.world, &csCamera->camera->at, &csCamera->camera->at, 1);
+ csCamera->camera->at.y += func_80163660(&player->actor);
+ break;
+
+ case CS_CAM_REL_1:
+ OLib_DbCameraVec3fSum(&player->actor.world, &csCamera->camera->at, &csCamera->camera->at, 1);
+ break;
+
+ case CS_CAM_REL_4:
+ OLib_DbCameraVec3fSum(&target->world, &csCamera->camera->at, &csCamera->camera->at, 1);
+ break;
+
+ case CS_CAM_REL_5:
+ OLib_DbCameraVec3fSum(&target->world, &csCamera->camera->at, &csCamera->camera->at, 2);
+ break;
+
+ default: // CS_CAM_REL_0
+ break;
+ }
+
+ csCamera->eyeInterp.curPoint += numPoints;
+
+ if (sp5C) {
+ fov = &csCamera->camera->fov;
+ } else {
+ fov = NULL;
+ }
+
+ if (sp5C) {
+ roll = &csCamera->camera->roll;
+ } else {
+ roll = NULL;
+ }
+
+ interpHandler = CutsceneCamera_Interpolate(csCamera->eyeCmd[csCamera->atInterp.curPoint].interpType);
+
+ switch (csCamera->eyeCmd[csCamera->atInterp.curPoint].relativeTo) {
+ case CS_CAM_REL_2:
+ OLib_DbCameraVec3fDiff(&player->actor.world, &csCamera->camera->eye, &csCamera->camera->eye, 2);
+ break;
+
+ case CS_CAM_REL_3:
+ OLib_DbCameraVec3fDiff(&player->actor.world, &csCamera->camera->eye, &csCamera->camera->eye, 1);
+ break;
+
+ case CS_CAM_REL_1:
+ OLib_DbCameraVec3fDiff(&player->actor.world, &csCamera->camera->eye, &csCamera->camera->eye, 1);
+ break;
+
+ case CS_CAM_REL_4:
+ OLib_DbCameraVec3fDiff(&target->world, &csCamera->camera->eye, &csCamera->camera->eye, 1);
+ break;
+
+ case CS_CAM_REL_5:
+ OLib_DbCameraVec3fDiff(&target->world, &csCamera->camera->eye, &csCamera->camera->eye, 2);
+ break;
+
+ default: // CS_CAM_REL_0
+ break;
+ }
+
+ numPoints = interpHandler(&csCamera->camera->eye, fov, roll, &csCamera->eyeCmd[csCamera->atInterp.curPoint],
+ &csCamera->miscCmd[csCamera->atInterp.curPoint], &csCamera->atInterp);
+
+ switch (csCamera->eyeCmd[csCamera->atInterp.curPoint].relativeTo) {
+ case CS_CAM_REL_2:
+ OLib_DbCameraVec3fSum(&player->actor.world, &csCamera->camera->eye, &csCamera->camera->eye, 2);
+ break;
+
+ case CS_CAM_REL_3:
+ OLib_DbCameraVec3fSum(&player->actor.world, &csCamera->camera->eye, &csCamera->camera->eye, 1);
+ csCamera->camera->eye.y += func_80163660(&player->actor);
+ break;
+
+ case CS_CAM_REL_1:
+ OLib_DbCameraVec3fSum(&player->actor.world, &csCamera->camera->eye, &csCamera->camera->eye, 1);
+ break;
+
+ case CS_CAM_REL_4:
+ OLib_DbCameraVec3fSum(&target->world, &csCamera->camera->eye, &csCamera->camera->eye, 1);
+ break;
+
+ case CS_CAM_REL_5:
+ OLib_DbCameraVec3fSum(&target->world, &csCamera->camera->eye, &csCamera->camera->eye, 2);
+ break;
+
+ default: // CS_CAM_REL_0
+ break;
+ }
+
+ csCamera->atInterp.curPoint += numPoints;
+
+ if ((csCamera->eyeInterp.curPoint >= csCamera->eyeInterp.numEntries) ||
+ (csCamera->atInterp.curPoint >= csCamera->atInterp.numEntries)) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Processes camera cutscene commands
+ */
+s32 CutsceneCamera_UpdateSplines(u8* script, CutsceneCamera* csCamera) {
+ CsCmdCamSpline* spline;
+
+ switch (csCamera->state) {
+ case CS_CAM_STATE_DONE:
+ return 0;
+
+ case CS_CAM_STATE_PAUSE:
+ return csCamera->nextSplineTimer;
+
+ case CS_CAM_STATE_UPDATE_SPLINE:
+ if (csCamera->updateSplineTimer <= csCamera->duration) {
+ csCamera->updateSplineTimer++;
+ if (csCamera->updateSplineTimer <= csCamera->duration) {
+ // Process Spline
+ if (!CutsceneCamera_ProcessSpline(csCamera)) {
+ csCamera->state = CS_CAM_STATE_DONE_SPLINE;
+ }
+ }
+ }
+ break;
+
+ case CS_CAM_STATE_DONE_SPLINE:
+ break;
+
+ default: // CS_CAM_STATE_UPDATE_ALL
+ if (csCamera->splineNeedsInit == true) {
+ // Spline Header
+ spline = (CsCmdCamSpline*)&script[csCamera->cmdIndex];
+ csCamera->atInterp.numEntries = csCamera->eyeInterp.numEntries = spline->numEntries;
+ csCamera->duration = spline->duration;
+ csCamera->cmdIndex += sizeof(CsCmdCamSpline);
+
+ // At Point
+ csCamera->atCmd = (CsCmdCamPoint*)&script[csCamera->cmdIndex];
+ csCamera->cmdIndex += (s16)(csCamera->eyeInterp.numEntries * sizeof(CsCmdCamPoint));
+
+ // Misc Point
+ csCamera->eyeCmd = (CsCmdCamPoint*)&script[csCamera->cmdIndex];
+ csCamera->cmdIndex += (s16)(csCamera->eyeInterp.numEntries * sizeof(CsCmdCamPoint));
+
+ // Misc
+ csCamera->miscCmd = (CsCmdCamMisc*)&script[csCamera->cmdIndex];
+ csCamera->cmdIndex += (s16)(csCamera->eyeInterp.numEntries * sizeof(CsCmdCamMisc));
+
+ // Other Params
+ csCamera->eyeInterp.curPoint = 0;
+ csCamera->atInterp.curPoint = 0;
+
+ csCamera->splineNeedsInit = false;
+ //! FAKE: csCamera->splineIndex++;
+ csCamera->splineIndex = (csCamera->splineIndex & 0xFFFF) + 1;
+ csCamera->state = CS_CAM_STATE_UPDATE_ALL;
+ csCamera->nextSplineTimer = csCamera->updateSplineTimer = 0;
+ csCamera->eyeInterp.unk_2D = csCamera->atInterp.unk_2D = 7;
+ }
+
+ csCamera->nextSplineTimer++;
+
+ if (csCamera->updateSplineTimer <= csCamera->duration) {
+ csCamera->updateSplineTimer++;
+ if (csCamera->updateSplineTimer <= csCamera->duration) {
+ // Process SubCommands
+ if (!CutsceneCamera_ProcessSpline(csCamera)) {
+ csCamera->state = CS_CAM_STATE_DONE_SPLINE;
+ }
+ }
+ }
+ break;
+ }
+
+ if (csCamera->nextSplineTimer > csCamera->duration) {
+ // Next Spline
+ csCamera->splineNeedsInit = true;
+ spline = (CsCmdCamSpline*)&script[csCamera->cmdIndex];
+ if (spline->numEntries == -1) {
+ csCamera->state = CS_CAM_STATE_DONE;
+ return 0;
+ }
+ }
+
+ return csCamera->nextSplineTimer;
+}
+
+// Unused
+s16 func_80161BAC(void) {
+ return (sCurCsCamera->state == CS_CAM_STATE_PAUSE) || (sCurCsCamera->state == CS_CAM_STATE_UPDATE_SPLINE);
+}
+
+void CutsceneCamera_SetState(s16 state) {
+ if (sCurCsCamera->state == CS_CAM_STATE_UPDATE_ALL) {
+ sCurCsCamera->state = state;
+ }
+}
+
+void CutsceneCamera_Reset(void) {
+ sCurCsCamera->state = CS_CAM_STATE_UPDATE_ALL;
+}
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_80161C20.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_80161E4C.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_801620CC.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_8016237C.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_801623E4.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_801624EC.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_8016253C.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_801629BC.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_80162A50.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_80162FF8.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_801631DC.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_80163334.s")
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/cutscene_camera/func_80163660.s")