summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorAnghelo Carvajal <angheloalf95@gmail.com>2022-03-04 21:14:52 -0300
committerGitHub <noreply@github.com>2022-03-04 19:14:52 -0500
commit77cfd399d0dc4124c72b53f6385f063e601145ed (patch)
tree7656f2593f3bc5363d38e04ea7a2350bea4c8aa1 /src/code
parent8b7cbb1273ccccd505d10757c72b46d293329414 (diff)
`z_demo` with 4 NON_MATCHINGs (#514)
* starting * a bunch * and another bunch * a bunch * Match func_800EB1DC * func_800EB4B4 * func_800EB6F8 * 2 more * fix prototype of a random kankyo function * func_800EBD60 non matching * func_800EC678 matched? * func_800EC6D4 * break * func_800ECD7C * A bunch of functions * func_800EE200 * func_800EDF78 and func_800EE0CC * func_800EDBE0 NON_MATCHING * Cutscene_Init NON_MATCHING * func_800EA324 NON_EQUIVALENT * Fix warnings * func_800EC924 NON_EQUIVALENT * Cutscene_ProcessCommands NON_EQUIVALENT * Format * Split z_demo data and import it * Import bss * Match func_800EB364 * Rename Cutscene_Command_SetTime * Improve Cutscene_ProcessCommands a bit (still not equivalent, probably) * Improve Cutscene_ProcessCommands thanks to engineer and anon * Cutscene_ProcessCommands NON_MATCHING * Name some commands * Fix * Renames based on Engineer knowledge of Audio stuff * More command names * Cutscene_Command_GiveTatlToPlayer * Some cutscene commands macros * more command macros * Macros for unknown commands * Improve Cutscene_Command_Textbox a bit * Rename stuff * Name Terminator and Camera * MOTIONBLUR * Macros for textbox commands * CS_PLAYER_ACTION_LIST * A few macro renames * Small cleaning * A bit more of cleanup * Rumble * Entrance comments in func_800EB6F8 * Some var renames * CS_CMD_FADESCREEN * More clean up * Clean functions protos * Move CutsceneStateHandler out of z64.h * Cutscene_DoNothing * Cutscene_IsPlayingCs & Cutscene_GetSceneSetupIndex * And more renames * name some stuff in the cutscenecontext struct * npcActionIndex->actorActionIndex * Undo names of CS_STATE_ enum * Name Cutscene_ActorTranslate family of functions * small docs pass * sfxconvert and format * Hopefully last cleanup * Add some missing functions to actorfixer * Fix merge issues and remove trailing commas * Cutscene commands fix * Cutscene_Command_Misc improved by engineer * Update src/code/z_demo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Address review * bss * Match Cutscene_Command_Textbox by anon58 * Fix merge issues * Match Cutscene_Command_Misc by @hensldm * review * float time macros * fix merge issues * format * Fix building assets * fix merge issues * format * Fix * format * fix merge issues * fix * fix * format * fix issues and run format * bss * Fix conflicts, bss and formatter * Update include/functions.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update include/functions.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update include/z64.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update include/z64cutscene.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update include/z64cutscene.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update include/z64cutscene.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/z_demo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/z_demo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/z_demo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/z_demo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/z_demo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * address review and fix some stuff * fix merge problems * more fixes and format * Fixes * Update include/functions.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update include/functions.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/z_demo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/z_demo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/z_demo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/z_demo.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Engineer suggestions * format * Elliptic review * Use dec for ShrinkWindow_SetLetterboxTarget * add a few comments * Cutscene_Command_ChooseCreditsScenes * Update src/code/z_demo.c Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * format * some cleanups and some comments * change actorActionCmd from hex to dec in the codebase * minor comment on textboxcmd * ahhhh * Update src/code/z_demo.c Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * brackets * minor comments * rewording * im dumb * brackets * another bracket * Dawn of the New Day * Update src/code/z_demo.c Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * fixes * Cutscene_Command_TransitionFX by Anon Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>
Diffstat (limited to 'src/code')
-rw-r--r--src/code/audio/code_8019AF00.c2
-rw-r--r--src/code/z_demo.c1677
-rw-r--r--src/code/z_kankyo.c4
-rw-r--r--src/code/z_message.c2
-rw-r--r--src/code/z_room.c2
-rw-r--r--src/code/z_scene_proc.c1
6 files changed, 1636 insertions, 52 deletions
diff --git a/src/code/audio/code_8019AF00.c b/src/code/audio/code_8019AF00.c
index 3a498178c..17404280b 100644
--- a/src/code/audio/code_8019AF00.c
+++ b/src/code/audio/code_8019AF00.c
@@ -2233,7 +2233,7 @@ const char sAudioOcarinaUnusedText7[] = "check is over!!! %d %d %d\n";
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3EC0.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3F54.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_SetCutsceneFlag.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3F6C.s")
diff --git a/src/code/z_demo.c b/src/code/z_demo.c
index 72eeb742e..fb6f8687c 100644
--- a/src/code/z_demo.c
+++ b/src/code/z_demo.c
@@ -1,99 +1,1684 @@
#include "global.h"
+#include "overlays/gamestates/ovl_daytelop/z_daytelop.h"
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_Init.s")
+void Cutscene_DoNothing(GlobalContext* globalCtx, CutsceneContext* csCtx);
+void func_800EA258(GlobalContext* globalCtx, CutsceneContext* csCtx);
+void func_800ED9C4(GlobalContext* globalCtx, CutsceneContext* csCtx);
+void func_800EA2B8(GlobalContext* globalCtx, CutsceneContext* csCtx);
+void func_800ED980(GlobalContext* globalCtx, CutsceneContext* csCtx);
+void func_800EDA04(GlobalContext* globalCtx, CutsceneContext* csCtx);
+void func_800EDA84(GlobalContext* globalCtx, CutsceneContext* csCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA0D4.s")
+// Unused
+UNK_TYPE4 D_801BB120 = 0;
+u16 D_801BB124 = 0;
+u16 D_801BB128 = 0;
+u8 D_801BB12C = 0;
+u8 sCutsceneStoredPlayerForm = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA0EC.s")
+// bss
+#ifndef NON_MATCHING
+static u16 seqId;
+#endif
+s16 sCutsceneQuakeIndex;
+struct_801F4D48 sCutsceneCameraInfo;
+u16 D_801F4DC8[10];
+UNK_TYPE D_801F4DDC;
+u8 D_801F4DE0;
+s16 D_801F4DE2;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_StepCutscene1.s")
+void Cutscene_Init(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ s32 i;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_StepCutscene2.s")
+ csCtx->state = CS_STATE_0;
+ csCtx->frames = 0;
+ csCtx->unk_0C = 0.0f;
+ globalCtx->csCtx.sceneCsCount = 0;
+ globalCtx->csCtx.currentCsIndex = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_Nop800EA210.s")
+ for (i = 0; i < ARRAY_COUNT(D_801F4DC8); i++) {
+ D_801F4DC8[i] = 0;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA220.s")
+ D_801F4DE0 = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA258.s")
+ Audio_SetCutsceneFlag(false);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA2B8.s")
+void Cutscene_Start(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ csCtx->state = CS_STATE_1;
+ csCtx->playerAction = NULL;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA324.s")
+void Cutscene_End(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ if (csCtx->state != CS_STATE_4) {
+ csCtx->state = CS_STATE_3;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EABAC.s")
+typedef void (*CutsceneStateHandler)(GlobalContext* globalCtx, CutsceneContext* csCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAC08.s")
+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
+};
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAC44.s")
+void Cutscene_Update1(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ if (gSaveContext.cutscene < 0xFFF0) {
+ sCsStateHandlers1[csCtx->state](globalCtx, csCtx);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAC94.s")
+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
+};
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAD14.s")
+void Cutscene_Update2(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ if ((gSaveContext.cutsceneTrigger != 0) && (globalCtx->sceneLoadFlag == 0x14)) {
+ gSaveContext.cutsceneTrigger = 0;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAD48.s")
+ if ((gSaveContext.cutsceneTrigger != 0) && (csCtx->state == CS_STATE_0)) {
+ gSaveContext.cutscene = 0xFFFD;
+ gSaveContext.cutsceneTrigger = 1;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAD7C.s")
+ if (gSaveContext.cutscene >= 0xFFF0) {
+ func_800EDA84(globalCtx, csCtx);
+ sCsStateHandlers2[csCtx->state](globalCtx, csCtx);
+ }
+}
+void Cutscene_DoNothing(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+}
+
+s32 func_800EA220(GlobalContext* globalCtx, CutsceneContext* csCtx, f32 target) {
+ return Math_StepToF(&csCtx->unk_0C, target, 0.1f);
+}
+
+void func_800EA258(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ Interface_ChangeAlpha(1);
+ ShrinkWindow_SetLetterboxTarget(32);
+ if (func_800EA220(globalCtx, csCtx, 1.0f)) {
+ Audio_SetCutsceneFlag(true);
+ csCtx->state++;
+ }
+}
+
+void func_800EA2B8(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ func_800ED980(globalCtx, csCtx);
+ Interface_ChangeAlpha(1);
+ ShrinkWindow_SetLetterboxTarget(32);
+ if (func_800EA220(globalCtx, csCtx, 1.0f)) {
+ Audio_SetCutsceneFlag(true);
+ csCtx->state++;
+ }
+}
+
+/* Start of command handling section */
+
+// Command 0x96: Miscellaneous commands.
+void Cutscene_Command_Misc(GlobalContext* globalCtx2, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ static u16 D_801BB15C = 0xFFFF;
+ Player* player = GET_PLAYER(globalCtx2);
+ GlobalContext* globalCtx = globalCtx2;
+ u8 isStartFrame = false;
+ f32 progress;
+ SceneTableEntry* loadedScene;
+ u16 time;
+
+ if ((csCtx->frames < cmd->startFrame) || ((csCtx->frames >= cmd->endFrame) && (cmd->endFrame != cmd->startFrame))) {
+ return;
+ }
+
+ progress = Environment_LerpWeight(cmd->endFrame - 1, cmd->startFrame, csCtx->frames);
+ if (csCtx->frames == cmd->startFrame) {
+ isStartFrame = true;
+ }
+
+ // TODO: consider creating an enum for this when we understand what each value does
+ switch (cmd->base) {
+ case 0x1:
+ if (isStartFrame) {
+ func_800FD78C(globalCtx);
+ globalCtx->envCtx.unk_F2[0] = 0x3C;
+ }
+ break;
+ case 0x2:
+ if (isStartFrame) {
+ func_801A47DC(NATURE_CHANNEL_LIGHTNING, CHANNEL_IO_PORT_0, 0);
+ Environment_AddLightningBolts(globalCtx, 3);
+ D_801F4E68 = 1;
+ }
+ break;
+ case 0x3:
+ if (globalCtx->envCtx.lightSettings.fogFar < 12800) {
+ globalCtx->envCtx.lightSettings.fogFar += 35;
+ }
+ break;
+ case 0x4:
+ if (isStartFrame) {
+ globalCtx->envCtx.unk_19 = 1;
+ globalCtx->envCtx.unk_17 = 1;
+ globalCtx->envCtx.unk_18 = 0;
+ globalCtx->envCtx.unk_1A = 0x3C;
+ globalCtx->envCtx.unk_21 = 1;
+ globalCtx->envCtx.unk_1F = 0;
+ globalCtx->envCtx.unk_20 = 1;
+ globalCtx->envCtx.unk_24 = 0x3C;
+ globalCtx->envCtx.unk_22 = globalCtx->envCtx.unk_24;
+ }
+ break;
+ case 0x5:
+ if (isStartFrame && (csCtx->state != CS_STATE_4)) {
+ csCtx->state = CS_STATE_3;
+ }
+ break;
+ case 0x7:
+ if (isStartFrame) {
+ loadedScene = globalCtx->loadedScene;
+ if (loadedScene->titleTextId != 0) {
+ func_80151A68(globalCtx, loadedScene->titleTextId);
+ }
+ }
+ break;
+ case 0x8:
+ func_8019F128(NA_SE_EV_EARTHQUAKE_LAST - SFX_FLAG);
+ if (isStartFrame) {
+ sCutsceneQuakeIndex = Quake_Add(GET_ACTIVE_CAM(globalCtx), 6);
+ Quake_SetSpeed(sCutsceneQuakeIndex, 22000);
+ Quake_SetQuakeValues(sCutsceneQuakeIndex, 6, 4, 0, 0);
+ Quake_SetCountdown(sCutsceneQuakeIndex, 800);
+ }
+ break;
+ case 0x9:
+ if (isStartFrame) {
+ Quake_Init();
+ }
+ break;
+ case 0xA:
+ D_801F6D30.r = 255;
+ D_801F6D30.g = 255;
+ D_801F6D30.b = 255;
+ D_801F6D30.a = 255 * progress;
+ break;
+ case 0xB:
+ D_801F6D30.r = 255;
+ D_801F6D30.g = 180;
+ D_801F6D30.b = 100;
+ D_801F6D30.a = 255 * progress;
+ break;
+ case 0xC:
+ globalCtx->roomCtx.currRoom.segment = NULL;
+ break;
+ case 0xD:
+ if (globalCtx->state.frames & 8) {
+ if (globalCtx->envCtx.lightSettings.ambientColor[0] < 40) {
+ globalCtx->envCtx.lightSettings.ambientColor[0] += 2;
+ globalCtx->envCtx.lightSettings.diffuseColor1[1] -= 3;
+ globalCtx->envCtx.lightSettings.diffuseColor1[2] -= 3;
+ }
+ } else {
+ if (globalCtx->envCtx.lightSettings.ambientColor[0] > 2) {
+ globalCtx->envCtx.lightSettings.ambientColor[0] -= 2;
+ globalCtx->envCtx.lightSettings.diffuseColor1[1] += 3;
+ globalCtx->envCtx.lightSettings.diffuseColor1[2] += 3;
+ }
+ }
+ break;
+ case 0xE:
+ globalCtx->unk_18845 = 1;
+ break;
+ case 0xF:
+ globalCtx->unk_18845 = 0;
+ break;
+ case 0x10:
+ if (isStartFrame) {
+ globalCtx->envCtx.sandstormState = 1;
+ }
+ func_8019F128(NA_SE_EV_SAND_STORM - SFX_FLAG);
+ break;
+ case 0x11:
+ gSaveContext.sunsSongState = SUNSSONG_START;
+ break;
+ case 0x12:
+ if (!gSaveContext.isNight) {
+ time = gSaveContext.time;
+ gSaveContext.time = time - (u16)REG(15);
+ } else {
+ time = gSaveContext.time;
+ gSaveContext.time = time - (u16)(2 * REG(15));
+ }
+ break;
+ case 0x13:
+ // AudioOcarina_PlayLongScarecrowAfterCredits
+ func_8019D758();
+ csCtx->frames = cmd->startFrame - 1;
+ break;
+ case 0x14:
+ EnvFlags_Set(globalCtx, 3);
+ break;
+ case 0x15:
+ EnvFlags_Set(globalCtx, 4);
+ break;
+ case 0x16:
+ gSaveContext.playerForm = PLAYER_FORM_DEKU;
+ break;
+ case 0x17:
+ player->stateFlags2 |= 0x4000000;
+ break;
+ case 0x18:
+ player->stateFlags2 &= ~0x4000000;
+ break;
+ case 0x19:
+ sCutsceneStoredPlayerForm = gSaveContext.playerForm;
+ gSaveContext.playerForm = PLAYER_FORM_HUMAN;
+ gSaveContext.equippedMask = PLAYER_MASK_NONE;
+ break;
+ case 0x1A:
+ func_8019F128(NA_SE_EV_EARTHQUAKE_LAST2 - SFX_FLAG);
+ if (isStartFrame) {
+ sCutsceneQuakeIndex = Quake_Add(GET_ACTIVE_CAM(globalCtx), 6);
+ Quake_SetSpeed(sCutsceneQuakeIndex, 30000);
+ Quake_SetQuakeValues(sCutsceneQuakeIndex, 20, 10, 0, 0);
+ Quake_SetCountdown(sCutsceneQuakeIndex, 800);
+ }
+ break;
+ case 0x1B:
+ if (isStartFrame) {
+ globalCtx->nextEntranceIndex = 0x1C00;
+ gSaveContext.nextCutsceneIndex = 0xFFF8;
+ globalCtx->sceneLoadFlag = 0x14;
+ globalCtx->unk_1887F = 3;
+ }
+ break;
+ case 0x1C:
+ if (isStartFrame) {
+ globalCtx->envCtx.unk_17 = 0xD;
+ }
+ break;
+ case 0x1D:
+ gSaveContext.playerForm = sCutsceneStoredPlayerForm;
+ break;
+ case 0x1E:
+ D_801F4DE0 = true;
+ break;
+ case 0x1F:
+ D_801F4DE0 = false;
+ break;
+ case 0x21:
+ if (isStartFrame) {
+ func_80146EE8(globalCtx);
+ }
+ break;
+ case 0x22:
+ if (isStartFrame) {
+ func_80144A94(&globalCtx->sramCtx);
+ }
+ break;
+ case 0x23:
+ if (csCtx->frames != D_801BB15C) {
+ D_801BB15C = csCtx->frames;
+
+ if (REG(15) != 0) {
+ time = gSaveContext.time;
+ gSaveContext.time = (u16)REG(15) + time;
+ time = gSaveContext.time;
+ gSaveContext.time = (u16)gSaveContext.unk_14 + time;
+ }
+ }
+ break;
+ case 0x24:
+ func_8019F128(NA_SE_EV_EARTHQUAKE_LAST - SFX_FLAG);
+ if (isStartFrame) {
+ sCutsceneQuakeIndex = Quake_Add(GET_ACTIVE_CAM(globalCtx), 6);
+ Quake_SetSpeed(sCutsceneQuakeIndex, 22000);
+ Quake_SetQuakeValues(sCutsceneQuakeIndex, 2, 1, 0, 0);
+ Quake_SetCountdown(sCutsceneQuakeIndex, 800);
+ }
+ break;
+
+ case 0x26:
+ // Seems to be used to trigger "Dawn of A New Day"
+
+ gSaveContext.day = 9;
+
+ {
+ GameState* gameState = &globalCtx->state;
+ gameState->running = false;
+ }
+ SET_NEXT_GAMESTATE(&globalCtx->state, Daytelop_Init, DaytelopContext);
+
+ func_80146F5C(globalCtx);
+ break;
+
+ case 0x27:
+ gSaveContext.playerForm = PLAYER_FORM_ZORA;
+ break;
+
+ case 0x28:
+ csCtx->frames = cmd->startFrame - 1;
+ break;
+ }
+}
+
+// Command 0x97: Set Environment Lighting
+void Cutscene_Command_SetLighting(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdEnvLighting* cmd) {
+ if (csCtx->frames == cmd->startFrame) {
+ if (cmd->setting != 0x20) {
+ globalCtx->envCtx.lightSettingOverride = cmd->setting - 1;
+ globalCtx->envCtx.lightBlend = 1.0f;
+ } else {
+ globalCtx->envCtx.lightSettingOverride = 0xFF;
+ }
+ }
+}
+
+// Command 0x12C: Plays a sequence (Background music or Fanfare)
+void Cutscene_Command_PlaySequence(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdSequenceChange* cmd) {
+ if (csCtx->frames == cmd->startFrame) {
+ func_801A2C88(cmd->sequence - 1);
+ }
+}
+
+// Command 0x12D: Stops a sequence (Background music or Fanfare)
+void Cutscene_Command_StopSequence(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdSequenceChange* cmd) {
+ if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) {
+ func_801A2D54(cmd->sequence - 1);
+ }
+}
+
+// Command 0x9C: Fade a sequence (Background music or Fanfare) over duration
+void Cutscene_Command_FadeSequence(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdSequenceFade* cmd) {
+ if ((csCtx->frames == cmd->startFrame) && (csCtx->frames < cmd->endFrame)) {
+ u8 fadeTimer = cmd->endFrame - cmd->startFrame;
+
+ if (cmd->type == 2) {
+ Audio_QueueSeqCmd((fadeTimer << 0x10) | 0x110000FF);
+ } else {
+ Audio_QueueSeqCmd((fadeTimer << 0x10) | NA_BGM_STOP);
+ }
+ }
+}
+
+// Command 0x12E: Play Ambience sequence
+void Cutscene_Command_PlayAmbienceSequence(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ if (csCtx->frames == cmd->startFrame) {
+ // Audio_PlayNatureAmbienceSequence
+ // nightSeqIndex is natureAmbienceId
+ func_801A4A28(globalCtx->soundCtx.nightSeqIndex);
+ }
+}
+
+// Command 0x130:
+void func_800EAD48(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ if (csCtx->frames == cmd->startFrame) {
+ // Audio_SetSfxReverbIndexExceptOcarinaBank
+ func_801A4428(2);
+ }
+}
+
+// Command 0x131:
+void func_800EAD7C(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ if (csCtx->frames == cmd->startFrame) {
+ // Audio_SetSfxReverbIndexExceptOcarinaBank
+ func_801A4428(1);
+ }
+}
+
+#ifdef NON_MATCHING
+// needs in-function static bss
+// audio related
+void func_800EADB0(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ static u16 seqId;
+ u8 dayMinusOne;
+
+ if (csCtx->frames == cmd->startFrame) {
+ dayMinusOne = (gSaveContext.day - 1);
+ if (dayMinusOne >= 3) {
+ dayMinusOne = 0;
+ }
+
+ switch (cmd->base) {
+ case 1:
+ // func_801A246C(SEQ_PLAYER_BGM_MAIN, TYPE_1);
+ func_801A246C(SEQ_PLAYER_BGM_MAIN, 1);
+ break;
+
+ case 2:
+ // func_801A246C(SEQ_PLAYER_BGM_MAIN, TYPE_0);
+ func_801A246C(SEQ_PLAYER_BGM_MAIN, 0);
+ break;
+
+ case 3:
+ // func_801A246C(SEQ_PLAYER_BGM_MAIN, TYPE_2);
+ func_801A246C(SEQ_PLAYER_BGM_MAIN, 2);
+ break;
+
+ case 4:
+ // func_801A246C(SEQ_PLAYER_NATURE, TYPE_1);
+ func_801A246C(SEQ_PLAYER_NATURE, 1);
+ break;
+
+ case 5:
+ // func_801A246C(SEQ_PLAYER_NATURE, TYPE_0);
+ func_801A246C(SEQ_PLAYER_NATURE, 0);
+ break;
+
+ case 6:
+ // func_801A246C(SEQ_PLAYER_NATURE, TYPE_2);
+ func_801A246C(SEQ_PLAYER_NATURE, 2);
+ break;
+
+ case 7:
+ // Audio_GetActiveSequence
+ seqId = func_801A8A50(0);
+ break;
+
+ case 8:
+ if (seqId != NA_BGM_DISABLED) {
+ // Audio_PlayBgmForDayScene
+ func_801A25E4(seqId, dayMinusOne);
+ }
+ break;
+ }
+ }
+}
+#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EADB0.s")
+#endif
+
+// Command 0x12F: Fade Ambience sequence
+void Cutscene_Command_FadeAmbienceSequence(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ if (csCtx->frames == cmd->startFrame && csCtx->frames < cmd->endFrame) {
+ u8 fadeTimer = cmd->endFrame - cmd->startFrame;
+
+ Audio_QueueSeqCmd((fadeTimer << 0x10) | 0x140000FF);
+ }
+}
+
+// Command 0x190: Rumble
+void Cutscene_Command_Rumble(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdRumble* cmd) {
+ switch (cmd->type) {
+ case 1:
+ if (csCtx->frames == cmd->startFrame) {
+ func_8013ECE0(0.0f, cmd->unk6, cmd->unk7, cmd->unk8);
+ }
+ break;
+
+ case 2:
+ if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) {
+ if ((csCtx->frames == cmd->startFrame) || (globalCtx->state.frames % 64 == 0)) {
+ func_8013ECE0(0.0f, cmd->unk6, cmd->unk7, cmd->unk8);
+ }
+ }
+ break;
+ }
+}
+
+// Command 0x9B:
+void Cutscene_Command_FadeColorScreen(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdFadeScreen* cmd) {
+ if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) {
+ f32 alpha;
+
+ globalCtx->envCtx.fillScreen = true;
+ alpha = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->frames);
+
+ if (((cmd->unk0 == 1)) || (cmd->unk0 == 2)) {
+ globalCtx->envCtx.screenFillColor[0] = cmd->color.r;
+ globalCtx->envCtx.screenFillColor[1] = cmd->color.g;
+ globalCtx->envCtx.screenFillColor[2] = cmd->color.b;
+
+ if (cmd->unk0 == 2) {
+ globalCtx->envCtx.screenFillColor[3] = (1.0f - alpha) * 255.0f;
+ } else {
+ globalCtx->envCtx.screenFillColor[3] = 255.0f * alpha;
+ }
+ }
+ }
+}
+
+// Command 0x9D: Set Time of Day & Environment Time
+void Cutscene_Command_SetTime(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdDayTime* cmd) {
+ u16 nextTime;
+ u16 hourAsMinutes;
+ u16 minutes;
+
+ if (csCtx->frames == cmd->startFrame) {
+ hourAsMinutes = CLOCK_TIME_ALT_F(cmd->hour, 0);
+ minutes = CLOCK_TIME_ALT_F(0, cmd->minute + 1);
+
+ nextTime = hourAsMinutes + minutes;
+ gSaveContext.time = nextTime;
+ gSaveContext.environmentTime = nextTime;
+ }
+}
+
+void Cutscene_TerminatorImpl(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ csCtx->state = CS_STATE_4;
+ func_80165690();
+ Audio_SetCutsceneFlag(false);
+ gSaveContext.unk_3F48 = 1;
+
+ if ((gSaveContext.gameMode != 0) && (csCtx->frames != cmd->startFrame)) {
+ gSaveContext.unk_3F1E = 1;
+ }
+
+ gSaveContext.cutscene = 0;
+ if (cmd->base == 1) {
+ globalCtx->nextEntranceIndex = globalCtx->csCtx.sceneCsList[globalCtx->csCtx.currentCsIndex].nextEntranceIndex;
+ gSaveContext.nextCutsceneIndex = 0;
+ globalCtx->sceneLoadFlag = 0x14;
+ if (gSaveContext.gameMode != 1) {
+ Scene_SetExitFade(globalCtx);
+ } else {
+ D_801BB12C++;
+ if (D_801BB12C >= 2) {
+ D_801BB12C = 0;
+ }
+ globalCtx->unk_1887F = 4;
+ }
+
+ if ((globalCtx->nextEntranceIndex & 0xF) > 0) {
+ gSaveContext.nextCutsceneIndex = (globalCtx->nextEntranceIndex & 0xF) + 0xFFEF;
+ }
+
+ globalCtx->nextEntranceIndex &= ~0xF;
+ }
+}
+
+// Command 0x15E
+void Cutscene_Command_Terminator(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ if (cmd->base == 1) {
+ if (csCtx->frames == cmd->startFrame) {
+ Cutscene_TerminatorImpl(globalCtx, csCtx, cmd);
+ }
+ } else if (cmd->base == 2) {
+ if (csCtx->frames == cmd->startFrame) {
+ func_80165690();
+
+ switch (D_801F4DE2) {
+ case 0x1F:
+ if (gSaveContext.weekEventReg[0x14] & 2) {
+ globalCtx->nextEntranceIndex = 0x3010;
+ globalCtx->sceneLoadFlag = 0x14;
+ globalCtx->unk_1887F = 3;
+ } else {
+ globalCtx->nextEntranceIndex = 0x8600;
+ gSaveContext.nextCutsceneIndex = 0xFFF0;
+ globalCtx->sceneLoadFlag = 0x14;
+ globalCtx->unk_1887F = 3;
+ }
+ break;
+
+ case 0x44:
+ if (gSaveContext.weekEventReg[0x21] & 0x80) {
+ globalCtx->nextEntranceIndex = 0xAE70;
+ globalCtx->sceneLoadFlag = 0x14;
+ globalCtx->unk_1887F = 3;
+ } else {
+ globalCtx->nextEntranceIndex = 0xAE00;
+ gSaveContext.nextCutsceneIndex = 0xFFF0;
+ globalCtx->sceneLoadFlag = 0x14;
+ globalCtx->unk_1887F = 3;
+ }
+ break;
+
+ case 0x5F:
+ gSaveContext.weekEventReg[0x37] |= 0x80;
+ globalCtx->nextEntranceIndex = 0x6A80;
+ gSaveContext.nextCutsceneIndex = 0xFFF0;
+ globalCtx->sceneLoadFlag = 0x14;
+ globalCtx->unk_1887F = 3;
+ break;
+
+ case 0x36:
+ gSaveContext.weekEventReg[0x34] |= 0x20;
+ globalCtx->nextEntranceIndex = 0x2000;
+ gSaveContext.nextCutsceneIndex = 0xFFF1;
+ globalCtx->sceneLoadFlag = 0x14;
+ globalCtx->unk_1887F = 3;
+ break;
+ }
+ }
+ }
+}
+
+// Command 0x15F: Chooses between a cutscene or a rotating mask depending on whether the player has the corresponding
+// mask
+void Cutscene_Command_ChooseCreditsScenes(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ if ((csCtx->frames >= cmd->startFrame) && (func_801A3950(0, true) != 0xFF)) {
+ switch (cmd->base) {
+ case 1:
+ Cutscene_TerminatorImpl(globalCtx, csCtx, cmd);
+ break;
+
+ case 2:
+ if (INV_CONTENT(ITEM_MASK_KAMARO) == ITEM_MASK_KAMARO) {
+ // Milk bar
+ globalCtx->nextEntranceIndex = 0x2400;
+ gSaveContext.nextCutsceneIndex = 0xFFF0;
+ } else {
+ // SPOT00
+ globalCtx->nextEntranceIndex = 0x1C00;
+ gSaveContext.nextCutsceneIndex = 0xFFF9;
+ }
+ globalCtx->sceneLoadFlag = 0x14;
+ break;
+
+ case 3:
+ if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) {
+ // Fairy's fountain
+ globalCtx->nextEntranceIndex = 0x4600;
+ gSaveContext.nextCutsceneIndex = 0xFFF0;
+ } else {
+ // SPOT00
+ globalCtx->nextEntranceIndex = 0x1C10;
+ gSaveContext.nextCutsceneIndex = 0xFFF9;
+ }
+ globalCtx->sceneLoadFlag = 0x14;
+ break;
+
+ case 4:
+ if (INV_CONTENT(ITEM_MASK_ROMANI) == ITEM_MASK_ROMANI) {
+ // Romani ranch
+ globalCtx->nextEntranceIndex = 0x6400;
+ gSaveContext.nextCutsceneIndex = 0xFFF1;
+ } else {
+ // SPOT00
+ globalCtx->nextEntranceIndex = 0x1C20;
+ gSaveContext.nextCutsceneIndex = 0xFFF9;
+ }
+ globalCtx->sceneLoadFlag = 0x14;
+ break;
+
+ case 5:
+ if (INV_CONTENT(ITEM_MASK_BLAST) == ITEM_MASK_BLAST) {
+ // West clock town
+ globalCtx->nextEntranceIndex = 0xD400;
+ gSaveContext.nextCutsceneIndex = 0xFFF0;
+ } else {
+ // SPOT00
+ globalCtx->nextEntranceIndex = 0x1C30;
+ gSaveContext.nextCutsceneIndex = 0xFFF9;
+ }
+ globalCtx->sceneLoadFlag = 0x14;
+ break;
+
+ case 6:
+ if (INV_CONTENT(ITEM_MASK_CIRCUS_LEADER) == ITEM_MASK_CIRCUS_LEADER) {
+ // Milk bar
+ globalCtx->nextEntranceIndex = 0x2400;
+ gSaveContext.nextCutsceneIndex = 0xFFF1;
+ } else {
+ // SPOT00
+ globalCtx->nextEntranceIndex = 0x1C50;
+ gSaveContext.nextCutsceneIndex = 0xFFF9;
+ }
+ globalCtx->sceneLoadFlag = 0x14;
+ break;
+
+ case 7:
+ if (INV_CONTENT(ITEM_MASK_BREMEN) == ITEM_MASK_BREMEN) {
+ // Milk bar
+ globalCtx->nextEntranceIndex = 0x2400;
+ gSaveContext.nextCutsceneIndex = 0xFFF3;
+ } else {
+ // SPOT00
+ globalCtx->nextEntranceIndex = 0x1C60;
+ gSaveContext.nextCutsceneIndex = 0xFFF9;
+ }
+ globalCtx->sceneLoadFlag = 0x14;
+ break;
+
+ case 8:
+ // Ikana canyon
+ globalCtx->nextEntranceIndex = 0x2000;
+ gSaveContext.nextCutsceneIndex = 0xFFF3;
+ globalCtx->sceneLoadFlag = 0x14;
+ break;
+
+ case 9:
+ if (INV_CONTENT(ITEM_MASK_COUPLE) == ITEM_MASK_COUPLE) {
+ // Termina field
+ globalCtx->nextEntranceIndex = 0x5400;
+ gSaveContext.nextCutsceneIndex = 0xFFF8;
+ } else {
+ // SPOT00
+ globalCtx->nextEntranceIndex = 0x1C70;
+ gSaveContext.nextCutsceneIndex = 0xFFF9;
+ }
+ globalCtx->sceneLoadFlag = 0x14;
+ break;
+
+ case 10:
+ if (INV_CONTENT(ITEM_MASK_BUNNY) == ITEM_MASK_BUNNY) {
+ // Cucco shack
+ globalCtx->nextEntranceIndex = 0x7E00;
+ gSaveContext.nextCutsceneIndex = 0xFFF0;
+ } else {
+ // SPOT00
+ globalCtx->nextEntranceIndex = 0x1C40;
+ gSaveContext.nextCutsceneIndex = 0xFFF9;
+ }
+ globalCtx->sceneLoadFlag = 0x14;
+ break;
+
+ case 11:
+ if (INV_CONTENT(ITEM_MASK_POSTMAN) == ITEM_MASK_POSTMAN) {
+ // Termina field
+ globalCtx->nextEntranceIndex = 0x5410;
+ gSaveContext.nextCutsceneIndex = 0xFFF8;
+ } else {
+ // SPOT00
+ globalCtx->nextEntranceIndex = 0x1C80;
+ gSaveContext.nextCutsceneIndex = 0xFFF9;
+ }
+ globalCtx->sceneLoadFlag = 0x14;
+ break;
+ }
+ }
+}
+
+// Command 0x99: Motion blur
+void Cutscene_Command_MotionBlur(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) {
+ if ((csCtx->frames == cmd->startFrame) && (cmd->base == 1)) {
+ func_8016566C(180);
+ }
+
+ if (cmd->base == 2) {
+ f32 progress = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->frames);
+
+ if (progress >= 0.9f) {
+ func_80165690();
+ } else {
+ func_80165658((1.0f - progress) * 180.0f);
+ }
+ }
+ }
+}
+
+// Command 0x9A: Gives Tatl to the player
+void Cutscene_Command_GiveTatlToPlayer(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ Player* player = GET_PLAYER(globalCtx);
+
+ if (csCtx->frames == cmd->startFrame) {
+ if (cmd->base == 1) {
+ gSaveContext.hasTatl = true;
+ if (player->tatlActor != NULL) {
+ return;
+ }
+ player->tatlActor = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, player->actor.world.pos.x,
+ player->actor.world.pos.y, player->actor.world.pos.z, 0, 0, 0, 0);
+ }
+ }
+}
+
+// Command 0x98
+void Cutscene_Command_TransitionFX(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) {
+ if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) {
+ f32 temp_f0;
+
+ globalCtx->envCtx.fillScreen = true;
+ temp_f0 = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->frames);
+
+ switch (cmd->base) {
+ case 1:
+ case 5:
+ globalCtx->envCtx.screenFillColor[0] = 160;
+ globalCtx->envCtx.screenFillColor[1] = 160;
+ globalCtx->envCtx.screenFillColor[2] = 160;
+ if (cmd->base == 1) {
+ globalCtx->envCtx.screenFillColor[3] = 255.0f * temp_f0;
+ if (temp_f0 == 0.0f) {
+ func_8019F128(NA_SE_EV_S_STONE_FLASH);
+ }
+ } else {
+ globalCtx->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f;
+ }
+ break;
+
+ case 2:
+ case 6:
+ globalCtx->envCtx.screenFillColor[0] = 0;
+ globalCtx->envCtx.screenFillColor[1] = 0;
+ globalCtx->envCtx.screenFillColor[2] = 255;
+ if (cmd->base == 2) {
+ globalCtx->envCtx.screenFillColor[3] = 255.0f * temp_f0;
+ } else {
+ globalCtx->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAECC.s")
+ case 3:
+ case 7:
+ globalCtx->envCtx.screenFillColor[0] = 255;
+ globalCtx->envCtx.screenFillColor[1] = 0;
+ globalCtx->envCtx.screenFillColor[2] = 0;
+ if (cmd->base == 3) {
+ globalCtx->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f;
+ } else {
+ globalCtx->envCtx.screenFillColor[3] = 255.0f * temp_f0;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAF20.s")
+ case 4:
+ case 8:
+ globalCtx->envCtx.screenFillColor[0] = 0;
+ globalCtx->envCtx.screenFillColor[1] = 255;
+ globalCtx->envCtx.screenFillColor[2] = 0;
+ if (cmd->base == 4) {
+ globalCtx->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f;
+ } else {
+ globalCtx->envCtx.screenFillColor[3] = 255.0f * temp_f0;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAFE0.s")
+ case 9:
+ gSaveContext.unk_3F48 = 1;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EB1DC.s")
+ case 10:
+ case 11:
+ globalCtx->envCtx.screenFillColor[0] = 0;
+ globalCtx->envCtx.screenFillColor[1] = 0;
+ globalCtx->envCtx.screenFillColor[2] = 0;
+ if (cmd->base == 10) {
+ globalCtx->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f;
+ } else {
+ globalCtx->envCtx.screenFillColor[3] = 255.0f * temp_f0;
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EB364.s")
+ case 12:
+ globalCtx->envCtx.screenFillColor[0] = (160.0f * (1.0f - temp_f0));
+ globalCtx->envCtx.screenFillColor[1] = globalCtx->envCtx.screenFillColor[0];
+ globalCtx->envCtx.screenFillColor[2] = globalCtx->envCtx.screenFillColor[0];
+ globalCtx->envCtx.screenFillColor[3] = 255;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EB4B4.s")
+ case 13:
+ globalCtx->envCtx.screenFillColor[0] = (160.0f * temp_f0);
+ globalCtx->envCtx.screenFillColor[1] = globalCtx->envCtx.screenFillColor[0];
+ globalCtx->envCtx.screenFillColor[2] = globalCtx->envCtx.screenFillColor[0];
+ globalCtx->envCtx.screenFillColor[3] = 255;
+ break;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EB6F8.s")
+// Command 0x5A: Camera
+s32 Cutscene_Command_Camera(GlobalContext* globalCtx, u8* cmd) {
+ s32 sp1C = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EBB68.s")
+ bcopy(cmd, &sp1C, sizeof(s32));
+ cmd += sizeof(s32);
+ if (func_8016A168() == 0) {
+ func_80161998(cmd, &sCutsceneCameraInfo);
+ }
+ return sp1C + sizeof(s32);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EBCD0.s")
+/**
+ * Counts how many masks the player has
+ * The count doesn't include transformation masks
+ */
+s32 Cutscene_CountNormalMasks(void) {
+ s32 count = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EBD60.s")
+ if (INV_CONTENT(ITEM_MASK_TRUTH) == ITEM_MASK_TRUTH) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_KAFEIS_MASK) == ITEM_MASK_KAFEIS_MASK) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_ALL_NIGHT) == ITEM_MASK_ALL_NIGHT) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_BUNNY) == ITEM_MASK_BUNNY) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_KEATON) == ITEM_MASK_KEATON) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_GARO) == ITEM_MASK_GARO) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_ROMANI) == ITEM_MASK_ROMANI) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_CIRCUS_LEADER) == ITEM_MASK_CIRCUS_LEADER) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_POSTMAN) == ITEM_MASK_POSTMAN) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_COUPLE) == ITEM_MASK_COUPLE) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_GIBDO) == ITEM_MASK_GIBDO) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_DON_GERO) == ITEM_MASK_DON_GERO) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_KAMARO) == ITEM_MASK_KAMARO) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_CAPTAIN) == ITEM_MASK_CAPTAIN) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_STONE) == ITEM_MASK_STONE) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_BREMEN) == ITEM_MASK_BREMEN) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_BLAST) == ITEM_MASK_BLAST) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_SCENTS) == ITEM_MASK_SCENTS) {
+ count++;
+ }
+ if (INV_CONTENT(ITEM_MASK_GIANT) == ITEM_MASK_GIANT) {
+ count++;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EC678.s")
+ return count;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EC6D4.s")
+// Command 0xA: Textbox
+void Cutscene_Command_Textbox(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdTextbox* cmd) {
+ static s32 D_801BB160 = CS_TEXTBOX_TYPE_DEFAULT;
+ u8 dialogState;
+ s32 pad;
+ u16 originalCsFrames;
+ s32 pad2;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EC924.s")
+ if ((cmd->startFrame >= csCtx->frames) || ((cmd->endFrame < csCtx->frames))) {
+ return;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800ECD7C.s")
+ if (cmd->type != CS_TEXTBOX_TYPE_LEARN_SONG) {
+ if (D_801BB124 != cmd->base) {
+ if (D_801BB160 == CS_TEXTBOX_TYPE_3) {
+ csCtx->frames--;
+ }
+ D_801BB160 = CS_TEXTBOX_TYPE_1;
+ D_801BB124 = cmd->base;
+ if (cmd->type == CS_TEXTBOX_TYPE_BOSSES_REMAINS) {
+ if (CHECK_QUEST_ITEM(QUEST_REMAINS_ODOWLA) && CHECK_QUEST_ITEM(QUEST_REMAINS_GOHT) &&
+ CHECK_QUEST_ITEM(QUEST_REMAINS_GYORG) && CHECK_QUEST_ITEM(QUEST_REMAINS_TWINMOLD)) {
+ if (cmd->textId1 != 0xFFFF) {
+ Message_StartTextbox(globalCtx, cmd->textId1, NULL);
+ }
+ } else {
+ Message_StartTextbox(globalCtx, cmd->base, NULL);
+ }
+ } else if (cmd->type == CS_TEXTBOX_TYPE_ALL_NORMAL_MASKS) {
+ if (Cutscene_CountNormalMasks() == 20) {
+ if (cmd->textId1 != 0xFFFF) {
+ Message_StartTextbox(globalCtx, cmd->textId1, NULL);
+ }
+ } else {
+ Message_StartTextbox(globalCtx, cmd->base, NULL);
+ }
+ } else {
+ Message_StartTextbox(globalCtx, cmd->base, NULL);
+ }
+ } else {
+ goto else_label;
+ }
+ } else if (D_801BB128 != cmd->base) {
+ D_801BB160 = CS_TEXTBOX_TYPE_LEARN_SONG;
+ D_801BB128 = cmd->base;
+ func_80152434(globalCtx, 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;
+ dialogState = Message_GetState(&globalCtx->msgCtx);
+ if ((dialogState != 2) && (dialogState != 0) && (dialogState != 7) && (dialogState != 8)) {
+ csCtx->frames--;
+ if ((dialogState == 4) && func_80147624(globalCtx)) {
+ if (globalCtx->msgCtx.choiceIndex == 0) {
+ if (cmd->base == 0x33BD) {
+ func_8019F230();
+ }
+
+ if (cmd->textId1 != 0xFFFF) {
+ func_80151938(globalCtx, cmd->textId1);
+ if (cmd->type == CS_TEXTBOX_TYPE_3) {
+ D_801BB160 = CS_TEXTBOX_TYPE_3;
+ if (cmd->textId2 != 0xFFFF) {
+ csCtx->frames++;
+ }
+ }
+ } else {
+ func_801477B4(globalCtx);
+ csCtx->frames++;
+ }
+ } else {
+ if (cmd->base == 0x33BD) {
+ func_8019F208();
+ }
+
+ if (cmd->textId2 != 0xFFFF) {
+ func_80151938(globalCtx, cmd->textId2);
+ if (cmd->type == CS_TEXTBOX_TYPE_3) {
+ D_801BB160 = CS_TEXTBOX_TYPE_3;
+ if (cmd->textId1 != 0xFFFF) {
+ csCtx->frames++;
+ }
+ }
+ } else {
+ func_801477B4(globalCtx);
+ csCtx->frames++;
+ }
+ }
+ }
+
+ if (dialogState == 5 && func_80147624(globalCtx) != 0) {
+ func_80152434(globalCtx, cmd->base);
+ }
+ }
+
+ if ((dialogState == 2) && (D_801BB160 == CS_TEXTBOX_TYPE_3)) {
+ csCtx->frames--;
+ D_801BB124++;
+ }
+
+ if (originalCsFrames == csCtx->frames) {
+ Interface_ChangeAlpha(1);
+ D_801BB124 = 0;
+ D_801BB128 = 0;
+ func_80161C0C();
+ } else {
+ func_80161BE0(1);
+ }
+ }
+ }
+}
+
+// Related to actorActions. Maybe a generic actorAction setter?
+void func_800ECD7C(CutsceneContext* csCtx, u8** cutscenePtr, s16 index) {
+ s32 i;
+ s32 count;
+
+ bcopy(*cutscenePtr, &count, sizeof(s32));
+ *cutscenePtr += sizeof(s32);
+
+ for (i = 0; i < count; i++) {
+ CsCmdActorAction* actorAction = *(CsCmdActorAction**)cutscenePtr;
+
+ if ((csCtx->frames >= actorAction->startFrame) && (csCtx->frames < actorAction->endFrame)) {
+ csCtx->actorActions[index] = actorAction;
+ }
+
+ *cutscenePtr += sizeof(CsCmdActorAction);
+ }
+}
+
+#ifdef NON_MATCHING
+// Some stack issues, and a few instructions in the "wrong" places
+/**
+ * Loops over the cutscene data itself (`cutscenePtr`), 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
+ * - A beginning, which contains the number of command lists of this cutscene and the ending frame (see
+ * `CS_BEGIN_CUTSCENE`).
+ * - Any number of cutscene command lists (which should be the number specified in the beginning), each one of which
+ * contains commands of the corresponding category.
+ * - A end marker (see `CS_END`).
+ *
+ * This function iterates over each command list until either it has processed the number of command lists stated on
+ * `CS_BEGIN_CUTSCENE` or until it finds a end marker.
+ *
+ * A command list starts with a pair of words containing the command category and a count of how many commands this list
+ * 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 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.
+ */
+void Cutscene_ProcessCommands(GlobalContext* globalCtx, CutsceneContext* csCtx, u8* cutscenePtr) {
+ s32 i;
+ s16 phi_s0;
+ s32 totalEntries;
+ s32 j;
+ u32 cmdType; // sp5C
+ s32 pad;
+ s32 cmdEntries; // sp58
+ s32 cutsceneEndFrame; // sp50
+ s16 phi_s0_23;
+ CsCmdBase* 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) && (globalCtx->sceneLoadFlag != 0x14) && (csCtx->state != CS_STATE_4)) {
+ csCtx->state = CS_STATE_3;
+ 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);
+
+ // TODO: This should probably be added to the CutsceneCmd enum. Consider doing it when this function matches.
+ if (cmdType == 0xFFFFFFFF) {
+ 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 (phi_s0 = 0; phi_s0 < ARRAY_COUNT(D_801F4DC8); phi_s0++) {
+ if ((u16)cmdType == D_801F4DC8[phi_s0]) {
+ func_800ECD7C(csCtx, &cutscenePtr, phi_s0);
+ cmdType = -2;
+ break;
+ } else if (D_801F4DC8[phi_s0] == 0) {
+ D_801F4DC8[phi_s0] = cmdType;
+ func_800ECD7C(csCtx, &cutscenePtr, phi_s0);
+ cmdType = -2;
+ break;
+ }
+ }
+ }
+
+ switch (cmdType) {
+ case CS_CMD_MISC:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_Misc(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case CS_CMD_SET_LIGHTING:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_SetLighting(globalCtx, csCtx, (CsCmdEnvLighting*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdEnvLighting);
+ }
+ break;
+
+ case CS_CMD_PLAYSEQ:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_PlaySequence(globalCtx, csCtx, (CsCmdSequenceChange*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdSequenceChange);
+ }
+ break;
+
+ case CS_CMD_STOPSEQ:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_StopSequence(globalCtx, csCtx, (CsCmdSequenceChange*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdSequenceChange);
+ }
+ break;
+
+ case CS_CMD_FADESEQ:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_FadeSequence(globalCtx, csCtx, (CsCmdSequenceFade*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdSequenceFade);
+ }
+ break;
+
+ case CS_CMD_PLAYAMBIENCE:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_PlayAmbienceSequence(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case CS_CMD_FADEAMBIENCE:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_FadeAmbienceSequence(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case CS_CMD_130:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ func_800EAD48(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case CS_CMD_131:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ func_800EAD7C(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case CS_CMD_132:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ func_800EADB0(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case CS_CMD_RUMBLE:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_Rumble(globalCtx, csCtx, (CsCmdRumble*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdRumble);
+ }
+ break;
+
+ case CS_CMD_FADESCREEN:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_FadeColorScreen(globalCtx, csCtx, (CsCmdFadeScreen*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdFadeScreen);
+ }
+ break;
+
+ case CS_CMD_SETTIME:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_SetTime(globalCtx, csCtx, (CsCmdDayTime*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdDayTime);
+ }
+ break;
+
+ case CS_CMD_SET_PLAYER_ACTION:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ cmd = (CsCmdBase*)cutscenePtr;
+ if ((csCtx->frames >= cmd->startFrame) && (csCtx->frames < cmd->endFrame)) {
+ csCtx->playerAction = (CsCmdActorAction*)cutscenePtr;
+ }
+ cutscenePtr += sizeof(CsCmdActorAction);
+ }
+ break;
+
+ case CS_CMD_CAMERA:
+ cutscenePtr = &cutscenePtr[Cutscene_Command_Camera(globalCtx, cutscenePtr)];
+ break;
+
+ case CS_CMD_TERMINATOR:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_Terminator(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case CS_CMD_CHOOSE_CREDITS_SCENES:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_ChooseCreditsScenes(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case CS_CMD_TEXTBOX:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ cmd = (CsCmdBase*)cutscenePtr;
+ if (cmd->base != 0xFFFF) {
+ Cutscene_Command_Textbox(globalCtx, csCtx, (CsCmdTextbox*)cutscenePtr);
+ }
+ cutscenePtr += sizeof(CsCmdTextbox);
+ }
+ break;
+
+ case CS_CMD_SCENE_TRANS_FX:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_TransitionFX(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case CS_CMD_MOTIONBLUR:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_MotionBlur(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case CS_CMD_GIVETATL:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ Cutscene_Command_GiveTatlToPlayer(globalCtx, csCtx, (CsCmdBase*)cutscenePtr);
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+
+ case -2:
+ break;
+
+ default:
+ bcopy(cutscenePtr, &cmdEntries, sizeof(s32));
+ cutscenePtr += sizeof(s32);
+ for (j = 0; j < cmdEntries; j++) {
+ cutscenePtr += sizeof(CsCmdBase);
+ }
+ break;
+ }
+ }
+}
+#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_ProcessCommands.s")
+#endif
+
+/* End of command handling section */
+
+void func_800ED980(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ if (gSaveContext.cutscene >= 0xFFF0) {
+ csCtx->frames++;
+ Cutscene_ProcessCommands(globalCtx, csCtx, (u8*)globalCtx->csCtx.csData);
+ }
+}
+
+void func_800ED9C4(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ if (func_800EA220(globalCtx, csCtx, 0.0f)) {
+ Audio_SetCutsceneFlag(false);
+ csCtx->state = CS_STATE_0;
+ }
+}
+
+// unused
+void func_800EDA04(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ if (func_800EA220(globalCtx, csCtx, 0.0f)) {
+ s16 i;
+
+ csCtx->playerAction = NULL;
+
+ for (i = 0; i < ARRAY_COUNT(csCtx->actorActions); i++) {
+ csCtx->actorActions[i] = NULL;
+ }
+
+ gSaveContext.cutscene = 0;
+ gSaveContext.gameMode = 0;
+ ActorCutscene_Stop(0x7F);
+ Audio_SetCutsceneFlag(false);
+ csCtx->state = CS_STATE_0;
+ }
+}
+
+void func_800EDA84(GlobalContext* globalCtx, CutsceneContext* csCtx) {
+ if ((gSaveContext.cutsceneTrigger != 0) && (csCtx->state == CS_STATE_0) && !Player_InCsMode(&globalCtx->state)) {
+ gSaveContext.cutscene = 0xFFFD;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800ED980.s")
+ if ((gSaveContext.cutscene >= 0xFFF0) && (csCtx->state == CS_STATE_0)) {
+ s16 i;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800ED9C4.s")
+ D_801BB124 = 0;
+ D_801BB128 = 0;
+ csCtx->playerAction = NULL;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDA04.s")
+ for (i = 0; i < ARRAY_COUNT(csCtx->actorActions); i++) {
+ csCtx->actorActions[i] = NULL;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDA84.s")
+ csCtx->state++;
+ if (csCtx->state == CS_STATE_1) {
+ Audio_SetCutsceneFlag(true);
+ csCtx->frames = 0xFFFF;
+ csCtx->csCamId = ActorCutscene_GetCurrentCamera(0x7F);
+ func_8016119C(Play_GetCamera(globalCtx, csCtx->csCamId), &sCutsceneCameraInfo);
+ csCtx->unk_18 = 0xFFFF;
+
+ if (gSaveContext.cutsceneTrigger == 0) {
+ Interface_ChangeAlpha(1);
+ ShrinkWindow_SetLetterboxTarget(32);
+ ShrinkWindow_SetLetterboxMagnitude(0x20);
+ csCtx->state++;
+ }
+
+ func_800ED980(globalCtx, csCtx);
+ }
+
+ gSaveContext.cutsceneTrigger = 0;
+ }
+}
+
+#ifdef NON_MATCHING
+// HandleFlags?
+// regalloc
+void func_800EDBE0(GlobalContext* globalCtx) {
+ CutsceneEntry* temp_a3;
+ s16 sp2A;
+ SceneTableEntry* sp24;
+ s32 temp_v0_3;
+
+ if (((gSaveContext.gameMode == 0) || (gSaveContext.gameMode == 1)) && (gSaveContext.respawnFlag <= 0)) {
+ sp2A = func_800F21CC();
+ if (sp2A != -1) {
+ temp_v0_3 = func_800F2138(sp2A);
+ if (temp_v0_3 != -1) {
+ temp_a3 = ((void)0, globalCtx->csCtx.sceneCsList);
+ if ((temp_a3[temp_v0_3].unk7 != 0xFF) && (gSaveContext.respawnFlag == 0)) {
+ if (temp_a3[temp_v0_3].unk7 == 0xFE) {
+ ActorCutscene_Start(sp2A, NULL);
+ gSaveContext.showTitleCard = false;
+ } else if (!((1 << (temp_a3[temp_v0_3].unk7 % 8)) &
+ gSaveContext.weekEventReg[temp_a3[temp_v0_3].unk7 / 8])) {
+ gSaveContext.weekEventReg[(temp_a3[temp_v0_3].unk7 / 8)] |= 1 << (temp_a3[temp_v0_3].unk7 % 8);
+ ActorCutscene_Start(sp2A, NULL);
+ gSaveContext.showTitleCard = false;
+ }
+ }
+ } else {
+ ActorCutscene_StartAndSetUnkLinkFields(sp2A, NULL);
+ }
+ }
+ }
+
+ if ((gSaveContext.respawnFlag == 0) || (gSaveContext.respawnFlag == -2)) {
+ sp24 = globalCtx->loadedScene;
+ if ((sp24->titleTextId != 0) && gSaveContext.showTitleCard) {
+ if ((Entrance_GetTransitionFlags(gSaveContext.sceneSetupIndex + gSaveContext.entranceIndex) & 0x4000) !=
+ 0) {
+ func_80151A68(globalCtx, sp24->titleTextId);
+ }
+ }
+
+ gSaveContext.showTitleCard = true;
+ }
+}
+#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDBE0.s")
+#endif
+
+void func_800EDDB0(GlobalContext* globalCtx) {
+}
+
+void func_800EDDBC(UNK_TYPE arg0, UNK_TYPE arg1) {
+}
+
+void Cutscene_LoadCutsceneData(GlobalContext* globalCtx, u8 csIndex) {
+ if (dREG(95) == 0) {
+ globalCtx->csCtx.currentCsIndex = csIndex;
+ globalCtx->csCtx.csData = Lib_SegmentedToVirtual(globalCtx->csCtx.sceneCsList[csIndex].segmentedData);
+ }
+
+ gSaveContext.cutsceneTrigger = 1;
+}
+
+/* Start of actor utilities section */
+
+/**
+ * Interpolates the actor's position based on the corresponding actor action's position
+ * and the current cutscene frame
+ */
+void Cutscene_ActorTranslate(Actor* actor, GlobalContext* globalCtx, s32 actorActionIndex) {
+ Vec3f start;
+ Vec3f end;
+ CsCmdActorAction* entry = globalCtx->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, globalCtx->csCtx.frames);
+
+ VEC3F_LERPIMPDST(&actor->world.pos, &start, &end, progress);
+}
+
+/**
+ * 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, GlobalContext* globalCtx, s32 actorActionIndex) {
+ Cutscene_ActorTranslate(actor, globalCtx, actorActionIndex);
+
+ actor->world.rot.y = globalCtx->csCtx.actorActions[actorActionIndex]->urot.y;
+ actor->shape.rot.y = actor->world.rot.y;
+}
+
+/**
+ * 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, GlobalContext* globalCtx, s32 actorActionIndex) {
+ Vec3f start;
+ Vec3f end;
+ CsCmdActorAction* entry;
+ f32 progress;
+
+ start.x = globalCtx->csCtx.actorActions[actorActionIndex]->startPos.x;
+ start.y = globalCtx->csCtx.actorActions[actorActionIndex]->startPos.y;
+ start.z = globalCtx->csCtx.actorActions[actorActionIndex]->startPos.z;
+ end.x = globalCtx->csCtx.actorActions[actorActionIndex]->endPos.x;
+ end.y = globalCtx->csCtx.actorActions[actorActionIndex]->endPos.y;
+ end.z = globalCtx->csCtx.actorActions[actorActionIndex]->endPos.z;
+
+ entry = globalCtx->csCtx.actorActions[actorActionIndex];
+ progress = Environment_LerpWeight(entry->endFrame, entry->startFrame, globalCtx->csCtx.frames);
+
+ VEC3F_LERPIMPDST(&actor->world.pos, &start, &end, progress);
+
+ Math_SmoothStepToS(&actor->world.rot.y, Math_Vec3f_Yaw(&start, &end), 10, 1000, 1);
+ actor->shape.rot.y = actor->world.rot.y;
+}
+
+/**
+ * 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, GlobalContext* globalCtx, s32 actorActionIndex) {
+ Vec3f start;
+ Vec3f end;
+ CsCmdActorAction* entry;
+ f32 progress;
+
+ start.x = globalCtx->csCtx.actorActions[actorActionIndex]->startPos.x;
+ start.z = globalCtx->csCtx.actorActions[actorActionIndex]->startPos.z;
+ end.x = globalCtx->csCtx.actorActions[actorActionIndex]->endPos.x;
+ end.z = globalCtx->csCtx.actorActions[actorActionIndex]->endPos.z;
+
+ entry = globalCtx->csCtx.actorActions[actorActionIndex];
+ progress = Environment_LerpWeight(entry->endFrame, entry->startFrame, globalCtx->csCtx.frames);
+
+ actor->world.pos.x = start.x + (end.x - start.x) * progress;
+ actor->world.pos.z = start.z + (end.z - start.z) * progress;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/nop_800EDDB0.s")
+ Math_SmoothStepToS(&actor->world.rot.y, Math_Vec3f_Yaw(&start, &end), 10, 1000, 1);
+ actor->shape.rot.y = actor->world.rot.y;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDDBC.s")
+s32 Cutscene_GetSceneSetupIndex(GlobalContext* globalCtx) {
+ s32 sceneSetupIndex = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDDCC.s")
+ if (gSaveContext.sceneSetupIndex > 0) {
+ sceneSetupIndex = gSaveContext.sceneSetupIndex;
+ }
+ return sceneSetupIndex;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDE34.s")
+s32 Cutscene_GetActorActionIndex(GlobalContext* globalCtx, u16 actorActionCmd) {
+ s32 i;
+ s32 index = -1;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDF24.s")
+ for (i = 0; i < ARRAY_COUNT(D_801F4DC8); i++) {
+ if (actorActionCmd == D_801F4DC8[i]) {
+ index = i;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDF78.s")
+ return index;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EE0CC.s")
+s32 Cutscene_CheckActorAction(GlobalContext* globalCtx, u16 actorActionCmd) {
+ if (globalCtx->csCtx.state != CS_STATE_0) {
+ s32 index = Cutscene_GetActorActionIndex(globalCtx, actorActionCmd);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EE1D8.s")
+ if (index != -1) {
+ return globalCtx->csCtx.actorActions[index] != NULL;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EE200.s")
+ return false;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EE29C.s")
+u8 Cutscene_IsPlaying(GlobalContext* globalCtx) {
+ return (gSaveContext.cutsceneTrigger != 0) || (globalCtx->csCtx.state != CS_STATE_0);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EE2F4.s")
+/* End of actor utilities section */
diff --git a/src/code/z_kankyo.c b/src/code/z_kankyo.c
index 6221e0910..ad66fe4a1 100644
--- a/src/code/z_kankyo.c
+++ b/src/code/z_kankyo.c
@@ -8,7 +8,7 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F5954.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F5A8C.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_LerpWeight.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F5B10.s")
@@ -64,7 +64,7 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FB010.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FB320.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_AddLightningBolts.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FB388.s")
diff --git a/src/code/z_message.c b/src/code/z_message.c
index 84f2ab951..0eceeee30 100644
--- a/src/code/z_message.c
+++ b/src/code/z_message.c
@@ -64,7 +64,7 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_801514B0.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_801518B0.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/Message_StartTextbox.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80151938.s")
diff --git a/src/code/z_room.c b/src/code/z_room.c
index f54882fd6..67c6c6158 100644
--- a/src/code/z_room.c
+++ b/src/code/z_room.c
@@ -114,7 +114,7 @@ s32 Room_HandleLoadCallbacks(GlobalContext* globalCtx, RoomContext* roomCtx) {
if (((globalCtx->sceneNum != SCENE_IKANA) || (roomCtx->currRoom.num != 1)) &&
(globalCtx->sceneNum != SCENE_IKNINSIDE)) {
- globalCtx->envCtx.unk_C3 = 0xff;
+ globalCtx->envCtx.lightSettingOverride = 0xff;
globalCtx->envCtx.unk_E0 = 0;
}
func_800FEAB0();
diff --git a/src/code/z_scene_proc.c b/src/code/z_scene_proc.c
index 57e2930a2..b04b79bb4 100644
--- a/src/code/z_scene_proc.c
+++ b/src/code/z_scene_proc.c
@@ -1,4 +1,3 @@
-#include "prevent_bss_reordering.h"
#include "global.h"
s32 sMatAnimStep;