From 8f2fe9b3c703418e6b4a3a420b9a026f1ef94210 Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Thu, 29 Sep 2022 08:57:44 -0400 Subject: [PATCH] `z_parameter`: Timers (#1031) * import timers from parameter branch * more cleanup * small namechange * improved docs * more cleanup * one more namechange * another small cleanup... * fix destroy * plurals * revert graphic function names * PR suggestions, better docs * revert namechange, better postman timer name * oops * fix merge * fix merge * fix bss * PR Suggestions --- include/functions.h | 27 +- include/regs.h | 2 + include/variables.h | 26 +- include/z64player.h | 10 +- include/z64save.h | 81 +- src/boot_O2_g3/idle.c | 1 - src/code/code_8012EC80.c | 2 +- src/code/z_bgcheck.c | 1 + src/code/z_game_over.c | 6 +- src/code/z_map_exp.c | 4 +- src/code/z_parameter.c | 730 +++++++++++++++++- src/code/z_player_lib.c | 25 +- src/code/z_sram_NES.c | 44 +- src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c | 16 +- src/overlays/actors/ovl_En_Az/z_en_az.c | 14 +- src/overlays/actors/ovl_En_Dno/z_en_dno.c | 4 +- src/overlays/actors/ovl_En_Fu/z_en_fu.c | 25 +- src/overlays/actors/ovl_En_Gb2/z_en_gb2.c | 10 +- src/overlays/actors/ovl_En_Gk/z_en_gk.c | 2 +- .../z_en_horse_game_check.c | 14 +- .../actors/ovl_En_Invadepoh/z_en_invadepoh.c | 1 - .../actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c | 8 +- src/overlays/actors/ovl_En_Kusa/z_en_kusa.c | 1 - src/overlays/actors/ovl_En_Ma4/z_en_ma4.c | 22 +- src/overlays/actors/ovl_En_Mm3/z_en_mm3.c | 35 +- src/overlays/actors/ovl_En_Mm3/z_en_mm3.h | 5 + .../actors/ovl_En_Mt_tag/z_en_mt_tag.c | 16 +- .../z_en_syateki_dekunuts.c | 3 +- .../ovl_En_Syateki_Man/z_en_syateki_man.c | 44 +- src/overlays/actors/ovl_En_Test4/z_en_test4.c | 2 +- .../actors/ovl_En_Time_Tag/z_en_time_tag.c | 4 +- .../ovl_Obj_Roomtimer/z_obj_roomtimer.c | 10 +- src/overlays/gamestates/ovl_select/z_select.c | 14 +- tools/disasm/functions.txt | 24 +- tools/disasm/variables.txt | 28 +- tools/namefixer.py | 13 + tools/sizes/code_functions.csv | 24 +- 37 files changed, 1016 insertions(+), 282 deletions(-) diff --git a/include/functions.h b/include/functions.h index f04ab19816..8396d4a418 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1651,7 +1651,7 @@ s16 func_80105318(void); void func_8010549C(PlayState* play, void* segmentAddress); void func_8010565C(PlayState* play, u8 num, void* segmentAddress); void func_80105818(PlayState* play, u32 uParm2, TransitionActorEntry* puParm3); -void func_80105A40(void); +void func_80105A40(PlayState* play); void func_80105B34(PlayState* play); void func_80105C40(s16 arg0); // void func_80105FE0(void); @@ -1728,7 +1728,7 @@ s32 func_8010A0A4(PlayState* play); // void func_8010A2AC(PlayState* play); void Minimap_SavePlayerRoomInitInfo(PlayState* play); void Map_InitRoomData(PlayState* play, s16 room); -// void Map_Destroy(void); +void Map_Destroy(PlayState* play); // void Map_Init(PlayState* play); // void Minimap_Draw(PlayState* play); // void Map_Update(PlayState* play); @@ -1811,17 +1811,13 @@ Gfx* func_8010CD98(Gfx* displayListHead, void* texture, s16 textureWidth, s16 te // void func_8010CFBC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10, UNK_TYPE2 param_11, UNK_TYPE2 param_12, UNK_TYPE2 param_13, UNK_TYPE2 param_14); // void func_8010D2D4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10, UNK_TYPE2 param_11); // void func_8010D480(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10, UNK_TYPE2 param_11, UNK_TYPE2 param_12, UNK_TYPE2 param_13, UNK_TYPE2 param_14, UNK_TYPE4 param_15, UNK_TYPE4 param_16); -// void func_8010D7D0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10); +Gfx* func_8010D7D0(Gfx* displayListHead, void* texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy); // void func_8010D9F4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE4 param_10, UNK_TYPE4 param_11, UNK_TYPE4 param_12, UNK_TYPE2 param_13, UNK_TYPE2 param_14); Gfx* func_8010DC58(Gfx* displayListHead, void* texture, s16 textureWidth, s16 textureHeight, u16 i); // void func_8010DE38(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6); // void func_8010E028(void); -// void func_8010E968(void); -void func_8010E9F0(s16 arg0, s16 arg1); -void func_8010EA9C(s32 arg0, s32 arg1); -// void func_8010EB50(void); -// void func_8010EBA0(void); -// void func_8010EC54(void); +void Interface_StartTimer(s16 timerId, s16 seconds); +void Interface_StartPostmanTimer(s16 seconds, s16 bunnyHoodState); void func_8010EE74(PlayState* play, s32 day); void Interface_SetHudVisibility(u16 hudVisibility); // void func_80110038(void); @@ -1870,17 +1866,14 @@ void func_8011B4E0(PlayState* play, s32 arg1); // void func_8011B9E0(void); // void func_8011BF70(void); // void func_8011C4C4(void); -void func_8011C808(PlayState* play); -// void func_8011C898(void); -// void func_8011CA64(void); -// void func_8011E3B4(void); +void Interface_StartMoonCrash(PlayState* play); // void func_8011E730(void); // void func_8011F0E0(UNK_TYPE4 ctxt); // void func_80120F90(void); // void func_80121000(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE1 param_8, UNK_TYPE1 param_9, UNK_TYPE1 param_10, UNK_TYPE4 param_11, UNK_TYPE4 param_12, UNK_TYPE4 param_13, UNK_TYPE4 param_14); // void func_80121064(void); // void func_801210E0(void); -// void func_80121F94(void); +void Interface_Destroy(PlayState* play); void func_80121FC4(PlayState* play); Path* Path_GetByIndex(PlayState* play, s16 index, s16 max); f32 Path_OrientAndGetDistSq(Actor* actor, Path* path, s16 waypoint, s16* yaw); @@ -1947,7 +1940,7 @@ s32 Player_ActionToExplosive(Player* player, s32 actionParam); s32 Player_GetExplosiveHeld(Player* player); s32 func_80124278(Actor* actor, s32 arg1); s32 func_801242B4(Player* player); -s32 func_801242DC(PlayState* play); +s32 Player_GetEnvTimerType(PlayState* play); void func_80124420(Player* player); void func_80124618(struct_80124618 arg0[], f32 curFrame, Vec3f* arg2); void func_801246F4(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount, s32 lod, s32 tunic, s32 boots, s32 face, OverrideLimbDrawFlex overrideLimbDraw, PostLimbDrawFlex postLimbDraw, Actor* actor); @@ -2703,8 +2696,8 @@ void Main(void* arg); u32 Padmgr_GetControllerBitmask(void); void func_80174F24(void (*arg0)(void*), void* arg1); void func_80174F44(void (*arg0)(void*), void* arg1); -// void func_80174F7C(void); -// void func_80174F9C(void); +void func_80174F7C(void (*arg0)(s32), void* arg1); +void func_80174F9C(void (*arg0)(s32), void* arg1); // OSMesgQueue* Padmgr_GetEventCallback(void); // void func_80175008(void); void Padmgr_SetEventCallback(OSMesg pvParm1); diff --git a/include/regs.h b/include/regs.h index aa3ba523b2..cf15b236af 100644 --- a/include/regs.h +++ b/include/regs.h @@ -71,6 +71,8 @@ #define R_A_ICON_X XREG(20) #define R_A_BTN_COLOR(i) XREG(22 + i) #define R_MAGIC_CONSUME_TIMER_GIANTS_MASK XREG(41) +#define R_MOON_CRASH_TIMER_Y XREG(80) +#define R_MOON_CRASH_TIMER_X XREG(81) #define R_MINIMAP_DISABLED XREG(95) #define R_B_LABEL_DD WREG(0) #define R_OW_MINIMAP_X WREG(29) diff --git a/include/variables.h b/include/variables.h index 05602af8fe..1ee739c4af 100644 --- a/include/variables.h +++ b/include/variables.h @@ -1031,21 +1031,21 @@ extern UNK_PTR D_801BF5C0; // extern UNK_TYPE2 sMagicMeterOutlinePrimBlue; // extern UNK_TYPE2 sMagicBorderRatio; // extern UNK_TYPE2 sMagicBorderStep; -// extern UNK_TYPE2 D_801BF8DC; -// extern UNK_TYPE2 D_801BF8E0; -// extern UNK_TYPE2 D_801BF8E4; -// extern UNK_TYPE4 D_801BF8E8; -// extern UNK_TYPE4 D_801BF8F0; +// extern UNK_TYPE2 sEnvTimerType; +// extern UNK_TYPE2 sEnvTimerActive; +// extern UNK_TYPE2 sPostmanBunnyHoodState; +// extern UNK_TYPE4 sTimerPausedOsTime; +// extern UNK_TYPE4 sBottleTimerPausedOsTime; // extern UNK_TYPE4 D_801BF8F4; // extern UNK_TYPE4 D_801BF8F8; // extern UNK_TYPE4 D_801BF8FC; // extern UNK_TYPE4 D_801BF930; // extern UNK_TYPE4 D_801BF934; -// extern UNK_TYPE1 D_801BF968; +// extern UNK_TYPE1 sIsTimerPaused; // extern UNK_TYPE1 D_801BF96A; -// extern UNK_TYPE1 D_801BF96C; +// extern UNK_TYPE1 sIsBottleTimerPaused; // extern UNK_TYPE1 D_801BF96E; -// extern UNK_TYPE2 D_801BF970; +// extern UNK_TYPE2 sTimerId; // extern UNK_TYPE1 D_801BF972; // extern UNK_TYPE2 D_801BF974; // extern UNK_TYPE2 D_801BF978; @@ -1083,7 +1083,7 @@ extern UNK_PTR D_801BF5C0; // extern UNK_TYPE2 D_801BFA4C; // extern UNK_TYPE2 D_801BFA64; // extern UNK_TYPE2 D_801BFA74; -// extern UNK_TYPE4 D_801BFA84; +// extern UNK_TYPE4 sPostmanTimerInputBtnAPressed; // extern UNK_TYPE1 D_801BFAB0; // extern UNK_TYPE1 D_801BFAB8; // extern UNK_TYPE1 D_801BFAC4; @@ -1135,15 +1135,15 @@ extern UNK_PTR D_801BF5C0; // extern UNK_TYPE2 D_801BFCA8; // extern UNK_TYPE1 D_801BFCB8; // extern UNK_TYPE4 D_801BFCC4; -// extern UNK_TYPE2 D_801BFCE4; -// extern UNK_TYPE2 D_801BFCE8; +// extern UNK_TYPE2 sTimerStateTimer; +// extern UNK_TYPE2 sTimerDigits; // extern UNK_TYPE2 D_801BFCEA; // extern UNK_TYPE2 D_801BFCEC; // extern UNK_TYPE2 D_801BFCEE; // extern UNK_TYPE2 D_801BFCF0; // extern UNK_TYPE2 D_801BFCF2; // extern UNK_TYPE2 D_801BFCF4; -// extern UNK_TYPE2 D_801BFCF8; +// extern UNK_TYPE2 sTimerBeepSfxSeconds; // extern UNK_TYPE2 D_801BFCFC; // extern UNK_TYPE2 D_801BFD0C; // extern UNK_TYPE1 D_801BFD1C; @@ -3151,7 +3151,7 @@ extern s16 D_801F4E7A; // extern UNK_TYPE1 D_801F57B4; // extern UNK_TYPE1 D_801F5834; // extern NmiBuff* gNMIBuffer; -// extern UNK_TYPE1 D_801F5850; +// extern UNK_TYPE1 sPostmanTimerInput; // extern UNK_TYPE1 D_801F58B0; // extern UNK_TYPE1 D_801F59AC; // extern UNK_TYPE1 D_801F59B0; diff --git a/include/z64player.h b/include/z64player.h index f49f30688a..2f101b5588 100644 --- a/include/z64player.h +++ b/include/z64player.h @@ -70,6 +70,14 @@ typedef enum { /* 0x19 */ PLAYER_MASK_MAX } PlayerMask; +typedef enum { + /* 0 */ PLAYER_ENV_TIMER_NONE, + /* 1 */ PLAYER_ENV_TIMER_HOTROOM, + /* 2 */ PLAYER_ENV_TIMER_UNDERWATER_FLOOR, + /* 3 */ PLAYER_ENV_TIMER_SWIMMING, + /* 4 */ PLAYER_ENV_TIMER_UNDERWATER_FREE +} PlayerEnvTimerType; + typedef enum PlayerActionParam { /* -1 */ PLAYER_AP_MINUS1 = -1, /* 0x00 */ PLAYER_AP_NONE, @@ -594,7 +602,7 @@ typedef struct Player { /* 0xAD0 */ f32 linearVelocity; /* 0xAD4 */ s16 currentYaw; /* 0xAD6 */ s16 targetYaw; - /* 0xAD8 */ u16 unk_AD8; + /* 0xAD8 */ u16 underwaterTimer; /* 0xADA */ s8 meleeWeaponAnimation; /* 0xADB */ s8 meleeWeaponState; /* 0xADC */ s8 unk_ADC; diff --git a/include/z64save.h b/include/z64save.h index 57801684f3..fc24aa5b6b 100644 --- a/include/z64save.h +++ b/include/z64save.h @@ -2,6 +2,7 @@ #define Z64SAVE_H #include "ultra64.h" +#include "z64item.h" #include "z64math.h" #include "os.h" @@ -54,6 +55,56 @@ typedef enum { #define MAGIC_NORMAL_METER 0x30 #define MAGIC_DOUBLE_METER (2 * MAGIC_NORMAL_METER) +#define SECONDS_TO_TIMER(seconds) ((seconds) * 100) + +#define OSTIME_TO_TIMER(osTime) ((osTime) * 64 / 3000 / 10000) +#define OSTIME_TO_TIMER_ALT(osTime) ((osTime) / 10000 * 64 / 3000) + +// 1 centisecond = 10 milliseconds = 1/100 seconds +#define SECONDS_TO_TIMER_PRECISE(seconds, centiSeconds) ((seconds) * 100 + (centiSeconds)) + +typedef enum { + /* 0 */ TIMER_ID_POSTMAN, // postman's counting minigame + /* 1 */ TIMER_ID_MINIGAME_1, // minigame timer + /* 2 */ TIMER_ID_2, + /* 3 */ TIMER_ID_MOON_CRASH, // timer used for mooncrash on the clocktower roof + /* 4 */ TIMER_ID_MINIGAME_2, // minigame timer + /* 5 */ TIMER_ID_ENV, // environmental timer (underwater or hot room) + /* 6 */ TIMER_ID_GORON_RACE_UNUSED, + /* 7 */ TIMER_ID_MAX, + /* 99 */ TIMER_ID_NONE = 99, +} TimerId; + +typedef enum { + /* 0 */ TIMER_COUNT_DOWN, + /* 1 */ TIMER_COUNT_UP +} TimerDirection; + +typedef enum { + /* 0 */ TIMER_STATE_OFF, + /* 1 */ TIMER_STATE_START, + /* 2 */ TIMER_STATE_HOLD_TIMER, // Hold timer frozen at the screen center + /* 3 */ TIMER_STATE_MOVING_TIMER, // Move timer to a target location + /* 4 */ TIMER_STATE_COUNTING, + /* 5 */ TIMER_STATE_STOP, + /* 6 */ TIMER_STATE_6, // like `TIMER_STATE_STOP` but with extra minigame checks + /* 7 */ TIMER_STATE_7, // stopped but still update `timerCurTimes` + /* 8 */ TIMER_STATE_ENV_START, + /* 9 */ TIMER_STATE_ALT_START, + /* 10 */ TIMER_STATE_10, // precursor to `TIMER_STATE_ALT_COUNTING` + /* 11 */ TIMER_STATE_ALT_COUNTING, + /* 12 */ TIMER_STATE_12, // Updated paused time? + /* 13 */ TIMER_STATE_POSTMAN_START, + /* 14 */ TIMER_STATE_POSTMAN_COUNTING, + /* 15 */ TIMER_STATE_POSTMAN_STOP, + /* 16 */ TIMER_STATE_POSTMAN_END +} TimerState; + +typedef enum { + /* 0 */ BOTTLE_TIMER_STATE_OFF, + /* 1 */ BOTTLE_TIMER_STATE_COUNTING +} BottleTimerState; + typedef enum { /* 0 */ HUD_VISIBILITY_IDLE, /* 1 */ HUD_VISIBILITY_NONE, @@ -242,11 +293,11 @@ typedef struct SaveContext { /* 0x1015 */ u8 unk_1015; /* 0x1016 */ u16 jinxTimer; /* 0x1018 */ s16 rupeeAccumulator; // "lupy_udct" - /* 0x101A */ u8 unk_101A[6]; // "bottle_status", one entry for each bottle - /* 0x1020 */ OSTime unk_1020[6]; // "bottle_ostime", one entry for each bottle - /* 0x1050 */ OSTime unk_1050[6]; // "bottle_sub", one entry for each bottle - /* 0x1080 */ OSTime unk_1080[6]; // "bottle_time", one entry for each bottle - /* 0x10B0 */ OSTime unk_10B0[6]; // "bottle_stop_time", one entry for each bottle + /* 0x101A */ u8 bottleTimerStates[BOTTLE_MAX]; // See the `BottleTimerState` enum. "bottle_status" + /* 0x1020 */ OSTime bottleTimerStartOsTimes[BOTTLE_MAX]; // The osTime when the timer starts. "bottle_ostime" + /* 0x1050 */ u64 bottleTimerTimeLimits[BOTTLE_MAX]; // The original total time given before the timer expires, in centiseconds (1/100th sec). "bottle_sub" + /* 0x1080 */ u64 bottleTimerCurTimes[BOTTLE_MAX]; // The remaining time left before the timer expires, in centiseconds (1/100th sec). "bottle_time" + /* 0x10B0 */ OSTime bottleTimerPausedOsTimes[BOTTLE_MAX]; // The cumulative osTime spent with the timer paused. "bottle_stop_time" /* 0x10E0 */ u64 pictoPhoto[1400]; // buffer containing the pictograph photo /* 0x3CA0 */ s32 fileNum; // "file_no" /* 0x3CA4 */ s16 powderKegTimer; // "big_bom_timer" @@ -265,16 +316,16 @@ typedef struct SaveContext { /* 0x3DBF */ u8 showTitleCard; // "name_display" /* 0x3DC0 */ s16 unk_3DC0; // "shield_magic_timer" /* 0x3DC2 */ u8 unk_3DC2; // "pad1" - /* 0x3DC8 */ OSTime unk_3DC8; // "get_time" - /* 0x3DD0 */ u8 unk_3DD0[7]; // "event_fg" - /* 0x3DD7 */ u8 unk_3DD7[7]; // "calc_flag" - /* 0x3DE0 */ OSTime unk_3DE0[7]; // "event_ostime" - /* 0x3E18 */ OSTime unk_3E18[7]; // "event_sub" - /* 0x3E50 */ OSTime unk_3E50[7]; // "func_time" - /* 0x3E88 */ OSTime unk_3E88[7]; // "func_end_time" - /* 0x3EC0 */ OSTime unk_3EC0[7]; // "func_stop_time" - /* 0x3EF8 */ s16 timerX[7]; // "event_xp" - /* 0x3F06 */ s16 timerY[7]; // "event_yp" + /* 0x3DC8 */ OSTime postmanTimerStopOsTime; // The osTime when the timer stops for the postman minigame. "get_time" + /* 0x3DD0 */ u8 timerStates[TIMER_ID_MAX]; // See the `TimerState` enum. "event_fg" + /* 0x3DD7 */ u8 timerDirections[TIMER_ID_MAX]; // See the `TimerDirection` enum. "calc_flag" + /* 0x3DE0 */ u64 timerCurTimes[TIMER_ID_MAX]; // For countdown, the remaining time left. For countup, the time since the start. In centiseconds (1/100th sec). "event_ostime" + /* 0x3E18 */ u64 timerTimeLimits[TIMER_ID_MAX]; // The original total time given for the timer to count from, in centiseconds (1/100th sec). "event_sub" + /* 0x3E50 */ OSTime timerStartOsTimes[TIMER_ID_MAX]; // The osTime when the timer starts. "func_time" + /* 0x3E88 */ u64 timerStopTimes[TIMER_ID_MAX]; // The total amount of time taken between the start and end of the timer, in centiseconds (1/100th sec). "func_end_time" + /* 0x3EC0 */ OSTime timerPausedOsTimes[TIMER_ID_MAX]; // The cumulative osTime spent with the timer paused. "func_stop_time" + /* 0x3EF8 */ s16 timerX[TIMER_ID_MAX]; // "event_xp" + /* 0x3F06 */ s16 timerY[TIMER_ID_MAX]; // "event_yp" /* 0x3F14 */ s16 unk_3F14; // "character_change" /* 0x3F16 */ u8 seqIndex; // "old_bgm" /* 0x3F17 */ u8 nightSeqIndex; // "old_env" diff --git a/src/boot_O2_g3/idle.c b/src/boot_O2_g3/idle.c index da93f13fdb..942435fa7b 100644 --- a/src/boot_O2_g3/idle.c +++ b/src/boot_O2_g3/idle.c @@ -1,4 +1,3 @@ -#include "prevent_bss_reordering.h" #include "global.h" u8 D_80096B20 = 1; diff --git a/src/code/code_8012EC80.c b/src/code/code_8012EC80.c index ee2070610b..a29a8279eb 100644 --- a/src/code/code_8012EC80.c +++ b/src/code/code_8012EC80.c @@ -688,7 +688,7 @@ void Inventory_SetMapVisibility(s16 tingleIndex) { void Inventory_SaveDekuPlaygroundHighScore(s16 timerId) { s16 i; - gSaveContext.save.dekuPlaygroundHighScores[CURRENT_DAY - 1] = gSaveContext.unk_3DE0[timerId]; + gSaveContext.save.dekuPlaygroundHighScores[CURRENT_DAY - 1] = gSaveContext.timerCurTimes[timerId]; for (i = 0; i < 8; i++) { gSaveContext.save.inventory.dekuPlaygroundPlayerName[CURRENT_DAY - 1][i] = diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c index 1b8dbfb2ec..f9b23ac791 100644 --- a/src/code/z_bgcheck.c +++ b/src/code/z_bgcheck.c @@ -1,3 +1,4 @@ +#include "prevent_bss_reordering.h" #include "global.h" #include "vt.h" #include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h" diff --git a/src/code/z_game_over.c b/src/code/z_game_over.c index 394a106006..9fc3dee25b 100644 --- a/src/code/z_game_over.c +++ b/src/code/z_game_over.c @@ -18,14 +18,14 @@ static s16 sGameOverTimer = 0; void GameOver_Update(PlayState* play) { GameOverContext* gameOverCtx = &play->gameOverCtx; - s16 i; + s16 timerId; switch (gameOverCtx->state) { case GAMEOVER_DEATH_START: func_801477B4(play); - for (i = 0; i < ARRAY_COUNT(gSaveContext.unk_3DD0); i++) { - gSaveContext.unk_3DD0[i] = 0; + for (timerId = 0; timerId < TIMER_ID_MAX; timerId++) { + gSaveContext.timerStates[timerId] = TIMER_STATE_OFF; } gSaveContext.eventInf[1] &= ~1; diff --git a/src/code/z_map_exp.c b/src/code/z_map_exp.c index 40ffb42132..ffad44e6ed 100644 --- a/src/code/z_map_exp.c +++ b/src/code/z_map_exp.c @@ -169,8 +169,8 @@ void Map_InitRoomData(PlayState* play, s16 room) { } } -void Map_Destroy(void) { - func_80105A40(); +void Map_Destroy(PlayState* play) { + func_80105A40(play); } void Map_Init(PlayState* play) { diff --git a/src/code/z_parameter.c b/src/code/z_parameter.c index 679b8abf48..ef108c43aa 100644 --- a/src/code/z_parameter.c +++ b/src/code/z_parameter.c @@ -1,8 +1,11 @@ #include "global.h" + #include "interface/parameter_static/parameter_static.h" #include "interface/do_action_static/do_action_static.h" #include "misc/story_static/story_static.h" + #include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h" +#include "overlays/actors/ovl_En_Mm3/z_en_mm3.h" typedef struct { /* 0x00 */ u8 scene; @@ -11,7 +14,7 @@ typedef struct { /* 0x03 */ u8 flags3; } RestrictionFlags; -Input D_801F5850[4]; +Input sPostmanTimerInput[4]; RestrictionFlags sRestrictionFlags[] = { { SCENE_20SICHITAI2, 0x00, 0x00, 0x00 }, @@ -167,23 +170,21 @@ s16 sExtraItemBases[] = { ITEM_NUT, // ITEM_NUT_UPGRADE_30 }; -s16 D_801BF8DC = 0; -s16 D_801BF8E0 = 0; -s16 D_801BF8E4 = 0; - -OSTime D_801BF8E8 = 0; -OSTime D_801BF8F0 = 0; +s16 sEnvTimerType = PLAYER_ENV_TIMER_NONE; +s16 sEnvTimerActive = false; +s16 sPostmanBunnyHoodState = POSTMAN_MINIGAME_BUNNY_HOOD_OFF; +OSTime sTimerPausedOsTime = 0; +OSTime sBottleTimerPausedOsTime = 0; OSTime D_801BF8F8[] = { 0, 0, 0, 0, 0, 0, 0, }; OSTime D_801BF930[] = { 0, 0, 0, 0, 0, 0, 0, }; +u8 sIsTimerPaused = false; +u8 sIsBottleTimerPaused = false; +s16 sTimerId = TIMER_ID_NONE; -u8 D_801BF968 = false; -u8 D_801BF96C = false; - -s16 D_801BF970 = 99; s16 D_801BF974 = 0; s16 D_801BF978 = 10; s16 D_801BF97C = 255; @@ -264,20 +265,112 @@ s16 D_801BFA74[] = { #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010E028.s") -s32 D_801BFA84 = 0; +s32 sPostmanTimerInputBtnAPressed = false; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010E968.s") +void Interface_PostmanTimerCallback(s32 arg0) { + s32 btnAPressed; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010E9F0.s") + func_80175E68(&sPostmanTimerInput[0], 0); + btnAPressed = CHECK_BTN_ALL(sPostmanTimerInput[0].cur.button, BTN_A); + if ((btnAPressed != sPostmanTimerInputBtnAPressed) && btnAPressed) { + gSaveContext.postmanTimerStopOsTime = osGetTime(); + gSaveContext.timerStates[TIMER_ID_POSTMAN] = TIMER_STATE_POSTMAN_STOP; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010EA9C.s") + sPostmanTimerInputBtnAPressed = btnAPressed; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010EB50.s") +void Interface_StartTimer(s16 timerId, s16 seconds) { + gSaveContext.timerX[timerId] = 115; + gSaveContext.timerY[timerId] = 80; -void func_8010EBA0(s16 timer, s16 timerId); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010EBA0.s") + sEnvTimerActive = false; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010EC54.s") + gSaveContext.timerCurTimes[timerId] = SECONDS_TO_TIMER(seconds); + gSaveContext.timerTimeLimits[timerId] = gSaveContext.timerCurTimes[timerId]; + + if (gSaveContext.timerCurTimes[timerId] != SECONDS_TO_TIMER(0)) { + gSaveContext.timerDirections[timerId] = TIMER_COUNT_DOWN; + } else { + gSaveContext.timerDirections[timerId] = TIMER_COUNT_UP; + } + + gSaveContext.timerStates[timerId] = TIMER_STATE_START; +} + +void Interface_StartPostmanTimer(s16 seconds, s16 bunnyHoodState) { + gSaveContext.timerX[TIMER_ID_POSTMAN] = 115; + gSaveContext.timerY[TIMER_ID_POSTMAN] = 80; + + sPostmanBunnyHoodState = bunnyHoodState; + + gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] = SECONDS_TO_TIMER(seconds); + gSaveContext.timerTimeLimits[TIMER_ID_POSTMAN] = gSaveContext.timerCurTimes[TIMER_ID_POSTMAN]; + + if (gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] != SECONDS_TO_TIMER(0)) { + gSaveContext.timerDirections[TIMER_ID_POSTMAN] = TIMER_COUNT_DOWN; + } else { + gSaveContext.timerDirections[TIMER_ID_POSTMAN] = TIMER_COUNT_UP; + } + + gSaveContext.timerStates[TIMER_ID_POSTMAN] = TIMER_STATE_POSTMAN_START; + gSaveContext.timerStopTimes[TIMER_ID_POSTMAN] = SECONDS_TO_TIMER(0); + gSaveContext.timerPausedOsTimes[TIMER_ID_POSTMAN] = 0; +} + +// Unused, goron race actually uses TIMER_ID_MINIGAME_2 +void Interface_StartGoronRaceTimer(s32 arg0) { + if (gSaveContext.timerStates[TIMER_ID_GORON_RACE_UNUSED] != TIMER_STATE_OFF) { + // Goron race started + if (gSaveContext.eventInf[1] & 1) { + gSaveContext.timerCurTimes[TIMER_ID_GORON_RACE_UNUSED] = SECONDS_TO_TIMER_PRECISE(2, 39); + } else { + gSaveContext.timerCurTimes[TIMER_ID_GORON_RACE_UNUSED] = SECONDS_TO_TIMER_PRECISE(0, 1); + } + } +} + +void Interface_StartBottleTimer(s16 seconds, s16 timerId) { + gSaveContext.bottleTimerStates[timerId] = BOTTLE_TIMER_STATE_COUNTING; + gSaveContext.bottleTimerCurTimes[timerId] = SECONDS_TO_TIMER(seconds); + gSaveContext.bottleTimerTimeLimits[timerId] = gSaveContext.bottleTimerCurTimes[timerId]; + gSaveContext.bottleTimerStartOsTimes[timerId] = osGetTime(); + gSaveContext.bottleTimerPausedOsTimes[timerId] = 0; + sBottleTimerPausedOsTime = 0; +} + +u32 Interface_GetCompressedTimerDigits(s16 timerId) { + u64 time; + s16 timerArr[6]; + + time = gSaveContext.timerCurTimes[timerId]; + + // 6 minutes + timerArr[0] = time / SECONDS_TO_TIMER(360); + time -= timerArr[0] * SECONDS_TO_TIMER(360); + + // minutes + timerArr[1] = time / SECONDS_TO_TIMER(60); + time -= timerArr[1] * SECONDS_TO_TIMER(60); + + // 10 seconds + timerArr[2] = time / SECONDS_TO_TIMER(10); + time -= timerArr[2] * SECONDS_TO_TIMER(10); + + // seconds + timerArr[3] = time / SECONDS_TO_TIMER(1); + time -= timerArr[3] * SECONDS_TO_TIMER(1); + + // 100 milliseconds + timerArr[4] = time / SECONDS_TO_TIMER_PRECISE(0, 10); + time -= timerArr[4] * SECONDS_TO_TIMER_PRECISE(0, 10); + + // 10 milliseconds + timerArr[5] = time; + + return (timerArr[0] << 0x14) | (timerArr[1] << 0x10) | (timerArr[2] << 0xC) | (timerArr[3] << 8) | + (timerArr[4] << 4) | timerArr[5]; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010EE74.s") @@ -1440,7 +1533,7 @@ u8 Item_Give(PlayState* play, u8 item) { for (i = BOTTLE_FIRST; i < BOTTLE_MAX; i++) { if (gSaveContext.save.inventory.items[slot + i] == ITEM_BOTTLE) { if (item == ITEM_HOT_SPRING_WATER) { - func_8010EBA0(60, i); + Interface_StartBottleTimer(60, i); } if ((slot + i) == C_SLOT_EQUIP(0, EQUIP_SLOT_C_LEFT)) { @@ -1754,7 +1847,7 @@ void Inventory_UpdateBottleItem(PlayState* play, u8 item, u8 btn) { gSaveContext.buttonStatus[btn] = BTN_ENABLED; if (item == ITEM_HOT_SPRING_WATER) { - func_8010EBA0(60, GET_CUR_FORM_BTN_SLOT(btn) - SLOT_BOTTLE_1); + Interface_StartBottleTimer(60, GET_CUR_FORM_BTN_SLOT(btn) - SLOT_BOTTLE_1); } } @@ -2220,7 +2313,8 @@ void Magic_Update(PlayState* play) { !Play_InCsMode(play)) { if ((gSaveContext.save.playerData.magic == 0) || - ((func_801242DC(play) >= 2) && (func_801242DC(play) <= 4)) || + ((Player_GetEnvTimerType(play) >= PLAYER_ENV_TIMER_UNDERWATER_FLOOR) && + (Player_GetEnvTimerType(play) <= PLAYER_ENV_TIMER_UNDERWATER_FREE)) || ((BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_C_LEFT) != ITEM_LENS) && (BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_C_DOWN) != ITEM_LENS) && (BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_C_RIGHT) != ITEM_LENS)) || @@ -2512,25 +2606,582 @@ TexturePtr D_801BFCC4[] = { #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011C4C4.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011C808.s") +void Interface_StartMoonCrash(PlayState* play) { + if (play->actorCtx.flags & ACTORCTX_FLAG_1) { + Audio_QueueSeqCmd(0xE0000100); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011C898.s") + gSaveContext.save.day = 4; + gSaveContext.save.daysElapsed = 4; + gSaveContext.save.time = CLOCK_TIME(6, 0) + 10; + play->nextEntrance = ENTRANCE(TERMINA_FIELD, 12); + gSaveContext.nextCutsceneIndex = 0; + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_03; +} -s16 D_801BFCE4 = 0; -s16 D_801BFCE8[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -s16 D_801BFCF8 = 99; -s16 D_801BFCFC[] = { - // timer digit width - 16, 25, 34, 42, 51, 60, 68, 77, -}; -s16 D_801BFD0C[] = { - // digit width - 9, 9, 8, 9, 9, 8, 9, 9, -}; +void Interface_GetTimerDigits(u64 timer, s16* timerArr) { + u64 time = timer; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011CA64.s") + // 6 minutes + timerArr[0] = time / SECONDS_TO_TIMER(360); + time -= timerArr[0] * SECONDS_TO_TIMER(360); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011E3B4.s") + // minutes + timerArr[1] = time / SECONDS_TO_TIMER(60); + time -= timerArr[1] * SECONDS_TO_TIMER(60); + + // 10 seconds + timerArr[3] = time / SECONDS_TO_TIMER(10); + time -= timerArr[3] * SECONDS_TO_TIMER(10); + + // seconds + timerArr[4] = time / SECONDS_TO_TIMER(1); + time -= timerArr[4] * SECONDS_TO_TIMER(1); + + // 100 milliseconds + timerArr[6] = time / SECONDS_TO_TIMER_PRECISE(0, 10); + time -= timerArr[6] * SECONDS_TO_TIMER_PRECISE(0, 10); + + // 10 milliseconds + timerArr[7] = time; +} + +#define IS_POSTMAN_TIMER_DRAWN \ + (((sTimerId == TIMER_ID_POSTMAN) && \ + (gSaveContext.timerStates[TIMER_ID_POSTMAN] == TIMER_STATE_POSTMAN_COUNTING) && \ + (sPostmanBunnyHoodState == POSTMAN_MINIGAME_BUNNY_HOOD_OFF) && \ + (gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] < SECONDS_TO_TIMER(3))) || \ + (sPostmanBunnyHoodState == POSTMAN_MINIGAME_BUNNY_HOOD_ON)) + +/** + * Update and draw the timers + */ +void Interface_DrawTimers(PlayState* play) { + static s16 sTimerStateTimer = 0; + static s16 sTimerDigits[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + static s16 sTimerBeepSfxSeconds = 99; + static s16 sTimerDigitsOffsetX[] = { + 16, 25, 34, 42, 51, 60, 68, 77, + }; + static s16 sTimerDigitsWidth[] = { + 9, 9, 8, 9, 9, 8, 9, 9, + }; + InterfaceContext* interfaceCtx = &play->interfaceCtx; + MessageContext* msgCtx = &play->msgCtx; + Player* player = GET_PLAYER(play); + OSTime osTime; + OSTime timerOsTime; + s16 j; + s16 i; + + OPEN_DISPS(play->state.gfxCtx); + + // Not satisfying any of these conditions will pause the timer + if ((play->pauseCtx.state == 0) && (play->pauseCtx.debugEditor == DEBUG_EDITOR_NONE) && + (play->gameOverCtx.state == GAMEOVER_INACTIVE) && + ((msgCtx->msgMode == 0) || + ((msgCtx->msgMode != 0) && (msgCtx->currentTextId >= 0x1BB2) && (msgCtx->currentTextId <= 0x1BB6))) && + !(player->stateFlags1 & PLAYER_STATE1_200) && (play->transitionTrigger == TRANS_TRIGGER_OFF) && + (play->transitionMode == TRANS_MODE_OFF) && !Play_InCsMode(play)) { + + // Account for osTime when the timer is paused + if (sIsTimerPaused) { + osTime = osGetTime(); + + for (j = 0; j < TIMER_ID_MAX; j++) { + if (gSaveContext.timerStates[j] == TIMER_STATE_COUNTING) { + gSaveContext.timerPausedOsTimes[j] = + gSaveContext.timerPausedOsTimes[j] + (osTime - sTimerPausedOsTime); + } + } + sIsTimerPaused = false; + } + + sTimerId = TIMER_ID_NONE; + + // Update all timer states + for (i = 0; i < TIMER_ID_MAX; i++) { + if (gSaveContext.timerStates[i] == TIMER_STATE_OFF) { + continue; + } + + sTimerId = i; + + // Process the timer for the postman counting minigame + if (sTimerId == TIMER_ID_POSTMAN) { + switch (gSaveContext.timerStates[TIMER_ID_POSTMAN]) { + case TIMER_STATE_POSTMAN_START: + if (gSaveContext.timerDirections[TIMER_ID_POSTMAN] != TIMER_COUNT_DOWN) { + gSaveContext.timerStartOsTimes[TIMER_ID_POSTMAN] = osGetTime(); + } + gSaveContext.timerStates[TIMER_ID_POSTMAN] = TIMER_STATE_POSTMAN_COUNTING; + sPostmanTimerInputBtnAPressed = true; + func_80174F7C(Interface_PostmanTimerCallback, NULL); + break; + + case TIMER_STATE_POSTMAN_STOP: + timerOsTime = gSaveContext.postmanTimerStopOsTime; + gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] = + OSTIME_TO_TIMER(timerOsTime - ((void)0, gSaveContext.timerStartOsTimes[TIMER_ID_POSTMAN]) - + ((void)0, gSaveContext.timerPausedOsTimes[TIMER_ID_POSTMAN])); + gSaveContext.timerStates[TIMER_ID_POSTMAN] = TIMER_STATE_POSTMAN_END; + func_80174F9C(Interface_PostmanTimerCallback, NULL); + break; + + case TIMER_STATE_POSTMAN_COUNTING: + case TIMER_STATE_POSTMAN_END: + break; + } + break; + } + + // process the remaining timers + switch (gSaveContext.timerStates[sTimerId]) { + case TIMER_STATE_START: + case TIMER_STATE_ALT_START: + sTimerStateTimer = 20; + if (interfaceCtx->unk_280 != 0) { + + // Set the timer position + gSaveContext.timerX[sTimerId] = 26; + + if (interfaceCtx->magicAlpha != 255) { + gSaveContext.timerY[sTimerId] = 22; + } else if (gSaveContext.save.playerData.healthCapacity > 0xA0) { + gSaveContext.timerY[sTimerId] = 54; + } else { + gSaveContext.timerY[sTimerId] = 46; + } + + if ((interfaceCtx->unk_280 == 8) || (interfaceCtx->unk_280 == 30)) { + if (gSaveContext.timerStates[sTimerId] == TIMER_STATE_START) { + gSaveContext.timerStates[sTimerId] = TIMER_STATE_COUNTING; + } else { + gSaveContext.timerStates[sTimerId] = TIMER_STATE_ALT_COUNTING; + D_801BF8F8[sTimerId] = osGetTime(); + D_801BF930[sTimerId] = 0; + } + + gSaveContext.timerStartOsTimes[sTimerId] = osGetTime(); + gSaveContext.timerStopTimes[sTimerId] = SECONDS_TO_TIMER(0); + gSaveContext.timerPausedOsTimes[sTimerId] = 0; + } + } else { + gSaveContext.timerStates[sTimerId] = TIMER_STATE_HOLD_TIMER; + } + break; + + case TIMER_STATE_HOLD_TIMER: + sTimerStateTimer--; + if (sTimerStateTimer == 0) { + sTimerStateTimer = 20; + gSaveContext.timerStates[sTimerId] = TIMER_STATE_MOVING_TIMER; + } + break; + + case TIMER_STATE_MOVING_TIMER: + // Move the timer from the center of the screen to the timer location where it will count. + if (sTimerId == TIMER_ID_MOON_CRASH) { + j = ((((void)0, gSaveContext.timerX[sTimerId]) - R_MOON_CRASH_TIMER_X) / sTimerStateTimer); + gSaveContext.timerX[sTimerId] = ((void)0, gSaveContext.timerX[sTimerId]) - j; + j = ((((void)0, gSaveContext.timerY[sTimerId]) - R_MOON_CRASH_TIMER_Y) / sTimerStateTimer); + gSaveContext.timerY[sTimerId] = ((void)0, gSaveContext.timerY[sTimerId]) - j; + } else { + j = ((((void)0, gSaveContext.timerX[sTimerId]) - 26) / sTimerStateTimer); + gSaveContext.timerX[sTimerId] = ((void)0, gSaveContext.timerX[sTimerId]) - j; + + j = (gSaveContext.save.playerData.healthCapacity > 0xA0) + ? ((((void)0, gSaveContext.timerY[sTimerId]) - 54) / sTimerStateTimer) + : ((((void)0, gSaveContext.timerY[sTimerId]) - 46) / sTimerStateTimer); + gSaveContext.timerY[sTimerId] = ((void)0, gSaveContext.timerY[sTimerId]) - j; + } + + sTimerStateTimer--; + if (sTimerStateTimer == 0) { + sTimerStateTimer = 20; + + if (sTimerId == TIMER_ID_MOON_CRASH) { + gSaveContext.timerY[sTimerId] = R_MOON_CRASH_TIMER_Y; + } else { + gSaveContext.timerX[sTimerId] = 26; + if (gSaveContext.save.playerData.healthCapacity > 0xA0) { + gSaveContext.timerY[sTimerId] = 54; + } else { + gSaveContext.timerY[sTimerId] = 46; + } + } + + gSaveContext.timerStates[sTimerId] = TIMER_STATE_COUNTING; + gSaveContext.timerStartOsTimes[sTimerId] = osGetTime(); + gSaveContext.timerStopTimes[sTimerId] = SECONDS_TO_TIMER(0); + gSaveContext.timerPausedOsTimes[sTimerId] = 0; + } + // fallthrough + case TIMER_STATE_COUNTING: + if ((gSaveContext.timerStates[sTimerId] == TIMER_STATE_COUNTING) && + (sTimerId == TIMER_ID_MOON_CRASH)) { + gSaveContext.timerX[TIMER_ID_MOON_CRASH] = R_MOON_CRASH_TIMER_X; + gSaveContext.timerY[TIMER_ID_MOON_CRASH] = R_MOON_CRASH_TIMER_Y; + } + break; + + case TIMER_STATE_10: + D_801BF8F8[sTimerId] = osGetTime(); + D_801BF930[sTimerId] = 0; + gSaveContext.timerStates[sTimerId] = TIMER_STATE_ALT_COUNTING; + // fallthrough + case TIMER_STATE_ALT_COUNTING: + D_801BF930[sTimerId] = osGetTime() - D_801BF8F8[sTimerId]; + break; + + case TIMER_STATE_12: + osTime = osGetTime(); + + gSaveContext.timerPausedOsTimes[sTimerId] = + gSaveContext.timerPausedOsTimes[sTimerId] + osTime - D_801BF8F8[sTimerId]; + D_801BF930[sTimerId] = 0; + gSaveContext.timerStates[sTimerId] = TIMER_STATE_COUNTING; + break; + + case TIMER_STATE_ENV_START: + gSaveContext.timerCurTimes[sTimerId] = SECONDS_TO_TIMER(gSaveContext.save.playerData.health >> 1); + gSaveContext.timerDirections[sTimerId] = TIMER_COUNT_DOWN; + gSaveContext.timerTimeLimits[sTimerId] = gSaveContext.timerCurTimes[sTimerId]; + sTimerStateTimer = 20; + gSaveContext.timerStates[sTimerId] = TIMER_STATE_MOVING_TIMER; + break; + + case TIMER_STATE_STOP: + osTime = osGetTime(); + + gSaveContext.timerStopTimes[sTimerId] = + OSTIME_TO_TIMER(osTime - ((void)0, gSaveContext.timerStartOsTimes[sTimerId]) - + ((void)0, gSaveContext.timerPausedOsTimes[sTimerId])); + + gSaveContext.timerStates[sTimerId] = TIMER_STATE_OFF; + + if (sTimerId == TIMER_ID_MOON_CRASH) { + gSaveContext.save.day = 4; + if ((play->sceneNum == SCENE_OKUJOU) && (gSaveContext.sceneSetupIndex == 3)) { + play->nextEntrance = ENTRANCE(TERMINA_FIELD, 1); + gSaveContext.nextCutsceneIndex = 0xFFF0; + play->transitionTrigger = TRANS_TRIGGER_START; + } else { + Interface_StartMoonCrash(play); + } + } else if (gSaveContext.timerStates[TIMER_ID_GORON_RACE_UNUSED] != TIMER_STATE_OFF) { + gSaveContext.timerX[TIMER_ID_GORON_RACE_UNUSED] = 115; + gSaveContext.timerY[TIMER_ID_GORON_RACE_UNUSED] = 80; + if (gSaveContext.timerStates[TIMER_ID_GORON_RACE_UNUSED] <= TIMER_STATE_10) { + gSaveContext.timerStates[TIMER_ID_GORON_RACE_UNUSED] = TIMER_STATE_MOVING_TIMER; + } + } + break; + + case TIMER_STATE_6: + osTime = osGetTime(); + + gSaveContext.timerStopTimes[sTimerId] = + OSTIME_TO_TIMER(osTime - ((void)0, gSaveContext.timerStartOsTimes[sTimerId]) - + ((void)0, gSaveContext.timerPausedOsTimes[sTimerId])); + + if ((gSaveContext.minigameState == 1) && + (gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0))) { + if (gSaveContext.timerStopTimes[sTimerId] >= SECONDS_TO_TIMER(120)) { + gSaveContext.timerStopTimes[sTimerId] = SECONDS_TO_TIMER(120); + gSaveContext.timerCurTimes[sTimerId] = SECONDS_TO_TIMER(120); + } + } else if ((gSaveContext.eventInf[3] & 0x10) && (play->sceneNum == SCENE_DEKUTES) && + (gSaveContext.timerStopTimes[sTimerId] >= SECONDS_TO_TIMER(120))) { + gSaveContext.timerCurTimes[sTimerId] = SECONDS_TO_TIMER(120); + } + gSaveContext.timerStates[sTimerId] = TIMER_STATE_7; + + if (gSaveContext.timerStates[TIMER_ID_GORON_RACE_UNUSED] != TIMER_STATE_OFF) { + gSaveContext.timerX[TIMER_ID_GORON_RACE_UNUSED] = 115; + gSaveContext.timerY[TIMER_ID_GORON_RACE_UNUSED] = 80; + if (gSaveContext.timerStates[TIMER_ID_GORON_RACE_UNUSED] <= TIMER_STATE_10) { + gSaveContext.timerStates[TIMER_ID_GORON_RACE_UNUSED] = TIMER_STATE_MOVING_TIMER; + } + gSaveContext.timerStates[sTimerId] = TIMER_STATE_OFF; + } + break; + } + break; + } + + // Update timer counting + if ((sTimerId != TIMER_ID_NONE) && gSaveContext.timerStates[sTimerId]) { // != TIMER_STATE_OFF + if (gSaveContext.timerDirections[sTimerId] == TIMER_COUNT_DOWN) { + sTimerDigits[0] = sTimerDigits[1] = sTimerDigits[3] = sTimerDigits[4] = sTimerDigits[6] = 0; + + // Used to index the counter colon + sTimerDigits[2] = sTimerDigits[5] = 10; + + // Get the total amount of unpaused time since the start of the timer, centiseconds (1/100th sec). + if ((gSaveContext.timerStates[sTimerId] == TIMER_STATE_COUNTING) || + (gSaveContext.timerStates[sTimerId] == TIMER_STATE_10) || + (gSaveContext.timerStates[sTimerId] == TIMER_STATE_ALT_COUNTING) || + (gSaveContext.timerStates[sTimerId] == TIMER_STATE_POSTMAN_COUNTING)) { + osTime = osGetTime(); + + osTime = + OSTIME_TO_TIMER(osTime - ((void)0, gSaveContext.timerPausedOsTimes[sTimerId]) - + D_801BF930[sTimerId] - ((void)0, gSaveContext.timerStartOsTimes[sTimerId])); + } else if (gSaveContext.timerStates[sTimerId] == TIMER_STATE_7) { + osTime = gSaveContext.timerStopTimes[sTimerId]; + } else { + osTime = 0; + } + + // Check how much unpaused time has passed + if (osTime == 0) { + // No unpaused time has passed since the start of the timer. + gSaveContext.timerCurTimes[sTimerId] = gSaveContext.timerTimeLimits[sTimerId] - osTime; + } else if (osTime <= gSaveContext.timerTimeLimits[sTimerId]) { + // Time has passed, but the time limit has not been exceeded + if (osTime >= gSaveContext.timerTimeLimits[sTimerId]) { + // The time is exactly at the time limit. No time remaining. + gSaveContext.timerCurTimes[sTimerId] = SECONDS_TO_TIMER(0); + } else { + // Update the time remaining + gSaveContext.timerCurTimes[sTimerId] = gSaveContext.timerTimeLimits[sTimerId] - osTime; + } + } else { + // Time has passed, and the time limit has been exceeded. + gSaveContext.timerCurTimes[sTimerId] = SECONDS_TO_TIMER(0); + gSaveContext.timerStates[sTimerId] = TIMER_STATE_STOP; + if (sEnvTimerActive) { + gSaveContext.save.playerData.health = 0; + play->damagePlayer(play, -(((void)0, gSaveContext.save.playerData.health) + 2)); + } + sEnvTimerActive = false; + } + + Interface_GetTimerDigits(((void)0, gSaveContext.timerCurTimes[sTimerId]), sTimerDigits); + + // Use seconds to determine when to beep + if (gSaveContext.timerCurTimes[sTimerId] > SECONDS_TO_TIMER(60)) { + if ((sTimerBeepSfxSeconds != sTimerDigits[4]) && (sTimerDigits[4] == 1)) { + play_sound(NA_SE_SY_MESSAGE_WOMAN); + sTimerBeepSfxSeconds = sTimerDigits[4]; + } + } else if (gSaveContext.timerCurTimes[sTimerId] > SECONDS_TO_TIMER(10)) { + if ((sTimerBeepSfxSeconds != sTimerDigits[4]) && ((sTimerDigits[4] % 2) != 0)) { + play_sound(NA_SE_SY_WARNING_COUNT_N); + sTimerBeepSfxSeconds = sTimerDigits[4]; + } + } else if (sTimerBeepSfxSeconds != sTimerDigits[4]) { + play_sound(NA_SE_SY_WARNING_COUNT_E); + sTimerBeepSfxSeconds = sTimerDigits[4]; + } + } else { // TIMER_COUNT_UP + sTimerDigits[0] = sTimerDigits[1] = sTimerDigits[3] = sTimerDigits[4] = sTimerDigits[6] = 0; + + // Used to index the counter colon + sTimerDigits[2] = sTimerDigits[5] = 10; + + // Get the total amount of unpaused time since the start of the timer, centiseconds (1/100th sec). + if ((gSaveContext.timerStates[sTimerId] == TIMER_STATE_COUNTING) || + (gSaveContext.timerStates[sTimerId] == TIMER_STATE_POSTMAN_COUNTING)) { + osTime = osGetTime(); + osTime = + OSTIME_TO_TIMER(osTime - ((void)0, gSaveContext.timerStartOsTimes[sTimerId]) - + ((void)0, gSaveContext.timerPausedOsTimes[sTimerId]) - D_801BF930[sTimerId]); + } else if (gSaveContext.timerStates[sTimerId] == TIMER_STATE_7) { + osTime = gSaveContext.timerStopTimes[sTimerId]; + } else if (sTimerId == TIMER_ID_POSTMAN) { + osTime = gSaveContext.timerCurTimes[sTimerId]; + } else { + osTime = SECONDS_TO_TIMER(0); + } + + if ((gSaveContext.minigameState == 1) && (gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0))) { + if (osTime >= SECONDS_TO_TIMER(120)) { + osTime = SECONDS_TO_TIMER(120); + } + } else if ((gSaveContext.eventInf[3] & 0x10) && (play->sceneNum == SCENE_DEKUTES) && + (osTime >= SECONDS_TO_TIMER(120))) { + osTime = SECONDS_TO_TIMER(120); + } + + // Update the time remaining with the total amount of time since the start of the timer, + gSaveContext.timerCurTimes[sTimerId] = osTime; + + Interface_GetTimerDigits(osTime, sTimerDigits); + + // Use seconds to determine when to beep + if ((gSaveContext.minigameState == 1) && (gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0))) { + if ((gSaveContext.timerCurTimes[sTimerId] > SECONDS_TO_TIMER(110)) && + (sTimerBeepSfxSeconds != sTimerDigits[4])) { + play_sound(NA_SE_SY_WARNING_COUNT_E); + sTimerBeepSfxSeconds = sTimerDigits[4]; + } + } else if ((gSaveContext.eventInf[3] & 0x10) && (play->sceneNum == SCENE_DEKUTES)) { + if ((((void)0, gSaveContext.timerCurTimes[sTimerId]) > + (gSaveContext.save.dekuPlaygroundHighScores[CURRENT_DAY - 1] - SECONDS_TO_TIMER(9))) && + (sTimerBeepSfxSeconds != sTimerDigits[4])) { + play_sound(NA_SE_SY_WARNING_COUNT_E); + sTimerBeepSfxSeconds = sTimerDigits[4]; + } + } + } + + // Draw timer + gDPPipeSync(OVERLAY_DISP++); + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0); + OVERLAY_DISP = + func_8010CD98(OVERLAY_DISP, gTimerClockIconTex, 0x10, 0x10, ((void)0, gSaveContext.timerX[sTimerId]), + ((void)0, gSaveContext.timerY[sTimerId]) + 2, 0x10, 0x10, 1 << 10, 1 << 10); + gDPPipeSync(OVERLAY_DISP++); + gDPSetCombineLERP(OVERLAY_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, + 0, PRIMITIVE, 0); + + if (IS_POSTMAN_TIMER_DRAWN || (gSaveContext.timerStates[sTimerId] <= TIMER_STATE_12)) { + // Set the timer color + if (gSaveContext.timerStates[sTimerId]) { // != TIMER_STATE_OFF + if (sTimerId == TIMER_ID_2) { + if ((gSaveContext.timerCurTimes[sTimerId] == SECONDS_TO_TIMER(0)) || + (gSaveContext.timerStates[sTimerId] == TIMER_STATE_COUNTING)) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 50, 0, 255); + } else { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, 255); + } + } else if ((gSaveContext.minigameState == 1) && + (gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0))) { + if (gSaveContext.timerCurTimes[sTimerId] >= SECONDS_TO_TIMER(110)) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 50, 0, 255); + } else { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, 255); + } + } else if ((gSaveContext.eventInf[3] & 0x10) && (play->sceneNum == SCENE_DEKUTES)) { + if (((void)0, gSaveContext.timerCurTimes[sTimerId]) >= + gSaveContext.save.dekuPlaygroundHighScores[CURRENT_DAY - 1]) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 50, 0, 255); + } else if (((void)0, gSaveContext.timerCurTimes[sTimerId]) >= + (gSaveContext.save.dekuPlaygroundHighScores[CURRENT_DAY - 1] - + SECONDS_TO_TIMER(9))) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 0, 255); + } else { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, 255); + } + } else if ((gSaveContext.timerCurTimes[sTimerId] < SECONDS_TO_TIMER(10)) && + (gSaveContext.timerDirections[sTimerId] == TIMER_COUNT_DOWN) && + (gSaveContext.timerStates[sTimerId] != TIMER_STATE_ALT_COUNTING)) { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 50, 0, 255); + } else { + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, 255); + } + } + + // Draw the timer + if (sTimerId == TIMER_ID_POSTMAN) { + if (sPostmanBunnyHoodState == POSTMAN_MINIGAME_BUNNY_HOOD_ON) { + // draw sTimerDigits[3] (10s of seconds) to sTimerDigits[6] (100s of milliseconds) + for (j = 0; j < 4; j++) { + OVERLAY_DISP = func_8010D7D0( + OVERLAY_DISP, ((u8*)gCounterDigit0Tex + (8 * 16 * sTimerDigits[j + 3])), 8, 0x10, + ((void)0, gSaveContext.timerX[sTimerId]) + sTimerDigitsOffsetX[j], + ((void)0, gSaveContext.timerY[sTimerId]), sTimerDigitsWidth[j], 0xFA, 0x370, 0x370); + } + } else { + // draw sTimerDigits[3] (10s of seconds) to sTimerDigits[7] (10s of milliseconds) + for (j = 0; j < 5; j++) { + OVERLAY_DISP = func_8010D7D0( + OVERLAY_DISP, ((u8*)gCounterDigit0Tex + (8 * 16 * sTimerDigits[j + 3])), 8, 0x10, + ((void)0, gSaveContext.timerX[sTimerId]) + sTimerDigitsOffsetX[j], + ((void)0, gSaveContext.timerY[sTimerId]), sTimerDigitsWidth[j], 0xFA, 0x370, 0x370); + } + } + } else { + // draw sTimerDigits[3] (6s of minutes) to sTimerDigits[7] (10s of milliseconds) + for (j = 0; j < 8; j++) { + OVERLAY_DISP = func_8010D7D0( + OVERLAY_DISP, ((u8*)gCounterDigit0Tex + (8 * 16 * sTimerDigits[j])), 8, 0x10, + ((void)0, gSaveContext.timerX[sTimerId]) + sTimerDigitsOffsetX[j], + ((void)0, gSaveContext.timerY[sTimerId]), sTimerDigitsWidth[j], 0xFA, 0x370, 0x370); + } + } + } + } + + } else if (!sIsTimerPaused) { + sTimerPausedOsTime = osGetTime(); + sIsTimerPaused = true; + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void Interface_UpdateBottleTimers(PlayState* play) { + MessageContext* msgCtx = &play->msgCtx; + s16 i; + s16 j; + u64 osTime; + s32 pad[2]; + + // Not satisfying any of these conditions will pause the bottle timer + if ((play->pauseCtx.state == 0) && (play->pauseCtx.debugEditor == DEBUG_EDITOR_NONE) && + (play->gameOverCtx.state == GAMEOVER_INACTIVE) && + ((msgCtx->msgMode == 0) || ((msgCtx->currentTextId >= 0x100) && (msgCtx->currentTextId <= 0x200)) || + ((msgCtx->currentTextId >= 0x1BB2) && (msgCtx->currentTextId <= 0x1BB6))) && + (play->transitionTrigger == TRANS_TRIGGER_OFF) && (play->transitionMode == TRANS_MODE_OFF) && + !Play_InCsMode(play)) { + + // Account for osTime when the timer is paused + if (sIsBottleTimerPaused) { + osTime = osGetTime(); + + for (j = BOTTLE_FIRST; j < BOTTLE_MAX; j++) { + if (gSaveContext.bottleTimerStates[j] == BOTTLE_TIMER_STATE_COUNTING) { + gSaveContext.bottleTimerPausedOsTimes[j] += osTime - sBottleTimerPausedOsTime; + } + } + + sIsBottleTimerPaused = false; + } + + sTimerId = TIMER_ID_NONE; + + for (i = BOTTLE_FIRST; i < BOTTLE_MAX; i++) { + if (gSaveContext.bottleTimerStates[i] == BOTTLE_TIMER_STATE_COUNTING) { + osTime = osGetTime(); + + // Get the total amount of unpaused time since the start of the timer, centiseconds (1/100th sec). + osTime = OSTIME_TO_TIMER_ALT(osTime - ((void)0, gSaveContext.bottleTimerPausedOsTimes[i]) - + ((void)0, gSaveContext.bottleTimerStartOsTimes[i])); + + if (osTime == 0) { + // No unpaused time has passed since the start of the timer. + gSaveContext.bottleTimerCurTimes[i] = gSaveContext.bottleTimerTimeLimits[i] - osTime; + } else if (osTime <= gSaveContext.bottleTimerTimeLimits[i]) { + // Time has passed, but the time limit has not been exceeded + if (osTime >= gSaveContext.bottleTimerTimeLimits[i]) { + // The time is exactly at the time limit. No time remaining. + gSaveContext.bottleTimerCurTimes[i] = SECONDS_TO_TIMER(0); + } else { + // Update the time remaining + gSaveContext.bottleTimerCurTimes[i] = gSaveContext.bottleTimerTimeLimits[i] - osTime; + } + } else { + // Time has passed, and the time limit has been exceeded. + gSaveContext.bottleTimerCurTimes[i] = SECONDS_TO_TIMER(0); + + if (gSaveContext.save.inventory.items[i + SLOT_BOTTLE_1] == ITEM_HOT_SPRING_WATER) { + Inventory_UpdateItem(play, i + SLOT_BOTTLE_1, ITEM_SPRING_WATER); + Message_StartTextbox(play, 0xFA, NULL); + } + gSaveContext.bottleTimerStates[i] = BOTTLE_TIMER_STATE_OFF; + } + } + } + } else if (!sIsBottleTimerPaused) { + sBottleTimerPausedOsTime = osGetTime(); + sIsBottleTimerPaused = true; + } +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8011E730.s") @@ -2589,6 +3240,9 @@ s16 D_801BFD9C = 0; #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_801210E0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80121F94.s") +void Interface_Destroy(PlayState* play) { + Map_Destroy(play); + func_80174F9C(Interface_PostmanTimerCallback, NULL); +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80121FC4.s") diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index c8d1c802f3..3da84fe780 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -860,39 +860,40 @@ s32 func_80124278(Actor* actor, s32 actionParam) { } s32 func_801242B4(Player* player) { - return (player->stateFlags1 & PLAYER_STATE1_8000000) && player->currentBoots < PLAYER_BOOTS_ZORA_UNDERWATER; + return (player->stateFlags1 & PLAYER_STATE1_8000000) && (player->currentBoots < PLAYER_BOOTS_ZORA_UNDERWATER); } -s32 func_801242DC(PlayState* play) { +s32 Player_GetEnvTimerType(PlayState* play) { Player* player = GET_PLAYER(play); TextTriggerEntry* triggerEntry; - s32 envIndex; + s32 envTimerType; if (play->roomCtx.curRoom.unk2 == 3) { // Room is hot - envIndex = 0; - } else if ((player->transformation != PLAYER_FORM_ZORA) && (player->unk_AD8 > 80)) { - envIndex = 3; + envTimerType = PLAYER_ENV_TIMER_HOTROOM - 1; + } else if ((player->transformation != PLAYER_FORM_ZORA) && (player->underwaterTimer > 80)) { + envTimerType = PLAYER_ENV_TIMER_UNDERWATER_FREE - 1; } else if (player->stateFlags1 & PLAYER_STATE1_8000000) { if ((player->transformation == PLAYER_FORM_ZORA) && (player->currentBoots >= PLAYER_BOOTS_ZORA_UNDERWATER) && (player->actor.bgCheckFlags & 1)) { - envIndex = 1; + envTimerType = PLAYER_ENV_TIMER_UNDERWATER_FLOOR - 1; } else { - envIndex = 2; + envTimerType = PLAYER_ENV_TIMER_SWIMMING - 1; } } else { - return 0; + return PLAYER_ENV_TIMER_NONE; } // Trigger general textboxes under certain conditions, like "It's so hot in here!". Unused in MM - triggerEntry = &sEnvironmentTextTriggers[envIndex]; + triggerEntry = &sEnvironmentTextTriggers[envTimerType]; if (!Player_InCsMode(play)) { - if ((triggerEntry->flag) && !(gSaveContext.textTriggerFlags & triggerEntry->flag) && (envIndex == 0)) { + if ((triggerEntry->flag) && !(gSaveContext.textTriggerFlags & triggerEntry->flag) && + (envTimerType == (PLAYER_ENV_TIMER_HOTROOM - 1))) { Message_StartTextbox(play, triggerEntry->textId, NULL); gSaveContext.textTriggerFlags |= triggerEntry->flag; } } - return envIndex + 1; + return envTimerType + 1; } #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80124420.s") diff --git a/src/code/z_sram_NES.c b/src/code/z_sram_NES.c index ed7945ec37..5d018a9951 100644 --- a/src/code/z_sram_NES.c +++ b/src/code/z_sram_NES.c @@ -219,13 +219,13 @@ void Sram_ActivateOwl(u8 owlId) { void Sram_ClearHighscores(void) { gSaveContext.save.unk_EE8 = (gSaveContext.save.unk_EE8 & 0xFFFF) | 0x130000; gSaveContext.save.unk_EE8 = (gSaveContext.save.unk_EE8 & 0xFFFF0000) | 0xA; - gSaveContext.save.horseBackBalloonHighScore = 6000; // 60 seconds + gSaveContext.save.horseBackBalloonHighScore = SECONDS_TO_TIMER(60); SET_TOWN_SHOOTING_GALLERY_HIGH_SCORE(39); SET_SWAMP_SHOOTING_GALLERY_HIGH_SCORE(10); - gSaveContext.save.dekuPlaygroundHighScores[0] = 7500; // 75 seconds - gSaveContext.save.dekuPlaygroundHighScores[1] = 7500; // 75 seconds - gSaveContext.save.dekuPlaygroundHighScores[2] = 7600; // 76 seconds + gSaveContext.save.dekuPlaygroundHighScores[0] = SECONDS_TO_TIMER(75); + gSaveContext.save.dekuPlaygroundHighScores[1] = SECONDS_TO_TIMER(75); + gSaveContext.save.dekuPlaygroundHighScores[2] = SECONDS_TO_TIMER(76); } /** @@ -646,7 +646,7 @@ Inventory sSaveDefaultInventory = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // dungeonKeys { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - // defenceHearts + // defenseHearts 0, // strayFairies { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -792,7 +792,7 @@ Inventory sSaveDebugInventory = { { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }, // dungeonKeys { 8, 8, 8, 8, 8, 8, 8, 8, 8 }, - // defenceHearts + // defenseHearts 0, // strayFairies { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -894,13 +894,13 @@ void func_80144A94(SramContext* sramCtx) { gSaveContext.cycleSceneFlags[i].collectible = gSaveContext.save.permanentSceneFlags[i].collectible; } - for (i = 0; i < ARRAY_COUNT(gSaveContext.unk_3DD0); i++) { - gSaveContext.unk_3DD0[i] = 0; - gSaveContext.unk_3DE0[i] = 0; - gSaveContext.unk_3E18[i] = 0; - gSaveContext.unk_3E50[i] = 0; - gSaveContext.unk_3E88[i] = 0; - gSaveContext.unk_3EC0[i] = 0; + for (i = 0; i < TIMER_ID_MAX; i++) { + gSaveContext.timerStates[i] = TIMER_STATE_OFF; + gSaveContext.timerCurTimes[i] = SECONDS_TO_TIMER(0); + gSaveContext.timerTimeLimits[i] = SECONDS_TO_TIMER(0); + gSaveContext.timerStartOsTimes[i] = 0; + gSaveContext.timerStopTimes[i] = SECONDS_TO_TIMER(0); + gSaveContext.timerPausedOsTimes[i] = 0; } D_801BDAA0 = 1; @@ -969,13 +969,13 @@ void Sram_OpenSave(FileSelectState* fileSelect, SramContext* sramCtx) { gSaveContext.cycleSceneFlags[i].collectible = gSaveContext.save.permanentSceneFlags[i].collectible; } - for (i = 0; i < ARRAY_COUNT(gSaveContext.unk_3DD0); i++) { - gSaveContext.unk_3DD0[i] = 0; - gSaveContext.unk_3DE0[i] = 0; - gSaveContext.unk_3E18[i] = 0; - gSaveContext.unk_3E50[i] = 0; - gSaveContext.unk_3E88[i] = 0; - gSaveContext.unk_3EC0[i] = 0; + for (i = 0; i < TIMER_ID_MAX; i++) { + gSaveContext.timerStates[i] = TIMER_STATE_OFF; + gSaveContext.timerCurTimes[i] = SECONDS_TO_TIMER(0); + gSaveContext.timerTimeLimits[i] = SECONDS_TO_TIMER(0); + gSaveContext.timerStartOsTimes[i] = 0; + gSaveContext.timerStopTimes[i] = SECONDS_TO_TIMER(0); + gSaveContext.timerPausedOsTimes[i] = 0; } if (gSaveContext.save.isFirstCycle) { @@ -1598,7 +1598,7 @@ void func_80147068(SramContext* sramCtx) { sramCtx->status = 4; } } - } else if (((osGetTime() - sramCtx->unk_18) * 0x40) / 3000 / 10000 >= 200) { + } else if (OSTIME_TO_TIMER(osGetTime() - sramCtx->unk_18) >= SECONDS_TO_TIMER(2)) { sramCtx->status = 0; } } @@ -1635,7 +1635,7 @@ void func_80147198(SramContext* sramCtx) { sramCtx->status = 4; } } - } else if (((osGetTime() - sramCtx->unk_18) * 0x40) / 3000 / 10000 >= 200) { + } else if (OSTIME_TO_TIMER(osGetTime() - sramCtx->unk_18) >= SECONDS_TO_TIMER(2)) { sramCtx->status = 0; bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); gSaveContext.save.isOwlSave = false; diff --git a/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c b/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c index 120c9ea49c..f149a97d63 100644 --- a/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c +++ b/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c @@ -1045,11 +1045,11 @@ void DmStk_Init(Actor* thisx, PlayState* play) { if (gSaveContext.save.entrance == ENTRANCE(CLOCK_TOWER_ROOFTOP, 0)) { if (gSaveContext.sceneSetupIndex == 0) { - if (gSaveContext.unk_3DD0[3] == 0) { + if (gSaveContext.timerStates[TIMER_ID_MOON_CRASH] == TIMER_STATE_OFF) { // Starts a 5 minute (300 second) timer until the moon falls. - func_8010E9F0(3, 300); - XREG(80) = 200; - XREG(81) = 115; + Interface_StartTimer(TIMER_ID_MOON_CRASH, 300); + R_MOON_CRASH_TIMER_Y = 200; + R_MOON_CRASH_TIMER_X = 115; } if (gSaveContext.save.inventory.items[SLOT_OCARINA] == ITEM_NONE) { @@ -1062,12 +1062,12 @@ void DmStk_Init(Actor* thisx, PlayState* play) { } else if (gSaveContext.sceneSetupIndex == 3) { this->animIndex = SK_ANIM_FLOATING_ARMS_CROSSED; - if (gSaveContext.unk_3DD0[3] == 0) { + if (gSaveContext.timerStates[TIMER_ID_MOON_CRASH] == TIMER_STATE_OFF) { // This code is called when the Giants fail to stop the moon. // Starts a 1 minute (60 second) timer until the moon falls. - func_8010E9F0(3, 60); - XREG(80) = 200; - XREG(81) = 115; + Interface_StartTimer(TIMER_ID_MOON_CRASH, 60); + R_MOON_CRASH_TIMER_Y = 200; + R_MOON_CRASH_TIMER_X = 115; } this->actor.world.pos.y = 120.0f; diff --git a/src/overlays/actors/ovl_En_Az/z_en_az.c b/src/overlays/actors/ovl_En_Az/z_en_az.c index dcc6312bc8..4834256d6e 100644 --- a/src/overlays/actors/ovl_En_Az/z_en_az.c +++ b/src/overlays/actors/ovl_En_Az/z_en_az.c @@ -402,7 +402,7 @@ void EnAz_Destroy(Actor* thisx, PlayState* play2) { EnAz* this = THIS; if (gSaveContext.save.entrance != ENTRANCE(WATERFALL_RAPIDS, 1)) { - gSaveContext.unk_3DD0[4] = 5; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_STOP; } Collider_DestroyCylinder(play2, &this->collider); } @@ -1486,11 +1486,11 @@ void func_80A97D5C(EnAz* this, PlayState* play) { gSaveContext.minigameScore = (this->unk_374 & 2) ? 25 : 20; play->interfaceCtx.unk_280 = 1; if ((this->unk_2FA == 1) || (this->unk_2FA == 3)) { - func_8010E9F0(4, 120); + Interface_StartTimer(TIMER_ID_MINIGAME_2, 120); } else if (gSaveContext.save.weekEventReg[25] & 1) { - func_8010E9F0(4, 100); + Interface_StartTimer(TIMER_ID_MINIGAME_2, 100); } else { - func_8010E9F0(4, 110); + Interface_StartTimer(TIMER_ID_MINIGAME_2, 110); } this->actionFunc = func_80A97E48; } @@ -1547,7 +1547,7 @@ void func_80A97F9C(EnAz* this, PlayState* play) { } else { gSaveContext.save.weekEventReg[24] |= 1; } - gSaveContext.unk_3DD0[4] = 5; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_STOP; this->unk_374 &= ~0x10; play->nextEntrance = Entrance_CreateFromSpawn(2); gSaveContext.nextCutsceneIndex = 0; @@ -1557,8 +1557,8 @@ void func_80A97F9C(EnAz* this, PlayState* play) { this->actor.speedXZ = 0.0f; func_80A979DC(this, play); } else { - if (gSaveContext.unk_3DE0[4] == 0) { - gSaveContext.unk_3DD0[4] = 5; + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] == SECONDS_TO_TIMER(0)) { + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_STOP; this->unk_374 |= 0x4000; func_80A97A28(this, play); } diff --git a/src/overlays/actors/ovl_En_Dno/z_en_dno.c b/src/overlays/actors/ovl_En_Dno/z_en_dno.c index cb33ce4224..9b421dfd49 100644 --- a/src/overlays/actors/ovl_En_Dno/z_en_dno.c +++ b/src/overlays/actors/ovl_En_Dno/z_en_dno.c @@ -220,7 +220,7 @@ void EnDno_Init(Actor* thisx, PlayState* play) { } else { SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 14, &this->unk_32C); thisx->room = -1; - gSaveContext.unk_3DD0[1] = 5; + gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_STOP; this->lightNode = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo); this->unk_3B0 |= 1; this->actionFunc = func_80A72438; @@ -821,7 +821,7 @@ void func_80A73244(EnDno* this, PlayState* play) { this->unk_328 = 2; this->actor.speedXZ = 0.0f; Flags_UnsetSwitch(play, ENDNO_GET_3F80(&this->actor)); - gSaveContext.unk_3DD0[1] = 5; + gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_STOP; this->unk_44E = 0; this->actionFunc = func_80A732C8; } diff --git a/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/src/overlays/actors/ovl_En_Fu/z_en_fu.c index 66f57f323a..1704451ec3 100644 --- a/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -401,7 +401,8 @@ void func_80962340(EnFu* this, PlayState* play) { Message_StartTextbox(play, 0x287E, &this->actor); this->unk_552 = 0x287E; } - } else if ((gSaveContext.unk_3DE0[4] == 0) && (this->unk_552 != 0x2888)) { + } else if ((gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] == SECONDS_TO_TIMER(0)) && + (this->unk_552 != 0x2888)) { Message_StartTextbox(play, 0x2886, &this->actor); this->unk_552 = 0x2886; } else { @@ -644,7 +645,7 @@ void func_80962A10(EnFu* this, PlayState* play) { play_sound(NA_SE_SY_FOUND); player->stateFlags1 &= ~0x20; - func_8010E9F0(4, 60); + Interface_StartTimer(TIMER_ID_MINIGAME_2, 60); if (this->unk_546 == 1) { func_809616E0(this, play); } else { @@ -681,7 +682,7 @@ void func_80962BCC(EnFu* this, PlayState* play) { play_sound(NA_SE_SY_FOUND); player->stateFlags1 &= ~0x20; player->stateFlags3 |= 0x400000; - func_8010E9F0(4, 60); + Interface_StartTimer(TIMER_ID_MINIGAME_2, 60); if (this->unk_546 == 1) { func_809616E0(this, play); @@ -712,7 +713,7 @@ void func_80962D60(EnFu* this, PlayState* play) { play_sound(NA_SE_SY_FOUND); player->stateFlags1 &= ~0x20; player->stateFlags3 |= 0x400000; - func_8010E9F0(4, 60); + Interface_StartTimer(TIMER_ID_MINIGAME_2, 60); if (this->unk_546 == 1) { func_809616E0(this, play); @@ -760,11 +761,11 @@ void func_80962F4C(EnFu* this, PlayState* play) { break; } - if (gSaveContext.unk_3DE0[4] < 2000) { + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] < SECONDS_TO_TIMER(20)) { s16 val = D_80964B00[this->unk_542] + 200; Math_SmoothStepToS(&fuKaiten->rotationSpeed, val, 10, 5, 5); - } else if (gSaveContext.unk_3DE0[4] < 4000) { + } else if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] < SECONDS_TO_TIMER(40)) { s16 val = D_80964B00[this->unk_542] + 100; Math_SmoothStepToS(&fuKaiten->rotationSpeed, val, 10, 5, 5); @@ -776,12 +777,12 @@ void func_80962F4C(EnFu* this, PlayState* play) { if ((!DynaPolyActor_IsInRidingRotatingState((DynaPolyActor*)this->actor.child) && (player->actor.bgCheckFlags & 1)) || - (gSaveContext.unk_3DE0[4] < 1) || (this->unk_548 == this->unk_54C)) { + (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] <= SECONDS_TO_TIMER(0)) || (this->unk_548 == this->unk_54C)) { player->stateFlags3 &= ~0x400000; func_80961E88(play); player->stateFlags1 |= 0x20; if (this->unk_548 < this->unk_54C) { - if (gSaveContext.unk_3DE0[4] == 0) { + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] == SECONDS_TO_TIMER(0)) { Message_StartTextbox(play, 0x2885, &this->actor); this->unk_552 = 0x2885; } else { @@ -789,15 +790,15 @@ void func_80962F4C(EnFu* this, PlayState* play) { this->unk_552 = 0x2888; } func_801A2C20(); - gSaveContext.unk_3DE0[4] = 0; - gSaveContext.unk_3DD0[4] = 5; + gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] = SECONDS_TO_TIMER(0); + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_STOP; this->unk_548 = 0; func_809632D0(this); } else { this->unk_548 = 0; func_801A2C20(); - gSaveContext.unk_3DE0[4] = 0; - gSaveContext.unk_3DD0[4] = 5; + gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] = SECONDS_TO_TIMER(0); + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_STOP; func_801A3098(NA_BGM_GET_ITEM | 0x900); func_8011B4E0(play, 1); this->unk_54A = 3; diff --git a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c index a82434c21d..45d6661eb6 100644 --- a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c +++ b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c @@ -459,7 +459,7 @@ void func_80B10240(EnGb2* this, PlayState* play) { D_80B119B0[this->unk_280].unk_04.y, D_80B119B0[this->unk_280].unk_04.z, 0, 0, 0, this->unk_27E); if (this->unk_280 == 0) { - func_8010E9F0(1, 180); + Interface_StartTimer(TIMER_ID_MINIGAME_1, 180); } this->actionFunc = func_80B10344; } else { @@ -487,7 +487,7 @@ void func_80B10344(EnGb2* this, PlayState* play) { if (this->unk_26C & 0x200) { if (this->unk_280 == 3) { this->unk_26C &= ~0x200; - gSaveContext.unk_3DD0[1] = 5; + gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_STOP; func_800FE498(); gSaveContext.eventInf[4] |= 0x40; func_80B0FE7C(play); @@ -506,7 +506,7 @@ void func_80B10344(EnGb2* this, PlayState* play) { } if (gSaveContext.save.playerData.health < 49) { - gSaveContext.unk_3DD0[1] = 5; + gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_STOP; gSaveContext.eventInf[4] |= 0x40; gSaveContext.eventInf[4] |= 0x20; @@ -519,8 +519,8 @@ void func_80B10344(EnGb2* this, PlayState* play) { } func_80B0FE7C(play); - } else if (gSaveContext.unk_3DE0[1] == 0) { - gSaveContext.unk_3DD0[1] = 5; + } else if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1] == SECONDS_TO_TIMER(0)) { + gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_STOP; gSaveContext.eventInf[4] |= 0x40; gSaveContext.eventInf[4] |= 0x10; diff --git a/src/overlays/actors/ovl_En_Gk/z_en_gk.c b/src/overlays/actors/ovl_En_Gk/z_en_gk.c index 4c74a779cc..9f3f424d5e 100644 --- a/src/overlays/actors/ovl_En_Gk/z_en_gk.c +++ b/src/overlays/actors/ovl_En_Gk/z_en_gk.c @@ -645,7 +645,7 @@ void func_80B51760(EnGk* this, PlayState* play) { this->unk_1E4 |= 2; } } else if (((this->actor.xzDistToPlayer < 100.0f) || this->actor.isTargeted) && - (gSaveContext.save.entrance != 0xD010)) { + (gSaveContext.save.entrance != ENTRANCE(GORON_RACETRACK, 1))) { func_800B863C(&this->actor, play); } diff --git a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c index 1d2d0352c5..99d4eca14f 100644 --- a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c +++ b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c @@ -121,7 +121,7 @@ s32 func_808F8CCC(EnHorseGameCheck* this, PlayState* play2) { return false; } - func_8010E9F0(4, 0); + Interface_StartTimer(TIMER_ID_MINIGAME_2, 0); play->interfaceCtx.unk_280 = 1; this->horse1 = (EnHorse*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, -1149.0f, -106.0f, 470.0f, 0, 0x7FFF, 0, @@ -145,7 +145,7 @@ s32 func_808F8CCC(EnHorseGameCheck* this, PlayState* play2) { } s32 func_808F8E94(EnHorseGameCheck* this, PlayState* play) { - gSaveContext.unk_3DD0[4] = 0; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_OFF; return true; } @@ -247,11 +247,11 @@ s32 func_808F8FAC(EnHorseGameCheck* this, PlayState* play) { return true; } - if (gSaveContext.unk_3DE0[4] >= 0x4650) { + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] >= SECONDS_TO_TIMER(180)) { Audio_QueueSeqCmd(0x8041); play_sound(NA_SE_SY_START_SHOT); this->unk_164 |= 0x40000; - gSaveContext.unk_3DD0[4] = 6; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; SET_RACE_FLAGS(RACE_FLAG_4); this->unk_174 = 60; } @@ -284,7 +284,7 @@ s32 func_808F8FAC(EnHorseGameCheck* this, PlayState* play) { Audio_QueueSeqCmd(0x8041); play_sound(NA_SE_SY_START_SHOT); this->unk_164 |= 0x40000; - gSaveContext.unk_3DD0[4] = 6; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; SET_RACE_FLAGS(RACE_FLAG_3); this->unk_174 = 60; } @@ -317,7 +317,7 @@ s32 func_808F8FAC(EnHorseGameCheck* this, PlayState* play) { Audio_QueueSeqCmd(0x8041); play_sound(NA_SE_SY_START_SHOT); this->unk_164 |= 0x02000000; - gSaveContext.unk_3DD0[4] = 6; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; SET_RACE_FLAGS(RACE_FLAG_3); this->unk_174 = 60; } @@ -346,7 +346,7 @@ s32 func_808F8FAC(EnHorseGameCheck* this, PlayState* play) { Audio_QueueSeqCmd(0x8041); play_sound(NA_SE_SY_START_SHOT); this->unk_164 |= 0x800; - gSaveContext.unk_3DD0[4] = 6; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; SET_RACE_FLAGS(RACE_FLAG_2); this->unk_174 = 60; } diff --git a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c index c351f83c69..2ac1672352 100644 --- a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c +++ b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c @@ -4,7 +4,6 @@ * Description: Ranch nighttime actors */ -#include "prevent_bss_reordering.h" #include "z_en_invadepoh.h" #include "overlays/actors/ovl_En_Door/z_en_door.h" #include "objects/gameplay_keep/gameplay_keep.h" diff --git a/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c b/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c index 8957cfc211..f88e7c074c 100644 --- a/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c +++ b/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c @@ -155,7 +155,7 @@ void func_80C13BB8(EnJgameTsn* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { if (this->actor.flags & ACTOR_FLAG_10000) { this->actor.flags &= ~ACTOR_FLAG_10000; - if (gSaveContext.unk_3DE0[4] > 0) { + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] > SECONDS_TO_TIMER(0)) { Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimationInfo, 1); Message_StartTextbox(play, 0x10A2, &this->actor); this->unk_300 = 0x10A2; @@ -287,7 +287,7 @@ void func_80C1410C(EnJgameTsn* this, PlayState* play) { play->interfaceCtx.unk_280 = 1; func_80112AFC(play); gSaveContext.save.weekEventReg[90] |= 0x20; - func_8010E9F0(4, 0x78); + Interface_StartTimer(TIMER_ID_MINIGAME_2, 120); this->actionFunc = func_80C1418C; } @@ -352,7 +352,7 @@ void func_80C14230(EnJgameTsn* this, PlayState* play) { func_80C14030(this); } - if (gSaveContext.unk_3DE0[4] == 0) { + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] == SECONDS_TO_TIMER(0)) { Message_StartTextbox(play, 0x10A1, &this->actor); this->unk_300 = 0x10A1; player->stateFlags1 |= 0x20; @@ -479,7 +479,7 @@ void func_80C147B4(EnJgameTsn* this, PlayState* play) { case 0x10A1: func_801477B4(play); gSaveContext.minigameState = 3; - gSaveContext.unk_3DD0[4] = 5; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_STOP; gSaveContext.save.weekEventReg[90] &= (u8)~0x20; func_80C144E4(this); break; diff --git a/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c b/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c index a737c5008c..9d0c412953 100644 --- a/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c +++ b/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c @@ -4,7 +4,6 @@ * Description: Grass / Bush */ -#include "prevent_bss_reordering.h" #include "z_en_kusa.h" #include "objects/object_kusa/object_kusa.h" #include "objects/gameplay_keep/gameplay_keep.h" diff --git a/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c b/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c index a10b265143..47f0997eb2 100644 --- a/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c +++ b/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c @@ -674,7 +674,7 @@ void EnMa4_HorsebackGameCheckPlayerInteractions(EnMa4* this, PlayState* play) { // "You're feeling confident" Message_StartTextbox(play, 0x336E, &this->actor); this->actionFunc = EnMa4_HorsebackGameTalking; - } else if ((gSaveContext.unk_3DE0[4] < 115 * 100)) { // timer < 115 seconds + } else if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] < SECONDS_TO_TIMER(115)) { func_800B8614(&this->actor, play, 100.0f); } } @@ -689,7 +689,7 @@ void EnMa4_InitHorsebackGame(EnMa4* this, PlayState* play) { Player* player = GET_PLAYER(play); play->interfaceCtx.unk_280 = 1; - func_8010E9F0(4, 0); + Interface_StartTimer(TIMER_ID_MINIGAME_2, 0); gSaveContext.save.weekEventReg[8] |= 1; func_80112AFC(play); player->stateFlags1 |= 0x20; @@ -717,9 +717,9 @@ void EnMa4_HorsebackGameWait(EnMa4* this, PlayState* play) { play->interfaceCtx.unk_25C = 1; } - if ((gSaveContext.unk_3DE0[4] >= 2 * 60 * 100) // timer >= 2 minutes - || (this->poppedBalloonCounter == 10)) { - gSaveContext.unk_3DD0[4] = 6; + if ((gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] >= SECONDS_TO_TIMER(120)) || + (this->poppedBalloonCounter == 10)) { + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; EnMa4_SetupHorsebackGameEnd(this, play); D_80AC0258 = 0; } @@ -898,13 +898,13 @@ void EnMa4_StartDialogue(EnMa4* this, PlayState* play) { gSaveContext.save.weekEventReg[21] |= 0x40; } } else if (this->state == MA4_STATE_AFTERHORSEBACKGAME) { - if (gSaveContext.unk_3DE0[4] >= 2 * 60 * 100) { + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] >= SECONDS_TO_TIMER(120)) { // "Too bad Grasshopper" EnMa4_SetFaceExpression(this, 0, 0); Message_StartTextbox(play, 0x336D, &this->actor); this->textId = 0x336D; } else { - time = gSaveContext.unk_3DE0[4]; + time = gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2]; if ((s32)time < (s32)gSaveContext.save.horseBackBalloonHighScore) { // [Score] New record! gSaveContext.save.horseBackBalloonHighScore = time; @@ -943,12 +943,12 @@ void EnMa4_StartDialogue(EnMa4* this, PlayState* play) { Message_StartTextbox(play, 0x3354, &this->actor); this->textId = 0x3354; } else if (this->state == MA4_STATE_AFTERHORSEBACKGAME) { - if (gSaveContext.unk_3DE0[4] >= 2 * 60 * 100) { + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] >= SECONDS_TO_TIMER(120)) { // "Try again?" Message_StartTextbox(play, 0x3356, &this->actor); this->textId = 0x3356; } else { - time = gSaveContext.unk_3DE0[4]; + time = gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2]; if ((s32)time < (s32)gSaveContext.save.horseBackBalloonHighScore) { gSaveContext.save.horseBackBalloonHighScore = time; EnMa4_SetFaceExpression(this, 0, 3); @@ -970,12 +970,12 @@ void EnMa4_StartDialogue(EnMa4* this, PlayState* play) { Message_StartTextbox(play, 0x3358, &this->actor); this->textId = 0x3358; } else if (this->state == MA4_STATE_AFTERHORSEBACKGAME) { - if (gSaveContext.unk_3DE0[4] >= 2 * 60 * 100) { + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2] >= SECONDS_TO_TIMER(120)) { // "Try again?" Message_StartTextbox(play, 0x3356, &this->actor); this->textId = 0x3356; } else { - time = gSaveContext.unk_3DE0[4]; + time = gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_2]; if ((s32)time < (s32)gSaveContext.save.horseBackBalloonHighScore) { // New record gSaveContext.save.horseBackBalloonHighScore = time; diff --git a/src/overlays/actors/ovl_En_Mm3/z_en_mm3.c b/src/overlays/actors/ovl_En_Mm3/z_en_mm3.c index 0f73088263..6909183f38 100644 --- a/src/overlays/actors/ovl_En_Mm3/z_en_mm3.c +++ b/src/overlays/actors/ovl_En_Mm3/z_en_mm3.c @@ -249,13 +249,14 @@ void func_80A6F5E4(EnMm3* this, PlayState* play) { break; case 0x2791: - if (gSaveContext.unk_3DE0[0] == 1000) { + if (gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] == SECONDS_TO_TIMER(10)) { Message_StartTextbox(play, 0x2792, &this->actor); this->unk_2B4 = 0x2792; - } else if ((gSaveContext.unk_3DE0[0] >= 1500)) { + } else if ((gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] >= SECONDS_TO_TIMER(15))) { Message_StartTextbox(play, 0x2797, &this->actor); this->unk_2B4 = 0x2797; - } else if ((gSaveContext.unk_3DE0[0] <= 1050) && (gSaveContext.unk_3DE0[0] >= 950)) { + } else if ((gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] <= SECONDS_TO_TIMER_PRECISE(10, 50)) && + (gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] >= SECONDS_TO_TIMER_PRECISE(9, 50))) { Message_StartTextbox(play, 0x2795, &this->actor); this->unk_2B4 = 0x2795; } else { @@ -301,7 +302,7 @@ void func_80A6F5E4(EnMm3* this, PlayState* play) { } else if ((this->unk_2AC > 0) && (this->unk_2B4 == 0x2791)) { this->unk_2AC--; if (this->unk_2AC == 0) { - if (gSaveContext.unk_3DE0[0] == 1000) { + if (gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] == SECONDS_TO_TIMER(10)) { func_801A3098(0x922); } else { play_sound(NA_SE_SY_ERROR); @@ -342,9 +343,9 @@ void func_80A6F9DC(EnMm3* this, PlayState* play) { player->stateFlags1 |= 0x20; if (Player_GetMask(play) == PLAYER_MASK_BUNNY) { - func_8010EA9C(0, 2); + Interface_StartPostmanTimer(0, POSTMAN_MINIGAME_BUNNY_HOOD_ON); } else { - func_8010EA9C(0, 0); + Interface_StartPostmanTimer(0, POSTMAN_MINIGAME_BUNNY_HOOD_OFF); } func_801477B4(play); play_sound(NA_SE_SY_START_SHOT); @@ -381,18 +382,20 @@ void func_80A6FBA0(EnMm3* this) { void func_80A6FBFC(EnMm3* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (gSaveContext.unk_3DD0[0] == 0x10) { + if (gSaveContext.timerStates[TIMER_ID_POSTMAN] == TIMER_STATE_POSTMAN_END) { player->stateFlags1 &= ~0x20; this->actor.flags |= ACTOR_FLAG_10000; - if (gSaveContext.unk_3DE0[0] > 1500) { - gSaveContext.unk_3DE0[0] = 1500; - } else if ((((void)0, gSaveContext.unk_3DE0[0]) >= (OSTime)(995 - XREG(16))) && - (((void)0, gSaveContext.unk_3DE0[0]) <= (OSTime)(1005 + XREG(17)))) { - gSaveContext.unk_3DE0[0] = 1000; + if (gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] > SECONDS_TO_TIMER(15)) { + gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] = SECONDS_TO_TIMER(15); + } else if ((((void)0, gSaveContext.timerCurTimes[TIMER_ID_POSTMAN]) >= + (OSTime)(SECONDS_TO_TIMER_PRECISE(10, -5) - XREG(16))) && + (((void)0, gSaveContext.timerCurTimes[TIMER_ID_POSTMAN]) <= + (OSTime)(SECONDS_TO_TIMER_PRECISE(10, 5) + XREG(17)))) { + gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] = SECONDS_TO_TIMER(10); } - } else if (gSaveContext.unk_3DE0[0] > 1500) { - gSaveContext.unk_3DD0[0] = 15; - gSaveContext.unk_3DC8 = osGetTime(); + } else if (gSaveContext.timerCurTimes[TIMER_ID_POSTMAN] > SECONDS_TO_TIMER(15)) { + gSaveContext.timerStates[TIMER_ID_POSTMAN] = TIMER_STATE_POSTMAN_STOP; + gSaveContext.postmanTimerStopOsTime = osGetTime(); } if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { @@ -401,7 +404,7 @@ void func_80A6FBFC(EnMm3* this, PlayState* play) { Message_StartTextbox(play, 0x2791, &this->actor); this->unk_2B4 = 0x2791; this->unk_2AC = 7; - gSaveContext.unk_3DD0[0] = 0; + gSaveContext.timerStates[TIMER_ID_POSTMAN] = TIMER_STATE_OFF; this->actor.flags &= ~ACTOR_FLAG_10000; play_sound(NA_SE_SY_START_SHOT); func_80A6F9C8(this); diff --git a/src/overlays/actors/ovl_En_Mm3/z_en_mm3.h b/src/overlays/actors/ovl_En_Mm3/z_en_mm3.h index b6f653935e..1cc1946f54 100644 --- a/src/overlays/actors/ovl_En_Mm3/z_en_mm3.h +++ b/src/overlays/actors/ovl_En_Mm3/z_en_mm3.h @@ -7,6 +7,11 @@ struct EnMm3; typedef void (*EnMm3ActionFunc)(struct EnMm3*, PlayState*); +typedef enum { + /* 0 */ POSTMAN_MINIGAME_BUNNY_HOOD_OFF, + /* 2 */ POSTMAN_MINIGAME_BUNNY_HOOD_ON = 2 +} PostmanMinigameBunnyHoodState; + typedef struct EnMm3 { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; diff --git a/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.c b/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.c index eb6d4ab42d..ed67013d8a 100644 --- a/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.c +++ b/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.c @@ -253,7 +253,7 @@ s32 EnMttag_ExitRace(PlayState* play, s32 transitionType, s32 nextTransitionType * Displays the text which says that the player has made a false start. */ void EnMttag_ShowFalseStartMessage(EnMttag* this, PlayState* play) { - gSaveContext.unk_3DD0[4] = 0; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_OFF; Message_StartTextbox(play, 0xE95, NULL); // An entrant made a false start func_800B7298(play, &this->actor, 7); Audio_QueueSeqCmd(0x101400FF); @@ -314,7 +314,7 @@ void EnMttag_RaceStart(EnMttag* this, PlayState* play) { gSaveContext.eventInf[1] |= 8; } else { if (DECR(this->timer) == 60) { - func_8010E9F0(4, 0); + Interface_StartTimer(TIMER_ID_MINIGAME_2, 0); play->interfaceCtx.unk_280 = 1; Audio_QueueSeqCmd(NA_BGM_GORON_RACE | 0x8000); play->envCtx.unk_E4 = 0xFE; @@ -359,14 +359,14 @@ void EnMttag_Race(EnMttag* this, PlayState* play) { s32 playerCheatStatus; if (EnMttag_IsInFinishLine(playerPos)) { - gSaveContext.unk_3DD0[4] = 6; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; play_sound(NA_SE_SY_START_SHOT); Audio_QueueSeqCmd(NA_BGM_GORON_GOAL | 0x8000); this->timer = 55; gSaveContext.eventInf[1] |= 2; this->actionFunc = EnMttag_RaceFinish; } else if (EnMttag_IsAnyRaceGoronOverFinishLine(this)) { - gSaveContext.unk_3DD0[4] = 6; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_6; play_sound(NA_SE_SY_START_SHOT); Audio_QueueSeqCmd(NA_BGM_GORON_GOAL | 0x8000); this->timer = 55; @@ -456,7 +456,7 @@ void EnMttag_HandleCantWinChoice(EnMttag* this, PlayState* play) { if (play->msgCtx.choiceIndex != 0) { // Exit the race func_8019F230(); - gSaveContext.unk_3DD0[4] = 0; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_OFF; EnMttag_ExitRace(play, TRANS_TYPE_02, TRANS_TYPE_02); gSaveContext.eventInf[1] &= (u8)~8; gSaveContext.eventInf[1] |= 4; @@ -502,12 +502,14 @@ void EnMttag_Init(Actor* thisx, PlayState* play) { void EnMttag_Destroy(Actor* thisx, PlayState* play) { EnMttag* this = THIS; - if (gSaveContext.unk_3DD0[4] != 6) { - gSaveContext.unk_3DD0[4] = 5; + + if (gSaveContext.timerStates[TIMER_ID_MINIGAME_2] != TIMER_STATE_6) { + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_STOP; } } void EnMttag_Update(Actor* thisx, PlayState* play) { EnMttag* this = THIS; + this->actionFunc(this, play); } diff --git a/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c b/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c index 51a941b284..1d504dc621 100644 --- a/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c +++ b/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c @@ -271,7 +271,8 @@ void func_80A2C2E0(EnSyatekiDekunuts* this, PlayState* play) { void func_80A2C33C(EnSyatekiDekunuts* this, PlayState* play) { EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; - if ((gSaveContext.unk_3DE0[1] <= 0) || (syatekiMan->shootingGameState != SG_GAME_STATE_RUNNING)) { + if ((gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1] <= SECONDS_TO_TIMER(0)) || + (syatekiMan->shootingGameState != SG_GAME_STATE_RUNNING)) { func_80A2C3AC(this); } diff --git a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c index 7852aa24b8..5433aeec7a 100644 --- a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c +++ b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c @@ -154,7 +154,7 @@ static s32 sSwampTargetActorListLengths[] = { }; static Vec3f sSwampPlayerPos = { 0.0f, 10.0f, 140.0f }; -static Vec3f sTownFierceDietyPlayerPos = { -20.0f, 20.0f, 198.0f }; +static Vec3f sTownFierceDeityPlayerPos = { -20.0f, 20.0f, 198.0f }; static Vec3f sTownPlayerPos = { -20.0f, 40.0f, 175.0f }; /** @@ -1012,7 +1012,7 @@ void EnSyatekiMan_Swamp_StartGame(EnSyatekiMan* this, PlayState* play) { this->guayHitCounter = 0; this->currentWave = 0; this->perGameVar2.bonusDekuScrubHitCounter = 0; - func_8010E9F0(1, 100); + Interface_StartTimer(TIMER_ID_MINIGAME_1, 100); this->actor.draw = NULL; this->actionFunc = EnSyatekiMan_Swamp_RunGame; } @@ -1061,9 +1061,9 @@ void EnSyatekiMan_Swamp_RunGame(EnSyatekiMan* this, PlayState* play) { this->perGameVar1.guaySpawnTimer++; - if (gSaveContext.unk_3DE0[1] == 0) { - gSaveContext.unk_3DE0[1] = 0; - gSaveContext.unk_3DD0[1] = 5; + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1] == SECONDS_TO_TIMER(0)) { + gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1] = SECONDS_TO_TIMER(0); + gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_STOP; this->actor.draw = EnSyatekiMan_Draw; this->flagsIndex = 0; this->currentWave = 0; @@ -1082,10 +1082,10 @@ void EnSyatekiMan_Swamp_RunGame(EnSyatekiMan* this, PlayState* play) { this->shootingGameState = SG_GAME_STATE_GIVING_BONUS; if (this->score == 2120) { func_8011B4E0(play, 2); - gSaveContext.unk_3DD0[1] = 6; + gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_6; this->actionFunc = EnSyatekiMan_Swamp_AddBonusPoints; } else { - gSaveContext.unk_3DD0[1] = 5; + gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_STOP; this->actionFunc = EnSyatekiMan_Swamp_EndGame; } } @@ -1148,15 +1148,15 @@ void EnSyatekiMan_Swamp_AddBonusPoints(EnSyatekiMan* this, PlayState* play) { player->stateFlags1 |= 0x20; if (play->interfaceCtx.unk_286 == 0) { - if (gSaveContext.unk_3DE0[1] == 0) { - gSaveContext.unk_3DE0[1] = 0; - gSaveContext.unk_3DD0[1] = 5; + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1] == SECONDS_TO_TIMER(0)) { + gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1] = SECONDS_TO_TIMER(0); + gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_STOP; this->flagsIndex = 0; this->currentWave = 0; this->actionFunc = EnSyatekiMan_Swamp_EndGame; sBonusTimer = 0; } else if (sBonusTimer > 10) { - gSaveContext.unk_3E88[1] += 100; + gSaveContext.timerStopTimes[TIMER_ID_MINIGAME_1] += SECONDS_TO_TIMER(1); play->interfaceCtx.unk_25C += 10; this->score += 10; Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); @@ -1171,7 +1171,7 @@ void EnSyatekiMan_Town_MovePlayerAndSayHighScore(EnSyatekiMan* this, PlayState* Vec3f targetPlayerPos; if (gSaveContext.save.playerForm == PLAYER_FORM_FIERCE_DEITY) { - targetPlayerPos = sTownFierceDietyPlayerPos; + targetPlayerPos = sTownFierceDeityPlayerPos; } else { targetPlayerPos = sTownPlayerPos; } @@ -1198,7 +1198,7 @@ void EnSyatekiMan_Town_StartGame(EnSyatekiMan* this, PlayState* play) { if (sGameStartTimer == 30) { if (player->transformation == PLAYER_FORM_FIERCE_DEITY) { - player->actor.world.pos = sTownFierceDietyPlayerPos; + player->actor.world.pos = sTownFierceDeityPlayerPos; } else { player->actor.world.pos = sTownPlayerPos; } @@ -1220,7 +1220,7 @@ void EnSyatekiMan_Town_StartGame(EnSyatekiMan* this, PlayState* play) { this->perGameVar1.octorokState = SG_OCTO_STATE_INITIAL; this->perGameVar2.octorokHitType = SG_OCTO_HIT_TYPE_NONE; sGameStartTimer = 30; - func_8010E9F0(1, 75); + Interface_StartTimer(TIMER_ID_MINIGAME_1, 75); this->actor.draw = NULL; this->actionFunc = EnSyatekiMan_Town_RunGame; } @@ -1292,7 +1292,8 @@ static const s32 sOctorokFlagsPerWave[] = { void EnSyatekiMan_Town_RunGame(EnSyatekiMan* this, PlayState* play) { static s32 sModFromLosingTime = 0; Player* player = GET_PLAYER(play); - s32 timer = (((void)0, gSaveContext.unk_3DE0[1]) * 0.1f) + 1.0f; // unit is tenths of a second + s32 timer = + (((void)0, gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1]) * 0.1f) + 1.0f; // unit is tenths of a second if (timer <= 750) { s32 waveTimer; // unit is hundredths of a second @@ -1302,9 +1303,10 @@ void EnSyatekiMan_Town_RunGame(EnSyatekiMan* this, PlayState* play) { // begin hiding. This code will ultimately correct waveTimer such that its value is not affected by // hitting Blue Octoroks. if (sModFromLosingTime == 0) { - waveTimer = ((void)0, gSaveContext.unk_3DE0[1]) % 500; + waveTimer = ((void)0, gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1]) % SECONDS_TO_TIMER(5); } else { - waveTimer = (((void)0, gSaveContext.unk_3DE0[1]) + 250) % 500; + waveTimer = (((void)0, gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1]) + SECONDS_TO_TIMER_PRECISE(2, 50)) % + SECONDS_TO_TIMER(5); } // Octoroks begin hiding four seconds after a wave begins. @@ -1314,7 +1316,7 @@ void EnSyatekiMan_Town_RunGame(EnSyatekiMan* this, PlayState* play) { if (this->perGameVar2.octorokHitType != SG_OCTO_HIT_TYPE_NONE) { if (this->perGameVar2.octorokHitType == SG_OCTO_HIT_TYPE_BLUE) { - gSaveContext.unk_3E18[1] -= 250; + gSaveContext.timerTimeLimits[TIMER_ID_MINIGAME_1] -= SECONDS_TO_TIMER_PRECISE(2, 50); sModFromLosingTime = (sModFromLosingTime + 25) % 50; } @@ -1336,11 +1338,11 @@ void EnSyatekiMan_Town_RunGame(EnSyatekiMan* this, PlayState* play) { } } - if (gSaveContext.unk_3DE0[1] == 0) { + if (gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1] == SECONDS_TO_TIMER(0)) { this->flagsIndex = 0; this->perGameVar1.octorokState = SG_OCTO_STATE_HIDING; - gSaveContext.unk_3DE0[1] = 0; - gSaveContext.unk_3DD0[1] = 5; + gSaveContext.timerCurTimes[TIMER_ID_MINIGAME_1] = SECONDS_TO_TIMER(0); + gSaveContext.timerStates[TIMER_ID_MINIGAME_1] = TIMER_STATE_STOP; player->stateFlags1 |= 0x20; sModFromLosingTime = 0; this->actor.draw = EnSyatekiMan_Draw; diff --git a/src/overlays/actors/ovl_En_Test4/z_en_test4.c b/src/overlays/actors/ovl_En_Test4/z_en_test4.c index 88547581f3..f33a1f693a 100644 --- a/src/overlays/actors/ovl_En_Test4/z_en_test4.c +++ b/src/overlays/actors/ovl_En_Test4/z_en_test4.c @@ -388,7 +388,7 @@ void func_80A42AB8(EnTest4* this, PlayState* play) { func_80A41FA4(this, play); } else if (temp_a0 == CLOCK_TIME(6, 0)) { if (CURRENT_DAY == 3) { - func_8011C808(play); + Interface_StartMoonCrash(play); Actor_MarkForDeath(&this->actor); gSaveContext.eventInf[1] |= 0x80; } else if (((sCutscenes[this->unk_144] < 0) || (play->actorCtx.flags & ACTORCTX_FLAG_1)) && diff --git a/src/overlays/actors/ovl_En_Time_Tag/z_en_time_tag.c b/src/overlays/actors/ovl_En_Time_Tag/z_en_time_tag.c index b6dea09f33..0a013410be 100644 --- a/src/overlays/actors/ovl_En_Time_Tag/z_en_time_tag.c +++ b/src/overlays/actors/ovl_En_Time_Tag/z_en_time_tag.c @@ -90,7 +90,7 @@ void func_80AC9FE4(EnTimeTag* this, PlayState* play) { if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); this->actionFunc = func_80AC9FD4; - gSaveContext.unk_3DD0[3] = 0; + gSaveContext.timerStates[TIMER_ID_MOON_CRASH] = TIMER_STATE_OFF; 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)) { gSaveContext.save.weekEventReg[25] |= 2; @@ -107,7 +107,7 @@ void func_80ACA0A8(EnTimeTag* this, PlayState* play) { if (this->actor.cutscene != -1) { this->actionFunc = func_80AC9FE4; ActorCutscene_SetIntentToPlay(this2->actor.cutscene); - gSaveContext.unk_3DD0[3] = 0; + gSaveContext.timerStates[TIMER_ID_MOON_CRASH] = TIMER_STATE_OFF; } play->msgCtx.ocarinaMode = 4; } diff --git a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c index b39187c756..0ce2f38a16 100644 --- a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c +++ b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c @@ -45,14 +45,14 @@ void ObjRoomtimer_Init(Actor* thisx, PlayState* play) { void ObjRoomtimer_Destroy(Actor* thisx, PlayState* play) { ObjRoomtimer* this = THIS; - if (this->actor.params != 0x1FF && gSaveContext.unk_3DD0[4] > 0) { - gSaveContext.unk_3DD0[4] = 5; + if ((this->actor.params != 0x1FF) && (gSaveContext.timerStates[TIMER_ID_MINIGAME_2] >= TIMER_STATE_START)) { + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_STOP; } } void func_80973CD8(ObjRoomtimer* this, PlayState* play) { if (this->actor.params != 0x1FF) { - func_8010E9F0(4, this->actor.params); + Interface_StartTimer(TIMER_ID_MINIGAME_2, this->actor.params); } func_800BC154(play, &play->actorCtx, &this->actor, ACTORCAT_PROP); @@ -62,11 +62,11 @@ void func_80973CD8(ObjRoomtimer* this, PlayState* play) { void func_80973D3C(ObjRoomtimer* this, PlayState* play) { if (Flags_GetClearTemp(play, this->actor.room)) { if (this->actor.params != 0x1FF) { - gSaveContext.unk_3DD0[4] = 5; + gSaveContext.timerStates[TIMER_ID_MINIGAME_2] = TIMER_STATE_STOP; } ActorCutscene_SetIntentToPlay(this->actor.cutscene); this->actionFunc = func_80973DE0; - } else if (this->actor.params != 0x1FF && gSaveContext.unk_3DD0[4] == 0) { + } else if ((this->actor.params != 0x1FF) && (gSaveContext.timerStates[TIMER_ID_MINIGAME_2] == TIMER_STATE_OFF)) { play_sound(NA_SE_OC_ABYSS); func_80169EFC(&play->state); Actor_MarkForDeath(&this->actor); diff --git a/src/overlays/gamestates/ovl_select/z_select.c b/src/overlays/gamestates/ovl_select/z_select.c index b4cfe295c7..5d418c0fce 100644 --- a/src/overlays/gamestates/ovl_select/z_select.c +++ b/src/overlays/gamestates/ovl_select/z_select.c @@ -507,13 +507,13 @@ void MapSelect_UpdateMenu(MapSelectState* this) { if (this->verticalInputAccumulator == 0) { if (CHECK_BTN_ALL(controller1->press.button, BTN_A) || CHECK_BTN_ALL(controller1->press.button, BTN_START)) { - for (i = 0; i < ARRAY_COUNT(gSaveContext.unk_3EC0); i++) { - gSaveContext.unk_3DD0[i] = 0; - gSaveContext.unk_3DE0[i] = 0; - gSaveContext.unk_3E18[i] = 0; - gSaveContext.unk_3E50[i] = 0; - gSaveContext.unk_3E88[i] = 0; - gSaveContext.unk_3EC0[i] = 0; + for (i = 0; i < TIMER_ID_MAX; i++) { + gSaveContext.timerStates[i] = TIMER_STATE_OFF; + gSaveContext.timerCurTimes[i] = SECONDS_TO_TIMER(0); + gSaveContext.timerTimeLimits[i] = SECONDS_TO_TIMER(0); + gSaveContext.timerStartOsTimes[i] = 0; + gSaveContext.timerStopTimes[i] = SECONDS_TO_TIMER(0); + gSaveContext.timerPausedOsTimes[i] = 0; } gSaveContext.minigameState = 0; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index a83588b667..331f5c1934 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -2093,12 +2093,12 @@ 0x8010DC58:("func_8010DC58",), 0x8010DE38:("func_8010DE38",), 0x8010E028:("func_8010E028",), - 0x8010E968:("func_8010E968",), - 0x8010E9F0:("func_8010E9F0",), - 0x8010EA9C:("func_8010EA9C",), - 0x8010EB50:("func_8010EB50",), - 0x8010EBA0:("func_8010EBA0",), - 0x8010EC54:("func_8010EC54",), + 0x8010E968:("Interface_PostmanTimerCallback",), + 0x8010E9F0:("Interface_StartTimer",), + 0x8010EA9C:("Interface_StartPostmanTimer",), + 0x8010EB50:("Interface_StartGoronRaceTimer",), + 0x8010EBA0:("Interface_StartBottleTimer",), + 0x8010EC54:("Interface_GetCompressedTimerDigits",), 0x8010EE74:("func_8010EE74",), 0x8010EF68:("Interface_SetHudVisibility",), 0x8010EF9C:("Interface_UpdateButtonAlphasByStatus",), @@ -2156,16 +2156,16 @@ 0x8011B9E0:("func_8011B9E0",), 0x8011BF70:("func_8011BF70",), 0x8011C4C4:("func_8011C4C4",), - 0x8011C808:("func_8011C808",), - 0x8011C898:("func_8011C898",), - 0x8011CA64:("func_8011CA64",), - 0x8011E3B4:("func_8011E3B4",), + 0x8011C808:("Interface_StartMoonCrash",), + 0x8011C898:("Interface_GetTimerDigits",), + 0x8011CA64:("Interface_DrawTimers",), + 0x8011E3B4:("Interface_UpdateBottleTimers",), 0x8011E730:("func_8011E730",), 0x8011F0E0:("func_8011F0E0",), 0x80120F90:("func_80120F90",), 0x80121064:("func_80121064",), 0x801210E0:("func_801210E0",), - 0x80121F94:("func_80121F94",), + 0x80121F94:("Interface_Destroy",), 0x80121FC4:("func_80121FC4",), 0x801224E0:("Path_GetByIndex",), 0x80122524:("Path_OrientAndGetDistSq",), @@ -2232,7 +2232,7 @@ 0x80124258:("Player_GetExplosiveHeld",), 0x80124278:("func_80124278",), 0x801242B4:("func_801242B4",), - 0x801242DC:("func_801242DC",), + 0x801242DC:("Player_GetEnvTimerType",), 0x80124420:("func_80124420",), 0x80124618:("func_80124618",), 0x801246F4:("func_801246F4",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 0ea237d4bf..55609668b9 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -1074,16 +1074,16 @@ 0x801BF8A8:("sMagicMeterOutlinePrimBlue","UNK_TYPE2","",0x2), 0x801BF8AC:("sMagicBorderRatio","UNK_TYPE2","",0x2), 0x801BF8B0:("sMagicBorderStep","UNK_TYPE2","",0x2), - 0x801BF8DC:("D_801BF8DC","UNK_TYPE2","",0x2), - 0x801BF8E0:("D_801BF8E0","UNK_TYPE2","",0x2), - 0x801BF8E4:("D_801BF8E4","UNK_TYPE2","",0x2), - 0x801BF8E8:("D_801BF8E8","UNK_TYPE4","",0x4), - 0x801BF8F0:("D_801BF8F0","u64","",0x8), + 0x801BF8DC:("sEnvTimerType","UNK_TYPE2","",0x2), + 0x801BF8E0:("sEnvTimerActive","UNK_TYPE2","",0x2), + 0x801BF8E4:("sPostmanBunnyHoodState","UNK_TYPE2","",0x2), + 0x801BF8E8:("sTimerPausedOsTime","UNK_TYPE4","",0x4), + 0x801BF8F0:("sBottleTimerPausedOsTime","u64","",0x8), 0x801BF8F8:("D_801BF8F8","u64","[7]",0x38), 0x801BF930:("D_801BF930","u64","[7]",0x38), - 0x801BF968:("D_801BF968","UNK_TYPE4","",0x4), - 0x801BF96C:("D_801BF96C","UNK_TYPE4","",0x4), - 0x801BF970:("D_801BF970","UNK_TYPE4","",0x4), + 0x801BF968:("sIsTimerPaused","UNK_TYPE4","",0x4), + 0x801BF96C:("sIsBottleTimerPaused","UNK_TYPE4","",0x4), + 0x801BF970:("sTimerId","UNK_TYPE4","",0x4), 0x801BF974:("D_801BF974","UNK_TYPE4","",0x4), 0x801BF978:("D_801BF978","UNK_TYPE4","",0x4), 0x801BF97C:("D_801BF97C","UNK_TYPE4","",0x4), @@ -1113,7 +1113,7 @@ 0x801BFA4C:("D_801BFA4C","UNK_TYPE2","",0x2), 0x801BFA64:("D_801BFA64","UNK_TYPE2","",0x2), 0x801BFA74:("D_801BFA74","UNK_TYPE2","",0x2), - 0x801BFA84:("D_801BFA84","UNK_TYPE4","",0x4), + 0x801BFA84:("sPostmanTimerInputBtnAPressed","UNK_TYPE4","",0x4), 0x801BFAB0:("sDoActionTextures","UNK_TYPE1","",0x1), 0x801BFAB8:("magicBorderColors","UNK_TYPE1","",0x1), 0x801BFAC4:("magicBorderIndices","UNK_TYPE1","",0x1), @@ -1161,9 +1161,9 @@ 0x801BFCA8:("D_801BFCA8","UNK_TYPE2","",0x2), 0x801BFCB8:("D_801BFCB8","UNK_TYPE1","",0x1), 0x801BFCC4:("D_801BFCC4","UNK_TYPE4","",0x4), - 0x801BFCE4:("D_801BFCE4","UNK_TYPE4","",0x4), - 0x801BFCE8:("D_801BFCE8","u16","[8]",0x10), - 0x801BFCF8:("D_801BFCF8","UNK_TYPE4","",0x4), + 0x801BFCE4:("sTimerStateTimer","UNK_TYPE4","",0x4), + 0x801BFCE8:("sTimerDigits","u16","[8]",0x10), + 0x801BFCF8:("sTimerBeepSfxSeconds","UNK_TYPE4","",0x4), 0x801BFCFC:("D_801BFCFC","UNK_TYPE4","",0x4), 0x801BFD0C:("D_801BFD0C","UNK_TYPE4","",0x4), 0x801BFD1C:("D_801BFD1C","UNK_TYPE1","",0x1), @@ -4002,7 +4002,7 @@ 0x801F57B4:("D_801F57B4","UNK_TYPE1","",0x1), 0x801F5834:("D_801F5834","UNK_TYPE1","",0x1), 0x801F5840:("gNMIBuffer","s32*","",0x4), - 0x801F5850:("D_801F5850","UNK_TYPE1","",0x1), + 0x801F5850:("sPostmanTimerInput","UNK_TYPE1","",0x1), 0x801F58B0:("D_801F58B0","UNK_TYPE1","",0x1), 0x801F59AC:("D_801F59AC","UNK_TYPE1","",0x1), 0x801F59B0:("D_801F59B0","UNK_TYPE1","",0x1), @@ -9920,7 +9920,7 @@ 0x809C9464:("sSwampTargetActorLists","UNK_PTR","",0x4), 0x809C946C:("sSwampTargetActorListLengths","UNK_TYPE1","",0x1), 0x809C9474:("sSwampPlayerPos","UNK_TYPE4","",0x4), - 0x809C9480:("sTownFierceDietyPlayerPos","UNK_TYPE4","",0x4), + 0x809C9480:("sTownFierceDeityPlayerPos","UNK_TYPE4","",0x4), 0x809C948C:("sTownPlayerPos","UNK_TYPE4","",0x4), 0x809C9498:("sGameStartTimer","s16","",0x2), 0x809C949C:("sHasSpawnedGuaysForThisWave","UNK_TYPE2","",0x2), diff --git a/tools/namefixer.py b/tools/namefixer.py index 3008c0143f..4152c8d979 100755 --- a/tools/namefixer.py +++ b/tools/namefixer.py @@ -483,6 +483,9 @@ wordReplace = { "func_80169E6C": "Play_SetupRespawnPoint", "func_8016A0AC": "Play_IsUnderwater", "func_801690CC": "Play_InCsMode", + "func_8010E9F0": "Interface_StartTimer", + "func_8010EA9C": "Interface_StartPostmanTimer", + "func_80121F94": "Interface_Destroy", "Interface_ChangeAlpha": "Interface_SetHudVisibility", "func_80112B40": "Interface_LoadItemIconImpl", "func_80112BE4": "Interface_LoadItemIcon", @@ -697,6 +700,7 @@ wordReplace = { "player->unk_394": "player->csMode", "player->swordQuads": "player->meleeWeaponQuads", "player->blureEffectIndex": "player->meleeWeaponEffectIndex", + "player->unk_AD8": "player->underwaterTimer", "player->swordAnimation": "player->meleeWeaponAnimation", "player->swordState": "player->meleeWeaponState", "player->swordInfo": "player->meleeWeaponInfo", @@ -726,6 +730,15 @@ wordReplace = { "play->actorCtx.unk4": "play->actorCtx.lensMaskSize", "play->nextEntranceIndex": "play->nextEntrance", + "gSaveContext.unk_3DC8": "gSaveContext.timerOsTime", + "gSaveContext.unk_3DD0": "gSaveContext.timerStates", + "gSaveContext.unk_3DD7": "gSaveContext.timerDirections", + "gSaveContext.unk_3DE0": "gSaveContext.timerCurTimes", + "gSaveContext.unk_3E18": "gSaveContext.timerTimeLimits", + "gSaveContext.unk_3E50": "gSaveContext.timerStartOsTimes", + "gSaveContext.unk_3E88": "gSaveContext.timerStopTimes", + "gSaveContext.unk_3EC0": "gSaveContext.timerPausedOsTimes", + "play->sceneLoadFlag": "play->transitionTrigger", "play->unk_18B4A": "play->transitionMode", "play->unk_1887F": "play->transitionType", diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index 6d0e03cd1a..52cb53a608 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -1607,12 +1607,12 @@ asm/non_matchings/code/z_parameter/func_8010D9F4.s,func_8010D9F4,0x8010D9F4,0x99 asm/non_matchings/code/z_parameter/func_8010DC58.s,func_8010DC58,0x8010DC58,0x78 asm/non_matchings/code/z_parameter/func_8010DE38.s,func_8010DE38,0x8010DE38,0x7C asm/non_matchings/code/z_parameter/func_8010E028.s,func_8010E028,0x8010E028,0x250 -asm/non_matchings/code/z_parameter/func_8010E968.s,func_8010E968,0x8010E968,0x22 -asm/non_matchings/code/z_parameter/func_8010E9F0.s,func_8010E9F0,0x8010E9F0,0x2B -asm/non_matchings/code/z_parameter/func_8010EA9C.s,func_8010EA9C,0x8010EA9C,0x2D -asm/non_matchings/code/z_parameter/func_8010EB50.s,func_8010EB50,0x8010EB50,0x14 -asm/non_matchings/code/z_parameter/func_8010EBA0.s,func_8010EBA0,0x8010EBA0,0x2D -asm/non_matchings/code/z_parameter/func_8010EC54.s,func_8010EC54,0x8010EC54,0x88 +asm/non_matchings/code/z_parameter/Interface_PostmanTimerCallback.s,Interface_PostmanTimerCallback,0x8010E968,0x22 +asm/non_matchings/code/z_parameter/Interface_StartTimer.s,Interface_StartTimer,0x8010E9F0,0x2B +asm/non_matchings/code/z_parameter/Interface_StartPostmanTimer.s,Interface_StartPostmanTimer,0x8010EA9C,0x2D +asm/non_matchings/code/z_parameter/Interface_StartGoronRaceTimer.s,Interface_StartGoronRaceTimer,0x8010EB50,0x14 +asm/non_matchings/code/z_parameter/Interface_StartBottleTimer.s,Interface_StartBottleTimer,0x8010EBA0,0x2D +asm/non_matchings/code/z_parameter/Interface_GetCompressedTimerDigits.s,Interface_GetCompressedTimerDigits,0x8010EC54,0x88 asm/non_matchings/code/z_parameter/func_8010EE74.s,func_8010EE74,0x8010EE74,0x3D asm/non_matchings/code/z_parameter/Interface_SetHudVisibility.s,Interface_SetHudVisibility,0x8010EF68,0xD asm/non_matchings/code/z_parameter/Interface_UpdateButtonAlphasByStatus.s,Interface_UpdateButtonAlphasByStatus,0x8010EF9C,0x4E @@ -1670,16 +1670,16 @@ asm/non_matchings/code/z_parameter/func_8011B5C0.s,func_8011B5C0,0x8011B5C0,0x10 asm/non_matchings/code/z_parameter/func_8011B9E0.s,func_8011B9E0,0x8011B9E0,0x164 asm/non_matchings/code/z_parameter/func_8011BF70.s,func_8011BF70,0x8011BF70,0x155 asm/non_matchings/code/z_parameter/func_8011C4C4.s,func_8011C4C4,0x8011C4C4,0xD1 -asm/non_matchings/code/z_parameter/func_8011C808.s,func_8011C808,0x8011C808,0x24 -asm/non_matchings/code/z_parameter/func_8011C898.s,func_8011C898,0x8011C898,0x73 -asm/non_matchings/code/z_parameter/func_8011CA64.s,func_8011CA64,0x8011CA64,0x654 -asm/non_matchings/code/z_parameter/func_8011E3B4.s,func_8011E3B4,0x8011E3B4,0xDF +asm/non_matchings/code/z_parameter/Interface_StartMoonCrash.s,Interface_StartMoonCrash,0x8011C808,0x24 +asm/non_matchings/code/z_parameter/Interface_GetTimerDigits.s,Interface_GetTimerDigits,0x8011C898,0x73 +asm/non_matchings/code/z_parameter/Interface_DrawTimers.s,Interface_DrawTimers,0x8011CA64,0x654 +asm/non_matchings/code/z_parameter/Interface_UpdateBottleTimers.s,Interface_UpdateBottleTimers,0x8011E3B4,0xDF asm/non_matchings/code/z_parameter/func_8011E730.s,func_8011E730,0x8011E730,0x26C asm/non_matchings/code/z_parameter/func_8011F0E0.s,func_8011F0E0,0x8011F0E0,0x7AC asm/non_matchings/code/z_parameter/func_80120F90.s,func_80120F90,0x80120F90,0x35 asm/non_matchings/code/z_parameter/func_80121064.s,func_80121064,0x80121064,0x1F asm/non_matchings/code/z_parameter/func_801210E0.s,func_801210E0,0x801210E0,0x3AD -asm/non_matchings/code/z_parameter/func_80121F94.s,func_80121F94,0x80121F94,0xC +asm/non_matchings/code/z_parameter/Interface_Destroy.s,Interface_Destroy,0x80121F94,0xC asm/non_matchings/code/z_parameter/func_80121FC4.s,func_80121FC4,0x80121FC4,0x147 asm/non_matchings/code/z_path/func_801224E0.s,func_801224E0,0x801224E0,0x11 asm/non_matchings/code/z_path/func_80122524.s,func_80122524,0x80122524,0x2A @@ -1746,7 +1746,7 @@ asm/non_matchings/code/z_player_lib/Player_ActionToExplosive.s,Player_ActionToEx asm/non_matchings/code/z_player_lib/Player_GetExplosiveHeld.s,Player_GetExplosiveHeld,0x80124258,0x8 asm/non_matchings/code/z_player_lib/func_80124278.s,func_80124278,0x80124278,0xF asm/non_matchings/code/z_player_lib/func_801242B4.s,func_801242B4,0x801242B4,0xA -asm/non_matchings/code/z_player_lib/func_801242DC.s,func_801242DC,0x801242DC,0x51 +asm/non_matchings/code/z_player_lib/Player_GetEnvTimerType.s,Player_GetEnvTimerType,0x801242DC,0x51 asm/non_matchings/code/z_player_lib/func_80124420.s,func_80124420,0x80124420,0x7E asm/non_matchings/code/z_player_lib/func_80124618.s,func_80124618,0x80124618,0x37 asm/non_matchings/code/z_player_lib/func_801246F4.s,func_801246F4,0x801246F4,0x5F