diff --git a/include/functions.h b/include/functions.h index 6801b986b0..6bb0c03cc5 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1769,9 +1769,9 @@ void func_800FB320(GlobalContext* globalCtx, u8 param_2); void func_800FB758(GlobalContext* globalCtx); // void func_800FB9B4(void); // void func_800FBCBC(void); -// void func_800FBDEC(void); -void func_800FBF3C(GlobalContext* globalCtx); -// void func_800FC158(void); +void Kankyo_InitGameOverLights(GlobalContext* globalCtx); +void Kankyo_FadeInGameOverLights(GlobalContext* globalCtx); +void Kankyo_FadeOutGameOverLights(GlobalContext* globalCtx); // void func_800FC3DC(void); void func_800FC444(GraphicsContext* gfxCtx, u8 arg1, u8 arg2, u8 arg3, u8 arg4, UNK_TYPE arg5); // void func_800FC64C(void); @@ -2758,7 +2758,7 @@ void func_8013ECE0(f32 xyzDistToPlayerSq, u8 arg1, u8 arg2, u8 arg3); void func_8013ED9C(void); void func_8013EDD0(void); // void func_8013EE04(void); -// void func_8013EE24(void); +void func_8013EE24(void); // void func_8013EE38(void); // void func_8013EE48(void); void View_ViewportToVp(Vp* dest, Viewport* src); @@ -3070,7 +3070,7 @@ void func_80169DCC(GlobalContext* globalCtx, s32 arg1, u16 arg2, s32 arg3, s32 a void func_80169E6C(GlobalContext* globalCtx, s32 param_1, s32 param_2); // void func_80169ECC(void); void func_80169EFC(GlobalContext* globalCtx); -// void func_80169F78(void); +void func_80169F78(GlobalContext* globalCtx); // void func_80169FDC(void); // void func_80169FFC(void); s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx); @@ -4058,9 +4058,9 @@ s32 func_801A8A50(s32 param1); // void func_801AA248(void); // void func_801AA3E4(void); // void func_801AA520(void); -void func_801AA610(GlobalContext* globalCtx); -void func_801AA624(GlobalContext* globalCtx); -// void func_801AA68C(UNK_TYPE4 ctxt); +void GameOver_Init(GlobalContext* globalCtx); +void GameOver_FadeLights(GlobalContext* globalCtx); +void GameOver_Update(GlobalContext* globalCtx); void func_801AAAA0(GlobalContext* globalCtx); #endif diff --git a/include/macros.h b/include/macros.h index 915a3fff3e..607e5e9bc3 100644 --- a/include/macros.h +++ b/include/macros.h @@ -61,11 +61,13 @@ #define CUR_UPG_VALUE_VOID(upg) \ ((((void)0, gSaveContext.inventory.upgrades) & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) +#define CUR_FORM ((gSaveContext.playerForm == PLAYER_FORM_HUMAN) ? 0 : gSaveContext.playerForm) + #define ALL_EQUIP_VALUE(equip) ((gSaveContext.inventory.equipment & gEquipMasks[equip]) >> gEquipShifts[equip]) #define CUR_EQUIP_VALUE(equip) ((gSaveContext.equips.equipment & gEquipMasks[equip]) >> gEquipShifts[equip]) #define CUR_UPG_VALUE(upg) ((gSaveContext.inventory.upgrades & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) #define TAKE_EQUIPPED_ITEM(equip) (gSaveContext.equips.equipment = ((((void)0, gSaveContext.equips.equipment) & (gEquipNegMasks[equip])) | (u16)(0 << gEquipShifts[equip]))) -#define CUR_FORM_EQUIP(button) (gSaveContext.equips.buttonItems[gSaveContext.playerForm == PLAYER_FORM_HUMAN ? 0 : gSaveContext.playerForm][button]) +#define CUR_FORM_EQUIP(button) (gSaveContext.equips.buttonItems[CUR_FORM][button]) #define CHECK_QUEST_ITEM(item) (((void)0, gSaveContext.inventory.questItems) & gBitFlags[item]) #define REMOVE_QUEST_ITEM(item) (gSaveContext.inventory.questItems = (((void)0, gSaveContext.inventory.questItems) & (-1 - gBitFlags[item]))) diff --git a/include/variables.h b/include/variables.h index 0897d2bc96..ddc77f90ff 100644 --- a/include/variables.h +++ b/include/variables.h @@ -3134,7 +3134,6 @@ extern UNK_PTR D_801E10B0; // extern UNK_TYPE4 D_801E1104; // extern UNK_TYPE4 D_801E1108; // extern UNK_TYPE4 D_801E110C; -// extern UNK_TYPE2 D_801E1110; // extern UNK_TYPE2 D_801E1180; // extern UNK_TYPE1 D_801E1420; // extern UNK_TYPE2 D_801E1630; diff --git a/include/z64.h b/include/z64.h index 96ebb233b2..cd00fb86f6 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1509,6 +1509,19 @@ typedef struct { /* 0x04 */ s32 timer; } FrameAdvanceContext; // size = 0x8 +typedef enum { + /* 00 */ GAMEOVER_INACTIVE, + /* 01 */ GAMEOVER_DEATH_START, + /* 02 */ GAMEOVER_DEATH_WAIT_GROUND, // wait for player to fall and hit the ground + /* 03 */ GAMEOVER_DEATH_FADE_OUT, // wait before fading out + + /* 20 */ GAMEOVER_REVIVE_START = 20, + /* 21 */ GAMEOVER_REVIVE_RUMBLE, + /* 22 */ GAMEOVER_REVIVE_WAIT_GROUND, // wait for player to fall and hit the ground + /* 23 */ GAMEOVER_REVIVE_WAIT_FAIRY, // wait for the fairy to rise all the way up out of player's body + /* 24 */ GAMEOVER_REVIVE_FADE_OUT // fade out the game over lights as player is revived and gets back up +} GameOverState; + typedef struct { /* 0x00 */ u16 state; } GameOverContext; // size = 0x02 diff --git a/include/z64item.h b/include/z64item.h index 11c0201d6f..434b565fb3 100644 --- a/include/z64item.h +++ b/include/z64item.h @@ -34,6 +34,7 @@ typedef enum { /* 0x16 */ ITEM_FAIRY, /* 0x17 */ ITEM_DEKU_PRINCESS, /* 0x1E */ ITEM_MUSHROOM = 0x1E, + /* 0x32 */ ITEM_MASK_DEKU = 0x32, /* 0x38 */ ITEM_MASK_ALL_NIGHT = 0x38, /* 0x3A */ ITEM_MASK_KEATON = 0x3A, /* 0x3B */ ITEM_MASK_GARO, @@ -43,7 +44,8 @@ typedef enum { /* 0x4D */ ITEM_SWORD_KOKIRI = 0x4D, /* 0x4E */ ITEM_SWORD_RAZOR, /* 0x4F */ ITEM_SWORD_GILDED, - /* 0x51 */ ITEM_SHIELD_HERO = 0x51, + /* 0x50 */ ITEM_SWORD_DEITY, + /* 0x51 */ ITEM_SHIELD_HERO, /* 0x52 */ ITEM_SHIELD_MIRROR, /* 0x56 */ ITEM_BOMB_BAG_20 = 0x56, /* 0x57 */ ITEM_BOMB_BAG_30, diff --git a/spec b/spec index fc4845af48..40a76a93f9 100644 --- a/spec +++ b/spec @@ -675,7 +675,7 @@ beginseg include "build/data/code/code_801A7B10.bss.o" include "build/src/code/code_801AA020.o" include "build/data/code/code_801AA020.bss.o" - include "build/src/code/z_game_over.o" + include_readonly "build/src/code/z_game_over.o" include "build/src/code/z_construct.o" include "build/data/code/code_801D9090.data.o" include "build/data/code/code_801E1180.rodata.o" diff --git a/src/boot_O2_g3/boot_main.c b/src/boot_O2_g3/boot_main.c index 04bb9a33ae..ec6b446e71 100644 --- a/src/boot_O2_g3/boot_main.c +++ b/src/boot_O2_g3/boot_main.c @@ -1,4 +1,5 @@ #include "global.h" +#include "prevent_bss_reordering.h" StackEntry sBootThreadInfo; OSThread sIdleThread; diff --git a/src/code/z_game_over.c b/src/code/z_game_over.c index 412cb7080a..c510c1974b 100644 --- a/src/code/z_game_over.c +++ b/src/code/z_game_over.c @@ -1,7 +1,117 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_game_over/func_801AA610.s") +void GameOver_Init(GlobalContext* globalCtx) { + globalCtx->gameOverCtx.state = GAMEOVER_INACTIVE; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_game_over/func_801AA624.s") +void GameOver_FadeLights(GlobalContext* globalCtx) { + GameOverContext* gameOverCtx = &globalCtx->gameOverCtx; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_game_over/func_801AA68C.s") + if ((gameOverCtx->state >= GAMEOVER_DEATH_WAIT_GROUND && gameOverCtx->state < GAMEOVER_REVIVE_START) || + (gameOverCtx->state >= GAMEOVER_REVIVE_RUMBLE && gameOverCtx->state < GAMEOVER_REVIVE_FADE_OUT)) { + Kankyo_FadeInGameOverLights(globalCtx); + } +} + +static s16 sGameOverTimer = 0; + +void GameOver_Update(GlobalContext* globalCtx) { + GameOverContext* gameOverCtx = &globalCtx->gameOverCtx; + s16 i; + + switch (gameOverCtx->state) { + case GAMEOVER_DEATH_START: + func_801477B4(globalCtx); + + for (i = 0; i < ARRAY_COUNT(gSaveContext.unk_3DD0); i++) { + gSaveContext.unk_3DD0[i] = 0; + } + + gSaveContext.eventInf[1] &= ~1; + + if (CUR_FORM == 0) { + if (CUR_FORM_EQUIP(EQUIP_SLOT_B) != ITEM_SWORD_KOKIRI && + CUR_FORM_EQUIP(EQUIP_SLOT_B) != ITEM_SWORD_RAZOR && + CUR_FORM_EQUIP(EQUIP_SLOT_B) != ITEM_SWORD_GILDED && + CUR_FORM_EQUIP(EQUIP_SLOT_B) != ITEM_SWORD_DEITY) { + + if (gSaveContext.buttonStatus[0] != BTN_ENABLED) { + CUR_FORM_EQUIP(EQUIP_SLOT_B) = gSaveContext.buttonStatus[0]; + } else { + CUR_FORM_EQUIP(EQUIP_SLOT_B) = ITEM_NONE; + } + } + } + + gSaveContext.unk_3DC0 = 2000; + gSaveContext.naviTimer = 0; + gSaveContext.seqIndex = 0xFF; + gSaveContext.nightSeqIndex = 0xFF; + gSaveContext.eventInf[0] = 0; + gSaveContext.eventInf[1] = 0; + gSaveContext.eventInf[2] = 0; + gSaveContext.eventInf[3] = 0; + gSaveContext.buttonStatus[0] = BTN_ENABLED; + gSaveContext.buttonStatus[1] = BTN_ENABLED; + gSaveContext.buttonStatus[2] = BTN_ENABLED; + gSaveContext.buttonStatus[3] = BTN_ENABLED; + gSaveContext.buttonStatus[4] = BTN_ENABLED; + gSaveContext.unk_3F1E = 0; + gSaveContext.unk_3F20 = 0; + gSaveContext.unk_3F22 = 0; + gSaveContext.unk_3F24 = 0; + Kankyo_InitGameOverLights(globalCtx); + sGameOverTimer = 20; + func_8013ECE0(0.0f, 126, 124, 63); + gameOverCtx->state = GAMEOVER_DEATH_WAIT_GROUND; + break; + case GAMEOVER_DEATH_FADE_OUT: + if (func_801A8A50(1) != 32) { + func_80169F78(globalCtx); + if (gSaveContext.respawnFlag != -7) { + gSaveContext.respawnFlag = -6; + } + gSaveContext.nextTransition = 2; + gSaveContext.health = 48; + gameOverCtx->state++; + if (gSaveContext.inventory.items[SLOT(ITEM_MASK_DEKU)] == ITEM_MASK_DEKU) { + gSaveContext.playerForm = PLAYER_FORM_HUMAN; + gSaveContext.equippedMask = PLAYER_MASK_NONE; + } + func_8013EE24(); + } + break; + case GAMEOVER_REVIVE_START: + gameOverCtx->state++; + sGameOverTimer = 0; + Kankyo_InitGameOverLights(globalCtx); + ShrinkWindow_SetLetterboxTarget(32); + break; + case GAMEOVER_REVIVE_RUMBLE: + sGameOverTimer = 50; + gameOverCtx->state++; + func_8013ECE0(0.0f, 126, 124, 63); + break; + case GAMEOVER_REVIVE_WAIT_GROUND: + sGameOverTimer--; + if (sGameOverTimer == 0) { + sGameOverTimer = 64; + gameOverCtx->state++; + } + break; + case GAMEOVER_REVIVE_WAIT_FAIRY: + sGameOverTimer--; + if (sGameOverTimer == 0) { + sGameOverTimer = 50; + gameOverCtx->state++; + } + break; + case GAMEOVER_REVIVE_FADE_OUT: + Kankyo_FadeOutGameOverLights(globalCtx); + sGameOverTimer--; + if (sGameOverTimer == 0) { + gameOverCtx->state = GAMEOVER_INACTIVE; + } + break; + } +} diff --git a/src/code/z_kankyo.c b/src/code/z_kankyo.c index 22c96883ea..6221e09107 100644 --- a/src/code/z_kankyo.c +++ b/src/code/z_kankyo.c @@ -74,11 +74,11 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FBCBC.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FBDEC.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Kankyo_InitGameOverLights.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FBF3C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Kankyo_FadeInGameOverLights.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FC158.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Kankyo_FadeOutGameOverLights.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FC3DC.s") diff --git a/src/overlays/actors/ovl_En_Toto/z_en_toto.c b/src/overlays/actors/ovl_En_Toto/z_en_toto.c index 0fd8d2564d..4716439cb2 100644 --- a/src/overlays/actors/ovl_En_Toto/z_en_toto.c +++ b/src/overlays/actors/ovl_En_Toto/z_en_toto.c @@ -556,22 +556,22 @@ s32 func_80BA4530(EnToto* this, GlobalContext* globalCtx) { s32 func_80BA46D8(EnToto* this, GlobalContext* globalCtx) { func_800B7298(globalCtx, NULL, 0x44); - func_80152434(globalCtx, D_80BA5120[gSaveContext.playerForm == 4 ? 0 : gSaveContext.playerForm]); + func_80152434(globalCtx, D_80BA5120[CUR_FORM]); return 0; } s32 func_80BA4740(EnToto* this, GlobalContext* globalCtx) { if (globalCtx->msgCtx.unk1202A == 4) { - if (gSaveContext.playerForm == 4) { + if (gSaveContext.playerForm == PLAYER_FORM_HUMAN) { gSaveContext.weekEventReg[56] |= 0x10; } - if (gSaveContext.playerForm == 3) { + if (gSaveContext.playerForm == PLAYER_FORM_DEKU) { gSaveContext.weekEventReg[56] |= 0x20; } - if (gSaveContext.playerForm == 2) { + if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { gSaveContext.weekEventReg[56] |= 0x40; } - if (gSaveContext.playerForm == 1) { + if (gSaveContext.playerForm == PLAYER_FORM_GORON) { gSaveContext.weekEventReg[56] |= 0x80; } return 1; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 0bfa78b1df..cf6076b7fb 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -1743,9 +1743,9 @@ 0x800FB758:("func_800FB758",), 0x800FB9B4:("func_800FB9B4",), 0x800FBCBC:("func_800FBCBC",), - 0x800FBDEC:("func_800FBDEC",), - 0x800FBF3C:("func_800FBF3C",), - 0x800FC158:("func_800FC158",), + 0x800FBDEC:("Kankyo_InitGameOverLights",), + 0x800FBF3C:("Kankyo_FadeInGameOverLights",), + 0x800FC158:("Kankyo_FadeOutGameOverLights",), 0x800FC3DC:("func_800FC3DC",), 0x800FC444:("func_800FC444",), 0x800FC64C:("func_800FC64C",), @@ -4083,9 +4083,9 @@ 0x801AA248:("func_801AA248",), 0x801AA3E4:("func_801AA3E4",), 0x801AA520:("func_801AA520",), - 0x801AA610:("func_801AA610",), - 0x801AA624:("func_801AA624",), - 0x801AA68C:("func_801AA68C",), + 0x801AA610:("GameOver_Init",), + 0x801AA624:("GameOver_FadeLights",), + 0x801AA68C:("GameOver_Update",), 0x801AAAA0:("func_801AAAA0",), 0x80800000:("Title_UpdateCounters",), 0x8080009C:("Title_RenderView",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 6cbe303eed..b71f05517b 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -3890,7 +3890,7 @@ 0x801E1104:("D_801E1104","UNK_TYPE4","",0x4), 0x801E1108:("D_801E1108","UNK_TYPE4","",0x4), 0x801E110C:("D_801E110C","UNK_TYPE4","",0x4), - 0x801E1110:("D_801E1110","UNK_TYPE2","",0x2), + 0x801E1110:("sGameOverTimer","UNK_TYPE2","",0x2), 0x801E1120:("jtbl_801E1120","UNK_PTR","",0x4), 0x801E1180:("D_801E1180","UNK_TYPE2","",0x2), 0x801E1420:("D_801E1420","UNK_TYPE1","",0x1), diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index da6bc4acbe..14919f7549 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -1257,9 +1257,9 @@ asm/non_matchings/code/z_kankyo/func_800FB388.s,func_800FB388,0x800FB388,0xF4 asm/non_matchings/code/z_kankyo/func_800FB758.s,func_800FB758,0x800FB758,0x97 asm/non_matchings/code/z_kankyo/func_800FB9B4.s,func_800FB9B4,0x800FB9B4,0xC2 asm/non_matchings/code/z_kankyo/func_800FBCBC.s,func_800FBCBC,0x800FBCBC,0x4C -asm/non_matchings/code/z_kankyo/func_800FBDEC.s,func_800FBDEC,0x800FBDEC,0x54 -asm/non_matchings/code/z_kankyo/func_800FBF3C.s,func_800FBF3C,0x800FBF3C,0x87 -asm/non_matchings/code/z_kankyo/func_800FC158.s,func_800FC158,0x800FC158,0xA1 +asm/non_matchings/code/z_kankyo/Kankyo_InitGameOverLights.s,Kankyo_InitGameOverLights,0x800FBDEC,0x54 +asm/non_matchings/code/z_kankyo/Kankyo_FadeInGameOverLights.s,Kankyo_FadeInGameOverLights,0x800FBF3C,0x87 +asm/non_matchings/code/z_kankyo/Kankyo_FadeOutGameOverLights.s,Kankyo_FadeOutGameOverLights,0x800FC158,0xA1 asm/non_matchings/code/z_kankyo/func_800FC3DC.s,func_800FC3DC,0x800FC3DC,0x1A asm/non_matchings/code/z_kankyo/func_800FC444.s,func_800FC444,0x800FC444,0x82 asm/non_matchings/code/z_kankyo/func_800FC64C.s,func_800FC64C,0x800FC64C,0x31A @@ -3597,7 +3597,7 @@ asm/non_matchings/code/code_801AA020/func_801AA020.s,func_801AA020,0x801AA020,0x asm/non_matchings/code/code_801AA020/func_801AA248.s,func_801AA248,0x801AA248,0x67 asm/non_matchings/code/code_801AA020/func_801AA3E4.s,func_801AA3E4,0x801AA3E4,0x4F asm/non_matchings/code/code_801AA020/func_801AA520.s,func_801AA520,0x801AA520,0x3C -asm/non_matchings/code/z_game_over/func_801AA610.s,func_801AA610,0x801AA610,0x5 -asm/non_matchings/code/z_game_over/func_801AA624.s,func_801AA624,0x801AA624,0x1A -asm/non_matchings/code/z_game_over/func_801AA68C.s,func_801AA68C,0x801AA68C,0x105 +asm/non_matchings/code/z_game_over/GameOver_Init.s,GameOver_Init,0x801AA610,0x5 +asm/non_matchings/code/z_game_over/GameOver_FadeLights.s,GameOver_FadeLights,0x801AA624,0x1A +asm/non_matchings/code/z_game_over/GameOver_Update.s,GameOver_Update,0x801AA68C,0x105 asm/non_matchings/code/z_construct/func_801AAAA0.s,func_801AAAA0,0x801AAAA0,0x4