From cc52da995246bea3810c96ecd2deaba7851691c1 Mon Sep 17 00:00:00 2001
From: SonicDcer <96613413+sonicdcer@users.noreply.github.com>
Date: Wed, 28 Sep 2022 22:47:38 -0300
Subject: [PATCH 1/3] ovl_Obj_Swprize OK (#1021)
* ovl_Obj_Swprize OK
* Co-authored-by: mzxrules mzxrules@users.noreply.github.com
* pr review
* pr review
* pr review
---
spec | 3 +-
.../actors/ovl_Obj_Swprize/z_obj_swprize.c | 118 +++++++++++++++---
.../actors/ovl_Obj_Swprize/z_obj_swprize.h | 5 +-
tools/disasm/functions.txt | 4 +-
4 files changed, 109 insertions(+), 21 deletions(-)
diff --git a/spec b/spec
index 8cfc30556..813e821ce 100644
--- a/spec
+++ b/spec
@@ -5097,8 +5097,7 @@ beginseg
name "ovl_Obj_Swprize"
compress
include "build/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.o"
- include "build/data/ovl_Obj_Swprize/ovl_Obj_Swprize.data.o"
- include "build/data/ovl_Obj_Swprize/ovl_Obj_Swprize.reloc.o"
+ include "build/src/overlays/actors/ovl_Obj_Swprize/ovl_Obj_Swprize_reloc.o"
endseg
beginseg
diff --git a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.c b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.c
index 4472c4fc3..6a50a018f 100644
--- a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.c
+++ b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.c
@@ -14,12 +14,15 @@ void ObjSwprize_Init(Actor* thisx, PlayState* play);
void ObjSwprize_Destroy(Actor* thisx, PlayState* play);
void ObjSwprize_Update(Actor* thisx, PlayState* play);
+void ObjSwprize_DoNothing(ObjSwprize* this, PlayState* play);
void func_80C25654(ObjSwprize* this, PlayState* play);
+void func_80C25640(ObjSwprize* this);
+void func_80C25698(ObjSwprize* this);
void func_80C256AC(ObjSwprize* this, PlayState* play);
+void func_80C25710(ObjSwprize* this);
void func_80C2572C(ObjSwprize* this, PlayState* play);
-void func_80C25794(ObjSwprize* this, PlayState* play);
+void ObjSwprize_SetupDoNothing(ObjSwprize* this);
-#if 0
const ActorInit Obj_Swprize_InitVars = {
ACTOR_OBJ_SWPRIZE,
ACTORCAT_PROP,
@@ -32,30 +35,113 @@ const ActorInit Obj_Swprize_InitVars = {
(ActorFunc)NULL,
};
-#endif
+s16 D_80C257F0[] = { 2, 0x14, 1, 8 };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/func_80C25360.s")
+s16 D_80C257F8[] = { -0x888, 0, 0x888 };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/func_80C253D0.s")
+void func_80C25360(ObjSwprize* this, Vec3f* vec) {
+ Matrix_Push();
+ Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW);
+ Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY);
+ Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY);
+ Matrix_MultVecY(1.0f, vec);
+ Matrix_Pop();
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/ObjSwprize_Init.s")
+void func_80C253D0(ObjSwprize* this, PlayState* play) {
+ Actor* thisx = &this->actor;
+ s32 i;
+ Actor* collectible;
+ Vec3f sp78;
+ s32 type = OBJ_SWPRIZE_GET_TYPE(thisx);
+ s32 temp_s0 = D_80C257F0[type];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/ObjSwprize_Destroy.s")
+ func_80C25360(this, &sp78);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/func_80C25640.s")
+ if (type == 2) {
+ for (i = 0; i < 3; i++) {
+ collectible = Item_DropCollectible(play, &thisx->world.pos, temp_s0);
+ if (collectible != NULL) {
+ if (sp78.y < 0.98f) {
+ collectible->velocity.y = (sp78.y + 1.0f) * 4.0f;
+ collectible->speedXZ = (2.0f * (1.0f - fabsf(sp78.y))) + 2.0f;
+ collectible->world.rot.y = Math_FAtan2F(sp78.z, sp78.x) + D_80C257F8[i];
+ } else {
+ collectible->world.rot.y = i * (0x10000 / 3);
+ }
+ }
+ }
+ } else {
+ collectible = Item_DropCollectible(play, &thisx->world.pos, temp_s0);
+ if ((collectible != NULL) && (sp78.y < 0.98f)) {
+ collectible->velocity.y = (sp78.y + 1.0f) * 4.0f;
+ collectible->speedXZ = (2.0f * (1.0f - fabsf(sp78.y))) + 2.0f;
+ collectible->world.rot.y = Math_FAtan2F(sp78.z, sp78.x);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/func_80C25654.s")
+void ObjSwprize_Init(Actor* thisx, PlayState* play) {
+ ObjSwprize* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/func_80C25698.s")
+ if (Flags_GetSwitch(play, OBJ_SWPRIZE_GET_SWITCH_FLAG(&this->actor))) {
+ ObjSwprize_SetupDoNothing(this);
+ } else {
+ func_80C25640(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/func_80C256AC.s")
+void ObjSwprize_Destroy(Actor* thisx, PlayState* play) {
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/func_80C25710.s")
+void func_80C25640(ObjSwprize* this) {
+ this->actionFunc = func_80C25654;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/func_80C2572C.s")
+void func_80C25654(ObjSwprize* this, PlayState* play) {
+ if (Flags_GetSwitch(play, OBJ_SWPRIZE_GET_SWITCH_FLAG(&this->actor))) {
+ func_80C25698(this);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/func_80C25780.s")
+void func_80C25698(ObjSwprize* this) {
+ this->actionFunc = func_80C256AC;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/func_80C25794.s")
+void func_80C256AC(ObjSwprize* this, PlayState* play) {
+ if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) {
+ ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor);
+ func_80C253D0(this, play);
+ func_80C25710(this);
+ } else {
+ ActorCutscene_SetIntentToPlay(this->actor.cutscene);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Swprize/ObjSwprize_Update.s")
+void func_80C25710(ObjSwprize* this) {
+ this->timer = 40;
+ this->actionFunc = func_80C2572C;
+}
+
+void func_80C2572C(ObjSwprize* this, PlayState* play) {
+ if (this->timer > 0) {
+ this->timer--;
+ if (this->timer == 0) {
+ ActorCutscene_Stop(this->actor.cutscene);
+ ObjSwprize_SetupDoNothing(this);
+ }
+ }
+}
+
+void ObjSwprize_SetupDoNothing(ObjSwprize* this) {
+ this->actionFunc = ObjSwprize_DoNothing;
+}
+
+void ObjSwprize_DoNothing(ObjSwprize* this, PlayState* play) {
+}
+
+void ObjSwprize_Update(Actor* thisx, PlayState* play) {
+ ObjSwprize* this = THIS;
+
+ this->actionFunc(this, play);
+}
diff --git a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h
index 29654f992..5b7cd2e09 100644
--- a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h
+++ b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h
@@ -3,6 +3,9 @@
#include "global.h"
+#define OBJ_SWPRIZE_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F)
+#define OBJ_SWPRIZE_GET_TYPE(thisx) (((thisx)->params >> 8) & 3)
+
struct ObjSwprize;
typedef void (*ObjSwprizeActionFunc)(struct ObjSwprize*, PlayState*);
@@ -10,7 +13,7 @@ typedef void (*ObjSwprizeActionFunc)(struct ObjSwprize*, PlayState*);
typedef struct ObjSwprize {
/* 0x000 */ Actor actor;
/* 0x144 */ ObjSwprizeActionFunc actionFunc;
- /* 0x148 */ char unk_148[0x4];
+ /* 0x148 */ s16 timer;
} ObjSwprize; // size = 0x14C
extern const ActorInit Obj_Swprize_InitVars;
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index c5cd94e37..aa494f594 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -17125,8 +17125,8 @@
0x80C256AC:("func_80C256AC",),
0x80C25710:("func_80C25710",),
0x80C2572C:("func_80C2572C",),
- 0x80C25780:("func_80C25780",),
- 0x80C25794:("func_80C25794",),
+ 0x80C25780:("ObjSwprize_SetupDoNothing",),
+ 0x80C25794:("ObjSwprize_DoNothing",),
0x80C257A4:("ObjSwprize_Update",),
0x80C258A0:("func_80C258A0",),
0x80C2590C:("func_80C2590C",),
From 084bafcfccd6acdf2e0a48a4b298b9a9091cab04 Mon Sep 17 00:00:00 2001
From: StickyThwomp <89738536+StickyThwomp@users.noreply.github.com>
Date: Wed, 28 Sep 2022 21:57:00 -0500
Subject: [PATCH 2/3] ovl_En_Nimotsu OK and documented (#1028)
* Done-ish, looking for feedback.
* Finished decompile and rename of ovl_En_Nimotsu (Bomb shop bag)
* Revert unk->pad rename, leaving as unknown.
* Swap the reloc include to the src version
* Style/type updates from review comments
* Changes from review:
- Remove extra whitespace
- Remove unnecessary include
- Hex->Dec for alpha value.
* Changes from review, Texture name and comment formatting
* More changes from review, whitespace and dustTimer->timer rename.
---
assets/xml/objects/object_boj.xml | 6 +-
spec | 3 +-
.../actors/ovl_En_Nimotsu/z_en_nimotsu.c | 96 ++++++++++++++++---
.../actors/ovl_En_Nimotsu/z_en_nimotsu.h | 5 +-
.../actors/ovl_En_Suttari/z_en_suttari.c | 2 +-
tools/disasm/functions.txt | 2 +-
undefined_syms.txt | 4 -
7 files changed, 93 insertions(+), 25 deletions(-)
diff --git a/assets/xml/objects/object_boj.xml b/assets/xml/objects/object_boj.xml
index cfb10e97a..20c661bb5 100644
--- a/assets/xml/objects/object_boj.xml
+++ b/assets/xml/objects/object_boj.xml
@@ -87,8 +87,8 @@
-
-
-
+
+
+
diff --git a/spec b/spec
index 813e821ce..c894dabef 100644
--- a/spec
+++ b/spec
@@ -4567,8 +4567,7 @@ beginseg
name "ovl_En_Nimotsu"
compress
include "build/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.o"
- include "build/data/ovl_En_Nimotsu/ovl_En_Nimotsu.data.o"
- include "build/data/ovl_En_Nimotsu/ovl_En_Nimotsu.reloc.o"
+ include "build/src/overlays/actors/ovl_En_Nimotsu/ovl_En_Nimotsu_reloc.o"
endseg
beginseg
diff --git a/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.c b/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.c
index 966f3671b..11872a0a1 100644
--- a/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.c
+++ b/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.c
@@ -5,6 +5,7 @@
*/
#include "z_en_nimotsu.h"
+#include "assets/objects/object_boj/object_boj.h"
#define FLAGS (ACTOR_FLAG_10)
@@ -15,7 +16,8 @@ void EnNimotsu_Destroy(Actor* thisx, PlayState* play);
void EnNimotsu_Update(Actor* thisx, PlayState* play);
void EnNimotsu_Draw(Actor* thisx, PlayState* play);
-#if 0
+void EnNimotsu_UpdateCollision(EnNimotsu* this, PlayState* play);
+
const ActorInit En_Nimotsu_InitVars = {
ACTOR_EN_NIMOTSU,
ACTORCAT_PROP,
@@ -28,25 +30,93 @@ const ActorInit En_Nimotsu_InitVars = {
(ActorFunc)EnNimotsu_Draw,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_80BE1FB0 = {
- { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_2,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK4,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
{ 10, 30, 0, { 0, 0, 0 } },
};
-#endif
+void EnNimotsu_UpdateCollision(EnNimotsu* this, PlayState* play) {
+ Collider_UpdateCylinder(&this->actor, &this->collider);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
+ Actor_UpdateBgCheckInfo(play, &this->actor, 32.0f, 30.0f, 0.0f, 4);
+}
-extern ColliderCylinderInit D_80BE1FB0;
+void EnNimotsu_Init(Actor* thisx, PlayState* play) {
+ EnNimotsu* this = THIS;
-extern UNK_TYPE D_06013380;
+ Collider_InitCylinder(play, &this->collider);
+ Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nimotsu/func_80BE1C80.s")
+ this->timer = 10;
+ this->actor.gravity = -0.5f;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nimotsu/EnNimotsu_Init.s")
+ Actor_SetScale(&this->actor, 0.01f);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nimotsu/EnNimotsu_Destroy.s")
+void EnNimotsu_Destroy(Actor* thisx, PlayState* play) {
+ EnNimotsu* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nimotsu/EnNimotsu_Update.s")
+ Collider_DestroyCylinder(play, &this->collider);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nimotsu/EnNimotsu_Draw.s")
+void EnNimotsu_Update(Actor* thisx, PlayState* play) {
+ s32 pad;
+ EnNimotsu* this = THIS;
+ Vec3f dustPosition;
+
+ Actor_MoveWithGravity(&this->actor);
+
+ if (!(this->dustDone & 1) && (this->actor.bgCheckFlags & 1)) {
+ if (DECR(this->timer) == 0) {
+ this->dustDone |= 1;
+ }
+
+ if ((play->state.frames % 3) == 0) {
+ dustPosition.x = this->actor.world.pos.x + randPlusMinusPoint5Scaled(15.0f);
+ dustPosition.y = this->actor.world.pos.y;
+ dustPosition.z = this->actor.world.pos.z + randPlusMinusPoint5Scaled(15.0f);
+ Actor_SpawnFloorDustRing(play, &this->actor, &dustPosition, 20.0f, 0, 2.0f, 0, 0, 0);
+ }
+ }
+
+ EnNimotsu_UpdateCollision(this, play);
+}
+
+void EnNimotsu_Draw(Actor* thisx, PlayState* play) {
+ s32 pad;
+ EnNimotsu* this = THIS;
+ Vec3f position;
+ Vec3f scale;
+
+ OPEN_DISPS(play->state.gfxCtx);
+ func_8012C28C(play->state.gfxCtx);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, &gBombShopBagDL);
+ func_8012C2DC(play->state.gfxCtx);
+
+ position.x = this->actor.world.pos.x + 7.0f;
+ position.y = this->actor.world.pos.y;
+ position.z = this->actor.world.pos.z + 2.0f;
+
+ scale.x = 0.2f;
+ scale.y = 0.2f;
+ scale.z = 0.2f;
+
+ func_800BC620(&position, &scale, 255, play);
+ CLOSE_DISPS(play->state.gfxCtx);
+}
diff --git a/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.h b/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.h
index 634697736..e839c9393 100644
--- a/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.h
+++ b/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.h
@@ -7,7 +7,10 @@ struct EnNimotsu;
typedef struct EnNimotsu {
/* 0x000 */ Actor actor;
- /* 0x144 */ char unk_144[0x98];
+ /* 0x144 */ UNK_TYPE1 unk_144[0x48];
+ /* 0x18C */ ColliderCylinder collider;
+ /* 0x1D8 */ u16 dustDone;
+ /* 0x1DA */ s16 timer;
} EnNimotsu; // size = 0x1DC
extern const ActorInit En_Nimotsu_InitVars;
diff --git a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c
index 10cdec079..fbacce266 100644
--- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c
+++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c
@@ -1542,7 +1542,7 @@ void EnSuttari_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
} else {
func_8012C28C(play->state.gfxCtx);
OPEN_DISPS(play->state.gfxCtx);
- gSPDisplayList(POLY_OPA_DISP++, object_boj_DL_013380);
+ gSPDisplayList(POLY_OPA_DISP++, gBombShopBagDL);
CLOSE_DISPS(play->state.gfxCtx);
}
}
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index aa494f594..a83588b66 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -16061,7 +16061,7 @@
0x80BE16B4:("EnTab_PostLimbDraw",),
0x80BE1704:("EnTab_TransformLimbDraw",),
0x80BE1810:("EnTab_Draw",),
- 0x80BE1C80:("func_80BE1C80",),
+ 0x80BE1C80:("EnNimotsu_UpdateCollision",),
0x80BE1CEC:("EnNimotsu_Init",),
0x80BE1D5C:("EnNimotsu_Destroy",),
0x80BE1D88:("EnNimotsu_Update",),
diff --git a/undefined_syms.txt b/undefined_syms.txt
index 658dd5f05..aae06790f 100644
--- a/undefined_syms.txt
+++ b/undefined_syms.txt
@@ -1223,10 +1223,6 @@ D_06008C40 = 0x06008C40;
D_060001E4 = 0x060001E4;
D_06001EE8 = 0x06001EE8;
-// ovl_En_Nimotsu
-
-D_06013380 = 0x06013380;
-
// ovl_En_Nwc
D_060000E8 = 0x060000E8;
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 3/3] `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 f04ab1981..8396d4a41 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 aa3ba523b..cf15b236a 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 05602af8f..1ee739c4a 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 f49f30688..2f101b558 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 57801684f..fc24aa5b6 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 da93f13fd..942435fa7 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 ee2070610..a29a8279e 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 1b8dbfb2e..f9b23ac79 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 394a10600..9fc3dee25 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 40ffb4213..ffad44e6e 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 679b8abf4..ef108c43a 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 c8d1c802f..3da84fe78 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 ed7945ec3..5d018a995 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 120c9ea49..f149a97d6 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 dcc6312bc..4834256d6 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 cb33ce422..9b421dfd4 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 66f57f323..1704451ec 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 a82434c21..45d6661eb 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 4c74a779c..9f3f424d5 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 1d2d0352c..99d4eca14 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 c351f83c6..2ac167235 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 8957cfc21..f88e7c074 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 a737c5008..9d0c41295 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 a10b26514..47f0997eb 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 0f7308826..6909183f3 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 b6f653935..1cc1946f5 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 eb6d4ab42..ed67013d8 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 51a941b28..1d504dc62 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 7852aa24b..5433aeec7 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 88547581f..f33a1f693 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 b6dea09f3..0a013410b 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 b39187c75..0ce2f38a1 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 b4cfe295c..5d418c0fc 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 a83588b66..331f5c193 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 0ea237d4b..55609668b 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 3008c0143..4152c8d97 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 6d0e03cd1..52cb53a60 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