diff options
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/cutscene_camera.c | 380 | ||||
| -rw-r--r-- | src/code/db_camera.c | 43 | ||||
| -rw-r--r-- | src/code/z_actor.c | 26 | ||||
| -rw-r--r-- | src/code/z_camera_data.inc.c | 50 | ||||
| -rw-r--r-- | src/code/z_collision_check.c | 1 | ||||
| -rw-r--r-- | src/code/z_demo.c | 1409 | ||||
| -rw-r--r-- | src/code/z_env_flags.c | 18 | ||||
| -rw-r--r-- | src/code/z_eventmgr.c | 552 | ||||
| -rw-r--r-- | src/code/z_kaleido_setup.c | 2 | ||||
| -rw-r--r-- | src/code/z_parameter.c | 6 | ||||
| -rw-r--r-- | src/code/z_play.c | 96 | ||||
| -rw-r--r-- | src/code/z_player_lib.c | 4 | ||||
| -rw-r--r-- | src/code/z_scene.c | 22 | ||||
| -rw-r--r-- | src/code/z_sram_NES.c | 17 | ||||
| -rw-r--r-- | src/code/z_sub_s.c | 43 |
15 files changed, 1800 insertions, 869 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") diff --git a/src/code/db_camera.c b/src/code/db_camera.c deleted file mode 100644 index 92b6d87f9..000000000 --- a/src/code/db_camera.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80161180.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_8016119C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_8016122C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_801612B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80161998.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80161BAC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80161BE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80161C0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80161C20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80161E4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_801620CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_8016237C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_801623E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_801624EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_8016253C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_801629BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80162A50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80162FF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_801631DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80163334.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/db_camera/func_80163660.s") diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 8e2f65965..84501dcbb 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -1371,7 +1371,7 @@ void func_800B722C(GameState* gameState, Player* player) { s32 func_800B724C(PlayState* play, Actor* actor, u8 csMode) { Player* player = GET_PLAYER(play); - if ((player->csMode == PLAYER_CSMODE_5) || ((csMode == PLAYER_CSMODE_6) && (player->csMode == PLAYER_CSMODE_0))) { + if ((player->csMode == PLAYER_CSMODE_5) || ((csMode == PLAYER_CSMODE_END) && (player->csMode == PLAYER_CSMODE_0))) { return false; } @@ -1880,7 +1880,7 @@ s32 func_800B8500(Actor* actor, PlayState* play, f32 xzRange, f32 yRange, Player player->talkActorDistance = actor->xzDistToPlayer; player->exchangeItemId = exchangeItemId; - ActorCutscene_SetIntentToPlay(0x7C); + CutsceneManager_Queue(CS_ID_GLOBAL_TALK); return true; } @@ -2048,7 +2048,7 @@ s32 Actor_OfferGetItem(Actor* actor, PlayState* play, GetItemId getItemId, f32 x player->getItemDirection = absYawDiff; if ((getItemId > GI_NONE) && (getItemId < GI_MAX)) { - ActorCutscene_SetIntentToPlay(play->playerActorCsIds[1]); + CutsceneManager_Queue(play->playerCsIds[PLAYER_CS_ID_ITEM_GET]); } return true; @@ -2123,7 +2123,7 @@ s32 Actor_SetRideActor(PlayState* play, Actor* horse, s32 mountSide) { PLAYER_STATE1_40000 | PLAYER_STATE1_80000 | PLAYER_STATE1_100000 | PLAYER_STATE1_200000))) { player->rideActor = horse; player->mountSide = mountSide; - ActorCutscene_SetIntentToPlay(0x7C); + CutsceneManager_Queue(CS_ID_GLOBAL_TALK); return true; } @@ -3126,8 +3126,8 @@ void Actor_FreeOverlay(ActorOverlay* entry) { Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, s32 params) { - return Actor_SpawnAsChildAndCutscene(actorCtx, play, actorId, posX, posY, posZ, rotX, rotY, rotZ, params, -1, - HALFDAYBIT_ALL, NULL); + return Actor_SpawnAsChildAndCutscene(actorCtx, play, actorId, posX, posY, posZ, rotX, rotY, rotZ, params, + CS_ID_NONE, HALFDAYBIT_ALL, NULL); } ActorInit* Actor_LoadOverlay(ActorContext* actorCtx, s16 index) { @@ -3171,7 +3171,7 @@ ActorInit* Actor_LoadOverlay(ActorContext* actorCtx, s16 index) { } Actor* Actor_SpawnAsChildAndCutscene(ActorContext* actorCtx, PlayState* play, s16 index, f32 x, f32 y, f32 z, s16 rotX, - s16 rotY, s16 rotZ, s32 params, u32 cutscene, u32 halfDaysBits, Actor* parent) { + s16 rotY, s16 rotZ, s32 params, u32 csId, u32 halfDaysBits, Actor* parent) { s32 pad; Actor* actor; ActorInit* actorInit; @@ -3237,10 +3237,10 @@ Actor* Actor_SpawnAsChildAndCutscene(ActorContext* actorCtx, PlayState* play, s1 actor->home.rot.y = rotY; actor->home.rot.z = rotZ; actor->params = params & 0xFFFF; - actor->cutscene = (cutscene & 0x7F); + actor->csId = csId & 0x7F; - if (actor->cutscene == 0x7F) { - actor->cutscene = -1; + if (actor->csId == 0x7F) { + actor->csId = CS_ID_NONE; } if (halfDaysBits != 0) { @@ -3263,8 +3263,8 @@ Actor* Actor_SpawnAsChildAndCutscene(ActorContext* actorCtx, PlayState* play, s1 Actor* Actor_SpawnAsChild(ActorContext* actorCtx, Actor* parent, PlayState* play, s16 actorId, f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, s32 params) { - return Actor_SpawnAsChildAndCutscene(actorCtx, play, actorId, posX, posY, posZ, rotX, rotY, rotZ, params, -1, - parent->halfDaysBits, parent); + return Actor_SpawnAsChildAndCutscene(actorCtx, play, actorId, posX, posY, posZ, rotX, rotY, rotZ, params, + CS_ID_NONE, parent->halfDaysBits, parent); } void Actor_SpawnTransitionActors(PlayState* play, ActorContext* actorCtx) { @@ -4404,7 +4404,7 @@ s16 func_800BDB6C(Actor* actor, PlayState* play, s16 arg2, f32 arg3) { Player* player = GET_PLAYER(play); f32 phi_f2; - if ((play->csCtx.state != CS_STATE_0) || gDbgCamEnabled) { + if ((play->csCtx.state != CS_STATE_IDLE) || gDbgCamEnabled) { phi_f2 = Math_Vec3f_DistXYZ(&actor->world.pos, &play->view.eye) * 0.25f; } else { phi_f2 = Math_Vec3f_DistXYZ(&actor->world.pos, &player->actor.world.pos); diff --git a/src/code/z_camera_data.inc.c b/src/code/z_camera_data.inc.c index a8e9fbb80..3df77c0c4 100644 --- a/src/code/z_camera_data.inc.c +++ b/src/code/z_camera_data.inc.c @@ -3613,31 +3613,31 @@ CameraSetting sCameraSettings[] = { }; s16 sGlobalCamDataSettings[] = { - /* -25 */ CAM_SET_ELEGY_SHELL, - /* -24 */ CAM_SET_SIDED, - /* -23 */ CAM_SET_BOAT_CRUISE, - /* -22 */ CAM_SET_NONE, - /* -21 */ CAM_SET_SUBJECTD, - /* -20 */ CAM_SET_NORMALD, - /* -19 */ CAM_SET_NONE, - /* -18 */ CAM_SET_NONE, - /* -17 */ CAM_SET_NONE, - /* -16 */ CAM_SET_WARP_PAD_ENTRANCE, - /* -15 */ CAM_SET_ATTENTION, - /* -14 */ CAM_SET_CONNECT0, - /* -13 */ CAM_SET_REMOTEBOMB, - /* -12 */ CAM_SET_NONE, - /* -11 */ CAM_SET_MASK_TRANSFORMATION, - /* -10 */ CAM_SET_LONG_CHEST_OPENING, - /* -9 */ CAM_SET_REBIRTH, - /* -8 */ CAM_SET_DEATH, - /* -7 */ CAM_SET_WARP_PAD_MOON, - /* -6 */ CAM_SET_NAVI, - /* -5 */ CAM_SET_ITEM3, - /* -4 */ CAM_SET_ITEM2, - /* -3 */ CAM_SET_ITEM1, - /* -2 */ CAM_SET_ITEM0, - /* -1 */ CAM_SET_STOP0, + /* -25 */ CAM_SET_ELEGY_SHELL, // CS_CAM_ID_GLOBAL_ELEGY + /* -24 */ CAM_SET_SIDED, // CS_CAM_ID_GLOBAL_SIDED + /* -23 */ CAM_SET_BOAT_CRUISE, // CS_CAM_ID_GLOBAL_BOAT_CRUISE + /* -22 */ CAM_SET_NONE, // CS_CAM_ID_GLOBAL_N16 + /* -21 */ CAM_SET_SUBJECTD, // CS_CAM_ID_GLOBAL_SUBJECTD + /* -20 */ CAM_SET_NORMALD, // CS_CAM_ID_GLOBAL_NORMALD + /* -19 */ CAM_SET_NONE, // CS_CAM_ID_GLOBAL_N13 + /* -18 */ CAM_SET_NONE, // CS_CAM_ID_GLOBAL_N12 + /* -17 */ CAM_SET_NONE, // CS_CAM_ID_GLOBAL_N11 + /* -16 */ CAM_SET_WARP_PAD_ENTRANCE, // CS_CAM_ID_GLOBAL_WARP_PAD_ENTRANCE + /* -15 */ CAM_SET_ATTENTION, // CS_CAM_ID_GLOBAL_ATTENTION + /* -14 */ CAM_SET_CONNECT0, // CS_CAM_ID_GLOBAL_CONNECT + /* -13 */ CAM_SET_REMOTEBOMB, // CS_CAM_ID_GLOBAL_REMOTE_BOMB + /* -12 */ CAM_SET_NONE, // CS_CAM_ID_GLOBAL_N0C + /* -11 */ CAM_SET_MASK_TRANSFORMATION, // CS_CAM_ID_GLOBAL_MASK_TRANSFORMATION + /* -10 */ CAM_SET_LONG_CHEST_OPENING, // CS_CAM_ID_GLOBAL_LONG_CHEST_OPENING + /* -9 */ CAM_SET_REBIRTH, // CS_CAM_ID_GLOBAL_REVIVE + /* -8 */ CAM_SET_DEATH, // CS_CAM_ID_GLOBAL_DEATH + /* -7 */ CAM_SET_WARP_PAD_MOON, // CS_CAM_ID_GLOBAL_WARP_PAD_MOON + /* -6 */ CAM_SET_NAVI, // CS_CAM_ID_GLOBAL_SONG_WARP + /* -5 */ CAM_SET_ITEM3, // CS_CAM_ID_GLOBAL_ITEM_SHOW + /* -4 */ CAM_SET_ITEM2, // CS_CAM_ID_GLOBAL_ITEM_BOTTLE + /* -3 */ CAM_SET_ITEM1, // CS_CAM_ID_GLOBAL_ITEM_OCARINA + /* -2 */ CAM_SET_ITEM0, // CS_CAM_ID_GLOBAL_ITEM_GET + /* -1 */ CAM_SET_STOP0, // CS_CAM_ID_NONE /* 0 */ CAM_SET_NONE, }; diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c index 6ecbd617a..20083f3c4 100644 --- a/src/code/z_collision_check.c +++ b/src/code/z_collision_check.c @@ -1,4 +1,3 @@ -#include "prevent_bss_reordering.h" #include "global.h" Vec3f D_801EDE00; diff --git a/src/code/z_demo.c b/src/code/z_demo.c index dc32223a8..79270adce 100644 --- a/src/code/z_demo.c +++ b/src/code/z_demo.c @@ -1,171 +1,177 @@ +#include "prevent_bss_reordering.h" #include "global.h" #include "z64quake.h" #include "z64rumble.h" #include "z64shrink_window.h" #include "overlays/gamestates/ovl_daytelop/z_daytelop.h" -void Cutscene_DoNothing(PlayState* play, CutsceneContext* csCtx); -void func_800EA258(PlayState* play, CutsceneContext* csCtx); -void func_800ED9C4(PlayState* play, CutsceneContext* csCtx); -void func_800EA2B8(PlayState* play, CutsceneContext* csCtx); -void func_800ED980(PlayState* play, CutsceneContext* csCtx); -void func_800EDA04(PlayState* play, CutsceneContext* csCtx); -void func_800EDA84(PlayState* play, CutsceneContext* csCtx); +void CutsceneHandler_DoNothing(PlayState* play, CutsceneContext* csCtx); +void CutsceneHandler_StartManual(PlayState* play, CutsceneContext* csCtx); +void CutsceneHandler_StopManual(PlayState* play, CutsceneContext* csCtx); +void CutsceneHandler_StartScript(PlayState* play, CutsceneContext* csCtx); +void CutsceneHandler_RunScript(PlayState* play, CutsceneContext* csCtx); +void CutsceneHandler_StopScript(PlayState* play, CutsceneContext* csCtx); +void Cutscene_SetupScripted(PlayState* play, CutsceneContext* csCtx); // Unused UNK_TYPE4 D_801BB120 = 0; -u16 D_801BB124 = 0; -u16 D_801BB128 = 0; -u8 D_801BB12C = 0; +u16 sCurTextId = 0; +u16 sCurOcarinaAction = 0; +u8 gOpeningEntranceIndex = 0; u8 sCutsceneStoredPlayerForm = 0; // bss #ifndef NON_MATCHING -static u16 seqId; +static u16 sSeqId; #endif s16 sCutsceneQuakeIndex; -DbCameraUnkStruct sCutsceneCameraInfo; -u16 D_801F4DC8[10]; +CutsceneCamera sCutsceneCameraInfo; +u16 sCueTypeList[10]; UNK_TYPE D_801F4DDC; -u8 D_801F4DE0; -s16 D_801F4DE2; +u8 gDisablePlayerCsModeStartPos; +s16 gDungeonBossWarpSceneId; -void Cutscene_Init(PlayState* play, CutsceneContext* csCtx) { +void Cutscene_InitContext(PlayState* play, CutsceneContext* csCtx) { s32 i; - csCtx->state = CS_STATE_0; - csCtx->frames = 0; - csCtx->unk_0C = 0.0f; - play->csCtx.sceneCsCount = 0; - play->csCtx.currentCsIndex = 0; + csCtx->state = CS_STATE_IDLE; + csCtx->curFrame = 0; + csCtx->timer = 0.0f; + play->csCtx.scriptListCount = 0; + play->csCtx.scriptIndex = 0; - for (i = 0; i < ARRAY_COUNT(D_801F4DC8); i++) { - D_801F4DC8[i] = 0; + for (i = 0; i < ARRAY_COUNT(sCueTypeList); i++) { + sCueTypeList[i] = 0; } - D_801F4DE0 = 0; + gDisablePlayerCsModeStartPos = 0; Audio_SetCutsceneFlag(false); } -void Cutscene_Start(PlayState* play, CutsceneContext* csCtx) { - csCtx->state = CS_STATE_1; - csCtx->playerAction = NULL; +void Cutscene_StartManual(PlayState* play, CutsceneContext* csCtx) { + csCtx->state = CS_STATE_START; + csCtx->playerCue = NULL; } -void Cutscene_End(PlayState* play, CutsceneContext* csCtx) { - if (csCtx->state != CS_STATE_4) { - csCtx->state = CS_STATE_3; +void Cutscene_StopManual(PlayState* play, CutsceneContext* csCtx) { + if (csCtx->state != CS_STATE_RUN_UNSTOPPABLE) { + csCtx->state = CS_STATE_STOP; } } -typedef void (*CutsceneStateHandler)(PlayState* play, CutsceneContext* csCtx); +typedef void (*CutsceneHandler)(PlayState* play, CutsceneContext* csCtx); -CutsceneStateHandler sCsStateHandlers1[] = { - Cutscene_DoNothing, // CS_STATE_0 - func_800EA258, // CS_STATE_1 - Cutscene_DoNothing, // CS_STATE_2 - func_800ED9C4, // CS_STATE_3 - Cutscene_DoNothing, // CS_STATE_4 +CutsceneHandler sManualCutsceneHandlers[] = { + CutsceneHandler_DoNothing, // CS_STATE_IDLE + CutsceneHandler_StartManual, // CS_STATE_START + CutsceneHandler_DoNothing, // CS_STATE_RUN + CutsceneHandler_StopManual, // CS_STATE_STOP + CutsceneHandler_DoNothing, // CS_STATE_RUN_UNSTOPPABLE }; -void Cutscene_Update1(PlayState* play, CutsceneContext* csCtx) { - if (gSaveContext.save.cutscene < 0xFFF0) { - sCsStateHandlers1[csCtx->state](play, csCtx); +void Cutscene_UpdateManual(PlayState* play, CutsceneContext* csCtx) { + if (gSaveContext.save.cutsceneIndex < 0xFFF0) { + sManualCutsceneHandlers[csCtx->state](play, csCtx); } } -CutsceneStateHandler sCsStateHandlers2[] = { - Cutscene_DoNothing, // CS_STATE_0 - func_800EA2B8, // CS_STATE_1 - func_800ED980, // CS_STATE_2 - func_800EDA04, // CS_STATE_3 - func_800ED980, // CS_STATE_4 +CutsceneHandler sScriptedCutsceneHandlers[] = { + CutsceneHandler_DoNothing, // CS_STATE_IDLE + CutsceneHandler_StartScript, // CS_STATE_START + CutsceneHandler_RunScript, // CS_STATE_RUN + CutsceneHandler_StopScript, // CS_STATE_STOP + CutsceneHandler_RunScript, // CS_STATE_RUN_UNSTOPPABLE }; -void Cutscene_Update2(PlayState* play, CutsceneContext* csCtx) { +void Cutscene_UpdateScripted(PlayState* play, CutsceneContext* csCtx) { if ((gSaveContext.cutsceneTrigger != 0) && (play->transitionTrigger == TRANS_TRIGGER_START)) { gSaveContext.cutsceneTrigger = 0; } - if ((gSaveContext.cutsceneTrigger != 0) && (csCtx->state == CS_STATE_0)) { - gSaveContext.save.cutscene = 0xFFFD; + if ((gSaveContext.cutsceneTrigger != 0) && (csCtx->state == CS_STATE_IDLE)) { + gSaveContext.save.cutsceneIndex = 0xFFFD; gSaveContext.cutsceneTrigger = 1; } - if (gSaveContext.save.cutscene >= 0xFFF0) { - func_800EDA84(play, csCtx); - sCsStateHandlers2[csCtx->state](play, csCtx); + if (gSaveContext.save.cutsceneIndex >= 0xFFF0) { + Cutscene_SetupScripted(play, csCtx); + sScriptedCutsceneHandlers[csCtx->state](play, csCtx); } } -void Cutscene_DoNothing(PlayState* play, CutsceneContext* csCtx) { +void CutsceneHandler_DoNothing(PlayState* play, CutsceneContext* csCtx) { } -s32 func_800EA220(PlayState* play, CutsceneContext* csCtx, f32 target) { - return Math_StepToF(&csCtx->unk_0C, target, 0.1f); +s32 Cutscene_StepTimer(PlayState* play, CutsceneContext* csCtx, f32 target) { + return Math_StepToF(&csCtx->timer, target, 0.1f); } -void func_800EA258(PlayState* play, CutsceneContext* csCtx) { +void CutsceneHandler_StartManual(PlayState* play, CutsceneContext* csCtx) { Interface_SetHudVisibility(HUD_VISIBILITY_NONE); ShrinkWindow_Letterbox_SetSizeTarget(32); - if (func_800EA220(play, csCtx, 1.0f)) { + + if (Cutscene_StepTimer(play, csCtx, 1.0f)) { Audio_SetCutsceneFlag(true); - csCtx->state++; + csCtx->state++; // CS_STATE_RUN } } -void func_800EA2B8(PlayState* play, CutsceneContext* csCtx) { - func_800ED980(play, csCtx); +void CutsceneHandler_StartScript(PlayState* play, CutsceneContext* csCtx) { + CutsceneHandler_RunScript(play, csCtx); Interface_SetHudVisibility(HUD_VISIBILITY_NONE); ShrinkWindow_Letterbox_SetSizeTarget(32); - if (func_800EA220(play, csCtx, 1.0f)) { + + if (Cutscene_StepTimer(play, csCtx, 1.0f)) { Audio_SetCutsceneFlag(true); - csCtx->state++; + csCtx->state++; // CS_STATE_RUN } } /* Start of command handling section */ -// Command 0x96: Miscellaneous commands. -void Cutscene_Command_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { +void CutsceneCmd_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdMisc* cmd) { static u16 D_801BB15C = 0xFFFF; Player* player = GET_PLAYER(play); - f32 progress; - u8 isStartFrame = false; + f32 lerp; + u8 isFirstFrame = false; SceneTableEntry* loadedScene; - if ((csCtx->frames < cmd->startFrame) || ((csCtx->frames >= cmd->endFrame) && (cmd->endFrame != cmd->startFrame))) { + if (!((csCtx->curFrame >= cmd->startFrame) && + ((csCtx->curFrame < cmd->endFrame) || (cmd->endFrame == cmd->startFrame)))) { return; } - progress = Environment_LerpWeight(cmd->endFrame - 1, cmd->startFrame, csCtx->frames); - if (csCtx->frames == cmd->startFrame) { - isStartFrame = true; + lerp = Environment_LerpWeight(cmd->endFrame - 1, cmd->startFrame, csCtx->curFrame); + + if (csCtx->curFrame == cmd->startFrame) { + isFirstFrame = true; } - // TODO: consider creating an enum for this when we understand what each value does - switch (cmd->base) { - case 0x1: - if (isStartFrame) { + switch (cmd->type) { + case CS_MISC_RAIN: + if (isFirstFrame) { func_800FD78C(play); - play->envCtx.unk_F2[0] = 0x3C; + play->envCtx.unk_F2[0] = 60; } break; - case 0x2: - if (isStartFrame) { + + case CS_MISC_LIGHTNING: + if (isFirstFrame) { Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_LIGHTNING, CHANNEL_IO_PORT_0, 0); Environment_AddLightningBolts(play, 3); D_801F4E68 = 1; } break; - case 0x3: + + case CS_MISC_LIFT_FOG: if (play->envCtx.lightSettings.zFar < 12800) { play->envCtx.lightSettings.zFar += 35; } break; - case 0x4: - if (isStartFrame) { + + case CS_MISC_CLOUDY_SKY: + if (isFirstFrame) { play->envCtx.unk_19 = 1; play->envCtx.unk_17 = 1; play->envCtx.unk_18 = 0; @@ -177,49 +183,57 @@ void Cutscene_Command_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdBase* c play->envCtx.unk_22 = play->envCtx.unk_24; } break; - case 0x5: - if (isStartFrame && (csCtx->state != CS_STATE_4)) { - csCtx->state = CS_STATE_3; + + case CS_MISC_STOP_CUTSCENE: + if (isFirstFrame && (csCtx->state != CS_STATE_RUN_UNSTOPPABLE)) { + csCtx->state = CS_STATE_STOP; } break; - case 0x7: - if (isStartFrame) { + + case CS_MISC_SHOW_TITLE_CARD: + if (isFirstFrame) { loadedScene = play->loadedScene; if (loadedScene->titleTextId != 0) { func_80151A68(play, loadedScene->titleTextId); } } break; - case 0x8: + + case CS_MISC_EARTHQUAKE_MEDIUM: func_8019F128(NA_SE_EV_EARTHQUAKE_LAST - SFX_FLAG); - if (isStartFrame) { + if (isFirstFrame) { sCutsceneQuakeIndex = Quake_Add(GET_ACTIVE_CAM(play), QUAKE_TYPE_6); Quake_SetSpeed(sCutsceneQuakeIndex, 22000); Quake_SetQuakeValues(sCutsceneQuakeIndex, 6, 4, 0, 0); Quake_SetCountdown(sCutsceneQuakeIndex, 800); } break; - case 0x9: - if (isStartFrame) { + + case CS_MISC_EARTHQUAKE_STOP: + if (isFirstFrame) { Quake_Init(); } break; - case 0xA: + + case CS_MISC_VISMONO_BLACK_AND_WHITE: gVisMonoColor.r = 255; gVisMonoColor.g = 255; gVisMonoColor.b = 255; - gVisMonoColor.a = 255 * progress; + gVisMonoColor.a = 255 * lerp; break; - case 0xB: + + case CS_MISC_VISMONO_SEPIA: gVisMonoColor.r = 255; gVisMonoColor.g = 180; gVisMonoColor.b = 100; - gVisMonoColor.a = 255 * progress; + gVisMonoColor.a = 255 * lerp; break; - case 0xC: + + case CS_MISC_HIDE_ROOM: play->roomCtx.curRoom.segment = NULL; break; - case 0xD: + + case CS_MISC_RED_PULSATING_LIGHTS: if (play->state.frames & 8) { if (play->envCtx.lightSettings.ambientColor[0] < 40) { play->envCtx.lightSettings.ambientColor[0] += 2; @@ -234,96 +248,118 @@ void Cutscene_Command_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdBase* c } } break; - case 0xE: + + case CS_MISC_HALT_ALL_ACTORS: play->haltAllActors = true; break; - case 0xF: + + case CS_MISC_RESUME_ALL_ACTORS: play->haltAllActors = false; break; - case 0x10: - if (isStartFrame) { + + case CS_MISC_SANDSTORM_FILL: + if (isFirstFrame) { play->envCtx.sandstormState = 1; } func_8019F128(NA_SE_EV_SAND_STORM - SFX_FLAG); break; - case 0x11: + + case CS_MISC_SUNSSONG_START: gSaveContext.sunsSongState = SUNSSONG_START; break; - case 0x12: + + case CS_MISC_FREEZE_TIME: if (!gSaveContext.save.isNight) { gSaveContext.save.time = ((void)0, gSaveContext.save.time) - (u16)R_TIME_SPEED; } else { gSaveContext.save.time = ((void)0, gSaveContext.save.time) - (u16)(2 * R_TIME_SPEED); } break; - case 0x13: - AudioOcarina_PlayLongScarecrowAfterCredits(); - csCtx->frames = cmd->startFrame - 1; + + case CS_MISC_LONG_SCARECROW_SONG: + AudioOcarina_PlayLongScarecrowSong(); + csCtx->curFrame = cmd->startFrame - 1; // the cutscene runs forever break; - case 0x14: - EnvFlags_Set(play, 3); + + case CS_MISC_SET_CSFLAG_3: + CutsceneFlags_Set(play, 3); break; - case 0x15: - EnvFlags_Set(play, 4); + + case CS_MISC_SET_CSFLAG_4: + CutsceneFlags_Set(play, 4); break; - case 0x16: + + case CS_MISC_PLAYER_FORM_DEKU: gSaveContext.save.playerForm = PLAYER_FORM_DEKU; break; - case 0x17: + + case CS_MISC_ENABLE_PLAYER_REFLECTION: player->stateFlags2 |= PLAYER_STATE2_4000000; break; - case 0x18: + + case CS_MISC_DISABLE_PLAYER_REFLECTION: player->stateFlags2 &= ~PLAYER_STATE2_4000000; break; - case 0x19: + + case CS_MISC_PLAYER_FORM_HUMAN: sCutsceneStoredPlayerForm = gSaveContext.save.playerForm; gSaveContext.save.playerForm = PLAYER_FORM_HUMAN; gSaveContext.save.equippedMask = PLAYER_MASK_NONE; break; - case 0x1A: + + case CS_MISC_EARTHQUAKE_STRONG: func_8019F128(NA_SE_EV_EARTHQUAKE_LAST2 - SFX_FLAG); - if (isStartFrame) { + if (isFirstFrame) { sCutsceneQuakeIndex = Quake_Add(GET_ACTIVE_CAM(play), QUAKE_TYPE_6); Quake_SetSpeed(sCutsceneQuakeIndex, 30000); Quake_SetQuakeValues(sCutsceneQuakeIndex, 20, 10, 0, 0); Quake_SetCountdown(sCutsceneQuakeIndex, 800); } break; - case 0x1B: - if (isStartFrame) { + + case CS_MISC_DEST_MOON_CRASH_FIRE_WALL: + if (isFirstFrame) { play->nextEntrance = ENTRANCE(CUTSCENE, 0); gSaveContext.nextCutsceneIndex = 0xFFF8; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; } break; - case 0x1C: - if (isStartFrame) { + + case CS_MISC_MOON_CRASH_SKYBOX: + if (isFirstFrame) { + // skyboxConfig play->envCtx.unk_17 = 0xD; } break; - case 0x1D: + + case CS_MISC_PLAYER_FORM_RESTORED: gSaveContext.save.playerForm = sCutsceneStoredPlayerForm; break; - case 0x1E: - D_801F4DE0 = true; + + case CS_MISC_DISABLE_PLAYER_CSMODE_START_POS: + gDisablePlayerCsModeStartPos = true; break; - case 0x1F: - D_801F4DE0 = false; + + case CS_MISC_ENABLE_PLAYER_CSMODE_START_POS: + gDisablePlayerCsModeStartPos = false; break; - case 0x21: - if (isStartFrame) { + + case CS_MISC_SAVE_ENTER_CLOCK_TOWN: + if (isFirstFrame) { Sram_SaveSpecialEnterClockTown(play); } break; - case 0x22: - if (isStartFrame) { - func_80144A94(&play->sramCtx); + + case CS_MISC_RESET_SAVE_FROM_MOON_CRASH: + if (isFirstFrame) { + Sram_ResetSaveFromMoonCrash(&play->sramCtx); } break; - case 0x23: - if (csCtx->frames != D_801BB15C) { - D_801BB15C = csCtx->frames; + + case CS_MISC_TIME_ADVANCE: + if (csCtx->curFrame != D_801BB15C) { + D_801BB15C = csCtx->curFrame; if (R_TIME_SPEED != 0) { gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)R_TIME_SPEED; @@ -332,9 +368,10 @@ void Cutscene_Command_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdBase* c } } break; - case 0x24: + + case CS_MISC_EARTHQUAKE_WEAK: func_8019F128(NA_SE_EV_EARTHQUAKE_LAST - SFX_FLAG); - if (isStartFrame) { + if (isFirstFrame) { sCutsceneQuakeIndex = Quake_Add(GET_ACTIVE_CAM(play), QUAKE_TYPE_6); Quake_SetSpeed(sCutsceneQuakeIndex, 22000); Quake_SetQuakeValues(sCutsceneQuakeIndex, 2, 1, 0, 0); @@ -342,10 +379,8 @@ void Cutscene_Command_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdBase* c } break; - case 0x26: - // Seems to be used to trigger "Dawn of A New Day" - - gSaveContext.save.day = 9; + case CS_MISC_DAWN_OF_A_NEW_DAY: + gSaveContext.save.day = 9; // 9 % 5 is day number 4, see `CURRENT_DAY` STOP_GAMESTATE(&play->state); SET_NEXT_GAMESTATE(&play->state, DayTelop_Init, sizeof(DayTelopState)); @@ -353,21 +388,23 @@ void Cutscene_Command_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdBase* c Sram_SaveSpecialNewDay(play); break; - case 0x27: + case CS_MISC_PLAYER_FORM_ZORA: gSaveContext.save.playerForm = PLAYER_FORM_ZORA; break; - case 0x28: - csCtx->frames = cmd->startFrame - 1; + case CS_MISC_FINALE: + csCtx->curFrame = cmd->startFrame - 1; // the cutscene runs forever + break; + + default: break; } } -// Command 0x97: Set Environment Lighting -void Cutscene_Command_SetLighting(PlayState* play, CutsceneContext* csCtx, CsCmdEnvLighting* cmd) { - if (csCtx->frames == cmd->startFrame) { - if (cmd->setting != 0x20) { - play->envCtx.lightSettingOverride = cmd->setting - 1; +void CutsceneCmd_SetLightSetting(PlayState* play, CutsceneContext* csCtx, CsCmdLightSetting* cmd) { + if (csCtx->curFrame == cmd->startFrame) { + if (cmd->settingPlusOne != 32) { + play->envCtx.lightSettingOverride = cmd->settingPlusOne - 1; play->envCtx.lightBlend = 1.0f; } else { play->envCtx.lightSettingOverride = 0xFF; @@ -375,51 +412,45 @@ void Cutscene_Command_SetLighting(PlayState* play, CutsceneContext* csCtx, CsCmd } } -// Command 0x12C: Plays a sequence (Background music or Fanfare) -void Cutscene_Command_PlaySequence(PlayState* play, CutsceneContext* csCtx, CsCmdSequenceChange* cmd) { - if (csCtx->frames == cmd->startFrame) { - Audio_PlaySequenceInCutscene(cmd->sequence - 1); +void CutsceneCmd_StartSequence(PlayState* play, CutsceneContext* csCtx, CsCmdStartSeq* cmd) { + if (csCtx->curFrame == cmd->startFrame) { + Audio_PlaySequenceInCutscene(cmd->seqIdPlusOne - 1); } } -// Command 0x12D: Stops a sequence (Background music or Fanfare) -void Cutscene_Command_StopSequence(PlayState* play, CutsceneContext* csCtx, CsCmdSequenceChange* cmd) { - if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { - Audio_StopSequenceInCutscene(cmd->sequence - 1); +void CutsceneCmd_StopSequence(PlayState* play, CutsceneContext* csCtx, CsCmdStopSeq* cmd) { + if ((csCtx->curFrame >= cmd->startFrame) && (csCtx->curFrame <= cmd->endFrame)) { + Audio_StopSequenceInCutscene(cmd->seqIdPlusOne - 1); } } -// Command 0x9C: Fade a sequence (Background music or Fanfare) over duration -void Cutscene_Command_FadeSequence(PlayState* play, CutsceneContext* csCtx, CsCmdSequenceFade* cmd) { - if ((csCtx->frames == cmd->startFrame) && (csCtx->frames < cmd->endFrame)) { - u8 fadeTimer = cmd->endFrame - cmd->startFrame; +void CutsceneCmd_FadeOutSequence(PlayState* play, CutsceneContext* csCtx, CsCmdFadeOutSeq* cmd) { + if ((csCtx->curFrame == cmd->startFrame) && (csCtx->curFrame < cmd->endFrame)) { + u8 fadeOutDuration = cmd->endFrame - cmd->startFrame; - if (cmd->type == 2) { - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, fadeTimer); - } else { - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, fadeTimer); + if (cmd->seqPlayer == CS_FADE_OUT_FANFARE) { + SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, fadeOutDuration); + } else { // CS_FADE_OUT_BGM_MAIN + SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, fadeOutDuration); } } } -// Command 0x12E: Play Ambience sequence -void Cutscene_Command_PlayAmbienceSequence(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { - if (csCtx->frames == cmd->startFrame) { +void CutsceneCmd_StartAmbience(PlayState* play, CutsceneContext* csCtx, CsCmdStartAmbience* cmd) { + if (csCtx->curFrame == cmd->startFrame) { Audio_PlayAmbience(play->sequenceCtx.ambienceId); } } -// Command 0x130: -void func_800EAD48(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { - if (csCtx->frames == cmd->startFrame) { +void Cutscene_SetSfxReverbIndexTo2(PlayState* play, CutsceneContext* csCtx, CsCmdSfxReverbIndexTo2* cmd) { + if (csCtx->curFrame == cmd->startFrame) { // Audio_SetSfxReverbIndexExceptOcarinaBank func_801A4428(2); } } -// Command 0x131: -void func_800EAD7C(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { - if (csCtx->frames == cmd->startFrame) { +void Cutscene_SetSfxReverbIndexTo1(PlayState* play, CutsceneContext* csCtx, CsCmdSfxReverbIndexTo1* cmd) { + if (csCtx->curFrame == cmd->startFrame) { // Audio_SetSfxReverbIndexExceptOcarinaBank func_801A4428(1); } @@ -427,107 +458,103 @@ void func_800EAD7C(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { #ifdef NON_MATCHING // needs in-function static bss -// audio related -void func_800EADB0(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { - static u16 seqId; +void CutsceneCmd_ModifySequence(PlayState* play, CutsceneContext* csCtx, CsCmdModifySeq* cmd) { + static u16 sSeqId; u8 dayMinusOne; - if (csCtx->frames == cmd->startFrame) { - dayMinusOne = (gSaveContext.save.day - 1); + if (csCtx->curFrame == cmd->startFrame) { + dayMinusOne = gSaveContext.save.day - 1; if (dayMinusOne >= 3) { dayMinusOne = 0; } - switch (cmd->base) { - case 1: - // func_801A246C(SEQ_PLAYER_BGM_MAIN, TYPE_1); + switch (cmd->type) { + case CS_MOD_SEQ_0: func_801A246C(SEQ_PLAYER_BGM_MAIN, 1); break; - case 2: - // func_801A246C(SEQ_PLAYER_BGM_MAIN, TYPE_0); + case CS_MOD_SEQ_1: func_801A246C(SEQ_PLAYER_BGM_MAIN, 0); break; - case 3: - // func_801A246C(SEQ_PLAYER_BGM_MAIN, TYPE_2); + case CS_MOD_SEQ_2: func_801A246C(SEQ_PLAYER_BGM_MAIN, 2); break; - case 4: - // func_801A246C(SEQ_PLAYER_AMBIENCE, TYPE_1); + case CS_MOD_AMBIENCE_0: func_801A246C(SEQ_PLAYER_AMBIENCE, 1); break; - case 5: - // func_801A246C(SEQ_PLAYER_AMBIENCE, TYPE_0); + case CS_MOD_AMBIENCE_1: func_801A246C(SEQ_PLAYER_AMBIENCE, 0); break; - case 6: - // func_801A246C(SEQ_PLAYER_AMBIENCE, TYPE_2); + case CS_MOD_AMBIENCE_2: func_801A246C(SEQ_PLAYER_AMBIENCE, 2); break; - case 7: - seqId = AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN); + case CS_MOD_SEQ_STORE: + sSeqId = AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN); break; - case 8: - if (seqId != NA_BGM_DISABLED) { - Audio_PlaySceneSequence(seqId, dayMinusOne); + case CS_MOD_SEQ_RESTORE: + if (sSeqId != NA_BGM_DISABLED) { + Audio_PlaySceneSequence(sSeqId, dayMinusOne); } break; + + default: + break; } } } #else -void func_800EADB0(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EADB0.s") +void CutsceneCmd_ModifySequence(PlayState* play, CutsceneContext* csCtx, CsCmdModifySeq* cmd); +#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/CutsceneCmd_ModifySequence.s") #endif -// Command 0x12F: Fade Ambience sequence -void Cutscene_Command_FadeAmbienceSequence(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { - if (csCtx->frames == cmd->startFrame && csCtx->frames < cmd->endFrame) { - u8 fadeTimer = cmd->endFrame - cmd->startFrame; +void CutsceneCmd_FadeOutAmbience(PlayState* play, CutsceneContext* csCtx, CsCmdFadeOutAmbience* cmd) { + if ((csCtx->curFrame == cmd->startFrame) && (csCtx->curFrame < cmd->endFrame)) { + u8 fadeOutDuration = cmd->endFrame - cmd->startFrame; - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_AMBIENCE, fadeTimer); + SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_AMBIENCE, fadeOutDuration); } } -// Command 0x190: Rumble -void Cutscene_Command_Rumble(PlayState* play, CutsceneContext* csCtx, CsCmdRumble* cmd) { +void CutsceneCmd_RumbleController(PlayState* play, CutsceneContext* csCtx, CsCmdRumble* cmd) { switch (cmd->type) { - case 1: - if (csCtx->frames == cmd->startFrame) { + case CS_RUMBLE_ONCE: + if (csCtx->curFrame == cmd->startFrame) { Rumble_Request(0.0f, cmd->intensity, cmd->decayTimer, cmd->decayStep); } break; - case 2: - if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { - if ((csCtx->frames == cmd->startFrame) || (play->state.frames % 64 == 0)) { + case CS_RUMBLE_PULSE: + if ((csCtx->curFrame >= cmd->startFrame) && (csCtx->curFrame <= cmd->endFrame)) { + if ((csCtx->curFrame == cmd->startFrame) || (play->state.frames % 64 == 0)) { Rumble_Request(0.0f, cmd->intensity, cmd->decayTimer, cmd->decayStep); } } break; + + default: + break; } } -// Command 0x9B: -void Cutscene_Command_FadeColorScreen(PlayState* play, CutsceneContext* csCtx, CsCmdFadeScreen* cmd) { - if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { +void CutsceneCmd_TransitionGeneral(PlayState* play, CutsceneContext* csCtx, CsCmdTransitionGeneral* cmd) { + if ((csCtx->curFrame >= cmd->startFrame) && (cmd->endFrame >= csCtx->curFrame)) { f32 alpha; play->envCtx.fillScreen = true; - alpha = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->frames); + alpha = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->curFrame); - if (((cmd->unk0 == 1)) || (cmd->unk0 == 2)) { + if (((cmd->type == CS_TRANS_GENERAL_FILL_IN)) || (cmd->type == CS_TRANS_GENERAL_FILL_OUT)) { play->envCtx.screenFillColor[0] = cmd->color.r; play->envCtx.screenFillColor[1] = cmd->color.g; play->envCtx.screenFillColor[2] = cmd->color.b; - if (cmd->unk0 == 2) { + if (cmd->type == CS_TRANS_GENERAL_FILL_OUT) { play->envCtx.screenFillColor[3] = (1.0f - alpha) * 255.0f; } else { play->envCtx.screenFillColor[3] = 255.0f * alpha; @@ -536,43 +563,45 @@ void Cutscene_Command_FadeColorScreen(PlayState* play, CutsceneContext* csCtx, C } } -// Command 0x9D: Set Time of Day & Environment Time -void Cutscene_Command_SetTime(PlayState* play, CutsceneContext* csCtx, CsCmdDayTime* cmd) { - u16 nextTime; +void CutsceneCmd_SetTime(PlayState* play, CutsceneContext* csCtx, CsCmdTime* cmd) { u16 hourAsMinutes; u16 minutes; - if (csCtx->frames == cmd->startFrame) { + if (csCtx->curFrame == cmd->startFrame) { hourAsMinutes = CLOCK_TIME_ALT_F(cmd->hour, 0); minutes = CLOCK_TIME_ALT_F(0, cmd->minute + 1); - nextTime = hourAsMinutes + minutes; - gSaveContext.save.time = nextTime; - gSaveContext.skyboxTime = nextTime; + gSaveContext.save.time = hourAsMinutes + minutes; + gSaveContext.skyboxTime = hourAsMinutes + minutes; } } -void Cutscene_TerminatorImpl(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { - csCtx->state = CS_STATE_4; +void CutsceneCmd_DestinationDefault(PlayState* play, CutsceneContext* csCtx, CsCmdDestination* cmd) { + csCtx->state = CS_STATE_RUN_UNSTOPPABLE; Play_DisableMotionBlur(); Audio_SetCutsceneFlag(false); gSaveContext.cutsceneTransitionControl = 1; - if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (csCtx->frames != cmd->startFrame)) { + // `hudVisibilityForceButtonAlphasByStatus` has a secondary purpose, which is to signal to the title + // screen actor that it should display immediately. This occurs when a title screen cutscene that + // is not the main clock town scene is skipped. + if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (csCtx->curFrame != cmd->startFrame)) { gSaveContext.hudVisibilityForceButtonAlphasByStatus = true; } - gSaveContext.save.cutscene = 0; - if (cmd->base == 1) { - play->nextEntrance = play->csCtx.sceneCsList[play->csCtx.currentCsIndex].nextEntrance; + gSaveContext.save.cutsceneIndex = 0; + + if (cmd->type == CS_DESTINATION_DEFAULT) { + play->nextEntrance = play->csCtx.scriptList[play->csCtx.scriptIndex].nextEntrance; gSaveContext.nextCutsceneIndex = 0; play->transitionTrigger = TRANS_TRIGGER_START; + if (gSaveContext.gameMode != GAMEMODE_TITLE_SCREEN) { Scene_SetExitFade(play); } else { - D_801BB12C++; - if (D_801BB12C >= 2) { - D_801BB12C = 0; + gOpeningEntranceIndex++; + if (gOpeningEntranceIndex >= 2) { + gOpeningEntranceIndex = 0; } play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; } @@ -585,19 +614,18 @@ void Cutscene_TerminatorImpl(PlayState* play, CutsceneContext* csCtx, CsCmdBase* } } -// Command 0x15E -void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { - if (cmd->base == 1) { - if (csCtx->frames == cmd->startFrame) { - Cutscene_TerminatorImpl(play, csCtx, cmd); +void CutsceneCmd_Destination(PlayState* play, CutsceneContext* csCtx, CsCmdDestination* cmd) { + if (cmd->type == CS_DESTINATION_DEFAULT) { + if (csCtx->curFrame == cmd->startFrame) { + CutsceneCmd_DestinationDefault(play, csCtx, cmd); } - } else if (cmd->base == 2) { - if (csCtx->frames == cmd->startFrame) { + } else if (cmd->type == CS_DESTINATION_BOSS_WARP) { + if (csCtx->curFrame == cmd->startFrame) { Play_DisableMotionBlur(); - switch (D_801F4DE2) { - case 0x1F: - if (CHECK_WEEKEVENTREG(WEEKEVENTREG_20_02)) { + switch (gDungeonBossWarpSceneId) { + case SCENE_MITURIN_BS: + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_WOODFALL_TEMPLE)) { play->nextEntrance = ENTRANCE(WOODFALL_TEMPLE, 1); play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; @@ -609,8 +637,8 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB } break; - case 0x44: - if (CHECK_WEEKEVENTREG(WEEKEVENTREG_33_80)) { + case SCENE_HAKUGIN_BS: + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_SNOWHEAD_TEMPLE)) { play->nextEntrance = ENTRANCE(MOUNTAIN_VILLAGE_SPRING, 7); play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; @@ -622,36 +650,38 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB } break; - case 0x5F: - SET_WEEKEVENTREG(WEEKEVENTREG_55_80); + case SCENE_SEA_BS: + SET_WEEKEVENTREG(WEEKEVENTREG_CLEARED_GREAT_BAY_TEMPLE); play->nextEntrance = ENTRANCE(ZORA_CAPE, 8); gSaveContext.nextCutsceneIndex = 0xFFF0; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; break; - case 0x36: - SET_WEEKEVENTREG(WEEKEVENTREG_52_20); + case SCENE_INISIE_BS: + SET_WEEKEVENTREG(WEEKEVENTREG_CLEARED_STONE_TOWER_TEMPLE); play->nextEntrance = ENTRANCE(IKANA_CANYON, 0); gSaveContext.nextCutsceneIndex = 0xFFF1; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; break; + + default: + break; } } } } -// Command 0x15F: Chooses between a cutscene or a rotating mask depending on whether the player has the corresponding -// mask -void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { - if ((csCtx->frames >= cmd->startFrame) && (func_801A3950(SEQ_PLAYER_BGM_MAIN, true) != 0xFF)) { - switch (cmd->base) { - case 1: - Cutscene_TerminatorImpl(play, csCtx, cmd); +// Chooses between a cutscene or a rotating mask depending on whether the player has the corresponding mask +void CutsceneCmd_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCtx, CsCmdChooseCreditsScene* cmd) { + if ((csCtx->curFrame >= cmd->startFrame) && (func_801A3950(SEQ_PLAYER_BGM_MAIN, true) != 0xFF)) { + switch (cmd->type) { + case CS_CREDITS_DESTINATION: + CutsceneCmd_DestinationDefault(play, csCtx, (CsCmdDestination*)cmd); break; - case 2: + case CS_CREDITS_MASK_KAMARO: if (INV_CONTENT(ITEM_MASK_KAMARO) == ITEM_MASK_KAMARO) { play->nextEntrance = ENTRANCE(MILK_BAR, 0); gSaveContext.nextCutsceneIndex = 0xFFF0; @@ -662,7 +692,7 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt play->transitionTrigger = TRANS_TRIGGER_START; break; - case 3: + case CS_CREDITS_MASK_GREAT_FAIRY: if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) { play->nextEntrance = ENTRANCE(FAIRY_FOUNTAIN, 0); gSaveContext.nextCutsceneIndex = 0xFFF0; @@ -673,7 +703,7 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt play->transitionTrigger = TRANS_TRIGGER_START; break; - case 4: + case CS_CREDITS_MASK_ROMANI: if (INV_CONTENT(ITEM_MASK_ROMANI) == ITEM_MASK_ROMANI) { play->nextEntrance = ENTRANCE(ROMANI_RANCH, 0); gSaveContext.nextCutsceneIndex = 0xFFF1; @@ -684,7 +714,7 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt play->transitionTrigger = TRANS_TRIGGER_START; break; - case 5: + case CS_CREDITS_MASK_BLAST: if (INV_CONTENT(ITEM_MASK_BLAST) == ITEM_MASK_BLAST) { play->nextEntrance = ENTRANCE(WEST_CLOCK_TOWN, 0); gSaveContext.nextCutsceneIndex = 0xFFF0; @@ -695,7 +725,7 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt play->transitionTrigger = TRANS_TRIGGER_START; break; - case 6: + case CS_CREDITS_MASK_CIRCUS_LEADER: if (INV_CONTENT(ITEM_MASK_CIRCUS_LEADER) == ITEM_MASK_CIRCUS_LEADER) { play->nextEntrance = ENTRANCE(MILK_BAR, 0); gSaveContext.nextCutsceneIndex = 0xFFF1; @@ -706,7 +736,7 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt play->transitionTrigger = TRANS_TRIGGER_START; break; - case 7: + case CS_CREDITS_MASK_BREMEN: if (INV_CONTENT(ITEM_MASK_BREMEN) == ITEM_MASK_BREMEN) { play->nextEntrance = ENTRANCE(MILK_BAR, 0); gSaveContext.nextCutsceneIndex = 0xFFF3; @@ -717,13 +747,13 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt play->transitionTrigger = TRANS_TRIGGER_START; break; - case 8: + case CS_CREDITS_IKANA: play->nextEntrance = ENTRANCE(IKANA_CANYON, 0); gSaveContext.nextCutsceneIndex = 0xFFF3; play->transitionTrigger = TRANS_TRIGGER_START; break; - case 9: + case CS_CREDITS_MASK_COUPLE: if (INV_CONTENT(ITEM_MASK_COUPLE) == ITEM_MASK_COUPLE) { play->nextEntrance = ENTRANCE(TERMINA_FIELD, 0); gSaveContext.nextCutsceneIndex = 0xFFF8; @@ -734,7 +764,7 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt play->transitionTrigger = TRANS_TRIGGER_START; break; - case 10: + case CS_CREDITS_MASK_BUNNY: if (INV_CONTENT(ITEM_MASK_BUNNY) == ITEM_MASK_BUNNY) { play->nextEntrance = ENTRANCE(CUCCO_SHACK, 0); gSaveContext.nextCutsceneIndex = 0xFFF0; @@ -745,7 +775,7 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt play->transitionTrigger = TRANS_TRIGGER_START; break; - case 11: + case CS_CREDITS_MASK_POSTMAN: if (INV_CONTENT(ITEM_MASK_POSTMAN) == ITEM_MASK_POSTMAN) { play->nextEntrance = ENTRANCE(TERMINA_FIELD, 1); gSaveContext.nextCutsceneIndex = 0xFFF8; @@ -755,35 +785,36 @@ void Cutscene_Command_ChooseCreditsScenes(PlayState* play, CutsceneContext* csCt } play->transitionTrigger = TRANS_TRIGGER_START; break; + + default: + break; } } } -// Command 0x99: Motion blur -void Cutscene_Command_MotionBlur(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { - if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { - if ((csCtx->frames == cmd->startFrame) && (cmd->base == 1)) { +void CutsceneCmd_MotionBlur(PlayState* play, CutsceneContext* csCtx, CsCmdMotionBlur* cmd) { + if ((csCtx->curFrame >= cmd->startFrame) && (cmd->endFrame >= csCtx->curFrame)) { + if ((csCtx->curFrame == cmd->startFrame) && (cmd->type == CS_MOTION_BLUR_ENABLE)) { Play_EnableMotionBlur(180); } - if (cmd->base == 2) { - f32 progress = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->frames); + if (cmd->type == CS_MOTION_BLUR_DISABLE) { + f32 lerp = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->curFrame); - if (progress >= 0.9f) { + if (lerp >= 0.9f) { Play_DisableMotionBlur(); } else { - Play_SetMotionBlurAlpha((1.0f - progress) * 180.0f); + Play_SetMotionBlurAlpha((1.0f - lerp) * 180.0f); } } } } -// Command 0x9A: Gives Tatl to the player -void Cutscene_Command_GiveTatlToPlayer(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { +void CutsceneCmd_GiveTatlToPlayer(PlayState* play, CutsceneContext* csCtx, CsCmdGiveTatl* cmd) { Player* player = GET_PLAYER(play); - if (csCtx->frames == cmd->startFrame) { - if (cmd->base == 1) { + if (csCtx->curFrame == cmd->startFrame) { + if (cmd->giveTatl == true) { gSaveContext.save.hasTatl = true; if (player->tatlActor != NULL) { return; @@ -794,109 +825,112 @@ void Cutscene_Command_GiveTatlToPlayer(PlayState* play, CutsceneContext* csCtx, } } -// Command 0x98 -void Cutscene_Command_TransitionFX(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { - if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { - f32 temp_f0; +void CutsceneCmd_Transition(PlayState* play, CutsceneContext* csCtx, CsCmdTransition* cmd) { + if ((csCtx->curFrame >= cmd->startFrame) && (cmd->endFrame >= csCtx->curFrame)) { + f32 lerp; play->envCtx.fillScreen = true; - temp_f0 = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->frames); + lerp = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->curFrame); - switch (cmd->base) { - case 1: - case 5: + switch (cmd->type) { + case CS_TRANS_GRAY_FILL_IN: + case CS_TRANS_GRAY_FILL_OUT: play->envCtx.screenFillColor[0] = 160; play->envCtx.screenFillColor[1] = 160; play->envCtx.screenFillColor[2] = 160; - if (cmd->base == 1) { - play->envCtx.screenFillColor[3] = 255.0f * temp_f0; - if (temp_f0 == 0.0f) { + + if (cmd->type == CS_TRANS_GRAY_FILL_IN) { + play->envCtx.screenFillColor[3] = 255.0f * lerp; + if (lerp == 0.0f) { func_8019F128(NA_SE_EV_S_STONE_FLASH); } } else { - play->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f; + play->envCtx.screenFillColor[3] = (1.0f - lerp) * 255.0f; } break; - case 2: - case 6: + case CS_TRANS_BLUE_FILL_IN: + case CS_TRANS_BLUE_FILL_OUT: play->envCtx.screenFillColor[0] = 0; play->envCtx.screenFillColor[1] = 0; play->envCtx.screenFillColor[2] = 255; - if (cmd->base == 2) { - play->envCtx.screenFillColor[3] = 255.0f * temp_f0; + if (cmd->type == CS_TRANS_BLUE_FILL_IN) { + play->envCtx.screenFillColor[3] = 255.0f * lerp; } else { - play->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f; + play->envCtx.screenFillColor[3] = (1.0f - lerp) * 255.0f; } break; - case 3: - case 7: + case CS_TRANS_RED_FILL_OUT: + case CS_TRANS_RED_FILL_IN: play->envCtx.screenFillColor[0] = 255; play->envCtx.screenFillColor[1] = 0; play->envCtx.screenFillColor[2] = 0; - if (cmd->base == 3) { - play->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f; + if (cmd->type == CS_TRANS_RED_FILL_OUT) { + play->envCtx.screenFillColor[3] = (1.0f - lerp) * 255.0f; } else { - play->envCtx.screenFillColor[3] = 255.0f * temp_f0; + play->envCtx.screenFillColor[3] = 255.0f * lerp; } break; - case 4: - case 8: + case CS_TRANS_GREEN_FILL_OUT: + case CS_TRANS_GREEN_FILL_IN: play->envCtx.screenFillColor[0] = 0; play->envCtx.screenFillColor[1] = 255; play->envCtx.screenFillColor[2] = 0; - if (cmd->base == 4) { - play->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f; + if (cmd->type == CS_TRANS_GREEN_FILL_OUT) { + play->envCtx.screenFillColor[3] = (1.0f - lerp) * 255.0f; } else { - play->envCtx.screenFillColor[3] = 255.0f * temp_f0; + play->envCtx.screenFillColor[3] = 255.0f * lerp; } break; - case 9: + case CS_TRANS_TRIGGER_INSTANCE: gSaveContext.cutsceneTransitionControl = 1; break; - case 10: - case 11: + case CS_TRANS_BLACK_FILL_OUT: + case CS_TRANS_BLACK_FILL_IN: play->envCtx.screenFillColor[0] = 0; play->envCtx.screenFillColor[1] = 0; play->envCtx.screenFillColor[2] = 0; - if (cmd->base == 10) { - play->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f; + if (cmd->type == CS_TRANS_BLACK_FILL_OUT) { + play->envCtx.screenFillColor[3] = (1.0f - lerp) * 255.0f; } else { - play->envCtx.screenFillColor[3] = 255.0f * temp_f0; + play->envCtx.screenFillColor[3] = 255.0f * lerp; } break; - case 12: - play->envCtx.screenFillColor[0] = (160.0f * (1.0f - temp_f0)); + case CS_TRANS_GRAY_TO_BLACK: + play->envCtx.screenFillColor[0] = (1.0f - lerp) * 160.0f; play->envCtx.screenFillColor[1] = play->envCtx.screenFillColor[0]; play->envCtx.screenFillColor[2] = play->envCtx.screenFillColor[0]; play->envCtx.screenFillColor[3] = 255; break; - case 13: - play->envCtx.screenFillColor[0] = (160.0f * temp_f0); + case CS_TRANS_BLACK_TO_GRAY: + play->envCtx.screenFillColor[0] = 160.0f * lerp; play->envCtx.screenFillColor[1] = play->envCtx.screenFillColor[0]; play->envCtx.screenFillColor[2] = play->envCtx.screenFillColor[0]; play->envCtx.screenFillColor[3] = 255; break; + + default: + break; } } } -// Command 0x5A: Camera -s32 Cutscene_Command_Camera(PlayState* play, u8* cmd) { - s32 sp1C = 0; +s32 CutsceneCmd_UpdateCamSpline(PlayState* play, u8* script) { + s32 cmdBytes = 0; + + bcopy(script, &cmdBytes, sizeof(cmdBytes)); + script += sizeof(cmdBytes); - bcopy(cmd, &sp1C, sizeof(s32)); - cmd += sizeof(s32); if (!Play_IsDebugCamEnabled()) { - func_80161998(cmd, &sCutsceneCameraInfo); + CutsceneCamera_UpdateSplines(script, &sCutsceneCameraInfo); } - return sp1C + sizeof(s32); + return cmdBytes + sizeof(cmdBytes); } /** @@ -970,144 +1004,146 @@ s32 Cutscene_CountNormalMasks(void) { return count; } -// Command 0xA: Textbox -void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdTextbox* cmd) { - static s32 D_801BB160 = CS_TEXTBOX_TYPE_DEFAULT; +void CutsceneCmd_Text(PlayState* play, CutsceneContext* csCtx, CsCmdText* cmd) { + static s32 sCutsceneTextboxType = CS_TEXT_TYPE_DEFAULT; u8 talkState; s32 pad; - u16 originalCsFrames; - s32 pad2; + u16 endFrame; - if ((cmd->startFrame >= csCtx->frames) || ((cmd->endFrame < csCtx->frames))) { + if ((csCtx->curFrame <= cmd->startFrame) || (csCtx->curFrame > cmd->endFrame)) { return; } - if (cmd->type != CS_TEXTBOX_TYPE_LEARN_SONG) { - if (D_801BB124 != cmd->base) { - if (D_801BB160 == CS_TEXTBOX_TYPE_3) { - csCtx->frames--; + if (cmd->type != CS_TEXT_OCARINA_ACTION) { + if (sCurTextId != cmd->textId) { + if (sCutsceneTextboxType == CS_TEXT_TYPE_3) { + csCtx->curFrame--; } - D_801BB160 = CS_TEXTBOX_TYPE_1; - D_801BB124 = cmd->base; - if (cmd->type == CS_TEXTBOX_TYPE_BOSSES_REMAINS) { + sCutsceneTextboxType = CS_TEXT_TYPE_1; + sCurTextId = cmd->textId; + if (cmd->type == CS_TEXT_TYPE_BOSSES_REMAINS) { if (CHECK_QUEST_ITEM(QUEST_REMAINS_ODOLWA) && CHECK_QUEST_ITEM(QUEST_REMAINS_GOHT) && CHECK_QUEST_ITEM(QUEST_REMAINS_GYORG) && CHECK_QUEST_ITEM(QUEST_REMAINS_TWINMOLD)) { - if (cmd->textId1 != 0xFFFF) { - Message_StartTextbox(play, cmd->textId1, NULL); + if (cmd->altTextId1 != 0xFFFF) { + Message_StartTextbox(play, cmd->altTextId1, NULL); } } else { - Message_StartTextbox(play, cmd->base, NULL); + Message_StartTextbox(play, cmd->textId, NULL); } - } else if (cmd->type == CS_TEXTBOX_TYPE_ALL_NORMAL_MASKS) { + } else if (cmd->type == CS_TEXT_TYPE_ALL_NORMAL_MASKS) { if (Cutscene_CountNormalMasks() == 20) { - if (cmd->textId1 != 0xFFFF) { - Message_StartTextbox(play, cmd->textId1, NULL); + if (cmd->altTextId1 != 0xFFFF) { + Message_StartTextbox(play, cmd->altTextId1, NULL); } } else { - Message_StartTextbox(play, cmd->base, NULL); + Message_StartTextbox(play, cmd->textId, NULL); } } else { - Message_StartTextbox(play, cmd->base, NULL); + Message_StartTextbox(play, cmd->textId, NULL); } - } else { - goto else_label; + //! FAKE: return; + goto end; } - } else if (D_801BB128 != cmd->base) { - D_801BB160 = CS_TEXTBOX_TYPE_LEARN_SONG; - D_801BB128 = cmd->base; - func_80152434(play, cmd->base); } else { - else_label: - if (csCtx->frames >= cmd->endFrame) { - // The Textbox command can change the current cutscene frame, mainly to prevent advancing the cutscene when - // a textbox that is expected to be closed by the user is still open. - - originalCsFrames = csCtx->frames; - talkState = Message_GetState(&play->msgCtx); - if ((talkState != TEXT_STATE_CLOSING) && (talkState != TEXT_STATE_NONE) && (talkState != TEXT_STATE_7) && - (talkState != TEXT_STATE_8)) { - csCtx->frames--; - if ((talkState == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { - if (play->msgCtx.choiceIndex == 0) { - if (cmd->base == 0x33BD) { - func_8019F230(); - } + if (sCurOcarinaAction != cmd->textId) { + sCutsceneTextboxType = CS_TEXT_OCARINA_ACTION; + sCurOcarinaAction = cmd->textId; + func_80152434(play, cmd->textId); + return; + } + } + + if (csCtx->curFrame >= cmd->endFrame) { + // The Textbox command can change the current cutscene frame, mainly to prevent advancing the cutscene when + // a textbox that is expected to be closed by the user is still open. + endFrame = csCtx->curFrame; + talkState = Message_GetState(&play->msgCtx); + if ((talkState != TEXT_STATE_CLOSING) && (talkState != TEXT_STATE_NONE) && (talkState != TEXT_STATE_7) && + (talkState != TEXT_STATE_8)) { + csCtx->curFrame--; + + if ((talkState == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { + if (play->msgCtx.choiceIndex == 0) { + if (cmd->textId == 0x33BD) { + // Gorman Track: do you understand? + func_8019F230(); + } - if (cmd->textId1 != 0xFFFF) { - Message_ContinueTextbox(play, cmd->textId1); - if (cmd->type == CS_TEXTBOX_TYPE_3) { - D_801BB160 = CS_TEXTBOX_TYPE_3; - if (cmd->textId2 != 0xFFFF) { - csCtx->frames++; - } + if (cmd->altTextId1 != 0xFFFF) { + Message_ContinueTextbox(play, cmd->altTextId1); + if (cmd->type == CS_TEXT_TYPE_3) { + sCutsceneTextboxType = CS_TEXT_TYPE_3; + if (cmd->altTextId2 != 0xFFFF) { + csCtx->curFrame++; } - } else { - Message_CloseTextbox(play); - csCtx->frames++; } } else { - if (cmd->base == 0x33BD) { - func_8019F208(); - } + Message_CloseTextbox(play); + csCtx->curFrame++; + } + } else { + if (cmd->textId == 0x33BD) { + // Gorman Track: do you understand? + func_8019F208(); + } - if (cmd->textId2 != 0xFFFF) { - Message_ContinueTextbox(play, cmd->textId2); - if (cmd->type == CS_TEXTBOX_TYPE_3) { - D_801BB160 = CS_TEXTBOX_TYPE_3; - if (cmd->textId1 != 0xFFFF) { - csCtx->frames++; - } + if (cmd->altTextId2 != 0xFFFF) { + Message_ContinueTextbox(play, cmd->altTextId2); + if (cmd->type == CS_TEXT_TYPE_3) { + sCutsceneTextboxType = CS_TEXT_TYPE_3; + if (cmd->altTextId1 != 0xFFFF) { + csCtx->curFrame++; } - } else { - Message_CloseTextbox(play); - csCtx->frames++; } + } else { + Message_CloseTextbox(play); + csCtx->curFrame++; } } - - if ((talkState == TEXT_STATE_5) && Message_ShouldAdvance(play)) { - func_80152434(play, cmd->base); - } } - if ((talkState == TEXT_STATE_CLOSING) && (D_801BB160 == CS_TEXTBOX_TYPE_3)) { - csCtx->frames--; - D_801BB124++; + if ((talkState == TEXT_STATE_5) && Message_ShouldAdvance(play)) { + func_80152434(play, cmd->textId); } + } - if (originalCsFrames == csCtx->frames) { - Interface_SetHudVisibility(HUD_VISIBILITY_NONE); - D_801BB124 = 0; - D_801BB128 = 0; - func_80161C0C(); - } else { - func_80161BE0(1); - } + if ((talkState == TEXT_STATE_CLOSING) && (sCutsceneTextboxType == CS_TEXT_TYPE_3)) { + csCtx->curFrame--; + sCurTextId++; + } + + if (endFrame == csCtx->curFrame) { + Interface_SetHudVisibility(HUD_VISIBILITY_NONE); + sCurTextId = 0; + sCurOcarinaAction = 0; + CutsceneCamera_Reset(); + } else { + CutsceneCamera_SetState(CS_CAM_STATE_UPDATE_SPLINE); } } +end:; } -// Related to actorActions. Maybe a generic actorAction setter? -void func_800ECD7C(CutsceneContext* csCtx, u8** cutscenePtr, s16 index) { +void Cutscene_SetActorCue(CutsceneContext* csCtx, u8** script, s16 cueChannel) { s32 i; - s32 count; + s32 numCues; - bcopy(*cutscenePtr, &count, sizeof(s32)); - *cutscenePtr += sizeof(s32); + bcopy(*script, &numCues, sizeof(numCues)); + *script += sizeof(numCues); - for (i = 0; i < count; i++) { - CsCmdActorAction* actorAction = *(CsCmdActorAction**)cutscenePtr; + for (i = 0; i < numCues; i++) { + CsCmdActorCue* cue = *(CsCmdActorCue**)script; - if ((csCtx->frames >= actorAction->startFrame) && (csCtx->frames < actorAction->endFrame)) { - csCtx->actorActions[index] = actorAction; + if ((csCtx->curFrame >= cue->startFrame) && (csCtx->curFrame < cue->endFrame)) { + csCtx->actorCues[cueChannel] = cue; } - *cutscenePtr += sizeof(CsCmdActorAction); + *script += sizeof(CsCmdActorCue); } } /** - * Loops over the cutscene data itself (`cutscenePtr`), applying the effects of each command instantaneously (for most + * Loops over the cutscene data itself (`script`), applying the effects of each command instantaneously (for most * commands). * * The cutscene data is an irregularly-structured array of words, which is made up of @@ -1124,15 +1160,15 @@ void func_800ECD7C(CutsceneContext* csCtx, u8** cutscenePtr, s16 index) { * has (N). This is followed by N commands of the said category. (The exception is Camera, which has the length of the * list in bytes instead of the number of commands). * - * For most command lists categories (all but the actorActions and Camera commands): + * For most command lists categories (all but the actorCues and Camera commands): * - For each command list found, read the number of commands and loop over them, passing each one to the corresponding * function which handles the command, applying its effects and checking the frame range stored in the command. * * This function is invoked once per frame that a cutscene is active. * - * TODO: consider changing the type of `cutscenePtr` to `uintptr_t` when this function matches. + * TODO: consider changing the type of `script` to `uintptr_t` when this function matches. */ -void Cutscene_ProcessCommands(PlayState* play, CutsceneContext* csCtx, u8* cutscenePtr) { +void Cutscene_ProcessScript(PlayState* play, CutsceneContext* csCtx, u8* script) { s32 i; s32 j; s32 pad; @@ -1140,44 +1176,46 @@ void Cutscene_ProcessCommands(PlayState* play, CutsceneContext* csCtx, u8* cutsc u32 cmdType; s32 cmdEntries; s32 pad2; - s32 cutsceneEndFrame; - CsCmdBase* cmd; + s32 csFrameCount; + void* cmd; // Read the command list count and the ending frame for this cutscene - bcopy(cutscenePtr, &totalEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); - bcopy(cutscenePtr, &cutsceneEndFrame, sizeof(s32)); - cutscenePtr += sizeof(s32); - - if (((u16)cutsceneEndFrame < csCtx->frames) && (play->transitionTrigger != TRANS_TRIGGER_START) && - (csCtx->state != CS_STATE_4)) { - csCtx->state = CS_STATE_3; + bcopy(script, &totalEntries, sizeof(totalEntries)); + script += sizeof(totalEntries); + + bcopy(script, &csFrameCount, sizeof(csFrameCount)); + script += sizeof(csFrameCount); + + if ((csCtx->curFrame > (u16)csFrameCount) && (play->transitionTrigger != TRANS_TRIGGER_START) && + (csCtx->state != CS_STATE_RUN_UNSTOPPABLE)) { + csCtx->state = CS_STATE_STOP; return; } // Loop over every command list for (i = 0; i < totalEntries; i++) { // Read the command type of the current command list. - bcopy(cutscenePtr, &cmdType, sizeof(u32)); - cutscenePtr += sizeof(u32); + bcopy(script, &cmdType, sizeof(cmdType)); + script += sizeof(cmdType); - // TODO: This should probably be added to the CutsceneCmd enum. Consider doing it when this function matches. - if (cmdType == 0xFFFFFFFF) { + if (cmdType == CS_CAM_STOP) { break; } - // Check special cases of command types. This are generic ActorActions - // Ranges: [0x64, 0x96), 0xC9, [0x1C2, 0x258) - if (((cmdType >= 100) && (cmdType < 150)) || (cmdType == 201) || ((cmdType >= 450) && (cmdType < 600))) { - for (j = 0; j < ARRAY_COUNT(D_801F4DC8); j = (s16)(j + 1)) { - if (D_801F4DC8[j] == (u16)cmdType) { - func_800ECD7C(csCtx, &cutscenePtr, j); - cmdType = -2; + if (((cmdType >= CS_CMD_ACTOR_CUE_100) && (cmdType <= CS_CMD_ACTOR_CUE_149)) || + (cmdType == CS_CMD_ACTOR_CUE_201) || + ((cmdType >= CS_CMD_ACTOR_CUE_450) && (cmdType <= CS_CMD_ACTOR_CUE_599))) { + for (j = 0; j < ARRAY_COUNT(sCueTypeList); j = (s16)(j + 1)) { + if (sCueTypeList[j] == (u16)cmdType) { + Cutscene_SetActorCue(csCtx, &script, j); + cmdType = CS_CMD_ACTOR_CUE_POST_PROCESS; break; - } else if (D_801F4DC8[j] == 0) { - D_801F4DC8[j] = cmdType; - func_800ECD7C(csCtx, &cutscenePtr, j); - cmdType = -2; + } + + if (sCueTypeList[j] == 0) { + sCueTypeList[j] = cmdType; + Cutscene_SetActorCue(csCtx, &script, j); + cmdType = CS_CMD_ACTOR_CUE_POST_PROCESS; break; } } @@ -1185,203 +1223,227 @@ void Cutscene_ProcessCommands(PlayState* play, CutsceneContext* csCtx, u8* cutsc switch (cmdType) { case CS_CMD_MISC: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_Misc(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + CutsceneCmd_Misc(play, csCtx, (CsCmdMisc*)script); + script += sizeof(CsCmdMisc); } break; - case CS_CMD_SET_LIGHTING: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_LIGHT_SETTING: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_SetLighting(play, csCtx, (CsCmdEnvLighting*)cutscenePtr); - cutscenePtr += sizeof(CsCmdEnvLighting); + CutsceneCmd_SetLightSetting(play, csCtx, (CsCmdLightSetting*)script); + script += sizeof(CsCmdLightSetting); } break; - case CS_CMD_PLAYSEQ: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_START_SEQ: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_PlaySequence(play, csCtx, (CsCmdSequenceChange*)cutscenePtr); - cutscenePtr += sizeof(CsCmdSequenceChange); + CutsceneCmd_StartSequence(play, csCtx, (CsCmdStartSeq*)script); + script += sizeof(CsCmdStartSeq); } break; - case CS_CMD_STOPSEQ: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_STOP_SEQ: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_StopSequence(play, csCtx, (CsCmdSequenceChange*)cutscenePtr); - cutscenePtr += sizeof(CsCmdSequenceChange); + CutsceneCmd_StopSequence(play, csCtx, (CsCmdStopSeq*)script); + script += sizeof(CsCmdStartSeq); } break; - case CS_CMD_FADESEQ: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_FADE_OUT_SEQ: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_FadeSequence(play, csCtx, (CsCmdSequenceFade*)cutscenePtr); - cutscenePtr += sizeof(CsCmdSequenceFade); + CutsceneCmd_FadeOutSequence(play, csCtx, (CsCmdFadeOutSeq*)script); + script += sizeof(CsCmdFadeOutSeq); } break; - case CS_CMD_PLAYAMBIENCE: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_START_AMBIENCE: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_PlayAmbienceSequence(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + CutsceneCmd_StartAmbience(play, csCtx, (CsCmdStartAmbience*)script); + script += sizeof(CsCmdStartAmbience); } break; - case CS_CMD_FADEAMBIENCE: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_FADE_OUT_AMBIENCE: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_FadeAmbienceSequence(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + CutsceneCmd_FadeOutAmbience(play, csCtx, (CsCmdFadeOutAmbience*)script); + script += sizeof(CsCmdFadeOutAmbience); } break; - case CS_CMD_130: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_SFX_REVERB_INDEX_2: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - func_800EAD48(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + Cutscene_SetSfxReverbIndexTo2(play, csCtx, (CsCmdSfxReverbIndexTo2*)script); + script += sizeof(CsCmdSfxReverbIndexTo2); } break; - case CS_CMD_131: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_SFX_REVERB_INDEX_1: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - func_800EAD7C(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + Cutscene_SetSfxReverbIndexTo1(play, csCtx, (CsCmdSfxReverbIndexTo1*)script); + script += sizeof(CsCmdSfxReverbIndexTo1); } break; - case CS_CMD_132: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_MODIFY_SEQ: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - func_800EADB0(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + CutsceneCmd_ModifySequence(play, csCtx, (CsCmdModifySeq*)script); + script += sizeof(CsCmdModifySeq); } break; case CS_CMD_RUMBLE: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_Rumble(play, csCtx, (CsCmdRumble*)cutscenePtr); - cutscenePtr += sizeof(CsCmdRumble); + CutsceneCmd_RumbleController(play, csCtx, (CsCmdRumble*)script); + script += sizeof(CsCmdRumble); } break; - case CS_CMD_FADESCREEN: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_TRANSITION_GENERAL: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_FadeColorScreen(play, csCtx, (CsCmdFadeScreen*)cutscenePtr); - cutscenePtr += sizeof(CsCmdFadeScreen); + CutsceneCmd_TransitionGeneral(play, csCtx, (CsCmdTransitionGeneral*)script); + script += sizeof(CsCmdTransitionGeneral); } break; - case CS_CMD_SETTIME: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_TIME: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_SetTime(play, csCtx, (CsCmdDayTime*)cutscenePtr); - cutscenePtr += sizeof(CsCmdDayTime); + CutsceneCmd_SetTime(play, csCtx, (CsCmdTime*)script); + script += sizeof(CsCmdTime); } break; - case CS_CMD_SET_PLAYER_ACTION: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_PLAYER_CUE: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - cmd = (CsCmdBase*)cutscenePtr; - if ((cmd->startFrame <= csCtx->frames) && (csCtx->frames < cmd->endFrame)) { - csCtx->playerAction = (CsCmdActorAction*)cmd; + cmd = script; + + if ((((CsCmdActorCue*)cmd)->startFrame <= csCtx->curFrame) && + (csCtx->curFrame < ((CsCmdActorCue*)cmd)->endFrame)) { + csCtx->playerCue = (CsCmdActorCue*)cmd; } - cutscenePtr += sizeof(CsCmdActorAction); + script += sizeof(CsCmdActorCue); } break; - case CS_CMD_CAMERA: - cutscenePtr += Cutscene_Command_Camera(play, cutscenePtr); + case CS_CMD_CAMERA_SPLINE: + script += CutsceneCmd_UpdateCamSpline(play, script); break; - case CS_CMD_TERMINATOR: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_DESTINATION: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_Terminator(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + CutsceneCmd_Destination(play, csCtx, (CsCmdDestination*)script); + script += sizeof(CsCmdDestination); } break; case CS_CMD_CHOOSE_CREDITS_SCENES: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_ChooseCreditsScenes(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + CutsceneCmd_ChooseCreditsScenes(play, csCtx, (CsCmdChooseCreditsScene*)script); + script += sizeof(CsCmdChooseCreditsScene); } break; - case CS_CMD_TEXTBOX: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_TEXT: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - cmd = (CsCmdBase*)cutscenePtr; - if (cmd->base != 0xFFFF) { - Cutscene_Command_Textbox(play, csCtx, (CsCmdTextbox*)cmd); + cmd = script; + + if (((CsCmdText*)cmd)->textId != 0xFFFF) { + CutsceneCmd_Text(play, csCtx, (CsCmdText*)cmd); } - cutscenePtr += sizeof(CsCmdTextbox); + script += sizeof(CsCmdText); } break; - case CS_CMD_SCENE_TRANS_FX: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_TRANSITION: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_TransitionFX(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + CutsceneCmd_Transition(play, csCtx, (CsCmdTransition*)script); + script += sizeof(CsCmdTransition); } break; - case CS_CMD_MOTIONBLUR: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_MOTION_BLUR: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_MotionBlur(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + CutsceneCmd_MotionBlur(play, csCtx, (CsCmdMotionBlur*)script); + script += sizeof(CsCmdMotionBlur); } break; - case CS_CMD_GIVETATL: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + case CS_CMD_GIVE_TATL: + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - Cutscene_Command_GiveTatlToPlayer(play, csCtx, (CsCmdBase*)cutscenePtr); - cutscenePtr += sizeof(CsCmdBase); + CutsceneCmd_GiveTatlToPlayer(play, csCtx, (CsCmdGiveTatl*)script); + script += sizeof(CsCmdGiveTatl); } break; - case -2: + case CS_CMD_ACTOR_CUE_POST_PROCESS: break; default: - bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); - cutscenePtr += sizeof(s32); + bcopy(script, &cmdEntries, sizeof(cmdEntries)); + script += sizeof(cmdEntries); + for (j = 0; j < cmdEntries; j++) { - cutscenePtr += sizeof(CsCmdBase); + script += sizeof(CsCmdUnimplemented); } break; } @@ -1390,120 +1452,125 @@ void Cutscene_ProcessCommands(PlayState* play, CutsceneContext* csCtx, u8* cutsc /* End of command handling section */ -void func_800ED980(PlayState* play, CutsceneContext* csCtx) { - if (gSaveContext.save.cutscene >= 0xFFF0) { - csCtx->frames++; - Cutscene_ProcessCommands(play, csCtx, (u8*)play->csCtx.csData); +void CutsceneHandler_RunScript(PlayState* play, CutsceneContext* csCtx) { + if (gSaveContext.save.cutsceneIndex >= 0xFFF0) { + csCtx->curFrame++; + Cutscene_ProcessScript(play, csCtx, (u8*)play->csCtx.script); } } -void func_800ED9C4(PlayState* play, CutsceneContext* csCtx) { - if (func_800EA220(play, csCtx, 0.0f)) { +void CutsceneHandler_StopManual(PlayState* play, CutsceneContext* csCtx) { + if (Cutscene_StepTimer(play, csCtx, 0.0f)) { Audio_SetCutsceneFlag(false); - csCtx->state = CS_STATE_0; + csCtx->state = CS_STATE_IDLE; } } -// unused -void func_800EDA04(PlayState* play, CutsceneContext* csCtx) { - if (func_800EA220(play, csCtx, 0.0f)) { +void CutsceneHandler_StopScript(PlayState* play, CutsceneContext* csCtx) { + if (Cutscene_StepTimer(play, csCtx, 0.0f)) { s16 i; - csCtx->playerAction = NULL; + csCtx->playerCue = NULL; - for (i = 0; i < ARRAY_COUNT(csCtx->actorActions); i++) { - csCtx->actorActions[i] = NULL; + for (i = 0; i < ARRAY_COUNT(csCtx->actorCues); i++) { + csCtx->actorCues[i] = NULL; } - gSaveContext.save.cutscene = 0; + gSaveContext.save.cutsceneIndex = 0; gSaveContext.gameMode = GAMEMODE_NORMAL; - ActorCutscene_Stop(0x7F); + + CutsceneManager_Stop(CS_ID_GLOBAL_END); Audio_SetCutsceneFlag(false); - csCtx->state = CS_STATE_0; + csCtx->state = CS_STATE_IDLE; } } -void func_800EDA84(PlayState* play, CutsceneContext* csCtx) { - if ((gSaveContext.cutsceneTrigger != 0) && (csCtx->state == CS_STATE_0) && !Player_InCsMode(play)) { - gSaveContext.save.cutscene = 0xFFFD; +void Cutscene_SetupScripted(PlayState* play, CutsceneContext* csCtx) { + if ((gSaveContext.cutsceneTrigger != 0) && (csCtx->state == CS_STATE_IDLE) && !Player_InCsMode(play)) { + gSaveContext.save.cutsceneIndex = 0xFFFD; } - if ((gSaveContext.save.cutscene >= 0xFFF0) && (csCtx->state == CS_STATE_0)) { + if ((gSaveContext.save.cutsceneIndex >= 0xFFF0) && (csCtx->state == CS_STATE_IDLE)) { s16 i; - D_801BB124 = 0; - D_801BB128 = 0; - csCtx->playerAction = NULL; + sCurTextId = 0; + sCurOcarinaAction = 0; + csCtx->playerCue = NULL; - for (i = 0; i < ARRAY_COUNT(csCtx->actorActions); i++) { - csCtx->actorActions[i] = NULL; + for (i = 0; i < ARRAY_COUNT(csCtx->actorCues); i++) { + csCtx->actorCues[i] = NULL; } - csCtx->state++; - if (csCtx->state == CS_STATE_1) { + csCtx->state++; // CS_STATE_START + + if (csCtx->state == CS_STATE_START) { Audio_SetCutsceneFlag(true); - csCtx->frames = 0xFFFF; - csCtx->subCamId = ActorCutscene_GetCurrentSubCamId(0x7F); - func_8016119C(Play_GetCamera(play, csCtx->subCamId), &sCutsceneCameraInfo); - csCtx->unk_18 = 0xFFFF; + csCtx->curFrame = 0xFFFF; + + csCtx->subCamId = CutsceneManager_GetCurrentSubCamId(CS_ID_GLOBAL_END); + CutsceneCamera_Init(Play_GetCamera(play, csCtx->subCamId), &sCutsceneCameraInfo); + + // OoT Remnant + csCtx->camEyeSplinePointsAppliedFrame = CS_CAM_DATA_NOT_APPLIED; if (gSaveContext.cutsceneTrigger == 0) { Interface_SetHudVisibility(HUD_VISIBILITY_NONE); ShrinkWindow_Letterbox_SetSizeTarget(32); ShrinkWindow_Letterbox_SetSize(32); - csCtx->state++; + csCtx->state++; // CS_STATE_RUN } - func_800ED980(play, csCtx); + CutsceneHandler_RunScript(play, csCtx); } gSaveContext.cutsceneTrigger = 0; } } -// HandleFlags? -void func_800EDBE0(PlayState* play) { +void Cutscene_HandleEntranceTriggers(PlayState* play) { s32 pad; - s16 sp2A; - SceneTableEntry* sp24; - s32 temp_v0_3; + s16 csId; + SceneTableEntry* scene; + s32 scriptIndex; if (((gSaveContext.gameMode == GAMEMODE_NORMAL) || (gSaveContext.gameMode == GAMEMODE_TITLE_SCREEN)) && (gSaveContext.respawnFlag <= 0)) { - sp2A = func_800F21CC(); - if (sp2A != -1) { - temp_v0_3 = func_800F2138(sp2A); - if (temp_v0_3 != -1) { - if ((play->csCtx.sceneCsList[temp_v0_3].unk7 != 0xFF) && (gSaveContext.respawnFlag == 0)) { - if (play->csCtx.sceneCsList[temp_v0_3].unk7 == 0xFE) { - ActorCutscene_Start(sp2A, NULL); + // Try to find an actor cutscene that's triggered by the current spawn + csId = CutsceneManager_FindEntranceCsId(); + if (csId != CS_ID_NONE) { + scriptIndex = CutsceneManager_GetCutsceneScriptIndex(csId); + if (scriptIndex != CS_SCRIPT_ID_NONE) { + // A scripted cutscene is triggered by a spawn + if ((play->csCtx.scriptList[scriptIndex].spawnFlags != CS_SPAWN_FLAG_NONE) && + (gSaveContext.respawnFlag == 0)) { + if (play->csCtx.scriptList[scriptIndex].spawnFlags == CS_SPAWN_FLAG_ALWAYS) { + // Entrance cutscenes that always run + CutsceneManager_Start(csId, NULL); gSaveContext.showTitleCard = false; - } else if (!(((void)0, gSaveContext.save.saveInfo - .weekEventReg[(play->csCtx.sceneCsList[temp_v0_3].unk7 / 8)]) & - (1 << (play->csCtx.sceneCsList[temp_v0_3].unk7 % 8)))) { - // TODO: macros for this kind of weekEventReg access - gSaveContext.save.saveInfo.weekEventReg[(play->csCtx.sceneCsList[temp_v0_3].unk7 / 8)] = - ((void)0, - gSaveContext.save.saveInfo.weekEventReg[(play->csCtx.sceneCsList[temp_v0_3].unk7 / 8)]) | - (1 << (play->csCtx.sceneCsList[temp_v0_3].unk7 % 8)); - ActorCutscene_Start(sp2A, NULL); + + } else if (!CHECK_CS_SPAWN_FLAG_WEEKEVENTREG(play->csCtx.scriptList[scriptIndex].spawnFlags)) { + // Entrance cutscenes that only run once + SET_CS_SPAWN_FLAG_WEEKEVENTREG(play->csCtx.scriptList[scriptIndex].spawnFlags); + CutsceneManager_Start(csId, NULL); + // The title card will be used by the cs misc command if necessary. gSaveContext.showTitleCard = false; } } } else { - ActorCutscene_StartAndSetUnkLinkFields(sp2A, NULL); + // A non-scripted cutscene is triggered by a spawn + CutsceneManager_StartWithPlayerCs(csId, NULL); } } } if ((gSaveContext.respawnFlag == 0) || (gSaveContext.respawnFlag == -2)) { - sp24 = play->loadedScene; - if ((sp24->titleTextId != 0) && gSaveContext.showTitleCard) { + scene = play->loadedScene; + if ((scene->titleTextId != 0) && gSaveContext.showTitleCard) { if ((Entrance_GetTransitionFlags(((void)0, gSaveContext.save.entrance) + ((void)0, gSaveContext.sceneLayer)) & 0x4000) != 0) { - func_80151A68(play, sp24->titleTextId); + func_80151A68(play, scene->titleTextId); } } @@ -1517,10 +1584,10 @@ void func_800EDDB0(PlayState* play) { void func_800EDDBC(UNK_TYPE arg0, UNK_TYPE arg1) { } -void Cutscene_LoadCutsceneData(PlayState* play, u8 csIndex) { - if (dREG(95) == 0) { - play->csCtx.currentCsIndex = csIndex; - play->csCtx.csData = Lib_SegmentedToVirtual(play->csCtx.sceneCsList[csIndex].segmentedData); +void Cutscene_StartScripted(PlayState* play, u8 scriptIndex) { + if (!R_USE_DEBUG_CUTSCENE) { + play->csCtx.scriptIndex = scriptIndex; + play->csCtx.script = Lib_SegmentedToVirtual(play->csCtx.scriptList[scriptIndex].script); } gSaveContext.cutsceneTrigger = 1; @@ -1532,32 +1599,32 @@ void Cutscene_LoadCutsceneData(PlayState* play, u8 csIndex) { * Interpolates the actor's position based on the corresponding actor action's position * and the current cutscene frame */ -void Cutscene_ActorTranslate(Actor* actor, PlayState* play, s32 actorActionIndex) { - Vec3f start; - Vec3f end; - CsCmdActorAction* entry = play->csCtx.actorActions[actorActionIndex]; - f32 progress; - - start.x = entry->startPos.x; - start.y = entry->startPos.y; - start.z = entry->startPos.z; - end.x = entry->endPos.x; - end.y = entry->endPos.y; - end.z = entry->endPos.z; - - progress = Environment_LerpWeight(entry->endFrame, entry->startFrame, play->csCtx.frames); - - VEC3F_LERPIMPDST(&actor->world.pos, &start, &end, progress); +void Cutscene_ActorTranslate(Actor* actor, PlayState* play, s32 cueChannel) { + Vec3f startPos; + Vec3f endPos; + CsCmdActorCue* cue = play->csCtx.actorCues[cueChannel]; + f32 lerp; + + startPos.x = cue->startPos.x; + startPos.y = cue->startPos.y; + startPos.z = cue->startPos.z; + endPos.x = cue->endPos.x; + endPos.y = cue->endPos.y; + endPos.z = cue->endPos.z; + + lerp = Environment_LerpWeight(cue->endFrame, cue->startFrame, play->csCtx.curFrame); + + VEC3F_LERPIMPDST(&actor->world.pos, &startPos, &endPos, lerp); } /** * Interpolates the actor's position based on the corresponding actor action's position * and the current cutscene frame, and sets the actor's yaw using the actor action yaw */ -void Cutscene_ActorTranslateAndYaw(Actor* actor, PlayState* play, s32 actorActionIndex) { - Cutscene_ActorTranslate(actor, play, actorActionIndex); +void Cutscene_ActorTranslateAndYaw(Actor* actor, PlayState* play, s32 cueChannel) { + Cutscene_ActorTranslate(actor, play, cueChannel); - actor->world.rot.y = play->csCtx.actorActions[actorActionIndex]->urot.y; + actor->world.rot.y = play->csCtx.actorCues[cueChannel]->rot.y; actor->shape.rot.y = actor->world.rot.y; } @@ -1565,25 +1632,25 @@ void Cutscene_ActorTranslateAndYaw(Actor* actor, PlayState* play, s32 actorActio * Interpolates the actor's position and yaw based on the corresponding actor action's * position and the current cutscene frame */ -void Cutscene_ActorTranslateAndYawSmooth(Actor* actor, PlayState* play, s32 actorActionIndex) { - Vec3f start; - Vec3f end; - CsCmdActorAction* entry; - f32 progress; +void Cutscene_ActorTranslateAndYawSmooth(Actor* actor, PlayState* play, s32 cueChannel) { + Vec3f startPos; + Vec3f endPos; + CsCmdActorCue* cue; + f32 lerp; - start.x = play->csCtx.actorActions[actorActionIndex]->startPos.x; - start.y = play->csCtx.actorActions[actorActionIndex]->startPos.y; - start.z = play->csCtx.actorActions[actorActionIndex]->startPos.z; - end.x = play->csCtx.actorActions[actorActionIndex]->endPos.x; - end.y = play->csCtx.actorActions[actorActionIndex]->endPos.y; - end.z = play->csCtx.actorActions[actorActionIndex]->endPos.z; + startPos.x = play->csCtx.actorCues[cueChannel]->startPos.x; + startPos.y = play->csCtx.actorCues[cueChannel]->startPos.y; + startPos.z = play->csCtx.actorCues[cueChannel]->startPos.z; + endPos.x = play->csCtx.actorCues[cueChannel]->endPos.x; + endPos.y = play->csCtx.actorCues[cueChannel]->endPos.y; + endPos.z = play->csCtx.actorCues[cueChannel]->endPos.z; - entry = play->csCtx.actorActions[actorActionIndex]; - progress = Environment_LerpWeight(entry->endFrame, entry->startFrame, play->csCtx.frames); + cue = play->csCtx.actorCues[cueChannel]; + lerp = Environment_LerpWeight(cue->endFrame, cue->startFrame, play->csCtx.curFrame); - VEC3F_LERPIMPDST(&actor->world.pos, &start, &end, progress); + VEC3F_LERPIMPDST(&actor->world.pos, &startPos, &endPos, lerp); - Math_SmoothStepToS(&actor->world.rot.y, Math_Vec3f_Yaw(&start, &end), 10, 1000, 1); + Math_SmoothStepToS(&actor->world.rot.y, Math_Vec3f_Yaw(&startPos, &endPos), 10, 1000, 1); actor->shape.rot.y = actor->world.rot.y; } @@ -1591,24 +1658,24 @@ void Cutscene_ActorTranslateAndYawSmooth(Actor* actor, PlayState* play, s32 acto * Interpolates the actor's XZ position and yaw based on the corresponding actor action's * position and the current cutscene frame */ -void Cutscene_ActorTranslateXZAndYawSmooth(Actor* actor, PlayState* play, s32 actorActionIndex) { - Vec3f start; - Vec3f end; - CsCmdActorAction* entry; - f32 progress; +void Cutscene_ActorTranslateXZAndYawSmooth(Actor* actor, PlayState* play, s32 cueChannel) { + Vec3f startPos; + Vec3f endPos; + CsCmdActorCue* cue; + f32 lerp; - start.x = play->csCtx.actorActions[actorActionIndex]->startPos.x; - start.z = play->csCtx.actorActions[actorActionIndex]->startPos.z; - end.x = play->csCtx.actorActions[actorActionIndex]->endPos.x; - end.z = play->csCtx.actorActions[actorActionIndex]->endPos.z; + startPos.x = play->csCtx.actorCues[cueChannel]->startPos.x; + startPos.z = play->csCtx.actorCues[cueChannel]->startPos.z; + endPos.x = play->csCtx.actorCues[cueChannel]->endPos.x; + endPos.z = play->csCtx.actorCues[cueChannel]->endPos.z; - entry = play->csCtx.actorActions[actorActionIndex]; - progress = Environment_LerpWeight(entry->endFrame, entry->startFrame, play->csCtx.frames); + cue = play->csCtx.actorCues[cueChannel]; + lerp = Environment_LerpWeight(cue->endFrame, cue->startFrame, play->csCtx.curFrame); - actor->world.pos.x = start.x + (end.x - start.x) * progress; - actor->world.pos.z = start.z + (end.z - start.z) * progress; + actor->world.pos.x = startPos.x + (endPos.x - startPos.x) * lerp; + actor->world.pos.z = startPos.z + (endPos.z - startPos.z) * lerp; - Math_SmoothStepToS(&actor->world.rot.y, Math_Vec3f_Yaw(&start, &end), 10, 1000, 1); + Math_SmoothStepToS(&actor->world.rot.y, Math_Vec3f_Yaw(&startPos, &endPos), 10, 1000, 1); actor->shape.rot.y = actor->world.rot.y; } @@ -1621,25 +1688,35 @@ s32 Cutscene_GetSceneLayer(PlayState* play) { return sceneLayer; } -s32 Cutscene_GetActorActionIndex(PlayState* play, u16 actorActionCmd) { +/** + * @param play See `PlayState` + * @param cueType See `cmdType` + * @return cue channel + */ +s32 Cutscene_GetCueChannel(PlayState* play, u16 cueType) { s32 i; - s32 index = -1; + s32 cueChannel = -1; - for (i = 0; i < ARRAY_COUNT(D_801F4DC8); i++) { - if (actorActionCmd == D_801F4DC8[i]) { - index = i; + for (i = 0; i < ARRAY_COUNT(sCueTypeList); i++) { + if (cueType == sCueTypeList[i]) { + cueChannel = i; } } - return index; + return cueChannel; } -s32 Cutscene_CheckActorAction(PlayState* play, u16 actorActionCmd) { - if (play->csCtx.state != CS_STATE_0) { - s32 index = Cutscene_GetActorActionIndex(play, actorActionCmd); +/** + * @param play See `PlayState` + * @param cueType See `cmdType` + * @return is cuetype in a channel + */ +s32 Cutscene_IsCueInChannel(PlayState* play, u16 cueType) { + if (play->csCtx.state != CS_STATE_IDLE) { + s32 cueChannel = Cutscene_GetCueChannel(play, cueType); - if (index != -1) { - return play->csCtx.actorActions[index] != NULL; + if (cueChannel != -1) { + return play->csCtx.actorCues[cueChannel] != NULL; } } @@ -1647,7 +1724,7 @@ s32 Cutscene_CheckActorAction(PlayState* play, u16 actorActionCmd) { } u8 Cutscene_IsPlaying(PlayState* play) { - return (gSaveContext.cutsceneTrigger != 0) || (play->csCtx.state != CS_STATE_0); + return (gSaveContext.cutsceneTrigger != 0) || (play->csCtx.state != CS_STATE_IDLE); } /* End of actor utilities section */ diff --git a/src/code/z_env_flags.c b/src/code/z_env_flags.c index 06e216cd3..0057128e2 100644 --- a/src/code/z_env_flags.c +++ b/src/code/z_env_flags.c @@ -1,33 +1,33 @@ #include "global.h" -void EnvFlags_UnsetAll(PlayState* play) { +void CutsceneFlags_UnsetAll(PlayState* play) { u8 i; - for (i = 0; i < ARRAY_COUNT(play->envFlags); i++) { - play->envFlags[i] = 0; + for (i = 0; i < ARRAY_COUNT(play->cutsceneFlags); i++) { + play->cutsceneFlags[i] = 0; } } -void EnvFlags_Set(PlayState* play, s16 flag) { +void CutsceneFlags_Set(PlayState* play, s16 flag) { s16 index = flag / 16; s16 bit = flag % 16; s16 mask = 1 << bit; - play->envFlags[index] |= mask; + play->cutsceneFlags[index] |= mask; } -void EnvFlags_Unset(PlayState* play, s16 flag) { +void CutsceneFlags_Unset(PlayState* play, s16 flag) { s16 index = flag / 16; s16 bit = flag % 16; s16 mask = (1 << bit) ^ 0xFFFF; - play->envFlags[index] &= mask; + play->cutsceneFlags[index] &= mask; } -s32 EnvFlags_Get(PlayState* play, s16 flag) { +s32 CutsceneFlags_Get(PlayState* play, s16 flag) { s16 index = flag / 16; s16 bit = flag % 16; s16 mask = 1 << bit; - return play->envFlags[index] & mask; + return play->cutsceneFlags[index] & mask; } diff --git a/src/code/z_eventmgr.c b/src/code/z_eventmgr.c index 5b8b8dce3..2575899ca 100644 --- a/src/code/z_eventmgr.c +++ b/src/code/z_eventmgr.c @@ -1,52 +1,554 @@ +/** + * @file z_eventmgr.c + * + * Manages all cutscenes except for manual + */ #include "global.h" #include "z64shrink_window.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/func_800F1460.s") +ActorCutscene sGlobalCutsceneList[] = { + // CS_ID_GLOBAL_78 + { -100, -1, CS_CAM_ID_NONE, CS_SCRIPT_ID_NONE, CS_ID_NONE, CS_END_SFX_NONE_ALT, 255, CS_HUD_VISIBILITY_ALL_ALT, 255, + 255 }, + // CS_ID_GLOBAL_79 + { -100, -1, CS_CAM_ID_NONE, CS_SCRIPT_ID_NONE, CS_ID_NONE, CS_END_SFX_NONE_ALT, 255, CS_HUD_VISIBILITY_ALL_ALT, 255, + 255 }, + // CS_ID_GLOBAL_7A + { -100, -1, CS_CAM_ID_NONE, CS_SCRIPT_ID_NONE, CS_ID_NONE, CS_END_SFX_NONE_ALT, 255, CS_HUD_VISIBILITY_ALL_ALT, 255, + 255 }, + // CS_ID_GLOBAL_ELEGY + { 2, -1, CS_CAM_ID_GLOBAL_ELEGY, CS_SCRIPT_ID_NONE, CS_ID_NONE, CS_END_SFX_NONE_ALT, 255, CS_HUD_VISIBILITY_NONE, + CS_END_CAM_0, 32 }, + // CS_ID_GLOBAL_TALK + { 32765, -1, CS_CAM_ID_NONE, CS_SCRIPT_ID_NONE, CS_ID_NONE, CS_END_SFX_NONE_ALT, 255, CS_HUD_VISIBILITY_ALL_ALT, + CS_END_CAM_0, 255 }, + // CS_ID_GLOBAL_DOOR + { 32764, -1, CS_CAM_ID_NONE, CS_SCRIPT_ID_NONE, CS_ID_NONE, CS_END_SFX_NONE_ALT, 255, CS_HUD_VISIBILITY_ALL_ALT, + CS_END_CAM_0, 255 }, + // CS_ID_GLOBAL_RETURN_TO_CAM + { 32766, -2, CS_CAM_ID_GLOBAL_CONNECT, CS_SCRIPT_ID_NONE, CS_ID_NONE, CS_END_SFX_NONE, 255, + CS_HUD_VISIBILITY_ALL_ALT, CS_END_CAM_0, 32 }, + // CS_ID_GLOBAL_END + { 0, -1, CS_CAM_ID_NONE, CS_SCRIPT_ID_NONE, CS_ID_NONE, CS_END_SFX_NONE, 255, CS_HUD_VISIBILITY_ALL_ALT, + CS_END_CAM_0, 32 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_GetCutsceneImpl.s") +typedef enum { + /* 0 */ CS_START_0, + /* 1 */ CS_START_1, + /* 2 */ CS_START_2, +} ActorCutsceneStartMethod; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_Init.s") +typedef struct { + /* 0x00 */ s16 csId; + /* 0x02 */ s16 length; + /* 0x04 */ s16 endCsId; + /* 0x06 */ s16 subCamId; + /* 0x08 */ Actor* targetActor; + /* 0x0C */ s32 startMethod; + /* 0x10 */ PlayState* play; + /* 0x14 */ s16 retCamId; + /* 0x16 */ s16 isCameraStored; +} CutsceneManager; // size = 0x18 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/func_800F15D8.s") +CutsceneManager sCutsceneMgr = { + CS_ID_NONE, 0, CS_ID_NONE, SUB_CAM_ID_DONE, NULL, CS_START_0, NULL, CAM_ID_MAIN, false, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_ClearWaiting.s") +s16 CutsceneManager_SetHudVisibility(s16 csHudVisibility) { + u16 hudVisibility; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_ClearNextCutscenes.s") + switch (csHudVisibility) { + case CS_HUD_VISIBILITY_NONE: + hudVisibility = HUD_VISIBILITY_NONE_ALT; + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_MarkNextCutscenes.s") + case CS_HUD_VISIBILITY_ALL: + hudVisibility = HUD_VISIBILITY_ALL; + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_End.s") + case CS_HUD_VISIBILITY_A_HEARTS_MAGIC: + hudVisibility = HUD_VISIBILITY_A_HEARTS_MAGIC_WITH_OVERWRITE; + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_Update.s") + case CS_HUD_VISIBILITY_C_HEARTS_MAGIC: + hudVisibility = HUD_VISIBILITY_HEARTS_MAGIC_C; + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_SetIntentToPlay.s") + case CS_HUD_VISIBILITY_ALL_NO_MINIMAP: + hudVisibility = HUD_VISIBILITY_ALL_NO_MINIMAP; + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_GetCanPlayNext.s") + case CS_HUD_VISIBILITY_A_B_C: + hudVisibility = HUD_VISIBILITY_A_B_C; + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_StartAndSetUnkLinkFields.s") + case CS_HUD_VISIBILITY_B_MINIMAP: + hudVisibility = HUD_VISIBILITY_B_MINIMAP; + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_StartAndSetFlag.s") + case CS_HUD_VISIBILITY_A: + hudVisibility = HUD_VISIBILITY_A; + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_Start.s") + default: + hudVisibility = HUD_VISIBILITY_ALL; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_Stop.s") + Interface_SetHudVisibility(hudVisibility); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_GetCurrentIndex.s") + return hudVisibility; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_GetCutscene.s") +ActorCutscene* CutsceneManager_GetCutsceneEntryImpl(s16 csId) { + if (csId < CS_ID_GLOBAL_78) { + return &sSceneCutsceneList[csId]; + } else { + csId -= CS_ID_GLOBAL_78; + return &sGlobalCutsceneList[csId]; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_GetAdditionalCutscene.s") +void CutsceneManager_Init(PlayState* play, ActorCutscene* cutsceneList, s16 numEntries) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_GetLength.s") + sSceneCutsceneList = cutsceneList; + sSceneCutsceneCount = numEntries; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/func_800F2138.s") + for (i = 0; i < ARRAY_COUNT(sWaitingCutsceneList); i++) { + sWaitingCutsceneList[i] = 0; + sNextCutsceneList[i] = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/func_800F2178.s") + sCutsceneMgr.endCsId = CS_ID_NONE; + sCutsceneMgr.play = play; + sCutsceneMgr.length = -1; + sCutsceneMgr.targetActor = NULL; + sCutsceneMgr.subCamId = SUB_CAM_ID_DONE; + sCutsceneMgr.isCameraStored = false; + sCutsceneMgr.csId = sCutsceneMgr.endCsId; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_GetCurrentSubCamId.s") +/** + * Store camera into subCam 2, and keep subCam 2 INACTIVE to preserve the struct. + */ +void CutsceneManager_StoreCamera(Camera* camera) { + if (camera != NULL) { + memcpy(&sCutsceneMgr.play->subCameras[2], camera, sizeof(Camera)); + sCutsceneMgr.play->subCameras[2].camId = camera->camId; + Camera_ChangeStatus(&sCutsceneMgr.play->subCameras[2], CAM_STATUS_INACTIVE); + sCutsceneMgr.isCameraStored = true; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/func_800F21CC.s") +void CutsceneManager_ClearWaiting(void) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/func_800F22C4.s") + for (i = 0; i < ARRAY_COUNT(sWaitingCutsceneList); i++) { + sWaitingCutsceneList[i] = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eventmgr/ActorCutscene_SetReturnCamera.s") +void CutsceneManager_ClearNextCutscenes(void) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(sNextCutsceneList); i++) { + sNextCutsceneList[i] = 0; + } +} + +s16 CutsceneManager_MarkNextCutscenes(void) { + s16 bit; + s32 i; + s32 j; + s32 count = 0; + s16 csIdMax = CS_ID_NONE; + s16 priorityMax = SHT_MAX; // lower number means higher priority + s16 csId; + s16 priority; + + for (i = 0; i < ARRAY_COUNT(sNextCutsceneList); i++) { + for (bit = 1, j = 0; j < 8; j++) { + if (sWaitingCutsceneList[i] & bit) { + csId = (i << 3) | j; + priority = CutsceneManager_GetCutsceneEntryImpl(csId)->priority; + + if ((priority ^ 0) == -1) { + sNextCutsceneList[i] |= bit; + } else if ((priority < priorityMax) && (priority > 0)) { + csIdMax = csId; + priorityMax = priority; + } + count++; + } + bit <<= 1; + } + } + if (csIdMax != CS_ID_NONE) { + sNextCutsceneList[csIdMax >> 3] |= 1 << (csIdMax & 7); + } + return count; +} + +#define RET_CAM sCutsceneMgr.play->cameraPtrs[sCutsceneMgr.retCamId] +#define CUR_CAM sCutsceneMgr.play->cameraPtrs[sCutsceneMgr.subCamId] + +void CutsceneManager_End(void) { + ActorCutscene* csEntry; + s16 oldCamId; + s16 oldStateFlags; + + switch (sCutsceneMgr.startMethod) { + case CS_START_2: + sCutsceneMgr.targetActor->flags &= ~ACTOR_FLAG_100000; + // fallthrough + case CS_START_1: + func_800B7298(sCutsceneMgr.play, 0, PLAYER_CSMODE_END); + sCutsceneMgr.startMethod = CS_START_0; + break; + + default: + break; + } + + csEntry = CutsceneManager_GetCutsceneEntryImpl(sCutsceneMgr.csId); + + switch (csEntry->endSfx) { + case CS_END_SFX_TRE_BOX_APPEAR: + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + break; + + case CS_END_SFX_CORRECT_CHIME: + play_sound(NA_SE_SY_CORRECT_CHIME); + break; + + default: // CS_END_SFX_NONE + break; + } + + switch (csEntry->endCam) { + case CS_END_CAM_SMOOTH: + Play_CopyCamera(sCutsceneMgr.play, sCutsceneMgr.retCamId, sCutsceneMgr.subCamId); + RET_CAM->stateFlags = + (RET_CAM->stateFlags & ~CAM_STATE_UNDERWATER) | (CUR_CAM->stateFlags & CAM_STATE_UNDERWATER); + CutsceneManager_Queue(CS_ID_GLOBAL_RETURN_TO_CAM); + break; + + case CS_END_CAM_0: + default: + Play_CopyCamera(sCutsceneMgr.play, sCutsceneMgr.retCamId, sCutsceneMgr.subCamId); + RET_CAM->stateFlags = + (RET_CAM->stateFlags & ~CAM_STATE_UNDERWATER) | (CUR_CAM->stateFlags & CAM_STATE_UNDERWATER); + break; + + case CS_END_CAM_1: + oldCamId = RET_CAM->camId; + oldStateFlags = RET_CAM->stateFlags; + + if (sCutsceneMgr.isCameraStored) { + // Restore the camera that was stored in subCam 2 + memcpy(RET_CAM, &sCutsceneMgr.play->subCameras[2], sizeof(Camera)); + + RET_CAM->stateFlags = + (RET_CAM->stateFlags & ~CAM_STATE_UNDERWATER) | (CUR_CAM->stateFlags & CAM_STATE_UNDERWATER); + + RET_CAM->stateFlags = (RET_CAM->stateFlags & ~CAM_STATE_2) | (oldStateFlags & CAM_STATE_2); + sCutsceneMgr.isCameraStored = false; + } + RET_CAM->camId = oldCamId; + break; + } + + if (sCutsceneMgr.subCamId != SUB_CAM_ID_DONE) { + Play_ClearCamera(sCutsceneMgr.play, sCutsceneMgr.subCamId); + Play_ChangeCameraStatus(sCutsceneMgr.play, sCutsceneMgr.retCamId, CAM_STATUS_ACTIVE); + } + + sCutsceneMgr.csId = CS_ID_NONE; + sCutsceneMgr.endCsId = CS_ID_NONE; + sCutsceneMgr.length = -1; + sCutsceneMgr.targetActor = NULL; + sCutsceneMgr.subCamId = SUB_CAM_ID_DONE; +} + +s16 CutsceneManager_Update(void) { + s16 sp1E = 0; + + if (CutsceneManager_IsNext(CS_ID_GLOBAL_RETURN_TO_CAM)) { + CutsceneManager_StartWithPlayerCs(CS_ID_GLOBAL_RETURN_TO_CAM, &GET_PLAYER(sCutsceneMgr.play)->actor); + } + + if (sCutsceneMgr.endCsId == CS_ID_NONE) { + if (sCutsceneMgr.csId != CS_ID_NONE) { + if (sCutsceneMgr.length > 0) { + sCutsceneMgr.length--; + } + sp1E = 1; + if (sCutsceneMgr.length == 0) { + CutsceneManager_Stop(sCutsceneMgr.csId); + } + } + } + + if (sCutsceneMgr.endCsId != CS_ID_NONE) { + CutsceneManager_End(); + sp1E = 2; + } + + CutsceneManager_ClearNextCutscenes(); + + if (sCutsceneMgr.csId == CS_ID_NONE) { + if ((CutsceneManager_MarkNextCutscenes() == 0) && (sp1E != 0)) { + ShrinkWindow_Letterbox_SetSizeTarget(0); + } else if (sp1E == 0) { + CutsceneManager_StoreCamera(Play_GetCamera(sCutsceneMgr.play, sCutsceneMgr.retCamId)); + } + } + return sp1E; +} + +void CutsceneManager_Queue(s16 csId) { + if (csId >= 0) { + sWaitingCutsceneList[csId >> 3] |= 1 << (csId & 7); + } +} + +s16 CutsceneManager_IsNext(s16 csId) { + if (csId == CS_ID_GLOBAL_END) { + if (sCutsceneMgr.csId == CS_ID_NONE) { + return 0x7F; + } else { + return 0; + } + } + if (csId <= CS_ID_NONE) { + return -1; + } + return (sNextCutsceneList[csId >> 3] & (1 << (csId & 7))) ? 1 : 0; +} + +/** + * Start an actor cutscene, activate Player Cutscene Mode "Wait" + */ +s16 CutsceneManager_StartWithPlayerCs(s16 csId, Actor* actor) { + s16 startCsId = CutsceneManager_Start(csId, actor); + + if (startCsId >= 0) { + func_800B7298(sCutsceneMgr.play, 0, PLAYER_CSMODE_WAIT); + if (sCutsceneMgr.length == 0) { + CutsceneManager_Stop(sCutsceneMgr.csId); + } + sCutsceneMgr.startMethod = CS_START_1; + } + return startCsId; +} + +/** + * Start an actor cutscene, activate Player Cutscene Mode "Wait", turn on ACTOR_FLAG_100000 + */ +s16 CutsceneManager_StartWithPlayerCsAndSetFlag(s16 csId, Actor* actor) { + s16 startCsId = CutsceneManager_Start(csId, actor); + + if (startCsId >= 0) { + func_800B7298(sCutsceneMgr.play, 0, PLAYER_CSMODE_WAIT); + if (sCutsceneMgr.length == 0) { + CutsceneManager_Stop(sCutsceneMgr.csId); + } + if (actor != NULL) { + actor->flags |= ACTOR_FLAG_100000; + sCutsceneMgr.startMethod = CS_START_2; + } else { + sCutsceneMgr.startMethod = CS_START_1; + } + } + return startCsId; +} + +s16 CutsceneManager_Start(s16 csId, Actor* actor) { + ActorCutscene* csEntry; + Camera* subCam; + Camera* retCam; + s32 csType = 0; + + if ((csId < 0) || (sCutsceneMgr.csId != CS_ID_NONE)) { + return csId; + } + + sCutsceneMgr.startMethod = CS_START_0; + csEntry = CutsceneManager_GetCutsceneEntryImpl(csId); + + ShrinkWindow_Letterbox_SetSizeTarget(csEntry->letterboxSize); + CutsceneManager_SetHudVisibility(csEntry->hudVisibility); + + if (csId == CS_ID_GLOBAL_END) { + csType = 1; + } else if (csEntry->scriptIndex != CS_SCRIPT_ID_NONE) { + // scripted cutscene + csType = 1; + } else if ((csId != CS_ID_GLOBAL_DOOR) && (csId != CS_ID_GLOBAL_TALK)) { + csType = 2; + } + + if (csType != 0) { + sCutsceneMgr.retCamId = Play_GetActiveCamId(sCutsceneMgr.play); + sCutsceneMgr.subCamId = Play_CreateSubCamera(sCutsceneMgr.play); + + subCam = Play_GetCamera(sCutsceneMgr.play, sCutsceneMgr.subCamId); + retCam = Play_GetCamera(sCutsceneMgr.play, sCutsceneMgr.retCamId); + + if ((retCam->setting == CAM_SET_START0) || (retCam->setting == CAM_SET_START2) || + (retCam->setting == CAM_SET_START1)) { + if (CutsceneManager_FindEntranceCsId() != csId) { + func_800E0348(retCam); + } else { + Camera_ClearFlags(retCam, CAM_STATE_2); + } + } + + memcpy(subCam, retCam, sizeof(Camera)); + subCam->camId = sCutsceneMgr.subCamId; + Camera_ClearFlags(subCam, CAM_STATE_6 | CAM_STATE_0); + + Play_ChangeCameraStatus(sCutsceneMgr.play, sCutsceneMgr.retCamId, CAM_STATUS_WAIT); + Play_ChangeCameraStatus(sCutsceneMgr.play, sCutsceneMgr.subCamId, CAM_STATUS_ACTIVE); + + subCam->target = sCutsceneMgr.targetActor = actor; + subCam->behaviorFlags = 0; + + if (csType == 1) { + Camera_ChangeSetting(subCam, CAM_SET_FREE0); + Cutscene_StartScripted(sCutsceneMgr.play, csEntry->scriptIndex); + sCutsceneMgr.length = csEntry->length; + } else { + if (csEntry->csCamId != CS_CAM_ID_NONE) { + Camera_ChangeDataIdx(subCam, csEntry->csCamId); + } else { + Camera_ChangeSetting(subCam, CAM_SET_FREE0); + } + sCutsceneMgr.length = csEntry->length; + } + } + sCutsceneMgr.csId = csId; + + return csId; +} + +s16 CutsceneManager_Stop(s16 csId) { + ActorCutscene* csEntry; + + if (csId < 0) { + return csId; + } + + csEntry = CutsceneManager_GetCutsceneEntryImpl(sCutsceneMgr.csId); + if ((sCutsceneMgr.length > 0) && (csEntry->scriptIndex == CS_SCRIPT_ID_NONE)) { + return -2; + } + if ((csId != CS_ID_GLOBAL_END) && (csEntry->scriptIndex != CS_SCRIPT_ID_NONE)) { + return -3; + } + + if (csId == CS_ID_GLOBAL_END) { + csId = sCutsceneMgr.csId; + } + if (csId == sCutsceneMgr.csId) { + sCutsceneMgr.endCsId = sCutsceneMgr.csId; + return sCutsceneMgr.endCsId; + } + return -1; +} + +s16 CutsceneManager_GetCurrentCsId(void) { + return sCutsceneMgr.csId; +} + +ActorCutscene* CutsceneManager_GetCutsceneEntry(s16 csId) { + return CutsceneManager_GetCutsceneEntryImpl(csId); +} + +s16 CutsceneManager_GetAdditionalCsId(s16 csId) { + if (csId < 0) { + return CS_ID_NONE; + } + return CutsceneManager_GetCutsceneEntryImpl(csId)->additionalCsId; +} + +s16 CutsceneManager_GetLength(s16 csId) { + if (csId < 0) { + return -1; + } + return CutsceneManager_GetCutsceneEntryImpl(csId)->length; +} + +s16 CutsceneManager_GetCutsceneScriptIndex(s16 csId) { + if (csId < 0) { + return -1; + } + return CutsceneManager_GetCutsceneEntryImpl(csId)->scriptIndex; +} + +s16 CutsceneManager_GetCutsceneCustomValue(s16 csId) { + if (csId < 0) { + return -1; + } + return CutsceneManager_GetCutsceneEntryImpl(csId)->customValue; +} + +s16 CutsceneManager_GetCurrentSubCamId(s16 csId) { + return sCutsceneMgr.subCamId; +} + +s16 CutsceneManager_FindEntranceCsId(void) { + PlayState* play; + s32 csId; + + for (csId = 0; csId < sSceneCutsceneCount; csId++) { + //! FAKE: + if ((sSceneCutsceneList[csId].scriptIndex != CS_SCRIPT_ID_NONE) && + (sSceneCutsceneList[csId].scriptIndex < (play = sCutsceneMgr.play)->csCtx.scriptListCount) && + (sCutsceneMgr.play->curSpawn == + sCutsceneMgr.play->csCtx.scriptList[sSceneCutsceneList[csId].scriptIndex].spawn)) { + return csId; + } + } + + for (csId = 0; csId < sSceneCutsceneCount; csId++) { + if ((sSceneCutsceneList[csId].customValue >= 100) && + (sSceneCutsceneList[csId].customValue == (sCutsceneMgr.play->curSpawn + 100))) { + return csId; + } + } + + return -1; +} + +s32 func_800F22C4(s16 csId, Actor* actor) { + f32 dist; + s16 screenPosX; + s16 screenPosY; + + if ((sCutsceneMgr.csId == CS_ID_NONE) || (csId == CS_ID_NONE)) { + return 4; + } + + Actor_GetScreenPos(sCutsceneMgr.play, actor, &screenPosX, &screenPosY); + + dist = OLib_Vec3fDist(&actor->focus.pos, &Play_GetCamera(sCutsceneMgr.play, sCutsceneMgr.subCamId)->eye); + + if ((screenPosX > 40) && (screenPosX < SCREEN_WIDTH - 40) && (screenPosY > 40) && + (screenPosY < SCREEN_HEIGHT - 40) && (dist < 700.0f)) { + return 1; + } + if (sCutsceneMgr.length < 6) { + return 2; + } + if (csId == sCutsceneMgr.csId) { + return 0; + } + return 3; +} + +void CutsceneManager_SetReturnCamera(s16 camId) { + sCutsceneMgr.retCamId = camId; +} diff --git a/src/code/z_kaleido_setup.c b/src/code/z_kaleido_setup.c index f873ea8ff..148aad84e 100644 --- a/src/code/z_kaleido_setup.c +++ b/src/code/z_kaleido_setup.c @@ -92,7 +92,7 @@ void KaleidoSetup_Update(PlayState* play) { if ((pauseCtx->state == PAUSE_STATE_OFF) && (pauseCtx->debugEditor == DEBUG_EDITOR_NONE) && (play->gameOverCtx.state == GAMEOVER_INACTIVE)) { if ((play->transitionTrigger == TRANS_TRIGGER_OFF) && (play->transitionMode == TRANS_MODE_OFF)) { - if ((gSaveContext.save.cutscene < 0xFFF0) && (gSaveContext.nextCutsceneIndex < 0xFFF0)) { + if ((gSaveContext.save.cutsceneIndex < 0xFFF0) && (gSaveContext.nextCutsceneIndex < 0xFFF0)) { if (!Play_InCsMode(play) || ((msgCtx->msgMode != 0) && (msgCtx->currentTextId == 0xFF))) { if ((play->unk_1887C < 2) && (gSaveContext.magicState != MAGIC_STATE_STEP_CAPACITY) && (gSaveContext.magicState != MAGIC_STATE_FILL)) { diff --git a/src/code/z_parameter.c b/src/code/z_parameter.c index 1072587af..88b8f14cc 100644 --- a/src/code/z_parameter.c +++ b/src/code/z_parameter.c @@ -1990,7 +1990,7 @@ void Interface_UpdateButtonsPart2(PlayState* play) { } if ((play->transitionTrigger == TRANS_TRIGGER_OFF) && (play->transitionMode == TRANS_MODE_OFF)) { - if (ActorCutscene_GetCurrentIndex() == -1) { + if (CutsceneManager_GetCurrentCsId() == CS_ID_NONE) { Interface_SetHudVisibility(HUD_VISIBILITY_ALL); } } @@ -2267,7 +2267,7 @@ void Interface_UpdateButtonsPart1(PlayState* play) { s32 pad; s32 restoreHudVisibility = false; - if (gSaveContext.save.cutscene < 0xFFF0) { + if (gSaveContext.save.cutsceneIndex < 0xFFF0) { gSaveContext.hudVisibilityForceButtonAlphasByStatus = false; if ((player->stateFlags1 & PLAYER_STATE1_800000) || CHECK_WEEKEVENTREG(WEEKEVENTREG_08_01) || (!(CHECK_EVENTINF(EVENTINF_41)) && (play->unk_1887C >= 2))) { @@ -2434,7 +2434,7 @@ void Interface_UpdateButtonsPart1(PlayState* play) { sPictoState = PICTO_BOX_STATE_OFF; } else if (CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_A) || (func_801A5100() == 1)) { if (!(CHECK_EVENTINF(EVENTINF_41)) || - ((CHECK_EVENTINF(EVENTINF_41)) && (ActorCutscene_GetCurrentIndex() == -1))) { + ((CHECK_EVENTINF(EVENTINF_41)) && (CutsceneManager_GetCurrentCsId() == CS_ID_NONE))) { play_sound(NA_SE_SY_CAMERA_SHUTTER); SREG(89) = 1; play->haltAllActors = true; diff --git a/src/code/z_play.c b/src/code/z_play.c index 99073fb5c..bd4db8fec 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -567,11 +567,13 @@ void Play_UpdateTransition(PlayState* this) { if ((!(Entrance_GetTransitionFlags(this->nextEntrance + sceneLayer) & 0x8000) || ((this->nextEntrance == ENTRANCE(PATH_TO_MOUNTAIN_VILLAGE, 1)) && - !CHECK_WEEKEVENTREG(WEEKEVENTREG_33_80)) || + !CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_SNOWHEAD_TEMPLE)) || ((this->nextEntrance == ENTRANCE(ROAD_TO_SOUTHERN_SWAMP, 1)) && - !CHECK_WEEKEVENTREG(WEEKEVENTREG_20_02)) || - ((this->nextEntrance == ENTRANCE(TERMINA_FIELD, 2)) && !CHECK_WEEKEVENTREG(WEEKEVENTREG_55_80)) || - ((this->nextEntrance == ENTRANCE(ROAD_TO_IKANA, 1)) && !CHECK_WEEKEVENTREG(WEEKEVENTREG_52_20))) && + !CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_WOODFALL_TEMPLE)) || + ((this->nextEntrance == ENTRANCE(TERMINA_FIELD, 2)) && + !CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_GREAT_BAY_TEMPLE)) || + ((this->nextEntrance == ENTRANCE(ROAD_TO_IKANA, 1)) && + !CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_STONE_TOWER_TEMPLE))) && (!func_800FE590(this) || (Entrance_GetSceneId(this->nextEntrance + sceneLayer) < 0) || (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_FINAL_HOURS))) { func_801A4058(20); @@ -983,8 +985,8 @@ void Play_UpdateMain(PlayState* this) { if (!this->haltAllActors) { Actor_UpdateAll(this, &this->actorCtx); } - Cutscene_Update1(this, &this->csCtx); - Cutscene_Update2(this, &this->csCtx); + Cutscene_UpdateManual(this, &this->csCtx); + Cutscene_UpdateScripted(this, &this->csCtx); Effect_UpdateAll(this); EffectSS_UpdateAllParticles(this); EffFootmark_Update(this); @@ -1502,8 +1504,8 @@ void Play_Main(GameState* thisx) { *CONTROLLER1(&this->state) = input; } - ActorCutscene_Update(); - ActorCutscene_ClearWaiting(); + CutsceneManager_Update(); + CutsceneManager_ClearWaiting(); } s32 Play_InCsMode(PlayState* this) { @@ -2016,37 +2018,47 @@ s32 Play_IsDebugCamEnabled(void) { return gDbgCamEnabled; } -// A mapping from playerActorCsIds to sGlobalCamDataSettings indices. -s16 D_801D0D64[] = { -3, -2, -4, -5, -7, -11, -8, -9, -6, -16 }; +// A mapping from playerCsIds to sGlobalCamDataSettings indices. +s16 sPlayerCsIdToCsCamId[] = { + CS_CAM_ID_GLOBAL_ITEM_OCARINA, // PLAYER_CS_ID_ITEM_OCARINA + CS_CAM_ID_GLOBAL_ITEM_GET, // PLAYER_CS_ID_ITEM_GET + CS_CAM_ID_GLOBAL_ITEM_BOTTLE, // PLAYER_CS_ID_ITEM_BOTTLE + CS_CAM_ID_GLOBAL_ITEM_SHOW, // PLAYER_CS_ID_ITEM_SHOW + CS_CAM_ID_GLOBAL_WARP_PAD_MOON, // PLAYER_CS_ID_WARP_PAD_MOON + CS_CAM_ID_GLOBAL_MASK_TRANSFORMATION, // PLAYER_CS_ID_MASK_TRANSFORMATION + CS_CAM_ID_GLOBAL_DEATH, // PLAYER_CS_ID_DEATH + CS_CAM_ID_GLOBAL_REVIVE, // PLAYER_CS_ID_REVIVE + CS_CAM_ID_GLOBAL_SONG_WARP, // PLAYER_CS_ID_SONG_WARP + CS_CAM_ID_GLOBAL_WARP_PAD_ENTRANCE, // PLAYER_CS_ID_WARP_PAD_ENTRANCE +}; // Used by Player /** - * Extract the common actor cutscene ids used by Player from the scene and set the actor cutscene ids in - * this->playerActorCsIds. If a playerActorCsId is not present in the scene, then that particular id is set - * to -1. Otherwise, if there is an ActorCutscene where csCamSceneDataId matches the appropriate element of D_801D0D64, - * set the corresponding playerActorCsId (and possibly change its priority for the zeroth one) + * Extract the common cutscene ids used by Player from the scene and set the cutscene ids in this->playerCsIds. + * If a playerCsId is not present in the scene, then that particular id is set to CS_ID_NONE. + * Otherwise, if there is an ActorCutscene where csCamId matches the appropriate element of sPlayerCsIdToCsCamId, + * set the corresponding playerActorCsId (and possibly change its priority for the zeroth one). */ -void Play_AssignPlayerActorCsIdsFromScene(GameState* thisx, s32 startActorCsId) { +void Play_AssignPlayerCsIdsFromScene(GameState* thisx, s32 spawnCsId) { PlayState* this = (PlayState*)thisx; s32 i; - s16* curPlayerActorCsId = this->playerActorCsIds; - s16* phi_s1 = D_801D0D64; + s16* curPlayerCsId = this->playerCsIds; + s16* csCamId = sPlayerCsIdToCsCamId; - for (i = 0; i < ARRAY_COUNT(this->playerActorCsIds); i++, curPlayerActorCsId++, phi_s1++) { - ActorCutscene* actorCutscene; - s32 curActorCsId; + for (i = 0; i < ARRAY_COUNT(this->playerCsIds); i++, curPlayerCsId++, csCamId++) { + ActorCutscene* csEntry; + s32 curCsId; - *curPlayerActorCsId = -1; + *curPlayerCsId = CS_ID_NONE; - for (curActorCsId = startActorCsId; curActorCsId != -1; curActorCsId = actorCutscene->additionalCutscene) { - actorCutscene = ActorCutscene_GetCutscene(curActorCsId); + for (curCsId = spawnCsId; curCsId != CS_ID_NONE; curCsId = csEntry->additionalCsId) { + csEntry = CutsceneManager_GetCutsceneEntry(curCsId); - if (actorCutscene->csCamSceneDataId == *phi_s1) { - if ((actorCutscene->csCamSceneDataId == -3) && - (actorCutscene->priority == 700)) { // override ocarina cs priority - actorCutscene->priority = 550; + if (csEntry->csCamId == *csCamId) { + if ((csEntry->csCamId == CS_CAM_ID_GLOBAL_ITEM_OCARINA) && (csEntry->priority == 700)) { + csEntry->priority = 550; } - *curPlayerActorCsId = curActorCsId; + *curPlayerCsId = curCsId; break; } } @@ -2101,7 +2113,7 @@ void Play_Init(GameState* thisx) { scene = ((void)0, gSaveContext.save.entrance) >> 9; spawn = (((void)0, gSaveContext.save.entrance) >> 4) & 0x1F; - if (CHECK_WEEKEVENTREG(WEEKEVENTREG_33_80)) { + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_SNOWHEAD_TEMPLE)) { if (scene == ENTR_SCENE_MOUNTAIN_VILLAGE_WINTER) { scene = ENTR_SCENE_MOUNTAIN_VILLAGE_SPRING; } else if (scene == ENTR_SCENE_GORON_VILLAGE_WINTER) { @@ -2115,7 +2127,7 @@ void Play_Init(GameState* thisx) { } } - if (CHECK_WEEKEVENTREG(WEEKEVENTREG_20_02)) { + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_WOODFALL_TEMPLE)) { if (scene == ENTR_SCENE_SOUTHERN_SWAMP_POISONED) { scene = ENTR_SCENE_SOUTHERN_SWAMP_CLEARED; } else if (scene == ENTR_SCENE_WOODFALL) { @@ -2123,11 +2135,11 @@ void Play_Init(GameState* thisx) { } } - if (CHECK_WEEKEVENTREG(WEEKEVENTREG_52_20) && (scene == ENTR_SCENE_IKANA_CANYON)) { + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_STONE_TOWER_TEMPLE) && (scene == ENTR_SCENE_IKANA_CANYON)) { gSaveContext.nextCutsceneIndex = 0xFFF2; } - if (CHECK_WEEKEVENTREG(WEEKEVENTREG_55_80) && + if (CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_GREAT_BAY_TEMPLE) && ((scene == ENTR_SCENE_GREAT_BAY_COAST) || (scene == ENTR_SCENE_ZORA_CAPE))) { gSaveContext.nextCutsceneIndex = 0xFFF0; } @@ -2179,15 +2191,15 @@ void Play_Init(GameState* thisx) { EffectSS_Init(this, 100); CollisionCheck_InitContext(this, &this->colChkCtx); AnimationContext_Reset(&this->animationCtx); - Cutscene_Init(this, &this->csCtx); + Cutscene_InitContext(this, &this->csCtx); if (gSaveContext.nextCutsceneIndex != 0xFFEF) { - gSaveContext.save.cutscene = gSaveContext.nextCutsceneIndex; + gSaveContext.save.cutsceneIndex = gSaveContext.nextCutsceneIndex; gSaveContext.nextCutsceneIndex = 0xFFEF; } - if (gSaveContext.save.cutscene == 0xFFFD) { - gSaveContext.save.cutscene = 0; + if (gSaveContext.save.cutsceneIndex == 0xFFFD) { + gSaveContext.save.cutsceneIndex = 0; } if (gSaveContext.nextDayTime != 0xFFFF) { @@ -2204,13 +2216,13 @@ void Play_Init(GameState* thisx) { func_800EDDB0(this); if (((gSaveContext.gameMode != GAMEMODE_NORMAL) && (gSaveContext.gameMode != GAMEMODE_TITLE_SCREEN)) || - (gSaveContext.save.cutscene >= 0xFFF0)) { + (gSaveContext.save.cutsceneIndex >= 0xFFF0)) { gSaveContext.unk_3DC0 = 0; Magic_Reset(this); - gSaveContext.sceneLayer = (gSaveContext.save.cutscene & 0xF) + 1; + gSaveContext.sceneLayer = (gSaveContext.save.cutsceneIndex & 0xF) + 1; // Set saved cutscene to 0 so it doesn't immediately play, but instead let the `CutsceneManager` handle it. - gSaveContext.save.cutscene = 0; + gSaveContext.save.cutsceneIndex = 0; } else { gSaveContext.sceneLayer = 0; } @@ -2296,7 +2308,7 @@ void Play_Init(GameState* thisx) { D_801F6D4C->envColor.g = 0; D_801F6D4C->envColor.b = 0; D_801F6D4C->envColor.a = 0; - EnvFlags_UnsetAll(this); + CutsceneFlags_UnsetAll(this); THA_GetRemaining(&this->state.heap); zAllocSize = THA_GetRemaining(&this->state.heap); zAlloc = (uintptr_t)THA_AllocTailAlign16(&this->state.heap, zAllocSize); @@ -2319,13 +2331,13 @@ void Play_Init(GameState* thisx) { Camera_ChangeDataIdx(&this->mainCamera, player->actor.params & 0xFF); } - func_800F15D8(&this->mainCamera); + CutsceneManager_StoreCamera(&this->mainCamera); Interface_SetSceneRestrictions(this); func_800FB758(this); gSaveContext.seqId = this->sequenceCtx.seqId; gSaveContext.ambienceId = this->sequenceCtx.ambienceId; AnimationContext_Update(this, &this->animationCtx); - func_800EDBE0(this); + Cutscene_HandleEntranceTriggers(this); gSaveContext.respawnFlag = 0; sBombersNotebookOpen = false; BombersNotebook_Init(&sBombersNotebook); diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index 4c72496d0..f8b33b853 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -359,9 +359,9 @@ void func_80122F28(Player* player) { PLAYER_STATE1_20000000))) && (!(player->stateFlags2 & PLAYER_STATE2_1))) { if (player->doorType <= PLAYER_DOORTYPE_TALKING) { - ActorCutscene_SetIntentToPlay(0x7C); + CutsceneManager_Queue(CS_ID_GLOBAL_TALK); } else { - ActorCutscene_SetIntentToPlay(0x7D); + CutsceneManager_Queue(CS_ID_GLOBAL_DOOR); } } } diff --git a/src/code/z_scene.c b/src/code/z_scene.c index fc47c9bf7..26dc39507 100644 --- a/src/code/z_scene.c +++ b/src/code/z_scene.c @@ -402,7 +402,7 @@ void Scene_CommandTimeSettings(PlayState* play, SceneCmd* cmd) { play->envCtx.sunPos.y = (Math_CosS(((void)0, gSaveContext.save.time) - CLOCK_TIME(12, 0)) * 120.0f) * 25.0f; play->envCtx.sunPos.z = (Math_CosS(((void)0, gSaveContext.save.time) - CLOCK_TIME(12, 0)) * 20.0f) * 25.0f; - if ((play->envCtx.sceneTimeSpeed == 0) && (gSaveContext.save.cutscene < 0xFFF0)) { + if ((play->envCtx.sceneTimeSpeed == 0) && (gSaveContext.save.cutsceneIndex < 0xFFF0)) { gSaveContext.skyboxTime = gSaveContext.save.time; if ((gSaveContext.skyboxTime >= CLOCK_TIME(4, 0)) && (gSaveContext.skyboxTime < CLOCK_TIME(6, 30))) { @@ -470,15 +470,15 @@ void Scene_CommandAltHeaderList(PlayState* play, SceneCmd* cmd) { } } -// SceneTableEntry Header Command 0x17: Cutscene List -void Scene_CommandCutsceneList(PlayState* play, SceneCmd* cmd) { - play->csCtx.sceneCsCount = cmd->cutsceneList.sceneCsCount; - play->csCtx.sceneCsList = Lib_SegmentedToVirtual(cmd->cutsceneList.segment); +// SceneTableEntry Header Command 0x17: Cutscene Script List +void Scene_CommandCutsceneScriptList(PlayState* play, SceneCmd* cmd) { + play->csCtx.scriptListCount = cmd->scriptList.scriptListCount; + play->csCtx.scriptList = Lib_SegmentedToVirtual(cmd->scriptList.segment); } -// SceneTableEntry Header Command 0x1B: Actor Cutscene List -void Scene_CommandActorCutsceneList(PlayState* play, SceneCmd* cmd) { - ActorCutscene_Init(play, Lib_SegmentedToVirtual(cmd->cutsceneActorList.segment), cmd->cutsceneActorList.num); +// SceneTableEntry Header Command 0x1B: Cutscene List +void Scene_CommandCutsceneList(PlayState* play, SceneCmd* cmd) { + CutsceneManager_Init(play, Lib_SegmentedToVirtual(cmd->cutsceneList.segment), cmd->cutsceneList.num); } // SceneTableEntry Header Command 0x1C: Mini Maps @@ -560,11 +560,11 @@ void (*sSceneCmdHandlers[])(PlayState*, SceneCmd*) = { NULL, Scene_CommandSoundSettings, Scene_CommandEchoSetting, - Scene_CommandCutsceneList, + Scene_CommandCutsceneScriptList, Scene_CommandAltHeaderList, Scene_CommandSetRegionVisitedFlag, Scene_CommandAnimatedMaterials, - Scene_CommandActorCutsceneList, + Scene_CommandCutsceneList, Scene_CommandMiniMap, Scene_Command1D, Scene_CommandMiniMapCompassInfo, @@ -601,7 +601,7 @@ u16 Entrance_Create(s32 scene, s32 spawn, s32 layer) { } /** - * Creates an layer 0 entranace from the current entrance and the given spawn. + * Creates an layer 0 entrance from the current entrance and the given spawn. */ u16 Entrance_CreateFromSpawn(s32 spawn) { return Entrance_Create((u32)gSaveContext.save.entrance >> 9, spawn, 0); diff --git a/src/code/z_sram_NES.c b/src/code/z_sram_NES.c index c269e30f4..c10c1943e 100644 --- a/src/code/z_sram_NES.c +++ b/src/code/z_sram_NES.c @@ -939,10 +939,9 @@ void Sram_InitDebugSave(void) { Sram_GenerateRandomSaveFields(); } -// Unused -void func_80144A94(SramContext* sramCtx) { +void Sram_ResetSaveFromMoonCrash(SramContext* sramCtx) { s32 i; - s32 cutscene = gSaveContext.save.cutscene; + s32 cutsceneIndex = gSaveContext.save.cutsceneIndex; bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); @@ -957,7 +956,7 @@ void func_80144A94(SramContext* sramCtx) { D_801C67F0[gSaveContext.fileNum * 2 + 1]); Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, sizeof(Save)); } - gSaveContext.save.cutscene = cutscene; + gSaveContext.save.cutsceneIndex = cutsceneIndex; for (i = 0; i < ARRAY_COUNT(gSaveContext.eventInf); i++) { gSaveContext.eventInf[i] = 0; @@ -1067,10 +1066,10 @@ void Sram_OpenSave(FileSelectState* fileSelect, SramContext* sramCtx) { } else { gSaveContext.save.entrance = D_801C6A58[(void)0, gSaveContext.save.owlSaveLocation]; if ((gSaveContext.save.entrance == ENTRANCE(SOUTHERN_SWAMP_POISONED, 10)) && - CHECK_WEEKEVENTREG(WEEKEVENTREG_20_02)) { + CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_WOODFALL_TEMPLE)) { gSaveContext.save.entrance = ENTRANCE(SOUTHERN_SWAMP_CLEARED, 10); } else if ((gSaveContext.save.entrance == ENTRANCE(MOUNTAIN_VILLAGE_WINTER, 8)) && - CHECK_WEEKEVENTREG(WEEKEVENTREG_33_80)) { + CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_SNOWHEAD_TEMPLE)) { gSaveContext.save.entrance = ENTRANCE(MOUNTAIN_VILLAGE_SPRING, 8); } @@ -1532,7 +1531,7 @@ void Sram_InitSave(FileSelectState* fileSelect2, SramContext* sramCtx) { if (gSaveContext.unk_3F3F) { Sram_InitNewSave(); if (fileSelect->unk_24480 == 0) { - gSaveContext.save.cutscene = 0xFFF0; + gSaveContext.save.cutsceneIndex = 0xFFF0; } for (phi_v0 = 0; phi_v0 < ARRAY_COUNT(gSaveContext.save.saveInfo.playerData.playerName); phi_v0++) { @@ -1634,7 +1633,7 @@ void Sram_SaveSpecialEnterClockTown(PlayState* play) { * Saves when beating the game, after showing the "Dawn of the New Day" message */ void Sram_SaveSpecialNewDay(PlayState* play) { - s32 cutscene = gSaveContext.save.cutscene; + s32 cutsceneIndex = gSaveContext.save.cutsceneIndex; s32 day; u16 time = gSaveContext.save.time; @@ -1647,7 +1646,7 @@ void Sram_SaveSpecialNewDay(PlayState* play) { gSaveContext.save.day = day; gSaveContext.save.time = time; - gSaveContext.save.cutscene = cutscene; + gSaveContext.save.cutsceneIndex = cutsceneIndex; func_80185F64(play->sramCtx.saveBuf, D_801C67C8[gSaveContext.fileNum * 2], D_801C67F0[gSaveContext.fileNum * 2]); } diff --git a/src/code/z_sub_s.c b/src/code/z_sub_s.c index 210d6c36f..a4d95af64 100644 --- a/src/code/z_sub_s.c +++ b/src/code/z_sub_s.c @@ -1386,48 +1386,53 @@ void SubS_ChangeAnimationBySpeedInfo(SkelAnime* skelAnime, AnimationSpeedInfo* a *curAnimIndex = nextAnimIndex; } -s32 SubS_StartActorCutscene(Actor* actor, s16 nextCutscene, s16 curCutscene, s32 type) { +s32 SubS_StartCutscene(Actor* actor, s16 nextCsId, s16 curCsId, s32 type) { s32 isStarted = false; - if ((curCutscene != -1) && (ActorCutscene_GetCurrentIndex() == curCutscene)) { - ActorCutscene_Stop(curCutscene); - ActorCutscene_SetIntentToPlay(nextCutscene); - } else if (ActorCutscene_GetCanPlayNext(nextCutscene)) { + if ((curCsId != CS_ID_NONE) && (CutsceneManager_GetCurrentCsId() == curCsId)) { + CutsceneManager_Stop(curCsId); + CutsceneManager_Queue(nextCsId); + } else if (CutsceneManager_IsNext(nextCsId)) { switch (type) { - case SUBS_CUTSCENE_SET_UNK_LINK_FIELDS: - ActorCutscene_StartAndSetUnkLinkFields(nextCutscene, actor); + case SUBS_CUTSCENE_WITH_PLAYER: + CutsceneManager_StartWithPlayerCs(nextCsId, actor); break; + case SUBS_CUTSCENE_NORMAL: - ActorCutscene_Start(nextCutscene, actor); + CutsceneManager_Start(nextCsId, actor); + break; + + case SUBS_CUTSCENE_WITH_PLAYER_SET_FLAG: + CutsceneManager_StartWithPlayerCsAndSetFlag(nextCsId, actor); break; - case SUBS_CUTSCENE_SET_FLAG: - ActorCutscene_StartAndSetFlag(nextCutscene, actor); + + default: break; } isStarted = true; } else { - ActorCutscene_SetIntentToPlay(nextCutscene); + CutsceneManager_Queue(nextCsId); } return isStarted; } -s32 SubS_FillCutscenesList(Actor* actor, s16 cutscenes[], s16 numCutscenes) { - s16 cs; +s32 SubS_FillCutscenesList(Actor* actor, s16 csIdList[], s16 numCutscenes) { + s16 csId; s32 i; for (i = 0; i < numCutscenes; i++) { - cutscenes[i] = -1; + csIdList[i] = CS_ID_NONE; } - cs = actor->cutscene; + csId = actor->csId; i = 0; - while (cs != -1) { - // Note: Infinite loop if numCutscenes is less than possible additional cutscenes + while (csId != CS_ID_NONE) { + // Note: Infinite loop if numCutscenes is less than possible additional csIdList if (i < numCutscenes) { - cutscenes[i] = cs; - cs = ActorCutscene_GetAdditionalCutscene(cs); + csIdList[i] = csId; + csId = CutsceneManager_GetAdditionalCsId(csId); i++; } } |
