From 27ccadc77ee0a65eee0d5eb1cbd77dec6ee9d408 Mon Sep 17 00:00:00 2001 From: Tom Overton Date: Thu, 3 Aug 2023 20:06:36 -0700 Subject: [PATCH] Document the function that handles the Giant's Mask cutscene in Boss02 (#1345) * Document the function that handles the Giant's Mask cutscene in Boss02 * Remove newline between fallthrough and next case --- src/overlays/actors/ovl_Boss_02/z_boss_02.c | 419 ++++++++++++-------- src/overlays/actors/ovl_Boss_02/z_boss_02.h | 22 +- tools/disasm/functions.txt | 8 +- tools/disasm/variables.txt | 6 +- 4 files changed, 264 insertions(+), 191 deletions(-) diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/src/overlays/actors/ovl_Boss_02/z_boss_02.c index 02d9cfc4c9..255e2d3f76 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -31,12 +31,42 @@ void Boss02_Static_Update(Actor* thisx, PlayState* play); void Boss02_Static_Draw(Actor* thisx, PlayState* play); void Boss02_UpdateEffects(PlayState* play); void Boss02_DrawEffects(PlayState* play); -void func_809DD934(Boss02* this, PlayState* play); +void Boss02_HandleGiantsMaskCutscene(Boss02* this, PlayState* play); void func_809DEAC4(Boss02* this, PlayState* play); -u8 D_809E0420; -u8 D_809E0421; +typedef enum { + /* 0 */ GIANTS_MASK_CS_STATE_WAITING_FOR_MASK, // Starts the cutscene when the player puts on/takes off the mask. + /* 1 */ GIANTS_MASK_CS_STATE_MASK_ON, // Controls the cutscene where the player puts the mask on. + /* 2 */ GIANTS_MASK_CS_STATE_MASK_ON_SKIPPED, // Moves to the "done" state when the mask-on cutscene is skipped. + /* 10 */ GIANTS_MASK_CS_STATE_MASK_OFF = 10, // Controls the cutscene where the player takes the mask off. + /* 11 */ GIANTS_MASK_CS_STATE_MASK_OFF_SKIPPED, // Moves to the "done" state when the mask-off cutscene is skipped. + /* 20 */ GIANTS_MASK_CS_STATE_DONE = 20 // Stops the cutscene and resets the player's scale back to normal. +} GiantsMaskCsState; + +typedef enum { + /* 0 */ GIANTS_MASK_CS_FLASH_STATE_NOT_STARTED, // Does nothing at all. + /* 1 */ GIANTS_MASK_CS_FLASH_STATE_STARTED, // Plays the "mask flash" SFX and initializes a white FillScreen. + /* 2 */ GIANTS_MASK_CS_FLASH_STATE_INCREASE_ALPHA, // Increases the alpha for the FillScreen on every frame. + /* 3 */ GIANTS_MASK_CS_FLASH_STATE_DECREASE_ALPHA // Decreases the alpha for the FillScreen on every frame. +} GiantsMaskCsFlashState; + +/** + * If set to true, the player can skip the cutscene of putting on the Giant's Mask + * by pressing A, B, or any C-button. If false, they must watch it in full. + */ +u8 sCanSkipMaskOnCs; + +/** + * If set to true, the player can skip the cutscene of taking off the Giant's Mask + * by pressing A, B, or any C-button. If false, they must watch it in full. + */ +u8 sCanSkipMaskOffCs; + +/** + * True when the player is giant-sized (i.e. wearing the Giant's Mask), false when the player is normal-sized. + */ u8 sIsInGiantMode; + Boss02* sRedTwinmold; Boss02* sBlueTwinmold; Boss02* sTwinmoldStatic; @@ -468,7 +498,7 @@ Vec3f D_809DFA2C[] = { { -800.0f, -1000.0f, 0.0f }, { -800.0f, -1000.0f, 0.0f }, { -800.0f, -1000.0f, 0.0f }, }; -void func_809DA1D0(PlayState* play, u8 red, u8 green, u8 blue, u8 alpha) { +void Boss02_FillScreen(PlayState* play, u8 red, u8 green, u8 blue, u8 alpha) { R_PLAY_FILL_SCREEN_ON = true; R_PLAY_FILL_SCREEN_R = red; R_PLAY_FILL_SCREEN_G = green; @@ -476,11 +506,11 @@ void func_809DA1D0(PlayState* play, u8 red, u8 green, u8 blue, u8 alpha) { R_PLAY_FILL_SCREEN_ALPHA = alpha; } -void func_809DA22C(PlayState* play, u8 alpha) { +void Boss02_SetFillScreenAlpha(PlayState* play, u8 alpha) { R_PLAY_FILL_SCREEN_ALPHA = alpha; } -void func_809DA24C(PlayState* play) { +void Boss02_StopFillScreen(PlayState* play) { R_PLAY_FILL_SCREEN_ON = false; } @@ -572,7 +602,7 @@ void Boss02_Init(Actor* thisx, PlayState* play) { this->actor.update = Boss02_Static_Update; this->actor.draw = Boss02_Static_Draw; this->actor.flags &= ~ACTOR_FLAG_1; - this->unk_1D70 = 0.00999999977648f; + this->playerScale = 0.01f; if ((KREG(64) != 0) || CHECK_EVENTINF(EVENTINF_55) || (sBlueWarp != NULL)) { this->unk_1D20 = 0; sMusicStartTimer = KREG(15) + 20; @@ -1181,7 +1211,7 @@ void Boss02_Twinmold_Update(Actor* thisx, PlayState* play) { Actor_SetScale(&this->actor, 0.060000001f); } - if (sTwinmoldStatic->unk_1D18 == 0) { + if (sTwinmoldStatic->giantsMaskCsState == GIANTS_MASK_CS_STATE_WAITING_FOR_MASK) { for (i = 0; i < ARRAY_COUNT(this->unk_0146); i++) { if (this->unk_0146[i] != 0) { this->unk_0146[i]--; @@ -1294,17 +1324,17 @@ void Boss02_Static_Update(Actor* thisx, PlayState* play) { play->envCtx.sandstormState = 0xD; if (sBlueWarp != NULL) { - this->unk_1D74 = KREG(23) + -15.0f; + this->fogNear = KREG(23) + -15.0f; D_801F4E30 = 0; play->envCtx.lightSettingOverride = 1; play->skyboxId = SKYBOX_NORMAL_SKY; } else if (!sIsInGiantMode) { - this->unk_1D74 = 0.0f; + this->fogNear = 0.0f; D_801F4E30 = this->unk_1D7C; play->envCtx.lightSettingOverride = 0; play->skyboxId = SKYBOX_2; } else { - this->unk_1D74 = KREG(23) + -15.0f; + this->fogNear = KREG(23) + -15.0f; D_801F4E30 = ((KREG(24) * 0.1f) + 1.0f) * this->unk_1D7C; play->envCtx.lightSettingOverride = 1; play->skyboxId = SKYBOX_NORMAL_SKY; @@ -1327,7 +1357,7 @@ void Boss02_Static_Update(Actor* thisx, PlayState* play) { Boss02_UpdateEffects(play); func_809DEAC4(this, play); - func_809DD934(this, play); + Boss02_HandleGiantsMaskCutscene(this, play); } Gfx* D_809DFA9C[] = { @@ -1630,158 +1660,181 @@ void Boss02_DrawEffects(PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } -void func_809DD934(Boss02* this, PlayState* play) { +/** + * This function is primarily responsible for handling the cutscene where the player puts on + * or takes off the Giant's Mask. It does some manual camera control, adjusts the player's + * scale, switches between the "Normal" and "Giant" variations of the arena, and creates a + * "flash" when the cutscene ends by filling the screen with white. In addition, this function + * is responsible for updating the EnvironmentContext's fogNear variable, which it does even + * when the Giant's Mask cutscene is not playing. + */ +void Boss02_HandleGiantsMaskCutscene(Boss02* this, PlayState* play) { Player* player = GET_PLAYER(play); s16 i; - Actor* temp_a0_5; - Vec3f sp58; - u8 sp57 = 0; - f32 phi_f0_2; + Actor* actorIter; + Vec3f subCamEyeOffset; + u8 switchArena = false; + f32 scale; s16 alpha; - this->unk_1D14++; + this->giantsMaskCsTimer++; - switch (this->unk_1D18) { - case 0: + switch (this->giantsMaskCsState) { + case GIANTS_MASK_CS_STATE_WAITING_FOR_MASK: if (player->stateFlags1 & PLAYER_STATE1_100) { Cutscene_StartManual(play, &play->csCtx); this->subCamId = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, CAM_ID_MAIN, CAM_STATUS_WAIT); Play_ChangeCameraStatus(play, this->subCamId, CAM_STATUS_ACTIVE); Play_EnableMotionBlur(150); - this->unk_1D14 = 0; + this->giantsMaskCsTimer = 0; this->subCamAtVel = 0.0f; - this->unk_1D58 = 0.0f; + this->subCamUpRotZScale = 0.0f; if (!sIsInGiantMode) { - this->unk_1D18 = 1; - this->unk_1D68 = 10.0f; - this->unk_1D64 = 60.0f; - this->unk_1D6C = 23.0f; - this->unk_1D70 = 0.01f; - this->unk_1D74 = 0.0f; - goto label1; + this->giantsMaskCsState = GIANTS_MASK_CS_STATE_MASK_ON; + this->subCamEyeOffsetY = 10.0f; + this->subCamDistZFromPlayer = 60.0f; + this->subCamAtOffsetY = 23.0f; + this->playerScale = 0.01f; + this->fogNear = 0.0f; + goto maskOn; // Jumps to this label to prevent the player from skipping the cutscene immediately. } else { - this->unk_1D18 = 10; - this->unk_1D68 = 10.0f; - this->unk_1D64 = 200.0f; - this->unk_1D6C = 273.0f; - this->unk_1D70 = 0.1f; - this->unk_1D74 = -100.0f; - sp57 = 1; - goto label2; + this->giantsMaskCsState = GIANTS_MASK_CS_STATE_MASK_OFF; + this->subCamEyeOffsetY = 10.0f; + this->subCamDistZFromPlayer = 200.0f; + this->subCamAtOffsetY = 273.0f; + this->playerScale = 0.1f; + this->fogNear = -100.0f; + switchArena = true; + goto maskOff; // Jumps to this label to prevent the player from skipping the cutscene immediately. } } break; - case 1: - if ((this->unk_1D14 < 80) && (D_809E0420 != 0) && + case GIANTS_MASK_CS_STATE_MASK_ON: + if ((this->giantsMaskCsTimer < 80) && sCanSkipMaskOnCs && CHECK_BTN_ANY(CONTROLLER1(&play->state)->press.button, BTN_A | BTN_B | BTN_CUP | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT)) { - this->unk_1D18++; - this->unk_1D78 = 1; - this->unk_1D14 = 0; + this->giantsMaskCsState++; + this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_STARTED; + this->giantsMaskCsTimer = 0; + break; + } + + maskOn: + if (this->giantsMaskCsTimer >= 50) { + if (this->giantsMaskCsTimer == (u32)(BREG(43) + 60)) { + Audio_PlaySfx(NA_SE_PL_TRANSFORM_GIANT); + } + + // Makes the camera quickly move away from the player and look upwards as the player + // increases in size. Also decreases the fogNear from 0.0f to -100.0f. + Math_ApproachF(&this->subCamDistZFromPlayer, 200.0f, 0.1f, this->subCamAtVel * 640.0f); + Math_ApproachF(&this->subCamAtOffsetY, 273.0f, 0.1f, this->subCamAtVel * 150.0f); + Math_ApproachF(&this->playerScale, 0.1f, 0.2f, this->subCamAtVel * 0.1f); + Math_ApproachF(&this->fogNear, -100.0f, 1.0f, this->subCamAtVel * 100.0f); + Math_ApproachF(&this->subCamAtVel, 1.0f, 1.0f, 0.001f); } else { - label1: - if (this->unk_1D14 >= 50) { - if (this->unk_1D14 == (u32)(BREG(43) + 60)) { - Audio_PlaySfx(NA_SE_PL_TRANSFORM_GIANT); - } - Math_ApproachF(&this->unk_1D64, 200.0f, 0.1f, this->subCamAtVel * 640.0f); - Math_ApproachF(&this->unk_1D6C, 273.0f, 0.1f, this->subCamAtVel * 150.0f); - Math_ApproachF(&this->unk_1D70, 0.1f, 0.2f, this->subCamAtVel * 0.1f); - Math_ApproachF(&this->unk_1D74, -100.0f, 1.0f, this->subCamAtVel * 100.0f); - Math_ApproachF(&this->subCamAtVel, 1.0f, 1.0f, 0.001f); - } else { - Math_ApproachF(&this->unk_1D64, 30.0f, 0.1f, 1.0f); - } + // Makes the camera slowly approach the player. + Math_ApproachF(&this->subCamDistZFromPlayer, 30.0f, 0.1f, 1.0f); + } - if (this->unk_1D14 > 50) { - Math_ApproachZeroF(&this->unk_1D58, 1.0f, 0.06f); - } else { - Math_ApproachF(&this->unk_1D58, 0.4f, 1.0f, 0.02f); - } + // Makes the camera roll side-to-side at the start of the cutscene, and stops + // the camera from rolling after 51 frames have passed. + if (this->giantsMaskCsTimer > 50) { + Math_ApproachZeroF(&this->subCamUpRotZScale, 1.0f, 0.06f); + } else { + Math_ApproachF(&this->subCamUpRotZScale, 0.4f, 1.0f, 0.02f); + } - if (this->unk_1D14 == 107) { - this->unk_1D78 = 1; - } + if (this->giantsMaskCsTimer == 107) { + this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_STARTED; + } - if (this->unk_1D14 < 121) { - break; - } - - sp57 = 1; - D_809E0420 = 1; - goto block_38; + if (this->giantsMaskCsTimer > 120) { + switchArena = true; + sCanSkipMaskOnCs = true; + goto done; } break; - case 2: - if (this->unk_1D14 < 8) { - break; + case GIANTS_MASK_CS_STATE_MASK_ON_SKIPPED: + if (this->giantsMaskCsTimer >= 8) { + switchArena = true; + goto done; } - sp57 = 1; - goto block_38; + break; - case 10: - if ((this->unk_1D14 < 30) && (D_809E0421 != 0) && + case GIANTS_MASK_CS_STATE_MASK_OFF: + if ((this->giantsMaskCsTimer < 30) && sCanSkipMaskOffCs && CHECK_BTN_ANY(CONTROLLER1(&play->state)->press.button, BTN_A | BTN_B | BTN_CUP | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT)) { - this->unk_1D18++; - this->unk_1D78 = 1; - this->unk_1D14 = 0; + this->giantsMaskCsState++; + this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_STARTED; + this->giantsMaskCsTimer = 0; break; } - label2: - if (this->unk_1D14 != 0) { - if (this->unk_1D14 == (u32)(BREG(44) + 10)) { + maskOff: + if (this->giantsMaskCsTimer != 0) { + if (this->giantsMaskCsTimer == (u32)(BREG(44) + 10)) { Audio_PlaySfx(NA_SE_PL_TRANSFORM_NORAML); } - Math_ApproachF(&this->unk_1D64, 60.0f, 0.1f, this->subCamAtVel * 640.0f); - Math_ApproachF(&this->unk_1D6C, 23.0f, 0.1f, this->subCamAtVel * 150.0f); - Math_ApproachF(&this->unk_1D70, 0.01f, 0.1f, 0.003f); - Math_ApproachF(&this->unk_1D74, 0.0f, 1.0f, this->subCamAtVel * 100.0f); + + // Makes the camera move slowly towards the player and look downwards as the player + // decreases in size. Also increases the fogNear from -100.0f to 0.0f. + Math_ApproachF(&this->subCamDistZFromPlayer, 60.0f, 0.1f, this->subCamAtVel * 640.0f); + Math_ApproachF(&this->subCamAtOffsetY, 23.0f, 0.1f, this->subCamAtVel * 150.0f); + Math_ApproachF(&this->playerScale, 0.01f, 0.1f, 0.003f); + Math_ApproachF(&this->fogNear, 0.0f, 1.0f, this->subCamAtVel * 100.0f); Math_ApproachF(&this->subCamAtVel, 2.0f, 1.0f, 0.01f); } - if (this->unk_1D14 == 42) { - this->unk_1D78 = 1; + if (this->giantsMaskCsTimer == 42) { + this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_STARTED; } - if (this->unk_1D14 > 50) { - D_809E0421 = 1; - goto block_38; + if (this->giantsMaskCsTimer > 50) { + sCanSkipMaskOffCs = true; + goto done; } break; - case 11: - if (this->unk_1D14 < 8) { - break; + case GIANTS_MASK_CS_STATE_MASK_OFF_SKIPPED: + if (this->giantsMaskCsTimer >= 8) { + goto done; } + break; - block_38: - case 20: - this->unk_1D18 = 0; + done: + case GIANTS_MASK_CS_STATE_DONE: + // Ends the cutscene and restores the player's scale to its "original" value of 0.1f. + // This might seem strange in the case where the player has put on the Giant's Mask, + // since they seem so large after the cutscene ends. However, the player is still + // their normal size; the arena and everything in it has shrunk instead. + this->giantsMaskCsState = GIANTS_MASK_CS_STATE_WAITING_FOR_MASK; func_80169AFC(play, this->subCamId, 0); this->subCamId = SUB_CAM_ID_DONE; Cutscene_StopManual(play, &play->csCtx); this->actor.flags |= ACTOR_FLAG_1; player->stateFlags1 &= ~PLAYER_STATE1_100; - this->unk_1D70 = 0.01f; + this->playerScale = 0.01f; Play_DisableMotionBlur(); break; } if (player->transformation == PLAYER_FORM_FIERCE_DEITY) { - Actor_SetScale(&player->actor, this->unk_1D70 * 1.5f); + Actor_SetScale(&player->actor, this->playerScale * 1.5f); } else { - Actor_SetScale(&player->actor, this->unk_1D70); + Actor_SetScale(&player->actor, this->playerScale); } - play->envCtx.lightSettings.fogNear = this->unk_1D74; + play->envCtx.lightSettings.fogNear = this->fogNear; - if (sp57) { - sIsInGiantMode = 1 - sIsInGiantMode; + // Switches from the "normal" variation of the arena to the "giant" variation (or vice versa) + // at the appropriate point in the Giant's Mask cutscene. + if (switchArena) { + sIsInGiantMode = true - sIsInGiantMode; if (!sIsInGiantMode) { sGiantModeScaleFactor = 1.0f; } else { @@ -1789,7 +1842,12 @@ void func_809DD934(Boss02* this, PlayState* play) { } this->giantModeScaleFactor = sGiantModeScaleFactor; + if (!sIsInGiantMode) { + // In this case, the player is switching from the "giant" arena to the "normal" arena. + // The "giant" arena sits 3150 units above the "normal" arena, so this moves the player, + // Twinmold, and the blue warp down and scales their world coordinates upwards to be + // appropriate for the larger arena. if (sBlueWarp != NULL) { sBlueWarp->unk_203 = 0; sBlueWarp->unk_204 = 1.0f; @@ -1802,6 +1860,10 @@ void func_809DD934(Boss02* this, PlayState* play) { player->fallStartHeight = player->actor.world.pos.y; player->actor.world.pos.z *= 10.0f; + // If the blue warp exists, and if the player is within 60 units of its center after switching + // to the "normal" arena, this code will move the player to a fixed point next to the blue warp. + // This prevents the player from instantly activating the blue warp after switching arenas, and + // it relies on the blue warp's XZ-coordinates being (0, 0) as they are in Twinmold's boss room. if ((sBlueWarp != NULL) && ((SQ(player->actor.world.pos.z) + SQ(player->actor.world.pos.x)) < SQ(60.0f))) { player->actor.world.pos.z = 60.0f; player->actor.world.pos.x = 60.0f; @@ -1862,7 +1924,11 @@ void func_809DD934(Boss02* this, PlayState* play) { sBlueTwinmold->unk_0188.y *= 10.0f; } else { - if (sBlueWarp != 0) { + // In this case, the player is switching from the "normal" arena to the "giant" arena. + // The "giant" arena sits 3150 units above the "normal" arena, so this moves the player, + // Twinmold, and the blue warp up and scales their world coordinates downwards to be + // appropriate for the smaller arena. + if (sBlueWarp != NULL) { sBlueWarp->unk_203 = 1; sBlueWarp->unk_204 = 0.1f; sBlueWarp->dyna.actor.world.pos.y = 3155.0f; @@ -1932,113 +1998,120 @@ void func_809DD934(Boss02* this, PlayState* play) { player->actor.home.pos = player->actor.world.pos; player->actor.prevPos = player->actor.world.pos; - temp_a0_5 = play->actorCtx.actorLists[ACTORCAT_BG].first; - while (temp_a0_5 != NULL) { - if (temp_a0_5->id == ACTOR_BG_INIBS_MOVEBG) { - Actor_Kill(temp_a0_5); + // Kills the existing instance of Twinmold's arena and spawns a new instance with the appropriate + // scale and at the appropriate height. + actorIter = play->actorCtx.actorLists[ACTORCAT_BG].first; + while (actorIter != NULL) { + if (actorIter->id == ACTOR_BG_INIBS_MOVEBG) { + Actor_Kill(actorIter); break; } - temp_a0_5 = temp_a0_5->next; + + actorIter = actorIter->next; } { - f32 tmp = sIsInGiantMode ? 3150.0f : 0.0f; + f32 arenaPosY = sIsInGiantMode ? 3150.0f : 0.0f; - Actor_Spawn(&play->actorCtx, play, ACTOR_BG_INIBS_MOVEBG, 0, tmp, 0, 0, 0, 0, sIsInGiantMode); + Actor_Spawn(&play->actorCtx, play, ACTOR_BG_INIBS_MOVEBG, 0, arenaPosY, 0, 0, 0, 0, sIsInGiantMode); } - temp_a0_5 = play->actorCtx.actorLists[ACTORCAT_BOSS].first; - while (temp_a0_5 != NULL) { - if ((temp_a0_5->id == ACTOR_EN_TANRON5) || (temp_a0_5->id == ACTOR_ITEM_B_HEART)) { + // Moves the props in Twinmold's arena and the Heart Container 3150 units up or down + // so they're in the appropriate arena and scales them accordingly. + actorIter = play->actorCtx.actorLists[ACTORCAT_BOSS].first; + while (actorIter != NULL) { + if ((actorIter->id == ACTOR_EN_TANRON5) || (actorIter->id == ACTOR_ITEM_B_HEART)) { if (!sIsInGiantMode) { - temp_a0_5->world.pos.y -= 3150.0f; - temp_a0_5->world.pos.y *= 10.0f; + actorIter->world.pos.y -= 3150.0f; + actorIter->world.pos.y *= 10.0f; - temp_a0_5->floorHeight -= 3150.0f; - temp_a0_5->floorHeight *= 10.0f; + actorIter->floorHeight -= 3150.0f; + actorIter->floorHeight *= 10.0f; - phi_f0_2 = 10.0f; + scale = 10.0f; } else { - temp_a0_5->world.pos.y *= 0.1f; - temp_a0_5->world.pos.y += 3150.0f; + actorIter->world.pos.y *= 0.1f; + actorIter->world.pos.y += 3150.0f; - temp_a0_5->floorHeight *= 0.1f; - temp_a0_5->floorHeight += 3150.0f; + actorIter->floorHeight *= 0.1f; + actorIter->floorHeight += 3150.0f; - phi_f0_2 = 0.1f; + scale = 0.1f; } - temp_a0_5->world.pos.x *= phi_f0_2; - temp_a0_5->world.pos.z *= phi_f0_2; + actorIter->world.pos.x *= scale; + actorIter->world.pos.z *= scale; - temp_a0_5->speed *= phi_f0_2; + actorIter->speed *= scale; - temp_a0_5->velocity.x *= phi_f0_2; - temp_a0_5->velocity.y *= phi_f0_2; - temp_a0_5->velocity.z *= phi_f0_2; + actorIter->velocity.x *= scale; + actorIter->velocity.y *= scale; + actorIter->velocity.z *= scale; - temp_a0_5->gravity *= phi_f0_2; - temp_a0_5->terminalVelocity *= phi_f0_2; + actorIter->gravity *= scale; + actorIter->terminalVelocity *= scale; - temp_a0_5->scale.x *= phi_f0_2; - temp_a0_5->scale.y *= phi_f0_2; - temp_a0_5->scale.z *= phi_f0_2; + actorIter->scale.x *= scale; + actorIter->scale.y *= scale; + actorIter->scale.z *= scale; - if (temp_a0_5->id == ACTOR_ITEM_B_HEART) { - ((ItemBHeart*)temp_a0_5)->baseScale *= phi_f0_2; + if (actorIter->id == ACTOR_ITEM_B_HEART) { + ((ItemBHeart*)actorIter)->baseScale *= scale; } } - temp_a0_5 = temp_a0_5->next; + + actorIter = actorIter->next; } } - switch (this->unk_1D78) { - case 0: + switch (this->giantsMaskCsFlashState) { + case GIANTS_MASK_CS_FLASH_STATE_NOT_STARTED: break; - case 1: - this->unk_1D7A = 0; - func_809DA1D0(play, 255, 255, 255, 0); - this->unk_1D78 = 2; + case GIANTS_MASK_CS_FLASH_STATE_STARTED: + this->giantsMaskCsFlashAlpha = 0; + Boss02_FillScreen(play, 255, 255, 255, 0); + this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_INCREASE_ALPHA; Audio_PlaySfx(NA_SE_SY_TRANSFORM_MASK_FLASH); - - case 2: - this->unk_1D7A += 40; - if (this->unk_1D7A >= 400) { - this->unk_1D78 = 3; + // fallthrough + case GIANTS_MASK_CS_FLASH_STATE_INCREASE_ALPHA: + this->giantsMaskCsFlashAlpha += 40; + if (this->giantsMaskCsFlashAlpha >= 400) { + this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_DECREASE_ALPHA; } - alpha = this->unk_1D7A; + + alpha = this->giantsMaskCsFlashAlpha; alpha = CLAMP_MAX(alpha, 255); - func_809DA22C(play, alpha); + Boss02_SetFillScreenAlpha(play, alpha); break; - case 3: - this->unk_1D7A -= 40; - if (this->unk_1D7A <= 0) { - this->unk_1D7A = 0; - this->unk_1D78 = 0; - func_809DA24C(play); + case GIANTS_MASK_CS_FLASH_STATE_DECREASE_ALPHA: + this->giantsMaskCsFlashAlpha -= 40; + if (this->giantsMaskCsFlashAlpha <= 0) { + this->giantsMaskCsFlashAlpha = 0; + this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_NOT_STARTED; + Boss02_StopFillScreen(play); } else { - alpha = this->unk_1D7A; + alpha = this->giantsMaskCsFlashAlpha; alpha = CLAMP_MAX(alpha, 255); - func_809DA22C(play, alpha); + Boss02_SetFillScreenAlpha(play, alpha); } break; } - if ((this->unk_1D18 != 0) && (this->subCamId != SUB_CAM_ID_DONE)) { + if ((this->giantsMaskCsState != GIANTS_MASK_CS_STATE_WAITING_FOR_MASK) && (this->subCamId != SUB_CAM_ID_DONE)) { Matrix_RotateYS(player->actor.shape.rot.y, MTXMODE_NEW); - Matrix_MultVecZ(this->unk_1D64, &sp58); + Matrix_MultVecZ(this->subCamDistZFromPlayer, &subCamEyeOffset); - this->subCamEye.x = player->actor.world.pos.x + sp58.x; - this->subCamEye.y = player->actor.world.pos.y + sp58.y + this->unk_1D68; - this->subCamEye.z = player->actor.world.pos.z + sp58.z; + this->subCamEye.x = player->actor.world.pos.x + subCamEyeOffset.x; + this->subCamEye.y = player->actor.world.pos.y + subCamEyeOffset.y + this->subCamEyeOffsetY; + this->subCamEye.z = player->actor.world.pos.z + subCamEyeOffset.z; this->subCamAt.x = player->actor.world.pos.x; - this->subCamAt.y = player->actor.world.pos.y + this->unk_1D6C; + this->subCamAt.y = player->actor.world.pos.y + this->subCamAtOffsetY; this->subCamAt.z = player->actor.world.pos.z; - this->unk_1D54 = Math_SinS(this->unk_1D14 * 1512) * this->unk_1D58; - Matrix_RotateZF(this->unk_1D54, MTXMODE_APPLY); + this->subCamUpRotZ = Math_SinS(this->giantsMaskCsTimer * 1512) * this->subCamUpRotZScale; + Matrix_RotateZF(this->subCamUpRotZ, MTXMODE_APPLY); Matrix_MultVecY(1.0f, &this->subCamUp); Play_SetCameraAtEyeUp(play, this->subCamId, &this->subCamAt, &this->subCamEye, &this->subCamUp); ShrinkWindow_Letterbox_SetSizeTarget(27); @@ -2049,7 +2122,7 @@ void func_809DEAC4(Boss02* this, PlayState* play) { Player* player = GET_PLAYER(play); Boss02* sp68; Vec3f subCamEye; - f32 sp58 = 0.0f; + f32 subCamEyeOffset = 0.0f; this->unk_1D1C++; if (this->unk_0194 == 0) { @@ -2089,7 +2162,7 @@ void func_809DEAC4(Boss02* this, PlayState* play) { Rumble_Override(0.0f, 50, 200, 1); } this->unk_0150 += 0x4000; - sp58 = (Math_SinS(this->unk_0150) * (BREG(19) + 5)) * 0.1f; + subCamEyeOffset = (Math_SinS(this->unk_0150) * (BREG(19) + 5)) * 0.1f; Matrix_RotateZF(Math_SinS(this->unk_1D1C * 0x3000) * ((KREG(28) * 0.001f) + 0.017f), MTXMODE_NEW); Matrix_MultVecY(1.0f, &this->subCamUp); Audio_PlaySfx_2(NA_SE_EV_EARTHQUAKE_LAST - SFX_FLAG); @@ -2208,8 +2281,8 @@ void func_809DEAC4(Boss02* this, PlayState* play) { case 103: this->unk_0150 += 0x4000; - sp58 = Math_SinS(this->unk_0150); - sp58 = (sp58 * this->unk_0146[0]) * 1.5f; + subCamEyeOffset = Math_SinS(this->unk_0150); + subCamEyeOffset = (subCamEyeOffset * this->unk_0146[0]) * 1.5f; if (this->unk_1D1C == 30) { func_80169AFC(play, this->subCamId, 0); this->subCamId = SUB_CAM_ID_DONE; @@ -2248,7 +2321,7 @@ void func_809DEAC4(Boss02* this, PlayState* play) { if ((this->unk_1D20 != 0) && (this->subCamId != SUB_CAM_ID_DONE)) { subCamEye = this->subCamEye; - subCamEye.y += sp58 * sGiantModeScaleFactor; + subCamEye.y += subCamEyeOffset * sGiantModeScaleFactor; Play_SetCameraAtEyeUp(play, this->subCamId, &this->subCamAt, &subCamEye, &this->subCamUp); this->subCamUp.z = this->subCamUp.x = 0.0f; this->subCamUp.y = 1.0f; diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.h b/src/overlays/actors/ovl_Boss_02/z_boss_02.h index f3024c241f..41f373b522 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.h +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.h @@ -87,8 +87,8 @@ typedef struct Boss02 { /* 0x1C28 */ ColliderJntSph colliderSphere2; /* 0x1C48 */ ColliderJntSphElement colliderSphere2Elements[2]; /* 0x1CC8 */ ColliderCylinder colliderCylinder; - /* 0x1D14 */ u32 unk_1D14; - /* 0x1D18 */ s16 unk_1D18; + /* 0x1D14 */ u32 giantsMaskCsTimer; + /* 0x1D18 */ s16 giantsMaskCsState; /* 0x1D1A */ s16 unk_1D1A; /* 0x1D1C */ u32 unk_1D1C; /* 0x1D20 */ s16 unk_1D20; @@ -97,17 +97,17 @@ typedef struct Boss02 { /* 0x1D30 */ Vec3f subCamAt; /* 0x1D3C */ Vec3f subCamUp; /* 0x1D48 */ Vec3f subCamAtNext; - /* 0x1D54 */ f32 unk_1D54; - /* 0x1D58 */ f32 unk_1D58; + /* 0x1D54 */ f32 subCamUpRotZ; + /* 0x1D58 */ f32 subCamUpRotZScale; /* 0x1D5C */ f32 subCamAtVel; /* 0x1D60 */ UNK_TYPE1 unk1D60[0x4]; - /* 0x1D64 */ f32 unk_1D64; - /* 0x1D68 */ f32 unk_1D68; - /* 0x1D6C */ f32 unk_1D6C; - /* 0x1D70 */ f32 unk_1D70; - /* 0x1D74 */ f32 unk_1D74; - /* 0x1D78 */ u8 unk_1D78; - /* 0x1D7A */ s16 unk_1D7A; + /* 0x1D64 */ f32 subCamDistZFromPlayer; + /* 0x1D68 */ f32 subCamEyeOffsetY; + /* 0x1D6C */ f32 subCamAtOffsetY; + /* 0x1D70 */ f32 playerScale; + /* 0x1D74 */ f32 fogNear; + /* 0x1D78 */ u8 giantsMaskCsFlashState; + /* 0x1D7A */ s16 giantsMaskCsFlashAlpha; /* 0x1D7C */ s16 unk_1D7C; /* 0x1D7E */ s16 unk_1D7E; } Boss02; // size = 0x1D80 diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 4db192c4bc..4adec0d218 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -9292,9 +9292,9 @@ 0x809D6C98:("func_809D6C98",), 0x809D6E7C:("func_809D6E7C",), 0x809D73D4:("func_809D73D4",), - 0x809DA1D0:("func_809DA1D0",), - 0x809DA22C:("func_809DA22C",), - 0x809DA24C:("func_809DA24C",), + 0x809DA1D0:("Boss02_FillScreen",), + 0x809DA22C:("Boss02_SetFillScreenAlpha",), + 0x809DA24C:("Boss02_StopFillScreen",), 0x809DA264:("Boss02_SpawnEffectSand",), 0x809DA344:("Boss02_SpawnEffectFragment",), 0x809DA460:("Boss02_SpawnEffectFlash",), @@ -9313,7 +9313,7 @@ 0x809DD0A8:("Boss02_Static_Draw",), 0x809DD0CC:("Boss02_UpdateEffects",), 0x809DD2F8:("Boss02_DrawEffects",), - 0x809DD934:("func_809DD934",), + 0x809DD934:("Boss02_HandleGiantsMaskCutscene",), 0x809DEAC4:("func_809DEAC4",), 0x809E2760:("Boss03_PlayUnderwaterSfx",), 0x809E2788:("Boss03_SpawnEffectWetSpot",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 6d6a74981e..7183aec295 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -10109,9 +10109,9 @@ 0x809DFD34:("D_809DFD34","f32","",0x4), 0x809DFD38:("D_809DFD38","f32","",0x4), 0x809DFD3C:("D_809DFD3C","f32","",0x4), - 0x809E0420:("D_809E0420","UNK_TYPE1","",0x1), - 0x809E0421:("D_809E0421","UNK_TYPE1","",0x1), - 0x809E0422:("D_809E0422","UNK_TYPE1","",0x1), + 0x809E0420:("sCanSkipMaskOnCs","UNK_TYPE1","",0x1), + 0x809E0421:("sCanSkipMaskOffCs","UNK_TYPE1","",0x1), + 0x809E0422:("sIsInGiantMode","UNK_TYPE1","",0x1), 0x809E0424:("sRedTwinmold","UNK_TYPE4","",0x4), 0x809E0428:("sBlueTwinmold","UNK_TYPE4","",0x4), 0x809E042C:("sTwinmoldStatic","UNK_TYPE4","",0x4),