From a59943bc4aee376eca48cbee429af75153b28570 Mon Sep 17 00:00:00 2001 From: emilybrooks Date: Wed, 22 Sep 2021 17:46:26 -0700 Subject: [PATCH 01/13] ovl_obj_lightblock OK (#282) * initial commit * review suggestions * changed opacity to alpha * changed to multiple of 10 --- spec | 3 +- .../ovl_Obj_Lightblock/z_obj_lightblock.c | 186 +++++++++++++++--- .../ovl_Obj_Lightblock/z_obj_lightblock.h | 11 +- 3 files changed, 172 insertions(+), 28 deletions(-) diff --git a/spec b/spec index 8ec349fd9..b2b784c25 100644 --- a/spec +++ b/spec @@ -3808,8 +3808,7 @@ beginseg name "ovl_Obj_Lightblock" compress include "build/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.o" - include "build/data/ovl_Obj_Lightblock/ovl_Obj_Lightblock.data.o" - include "build/data/ovl_Obj_Lightblock/ovl_Obj_Lightblock.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Lightblock/ovl_Obj_Lightblock_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.c b/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.c index 01231aec8..d955a5aa3 100644 --- a/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.c +++ b/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_lightblock.c + * Overlay: ovl_Obj_Lightblock + * Description: Sun Block + */ + #include "z_obj_lightblock.h" #define FLAGS 0x00000000 @@ -8,8 +14,13 @@ void ObjLightblock_Init(Actor* thisx, GlobalContext* globalCtx); void ObjLightblock_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjLightblock_Update(Actor* thisx, GlobalContext* globalCtx); void ObjLightblock_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80AF3AC8(ObjLightblock* this); +void func_80AF3ADC(ObjLightblock* this, GlobalContext* globalCtx); +void func_80AF3B8C(ObjLightblock* this); +void func_80AF3BA0(ObjLightblock* this, GlobalContext* globalCtx); +void func_80AF3C18(ObjLightblock* this); +void func_80AF3C34(ObjLightblock* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Lightblock_InitVars = { ACTOR_OBJ_LIGHTBLOCK, ACTORCAT_BG, @@ -22,46 +33,175 @@ const ActorInit Obj_Lightblock_InitVars = { (ActorFunc)ObjLightblock_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AF3EA0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00202000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00202000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 84, 120, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80AF3EEC[] = { +typedef struct { + /* 0x00 */ f32 scale; + /* 0x04 */ s16 radius; + /* 0x06 */ s16 height; + /* 0x08 */ s16 yShift; + /* 0x0C */ s32 params; +} LightblockTypeVars; // size = 0x10 + +static LightblockTypeVars sLightblockTypeVars[] = { + { 0.1f, 76, 80, 19, 2 }, + { (1.0f / 6), 126, 144, 19, 3 }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 500, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 500, ICHAIN_STOP), }; -#endif +extern CollisionHeader D_06000B80; +extern Gfx D_801AEF88[]; +extern Gfx D_06000178[]; +extern Gfx D_801AEFA0[]; -extern ColliderCylinderInit D_80AF3EA0; -extern InitChainEntry D_80AF3EEC[]; +void func_80AF3910(ObjLightblock* this, GlobalContext* globalCtx) { + LightblockTypeVars* typeVars = &sLightblockTypeVars[LIGHTBLOCK_TYPE(&this->dyna.actor)]; -extern UNK_TYPE D_06000178; -extern UNK_TYPE D_06000B80; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_DEMO_EFFECT, this->dyna.actor.world.pos.x, + this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, 0, 0, 0, typeVars->params); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/func_80AF3910.s") +void ObjLightblock_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjLightblock* this = THIS; + LightblockTypeVars* typeVars = &sLightblockTypeVars[LIGHTBLOCK_TYPE(&this->dyna.actor)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/ObjLightblock_Init.s") + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + Actor_SetScale(&this->dyna.actor, typeVars->scale); + BcCheck3_BgActorInit(&this->dyna, 0); + Collider_InitCylinder(globalCtx, &this->collider); + if (Flags_GetSwitch(globalCtx, LIGHTBLOCK_DESTROYED(&this->dyna.actor))) { + Actor_MarkForDeath(&this->dyna.actor); + } else { + BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000B80); + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + this->collider.dim.radius = typeVars->radius; + this->collider.dim.height = typeVars->height; + this->collider.dim.yShift = typeVars->yShift; + this->alpha = 255; + func_80AF3AC8(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/ObjLightblock_Destroy.s") +void ObjLightblock_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjLightblock* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/func_80AF3AC8.s") + BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/func_80AF3ADC.s") +void func_80AF3AC8(ObjLightblock* this) { + this->actionFunc = func_80AF3ADC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/func_80AF3B8C.s") +void func_80AF3ADC(ObjLightblock* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + // light arrows + if (this->collider.info.acHitInfo->toucher.dmgFlags & (1 << 13)) { + this->collisionCounter = 8; + } + // light ray + else { + this->collisionCounter++; + } + } else { + this->collisionCounter = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/func_80AF3BA0.s") + if (this->collisionCounter >= 8) { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + func_80AF3B8C(this); + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/func_80AF3C18.s") +void func_80AF3B8C(ObjLightblock* this) { + this->actionFunc = func_80AF3BA0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/func_80AF3C34.s") +void func_80AF3BA0(ObjLightblock* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + Actor_SetSwitchFlag(globalCtx, LIGHTBLOCK_DESTROYED(&this->dyna.actor)); + func_80AF3910(this, globalCtx); + func_80AF3C18(this); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/ObjLightblock_Update.s") +void func_80AF3C18(ObjLightblock* this) { + this->timer = 80; + this->actionFunc = func_80AF3C34; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Lightblock/ObjLightblock_Draw.s") +void func_80AF3C34(ObjLightblock* this, GlobalContext* globalCtx) { + s8 temp_a0; + + this->timer--; + if (this->timer <= 0) { + temp_a0 = this->dyna.actor.cutscene; + ActorCutscene_Stop(temp_a0); + Actor_MarkForDeath(&this->dyna.actor); + } else if (this->timer <= 60) { + if (this->alpha > 40) { + this->alpha -= 40; + } else { + this->alpha = 0; + this->dyna.actor.draw = NULL; + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } + } +} + +void ObjLightblock_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjLightblock* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void ObjLightblock_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjLightblock* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + if (this->alpha < 255) { + func_8012C2DC(globalCtx->state.gfxCtx); + gSPSegment(POLY_XLU_DISP++, 0x08, D_801AEF88); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, this->alpha); + gSPDisplayList(POLY_XLU_DISP++, D_06000178); + } else { + func_8012C28C(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, D_801AEFA0); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, D_06000178); + } + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.h b/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.h index ba76fa3a1..028d63754 100644 --- a/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.h +++ b/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.h @@ -3,15 +3,20 @@ #include "global.h" +#define LIGHTBLOCK_TYPE(thisx) ((thisx)->params & 1) +#define LIGHTBLOCK_DESTROYED(thisx) (((thisx)->params >> 8) & 0x7F) + struct ObjLightblock; typedef void (*ObjLightblockActionFunc)(struct ObjLightblock*, GlobalContext*); typedef struct ObjLightblock { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x64]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ ColliderCylinder collider; /* 0x01A8 */ ObjLightblockActionFunc actionFunc; - /* 0x01AC */ char unk_1AC[0x4]; + /* 0x01AC */ s8 timer; + /* 0x01AD */ u8 alpha; + /* 0x01AE */ s8 collisionCounter; } ObjLightblock; // size = 0x1B0 extern const ActorInit Obj_Lightblock_InitVars; From 2ff7320409d1f6340bed2ea37b7ceb3a49a57525 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Wed, 22 Sep 2021 22:50:35 -0300 Subject: [PATCH 02/13] `ovl_daytelop` OK (#277) * eeeee * nonequivalents * draw * Import data * Match Daytelop_LoadGraphics * draw kinda better * extract daytelops and gameover * SEGMENT_ROM macros * Use extracted symbols for daytelop * match Daytelop_Draw * Fix bss * draw cleanup * Daytelop_Update from non equivalent to non matching * Some renames and spec * Run formatter * enum * sfx * Use SEGMENT_ROM_START macros everywhere * more macros * run formatter * Add description * update variables.txt * Remove extra stuff in gbi.h * Would this fix it? * and again * whoops * Apply suggestions from code review Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * Tharo's suggestions * match Daytelop_Update * run formatter * fix merge issues Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> --- assets/xml/static/daytelop_static.xml | 19 ++ assets/xml/static/esp_daytelop_static.xml | 19 ++ assets/xml/static/fra_daytelop_static.xml | 19 ++ assets/xml/static/ger_daytelop_static.xml | 19 ++ .../xml/static/icon_item_gameover_static.xml | 10 + include/functions.h | 8 +- include/macros.h | 2 +- include/segment_symbols.h | 14 +- include/variables.h | 2 +- include/z64animation.h | 2 +- include/z64save.h | 2 +- spec | 18 +- src/boot_O2_g3/idle.c | 6 +- src/boot_O2_g3/z_std_dma.c | 3 +- src/code/z_actor_dlftbls.c | 8 +- src/code/z_kanfont.c | 8 +- src/code/z_scene.c | 20 +- src/code/z_scene_table.c | 2 +- src/code/z_vr_box.c | 32 +-- src/overlays/actors/ovl_En_Dns/z_en_dns.c | 2 +- .../actors/ovl_En_Invadepoh/z_en_invadepoh.c | 6 +- src/overlays/actors/ovl_En_Ma4/z_en_ma4.c | 6 +- .../actors/ovl_En_Ma_Yto/z_en_ma_yto.c | 2 +- .../gamestates/ovl_daytelop/z_daytelop.c | 243 +++++++++++++++++- .../gamestates/ovl_daytelop/z_daytelop.h | 19 +- tools/disasm/variables.txt | 7 +- tools/permuter_settings.toml | 3 +- 27 files changed, 419 insertions(+), 82 deletions(-) create mode 100644 assets/xml/static/daytelop_static.xml create mode 100644 assets/xml/static/esp_daytelop_static.xml create mode 100644 assets/xml/static/fra_daytelop_static.xml create mode 100644 assets/xml/static/ger_daytelop_static.xml create mode 100644 assets/xml/static/icon_item_gameover_static.xml diff --git a/assets/xml/static/daytelop_static.xml b/assets/xml/static/daytelop_static.xml new file mode 100644 index 000000000..2c558404f --- /dev/null +++ b/assets/xml/static/daytelop_static.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/static/esp_daytelop_static.xml b/assets/xml/static/esp_daytelop_static.xml new file mode 100644 index 000000000..2c55295dc --- /dev/null +++ b/assets/xml/static/esp_daytelop_static.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/static/fra_daytelop_static.xml b/assets/xml/static/fra_daytelop_static.xml new file mode 100644 index 000000000..f855ddbe1 --- /dev/null +++ b/assets/xml/static/fra_daytelop_static.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/static/ger_daytelop_static.xml b/assets/xml/static/ger_daytelop_static.xml new file mode 100644 index 000000000..398683f4b --- /dev/null +++ b/assets/xml/static/ger_daytelop_static.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/static/icon_item_gameover_static.xml b/assets/xml/static/icon_item_gameover_static.xml new file mode 100644 index 000000000..405167b86 --- /dev/null +++ b/assets/xml/static/icon_item_gameover_static.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/include/functions.h b/include/functions.h index bd61a60c4..98cfefe65 100644 --- a/include/functions.h +++ b/include/functions.h @@ -2814,9 +2814,9 @@ void func_801434E4(GameState* gamestate, SkyboxContext* skyboxCtx, s16 skyType); // void func_80143A04(void); void func_80143A10(u8 owlId); // void func_80143A54(void); -// void func_80143AC4(void); +void func_80143AC4(void); void func_80143B0C(GlobalContext* globalCtx); -// void Sram_IncrementDay(void); +void Sram_IncrementDay(void); u32 Sram_CalcChecksum(u8* data, u32 length); // void func_80144628(void); // void Sram_GenerateRandomSaveFields(void); @@ -2927,7 +2927,7 @@ void ShrinkWindow_SetPillarboxTarget(s8 target); void ShrinkWindow_SetPillarboxMagnitude(u8 magnitude); // s32 ShrinkWindow_GetPillarboxMagnitude(void); // void ShrinkWindow_Init(void); -// void ShrinkWindow_Fini(void); +void ShrinkWindow_Fini(void); void ShrinkWindow_Step(s32 framerateDivisor); void ShrinkWindow_Draw(GlobalContext* globalCtx); // void func_80161180(void); @@ -3061,7 +3061,7 @@ s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx); // void func_8016A168(void); // void func_8016A178(void); // void func_8016A268(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE1 param_6); -void Play_Init(GlobalContext* globalCtx); +void Play_Init(GameState* gameState); // void func_8016AC10(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_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10); // void func_8016AE1C(void); // void func_8016B278(void); diff --git a/include/macros.h b/include/macros.h index b7a0ff217..36af1534b 100644 --- a/include/macros.h +++ b/include/macros.h @@ -34,7 +34,7 @@ //#define LINK_IS_CHILD (gSaveContext.linkAge != 0) #define LINK_IS_ADULT (gSaveContext.linkAge == 0) -#define CURRENT_DAY (gSaveContext.day % 5) +#define CURRENT_DAY (((void)0, gSaveContext.day) % 5) #define CLOCK_TIME(hr, min) ((s32)(((hr) * 60 + (min)) * 0x10000 / (24 * 60))) diff --git a/include/segment_symbols.h b/include/segment_symbols.h index 7c8f4895a..a2dc30ff3 100644 --- a/include/segment_symbols.h +++ b/include/segment_symbols.h @@ -19,6 +19,18 @@ DECLARE_SEGMENT(ovl_##name) \ DECLARE_ROM_SEGMENT(ovl_##name) +#define SEGMENT_START(segment) (_ ## segment ## SegmentStart) +#define SEGMENT_END(segment) (_ ## segment ## SegmentEnd) +#define SEGMENT_SIZE(segment) ((uintptr_t)SEGMENT_END(segment) - (uintptr_t)SEGMENT_START(segment)) + +#define SEGMENT_ROM_START(segment) (_ ## segment ## SegmentRomStart) +#define SEGMENT_ROM_END(segment) (_ ## segment ## SegmentRomEnd) +#define SEGMENT_ROM_SIZE(segment) ((uintptr_t)SEGMENT_ROM_END(segment) - (uintptr_t)SEGMENT_ROM_START(segment)) + +#define SEGMENT_BSS_START(segment) (_ ## segment ## SegmentBssStart) +#define SEGMENT_BSS_END(segment) (_ ## segment ## SegmentBssEnd) +#define SEGMENT_BSS_SIZE(segment) ((uintptr_t)SEGMENT_BSS_END(segment) - (uintptr_t)SEGMENT_BSS_START(segment)) + DECLARE_SEGMENT(boot) DECLARE_ROM_SEGMENT(boot) @@ -1156,7 +1168,7 @@ DECLARE_ROM_SEGMENT(week_static) DECLARE_ROM_SEGMENT(daytelop_static) DECLARE_ROM_SEGMENT(ger_daytelop_static) DECLARE_ROM_SEGMENT(fra_daytelop_static) -DECLARE_ROM_SEGMENT(spa_daytelop_static) +DECLARE_ROM_SEGMENT(esp_daytelop_static) DECLARE_ROM_SEGMENT(d2_fine_static) DECLARE_ROM_SEGMENT(d2_cloud_static) DECLARE_ROM_SEGMENT(d2_fine_pal_static) diff --git a/include/variables.h b/include/variables.h index 0e17c2daa..258cec4df 100644 --- a/include/variables.h +++ b/include/variables.h @@ -983,7 +983,7 @@ extern u8 kanfontOrdering[92]; // extern UNK_TYPE1 D_801BDBBC; // extern UNK_TYPE1 D_801BDBC0; // extern UNK_TYPE1 D_801BDBC4; -// extern UNK_TYPE1 D_801BDBC8; +extern u8 D_801BDBC8; // extern UNK_TYPE1 D_801BDBCC; // extern UNK_TYPE1 D_801BDCF4; // extern UNK_TYPE1 D_801BE38E; diff --git a/include/z64animation.h b/include/z64animation.h index 1e5b8b0ed..aa5148e3b 100644 --- a/include/z64animation.h +++ b/include/z64animation.h @@ -7,7 +7,7 @@ #include "z64math.h" #define LINK_ANIMETION_OFFSET(addr, offset) \ - (((u32)&_link_animetionSegmentRomStart) + ((u32)addr & 0xFFFFFF) + ((u32)offset)) + (SEGMENT_ROM_START(link_animetion) + ((u32)addr & 0xFFFFFF) + ((u32)offset)) #define LIMB_DONE 0xFF #define ANIMATION_ENTRY_MAX 50 diff --git a/include/z64save.h b/include/z64save.h index 20efff7b8..d701d0a42 100644 --- a/include/z64save.h +++ b/include/z64save.h @@ -159,7 +159,7 @@ typedef struct { /* 0x3F45 */ u8 zTargetSetting; // 0: Switch; 1: Hold /* 0x3F46 */ u16 unk_3F46; // "NottoriBgm" /* 0x3F48 */ u8 unk_3F48; // "fade_go" - /* 0x3F4A */ u16 unk_3F4A; // "next_daytime" + /* 0x3F4A */ u16 nextCutsceneIndex; // "next_daytime" /* 0x3F4C */ u8 cutsceneTrigger; // "doukidemo" /* 0x3F4D */ u8 unk_3F4D; // "Kenjya_no" /* 0x3F4E */ u16 nextDayTime; // "next_zelda_time" diff --git a/spec b/spec index b2b784c25..eb6fbaad6 100644 --- a/spec +++ b/spec @@ -318,7 +318,8 @@ beginseg name "icon_item_gameover_static" compress romalign 0x1000 - include "build/baserom/icon_item_gameover_static.o" + include "build/assets/static/icon_item_gameover_static/icon_item_gameover_static.o" + number 12 endseg beginseg @@ -732,8 +733,7 @@ beginseg name "ovl_daytelop" compress include "build/src/overlays/gamestates/ovl_daytelop/z_daytelop.o" - include "build/data/ovl_daytelop/ovl_daytelop.data.o" - include "build/data/ovl_daytelop/ovl_daytelop.reloc.o" + include "build/src/overlays/gamestates/ovl_daytelop/ovl_daytelop_reloc.o" endseg beginseg @@ -8927,28 +8927,32 @@ beginseg name "daytelop_static" compress romalign 0x1000 - include "build/baserom/daytelop_static.o" + include "build/assets/static/daytelop_static/daytelop_static.o" + number 9 endseg beginseg name "ger_daytelop_static" compress romalign 0x1000 - include "build/baserom/ger_daytelop_static.o" + include "build/assets/static/ger_daytelop_static/ger_daytelop_static.o" + number 9 endseg beginseg name "fra_daytelop_static" compress romalign 0x1000 - include "build/baserom/fra_daytelop_static.o" + include "build/assets/static/fra_daytelop_static/fra_daytelop_static.o" + number 9 endseg beginseg name "esp_daytelop_static" compress romalign 0x1000 - include "build/baserom/esp_daytelop_static.o" + include "build/assets/static/esp_daytelop_static/esp_daytelop_static.o" + number 9 endseg beginseg diff --git a/src/boot_O2_g3/idle.c b/src/boot_O2_g3/idle.c index 4d01b4c37..4be8a1094 100644 --- a/src/boot_O2_g3/idle.c +++ b/src/boot_O2_g3/idle.c @@ -58,15 +58,15 @@ void Idle_InitCodeAndMemory(void) { oldSize = sDmaMgrDmaBuffSize; sDmaMgrDmaBuffSize = 0; - DmaMgr_SendRequestImpl(&dmaReq, _codeSegmentStart, _codeSegmentRomStart, _codeSegmentRomEnd - _codeSegmentRomStart, - 0, &queue, 0); + DmaMgr_SendRequestImpl(&dmaReq, SEGMENT_START(code), SEGMENT_ROM_START(code), + SEGMENT_ROM_END(code) - SEGMENT_ROM_START(code), 0, &queue, 0); Idle_InitScreen(); Idle_InitMemory(); osRecvMesg(&queue, NULL, 1); sDmaMgrDmaBuffSize = oldSize; - Idle_ClearMemory(_codeSegmentBssStart, _codeSegmentBssEnd); + Idle_ClearMemory(SEGMENT_BSS_START(code), SEGMENT_BSS_END(code)); } void Main_ThreadEntry(void* arg) { diff --git a/src/boot_O2_g3/z_std_dma.c b/src/boot_O2_g3/z_std_dma.c index 5a29d5d56..3a447b0e8 100644 --- a/src/boot_O2_g3/z_std_dma.c +++ b/src/boot_O2_g3/z_std_dma.c @@ -213,8 +213,7 @@ void DmaMgr_Start(void) { DmaEntry* iter; u32 idx; - DmaMgr_DMARomToRam((u32)_dmadataSegmentRomStart, (u32)dmadata, - (u32)_dmadataSegmentRomEnd - (u32)_dmadataSegmentRomStart); + DmaMgr_DMARomToRam(SEGMENT_ROM_START(dmadata), dmadata, SEGMENT_ROM_SIZE(dmadata)); dummy_label:; diff --git a/src/code/z_actor_dlftbls.c b/src/code/z_actor_dlftbls.c index 63dcc9c58..4165e4c9b 100644 --- a/src/code/z_actor_dlftbls.c +++ b/src/code/z_actor_dlftbls.c @@ -1,10 +1,10 @@ #include "global.h" #include "initvars.h" -#define ACTOR_OVERLAY(name, allocType) \ - { \ - (u32) _ovl_##name##SegmentRomStart, (u32)_ovl_##name##SegmentRomEnd, _ovl_##name##SegmentStart, \ - _ovl_##name##SegmentEnd, NULL, &name##_InitVars, NULL, allocType, 0 \ +#define ACTOR_OVERLAY(name, allocType) \ + { \ + SEGMENT_ROM_START(ovl_##name), SEGMENT_ROM_END(ovl_##name), SEGMENT_START(ovl_##name), \ + SEGMENT_END(ovl_##name), NULL, &name##_InitVars, NULL, allocType, 0 \ } #define ACTOR_OVERLAY_INTERNAL(name, allocType) \ diff --git a/src/code/z_kanfont.c b/src/code/z_kanfont.c index f85911fc6..b678642b1 100644 --- a/src/code/z_kanfont.c +++ b/src/code/z_kanfont.c @@ -9,12 +9,13 @@ void Font_LoadCharNES(GlobalContext* globalCtx, u8 codePointIndex, s32 offset) { Font* font = &msgCtx->font; DmaMgr_SendRequest0(&font->charBuf[font->unk_11D88][offset], - &_nes_font_staticSegmentRomStart[(codePointIndex - ' ') * FONT_CHAR_TEX_SIZE], + &((u8*)SEGMENT_ROM_START(nes_font_static))[(codePointIndex - ' ') * FONT_CHAR_TEX_SIZE], FONT_CHAR_TEX_SIZE); } void Font_LoadMessageBoxEndIcon(Font* font, u16 icon) { - DmaMgr_SendRequest0(&font->iconBuf, &_message_staticSegmentRomStart[5 * 0x1000 + icon * FONT_CHAR_TEX_SIZE], + DmaMgr_SendRequest0(&font->iconBuf, + &((u8*)SEGMENT_ROM_START(message_static))[5 * 0x1000 + icon * FONT_CHAR_TEX_SIZE], FONT_CHAR_TEX_SIZE); } @@ -36,7 +37,8 @@ void Font_LoadOrderedFont(Font* font) { loadOffset = 0; } // UB to convert pointer to u32 - DmaMgr_SendRequest0(writeLocation, (u32)_nes_font_staticSegmentRomStart + loadOffset, FONT_CHAR_TEX_SIZE); + DmaMgr_SendRequest0(writeLocation, (uintptr_t)SEGMENT_ROM_START(nes_font_static) + loadOffset, + FONT_CHAR_TEX_SIZE); if (sFontOrdering[codePointIndex] == 0x8C) { break; } diff --git a/src/code/z_scene.c b/src/code/z_scene.c index efaadf4bf..e77144528 100644 --- a/src/code/z_scene.c +++ b/src/code/z_scene.c @@ -221,8 +221,8 @@ void Scene_HeaderCmdEntranceList(GlobalContext* globalCtx, SceneCmd* cmd) { // SceneTableEntry Header Command 0x07: Special Files void Scene_HeaderCmdSpecialFiles(GlobalContext* globalCtx, SceneCmd* cmd) { static RomFile tatlMessageFiles[2] = { - { (u32)_elf_message_fieldSegmentRomStart, (u32)_elf_message_fieldSegmentRomEnd }, - { (u32)_elf_message_ydanSegmentRomStart, (u32)_elf_message_ydanSegmentRomEnd }, + { SEGMENT_ROM_START(elf_message_field), SEGMENT_ROM_END(elf_message_field) }, + { SEGMENT_ROM_START(elf_message_ydan), SEGMENT_ROM_END(elf_message_ydan) }, }; if (cmd->specialFiles.subKeepIndex != 0) { @@ -344,14 +344,14 @@ void Scene_HeaderCmdEnvLightSettings(GlobalContext* globalCtx, SceneCmd* cmd) { s32 Scene_LoadAreaTextures(GlobalContext* globalCtx, s32 fileIndex) { static RomFile sceneTextureFiles[9] = { { 0, 0 }, // Default - { (u32)_scene_texture_01SegmentRomStart, (u32)_scene_texture_01SegmentRomEnd }, - { (u32)_scene_texture_02SegmentRomStart, (u32)_scene_texture_02SegmentRomEnd }, - { (u32)_scene_texture_03SegmentRomStart, (u32)_scene_texture_03SegmentRomEnd }, - { (u32)_scene_texture_04SegmentRomStart, (u32)_scene_texture_04SegmentRomEnd }, - { (u32)_scene_texture_05SegmentRomStart, (u32)_scene_texture_05SegmentRomEnd }, - { (u32)_scene_texture_06SegmentRomStart, (u32)_scene_texture_06SegmentRomEnd }, - { (u32)_scene_texture_07SegmentRomStart, (u32)_scene_texture_07SegmentRomEnd }, - { (u32)_scene_texture_08SegmentRomStart, (u32)_scene_texture_08SegmentRomEnd }, + { SEGMENT_ROM_START(scene_texture_01), SEGMENT_ROM_END(scene_texture_01) }, + { SEGMENT_ROM_START(scene_texture_02), SEGMENT_ROM_END(scene_texture_02) }, + { SEGMENT_ROM_START(scene_texture_03), SEGMENT_ROM_END(scene_texture_03) }, + { SEGMENT_ROM_START(scene_texture_04), SEGMENT_ROM_END(scene_texture_04) }, + { SEGMENT_ROM_START(scene_texture_05), SEGMENT_ROM_END(scene_texture_05) }, + { SEGMENT_ROM_START(scene_texture_06), SEGMENT_ROM_END(scene_texture_06) }, + { SEGMENT_ROM_START(scene_texture_07), SEGMENT_ROM_END(scene_texture_07) }, + { SEGMENT_ROM_START(scene_texture_08), SEGMENT_ROM_END(scene_texture_08) }, }; u32 vromStart = sceneTextureFiles[fileIndex].vromStart; u32 size = sceneTextureFiles[fileIndex].vromEnd - vromStart; diff --git a/src/code/z_scene_table.c b/src/code/z_scene_table.c index cee8546f0..8372c350a 100644 --- a/src/code/z_scene_table.c +++ b/src/code/z_scene_table.c @@ -1,7 +1,7 @@ #include "global.h" #define SCENE_ENTRY(name, textId, config) \ - { { (u32)_##name##SegmentRomStart, (u32)_##name##SegmentRomEnd }, textId, 0, config, 0 } + { { SEGMENT_ROM_START(name), SEGMENT_ROM_END(name) }, textId, 0, config, 0 } #define SCENE_ENTRY_NONE() \ { { 0, 0 }, 0, 0, 0, 0 } diff --git a/src/code/z_vr_box.c b/src/code/z_vr_box.c index 5c00758d2..1fca4801d 100644 --- a/src/code/z_vr_box.c +++ b/src/code/z_vr_box.c @@ -50,21 +50,21 @@ void func_801431E8(GameState* gamestate, SkyboxContext* skyboxCtx, s16 skyType) } else { // Send a DMA request for the cloudy sky texture skyboxCtx->skyboxStaticSegment[0] = &D_80025D00; - size = (u32)_d2_cloud_staticSegmentRomEnd - (u32)_d2_cloud_staticSegmentRomStart; + size = SEGMENT_ROM_SIZE(d2_cloud_static); offset = (void*)ALIGN8((u32)skyboxCtx->skyboxStaticSegment[0] + size); - DmaMgr_SendRequest0(skyboxCtx->skyboxStaticSegment[0], (u32)_d2_cloud_staticSegmentRomStart, size); + DmaMgr_SendRequest0(skyboxCtx->skyboxStaticSegment[0], SEGMENT_ROM_START(d2_cloud_static), size); // Send a DMA request for the clear sky texture skyboxCtx->skyboxStaticSegment[1] = offset; - size = (u32)_d2_fine_staticSegmentRomEnd - (u32)_d2_fine_staticSegmentRomStart; + size = SEGMENT_ROM_SIZE(d2_fine_static); offset = (void*)ALIGN8((u32)offset + size); - DmaMgr_SendRequest0(skyboxCtx->skyboxStaticSegment[1], (u32)_d2_fine_staticSegmentRomStart, size); + DmaMgr_SendRequest0(skyboxCtx->skyboxStaticSegment[1], SEGMENT_ROM_START(d2_fine_static), size); // Send a DMA request for the skybox palette skyboxCtx->skyboxPaletteStaticSegment = offset; - size = (u32)_d2_fine_pal_staticSegmentRomEnd - (u32)_d2_fine_pal_staticSegmentRomStart; + size = SEGMENT_ROM_SIZE(d2_fine_pal_static); offset = (void*)ALIGN8((u32)offset + size); - DmaMgr_SendRequest0(skyboxCtx->skyboxPaletteStaticSegment, (u32)_d2_fine_pal_staticSegmentRomStart, size); + DmaMgr_SendRequest0(skyboxCtx->skyboxPaletteStaticSegment, SEGMENT_ROM_START(d2_fine_pal_static), size); skyboxCtx->primR = 145; skyboxCtx->primG = 120; @@ -91,16 +91,16 @@ void func_80143324(GlobalContext* globalCtx, SkyboxContext* skyboxCtx, s16 skyTy if (globalCtx->envCtx.unk_10 == 0) { // Send a DMA request for the clear sky texture - size = (u32)_d2_fine_staticSegmentRomEnd - (u32)_d2_fine_staticSegmentRomStart; + size = SEGMENT_ROM_SIZE(d2_fine_static); DmaMgr_SendRequestImpl(&skyboxCtx->unk188, skyboxCtx->skyboxStaticSegment[0], - (u32)_d2_fine_staticSegmentRomStart, size, 0, &skyboxCtx->loadQueue, NULL); + SEGMENT_ROM_START(d2_fine_static), size, 0, &skyboxCtx->loadQueue, NULL); } else { // Send a DMA request for the cloudy sky texture - size = (u32)_d2_cloud_staticSegmentRomEnd - (u32)_d2_cloud_staticSegmentRomStart; + size = SEGMENT_ROM_SIZE(d2_cloud_static); DmaMgr_SendRequestImpl(&skyboxCtx->unk188, skyboxCtx->skyboxStaticSegment[0], - (u32)_d2_cloud_staticSegmentRomStart, size, 0, &skyboxCtx->loadQueue, NULL); + SEGMENT_ROM_START(d2_cloud_static), size, 0, &skyboxCtx->loadQueue, NULL); } osRecvMesg(&skyboxCtx->loadQueue, NULL, 1); @@ -108,26 +108,26 @@ void func_80143324(GlobalContext* globalCtx, SkyboxContext* skyboxCtx, s16 skyTy if (globalCtx->envCtx.unk_11 == 0) { // Send a DMA request for the clear sky texture - size = (u32)_d2_fine_staticSegmentRomEnd - (u32)_d2_fine_staticSegmentRomStart; + size = SEGMENT_ROM_SIZE(d2_fine_static); DmaMgr_SendRequestImpl(&skyboxCtx->unk1A8, skyboxCtx->skyboxStaticSegment[1], - (u32)_d2_fine_staticSegmentRomStart, size, 0, &skyboxCtx->loadQueue, NULL); + SEGMENT_ROM_START(d2_fine_static), size, 0, &skyboxCtx->loadQueue, NULL); } else { // Send a DMA request for the cloudy sky texture - size = (u32)_d2_cloud_staticSegmentRomEnd - (u32)_d2_cloud_staticSegmentRomStart; + size = SEGMENT_ROM_SIZE(d2_cloud_static); DmaMgr_SendRequestImpl(&skyboxCtx->unk1A8, skyboxCtx->skyboxStaticSegment[1], - (u32)_d2_cloud_staticSegmentRomStart, size, 0, &skyboxCtx->loadQueue, NULL); + SEGMENT_ROM_START(d2_cloud_static), size, 0, &skyboxCtx->loadQueue, NULL); } osRecvMesg(&skyboxCtx->loadQueue, NULL, 1); osCreateMesgQueue(&skyboxCtx->loadQueue, &skyboxCtx->loadMsg, 1); - size = (u32)_d2_fine_pal_staticSegmentRomEnd - (u32)_d2_fine_pal_staticSegmentRomStart; + size = SEGMENT_ROM_SIZE(d2_fine_pal_static); // Send a DMA request for the skybox palette DmaMgr_SendRequestImpl(&skyboxCtx->unk1C8, skyboxCtx->skyboxPaletteStaticSegment, - (u32)_d2_fine_pal_staticSegmentRomStart, size, 0, &skyboxCtx->loadQueue, NULL); + SEGMENT_ROM_START(d2_fine_pal_static), size, 0, &skyboxCtx->loadQueue, NULL); osRecvMesg(&skyboxCtx->loadQueue, NULL, 1); } diff --git a/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/src/overlays/actors/ovl_En_Dns/z_en_dns.c index 98f8dd5d3..1249e2430 100644 --- a/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -431,7 +431,7 @@ void func_8092D330(EnDns* this, GlobalContext* globalCtx) { if ((this->unk_2C6 & 0x100) && (DECR(this->unk_2D0) == 0)) { this->unk_2C6 &= ~0x100; globalCtx->nextEntranceIndex = 0x5010; - gSaveContext.unk_3F4A = 0; + gSaveContext.nextCutsceneIndex = 0; globalCtx->sceneLoadFlag = 0x14; globalCtx->unk_1887F = 3; gSaveContext.nextTransition = 3; 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 1b3cf562f..613caad0a 100644 --- a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c +++ b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c @@ -2041,7 +2041,7 @@ void func_80B47108(EnInvadepoh* this, GlobalContext* globalCtx) { this->actionTimer--; if (this->actionTimer <= 0) { globalCtx->nextEntranceIndex = 0x6460; - gSaveContext.unk_3F4A = 0; + gSaveContext.nextCutsceneIndex = 0; globalCtx->sceneLoadFlag = 0x14; globalCtx->unk_1887F = 0x49; gSaveContext.nextTransition = 0x48; @@ -2059,7 +2059,7 @@ void func_80B471C0(EnInvadepoh* this) { void func_80B471E0(EnInvadepoh* this, GlobalContext* globalCtx) { if (D_80B4E998) { globalCtx->nextEntranceIndex = 0x6470; - gSaveContext.unk_3F4A = 0; + gSaveContext.nextCutsceneIndex = 0; globalCtx->sceneLoadFlag = 0x14; globalCtx->unk_1887F = 0x48; gSaveContext.nextTransition = 0x48; @@ -2082,7 +2082,7 @@ void func_80B47278(EnInvadepoh* this) { void func_80B47298(EnInvadepoh* this, GlobalContext* globalCtx) { globalCtx->nextEntranceIndex = 0x6400; - gSaveContext.unk_3F4A = 0xFFF3; + gSaveContext.nextCutsceneIndex = 0xFFF3; globalCtx->sceneLoadFlag = 0x14; globalCtx->unk_1887F = 0x48; gSaveContext.nextTransition = 0x48; 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 4d07c983a..a0d27353a 100644 --- a/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c +++ b/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c @@ -685,7 +685,7 @@ void EnMa4_SetupBeginHorsebackGame(EnMa4* this) { void EnMa4_BeginHorsebackGame(EnMa4* this, GlobalContext* globalCtx) { globalCtx->nextEntranceIndex = 0x6400; - gSaveContext.unk_3F4A = 0xFFF0; + gSaveContext.nextCutsceneIndex = 0xFFF0; globalCtx->sceneLoadFlag = 0x14; globalCtx->unk_1887F = 0x50; gSaveContext.nextTransition = 3; @@ -776,7 +776,7 @@ void EnMa4_HorsebackGameEnd(EnMa4* this, GlobalContext* globalCtx) { } else if (sFrameCounter == 50) { globalCtx->actorCtx.unk268 = 0; globalCtx->nextEntranceIndex = 0x6410; - gSaveContext.unk_3F4A = 0; + gSaveContext.nextCutsceneIndex = 0; sFrameCounter = 0; globalCtx->sceneLoadFlag = 0x14; @@ -883,7 +883,7 @@ void EnMa4_SetupBeginDescribeThemCs(EnMa4* this) { void EnMa4_BeginDescribeThemCs(EnMa4* this, GlobalContext* globalCtx) { globalCtx->nextEntranceIndex = 0x6400; - gSaveContext.unk_3F4A = 0xFFF5; + gSaveContext.nextCutsceneIndex = 0xFFF5; globalCtx->sceneLoadFlag = 0x14; globalCtx->unk_1887F = 0x40; gSaveContext.nextTransition = 2; diff --git a/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c b/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c index 04c1e060f..1c9987a8e 100644 --- a/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c +++ b/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c @@ -1119,7 +1119,7 @@ void EnMaYto_PostMilkRunEnd(EnMaYto* this, GlobalContext* globalCtx) { // Romani Ranch globalCtx->nextEntranceIndex = 0x6480; } - gSaveContext.unk_3F4A = 0; + gSaveContext.nextCutsceneIndex = 0; globalCtx->sceneLoadFlag = 0x14; globalCtx->unk_1887F = 0x50; gSaveContext.nextTransition = 3; diff --git a/src/overlays/gamestates/ovl_daytelop/z_daytelop.c b/src/overlays/gamestates/ovl_daytelop/z_daytelop.c index c6b9078a4..ba34c2448 100644 --- a/src/overlays/gamestates/ovl_daytelop/z_daytelop.c +++ b/src/overlays/gamestates/ovl_daytelop/z_daytelop.c @@ -1,22 +1,247 @@ /* * File: z_daytelop.c * Overlay: ovl_daytelop - * Description: + * Description: "Dawn of ... day" screen */ #include "z_daytelop.h" +#include "static/daytelop_static/daytelop_static.h" +#include "static/icon_item_gameover_static/icon_item_gameover_static.h" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_daytelop/Daytelop_Update.s") +// unused +UNK_TYPE D_808158E0[] = { + 0x00000C00, 0x00000000, 0x00000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000C04, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00100000, 0x00000000, 0x00000000, 0x40000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x04000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000F, 0x00000000, 0x00000000, 0x00000000, + 0x0070B000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x80000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01A00020, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00001000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000400, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0x00100400, 0x00000000, 0x00000000, 0x00000022, 0x00000400, + 0x00000000, 0x00000000, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x80000002, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0x00000C00, 0x00000000, 0x00000000, + 0x40000000, 0x00000102, 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0x00000000, 0x40000000, 0x00000070, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00100000, 0x00000000, 0x00000000, 0x80000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, + 0x00100000, 0x00000000, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00000400, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x00000000, 0x00000000, + 0x00000000, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000400, 0x00100000, 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, + 0x00000001, 0x00000000, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_daytelop/Daytelop_Draw.s") +void Daytelop_Update(DaytelopContext* this, GameState* gameState) { + static u8 D_80815FF0 = 0; + s16 new_var; + u8 temp_v0_2; -void Daytelop_Main(GameState* thisx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_daytelop/Daytelop_Main.s") + this->transitionCountdown--; + if (this->transitionCountdown == 0) { + if (gSaveContext.day < 9) { + gSaveContext.gameMode = 0; + } else { + gSaveContext.nextCutsceneIndex = 0xFFF6; + gSaveContext.day = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_daytelop/Daytelop_Destroy.s") + { + GameState* state = &this->state; + state->running = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_daytelop/Daytelop_nop80815770.s") + SET_NEXT_GAMESTATE(&this->state, Play_Init, GlobalContext); + gSaveContext.time = CLOCK_TIME(6, 0); + D_801BDBC8 = 0xFE; + } else if (this->transitionCountdown == 90) { + this->fadeInState = DAYTELOP_HOURSTEXT_FADEIN; + this->alpha = 0; + D_80815FF0 = 30; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_daytelop/Daytelop_LoadGraphics.s") + if (this->fadeInState == DAYTELOP_HOURSTEXT_FADEIN) { + this->alpha += (s16)(ABS_ALT(this->alpha - 0xFF) / D_80815FF0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_daytelop/Daytelop_Init.s") + D_80815FF0--; + if (D_80815FF0 == 0) { + this->fadeInState = DAYTELOP_HOURSTEXT_ON; + this->alpha = 255; + } + } +} + +TexturePtr sDayLeftTextures[] = { + gDaytelopFirstDayLeftNESTex, + gDaytelopSecondDayLeftNESTex, + gDaytelopFinalDayLeftNESTex, + + // Last element is the new day + gDaytelopNewDayLeftNESTex, +}; + +TexturePtr sDayRightTextures[] = { + gDaytelopFirstDayRightNESTex, + gDaytelopSecondDayRightNESTex, + gDaytelopFinalDayRightNESTex, + + // Last element is the new day + gDaytelopNewDayRightNESTex, +}; + +TexturePtr sHoursLeftTextures[] = { + gDaytelop72HoursNESTex, + gDaytelop48HoursNESTex, + gDaytelop24HoursNESTex, +}; + +void Daytelop_Draw(DaytelopContext* this) { + GraphicsContext* gfxCtx = this->state.gfxCtx; + + OPEN_DISPS(gfxCtx); + func_8012C628(this->state.gfxCtx); + + if (gSaveContext.day >= 9) { + // Draw a white screen + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gDPFillRectangle(POLY_OPA_DISP++, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + } + + func_8012C628(this->state.gfxCtx); + + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_OPA_SURF, G_RM_OPA_SURF2); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + + if (gSaveContext.day >= 9) { + gDPSetAlphaCompare(POLY_OPA_DISP++, G_AC_NONE); + } + + // Draw the left side of the "Dawn of" texture + if (gSaveContext.day < 9) { + gDPLoadTextureBlock_4b(POLY_OPA_DISP++, sDayLeftTextures[CURRENT_DAY - 1], G_IM_FMT_I, 128, 64, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } else { + gDPLoadTextureBlock_4b(POLY_OPA_DISP++, sDayLeftTextures[ARRAY_COUNT(sDayLeftTextures) - 1], G_IM_FMT_I, 128, + 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } + gSPTextureRectangle(POLY_OPA_DISP++, 32 << 2, 77 << 2, (32 + 128) << 2, (77 + 64) << 2, G_TX_RENDERTILE, 0, 0, + 0x0400, 0x0400); + + // Draw the right side of the "Dawn of" texture + if (gSaveContext.day < 9) { + gDPLoadTextureBlock_4b(POLY_OPA_DISP++, sDayRightTextures[CURRENT_DAY - 1], G_IM_FMT_I, 128, 64, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } else { + gDPLoadTextureBlock_4b(POLY_OPA_DISP++, sDayRightTextures[ARRAY_COUNT(sDayRightTextures) - 1], G_IM_FMT_I, 128, + 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } + gSPTextureRectangle(POLY_OPA_DISP++, 160 << 2, 77 << 2, (160 + 128) << 2, (77 + 64) << 2, G_TX_RENDERTILE, 0, 0, + 0x0400, 0x0400); + + // Draw the "Hours left" texture + if (gSaveContext.day < 9) { + gDPPipeSync(POLY_OPA_DISP++); + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->alpha); + gDPLoadTextureBlock_4b(POLY_OPA_DISP++, sHoursLeftTextures[CURRENT_DAY - 1], G_IM_FMT_I, 144, 32, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + gSPTextureRectangle(POLY_OPA_DISP++, 88 << 2, 144 << 2, (88 + 144) << 2, (144 + 32) << 2, G_TX_RENDERTILE, 0, 0, + 0x0400, 0x0400); + } + + CLOSE_DISPS(this->state.gfxCtx); +} + +void Daytelop_Main(GameState* thisx) { + DaytelopContext* this = (DaytelopContext*)thisx; + + func_8012CF0C(this->state.gfxCtx, 1, 1, 0, 0, 0); + + OPEN_DISPS(this->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x09, this->daytelopStaticFile); + gSPSegment(POLY_OPA_DISP++, 0x0C, this->gameoverStaticFile); + CLOSE_DISPS(this->state.gfxCtx); + + Daytelop_Draw(this); + Daytelop_Update(this, &this->state); +} + +void Daytelop_Destroy(GameState* thisx) { + ShrinkWindow_Fini(); +} + +void Daytelop_nop80815770(DaytelopContext* this) { +} + +void Daytelop_LoadGraphics(DaytelopContext* this) { + size_t segmentSize = SEGMENT_ROM_SIZE(daytelop_static); + + this->daytelopStaticFile = THA_AllocEndAlign16(&this->state.heap, segmentSize); + DmaMgr_SendRequest0(this->daytelopStaticFile, SEGMENT_ROM_START(daytelop_static), segmentSize); + + segmentSize = SEGMENT_ROM_SIZE(icon_item_gameover_static); + this->gameoverStaticFile = THA_AllocEndAlign16(&this->state.heap, segmentSize); + DmaMgr_SendRequest0(this->gameoverStaticFile, SEGMENT_ROM_START(icon_item_gameover_static), segmentSize); +} + +void Daytelop_Init(GameState* thisx) { + DaytelopContext* this = (DaytelopContext*)thisx; + + Game_SetFramerateDivisor(thisx, 1); + SysMatrix_StateAlloc(thisx); + ShrinkWindow_Fini(); + View_Init(&this->view, thisx->gfxCtx); + thisx->main = Daytelop_Main; + thisx->destroy = Daytelop_Destroy; + this->transitionCountdown = 140; + this->fadeInState = DAYTELOP_HOURSTEXT_OFF; + + if (gSaveContext.day < 9) { + if (gSaveContext.day == 0) { + func_80143AC4(); + } + Sram_IncrementDay(); + } + + Daytelop_nop80815770(this); + Daytelop_LoadGraphics(this); + play_sound(NA_SE_OC_TELOP_IMPACT); +} diff --git a/src/overlays/gamestates/ovl_daytelop/z_daytelop.h b/src/overlays/gamestates/ovl_daytelop/z_daytelop.h index d2788e0e9..eca743850 100644 --- a/src/overlays/gamestates/ovl_daytelop/z_daytelop.h +++ b/src/overlays/gamestates/ovl_daytelop/z_daytelop.h @@ -7,14 +7,21 @@ void Daytelop_Init(GameState* thisx); void Daytelop_Destroy(GameState* thisx); typedef struct { - /* 0x000 */ GameState common; - /* 0x0A4 */ UNK_TYPE1 padA4[0xC]; + /* 0x000 */ GameState state; + /* 0x0A4 */ void* daytelopStaticFile; + /* 0x0A8 */ void* gameoverStaticFile; + /* 0x0AC */ UNK_TYPE1 unk_AC[0x4]; /* 0x0B0 */ View view; - /* 0x218 */ UNK_TYPE1 pad218[0x28]; + /* 0x218 */ UNK_TYPE1 unk_218[0x28]; /* 0x240 */ s16 transitionCountdown; - /* 0x242 */ s16 unk242; - /* 0x244 */ s16 unk244; - /* 0x246 */ UNK_TYPE1 pad246[0x2]; + /* 0x242 */ s16 fadeInState; + /* 0x244 */ s16 alpha; } DaytelopContext; // size = 0x248 +typedef enum { + /* 0 */ DAYTELOP_HOURSTEXT_OFF, + /* 1 */ DAYTELOP_HOURSTEXT_FADEIN, + /* 2 */ DAYTELOP_HOURSTEXT_ON +} Daytelop_FadeState; + #endif diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 8a38052af..a2b28c247 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -4888,9 +4888,10 @@ 0x808147F0:("D_808147F0","f32","",0x4), 0x80814E80:("D_80814E80","UNK_TYPE1","",0x1), 0x80814E90:("D_80814E90","UNK_TYPE1","",0x1), - 0x80815FF0:("D_80815FF0","u32","[4]",0x10), - 0x80816000:("D_80816000","u32","[4]",0x10), - 0x80816010:("D_80816010","u32","[4]",0x10), + 0x80815FF0:("D_80815FF0","u8","",0x1), + 0x80815FF4:("sDayLeftTextures","TexturePtr","[4]",0x10), + 0x80816004:("sDayRightTextures","TexturePtr","[4]",0x10), + 0x80816014:("sHoursLeftTextures","TexturePtr","[3]",0xC), 0x8082AED0:("D_8082AED0","UNK_TYPE1","",0x1), 0x8082AED8:("D_8082AED8","UNK_TYPE1","",0x1), 0x8082AEE0:("D_8082AEE0","UNK_TYPE2","",0x2), diff --git a/tools/permuter_settings.toml b/tools/permuter_settings.toml index ac4e1533c..82ce7cdfe 100644 --- a/tools/permuter_settings.toml +++ b/tools/permuter_settings.toml @@ -11,6 +11,7 @@ CLOSE_DISPS = "void" ABS = "int" SQ = "int" CLAMP = "int" +CLOCK_TIME = "int" [decompme.compilers] "tools/ido_recomp/linux/7.1/cc" = "ido7.1" @@ -18,4 +19,4 @@ CLAMP = "int" "tools/ido_recomp/windows/7.1/cc" = "ido7.1" "tools/ido_recomp/linux/5.3/cc" = "ido5.3" "tools/ido_recomp/macos/5.3/cc" = "ido5.3" -"tools/ido_recomp/windows/5.3/cc" = "ido5.3" \ No newline at end of file +"tools/ido_recomp/windows/5.3/cc" = "ido5.3" From 9e4d51fb9ffc676607f6eb793fb21ef47c891ce5 Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Fri, 24 Sep 2021 00:14:12 +0100 Subject: [PATCH 03/13] printutils OK, add `va_end` to variadic functions (#294) * printutils OK * Add va_end to every variadic function --- include/functions.h | 4 ++-- src/boot_O2/gfxprint.c | 4 +++- src/boot_O2/printutils.c | 13 +++++++++++-- src/boot_O2_g3/fault_drawer.c | 4 ++++ src/libultra/rmon/sprintf.c | 9 ++++++--- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/include/functions.h b/include/functions.h index 98cfefe65..367d784ae 100644 --- a/include/functions.h +++ b/include/functions.h @@ -236,8 +236,8 @@ u32 __osCheckArena(Arena* heap); void* proutSprintf(void* s, const char* buf, size_t n); s32 vsprintf(char* dst, char* fmt, va_list args); s32 sprintf(char* s, char* fmt, ...); -void PrintUtils_VPrintf(void* callback, const char* fmt, va_list args); -// void PrintUtils_Printf(void); +void PrintUtils_VPrintf(PrintCallback* pfn, const char* fmt, va_list args); +void PrintUtils_Printf(PrintCallback* pfn, const char* fmt, ...); void Sleep_Cycles(OSTime time); // void Sleep_Nsec(void); void Sleep_Usec(s32); diff --git a/src/boot_O2/gfxprint.c b/src/boot_O2/gfxprint.c index 485799678..f671c6f5c 100644 --- a/src/boot_O2/gfxprint.c +++ b/src/boot_O2/gfxprint.c @@ -172,7 +172,7 @@ Gfx* GfxPrint_Close(GfxPrint* this) { } void GfxPrint_VPrintf(GfxPrint* this, const char* fmt, va_list args) { - PrintUtils_VPrintf(&this->callback, fmt, args); + PrintUtils_VPrintf((PrintCallback*)&this->callback, fmt, args); } void GfxPrint_Printf(GfxPrint* this, const char* fmt, ...) { @@ -180,4 +180,6 @@ void GfxPrint_Printf(GfxPrint* this, const char* fmt, ...) { va_start(args, fmt); GfxPrint_VPrintf(this, fmt, args); + + va_end(args); } diff --git a/src/boot_O2/printutils.c b/src/boot_O2/printutils.c index fb5b81033..4f04fca14 100644 --- a/src/boot_O2/printutils.c +++ b/src/boot_O2/printutils.c @@ -1,5 +1,14 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/printutils/PrintUtils_VPrintf.s") +void PrintUtils_VPrintf(PrintCallback* pfn, const char* fmt, va_list args) { + _Printf(*pfn, pfn, fmt, args); +} -#pragma GLOBAL_ASM("asm/non_matchings/boot/printutils/PrintUtils_Printf.s") +void PrintUtils_Printf(PrintCallback* pfn, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + + PrintUtils_VPrintf(pfn, fmt, args); + + va_end(args); +} diff --git a/src/boot_O2_g3/fault_drawer.c b/src/boot_O2_g3/fault_drawer.c index a5d728864..74a3b7e5e 100644 --- a/src/boot_O2_g3/fault_drawer.c +++ b/src/boot_O2_g3/fault_drawer.c @@ -153,6 +153,8 @@ void FaultDrawer_Printf(const char* fmt, ...) { va_start(args, fmt); FaultDrawer_VPrintf(fmt, args); + + va_end(args); } void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...) { @@ -161,6 +163,8 @@ void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...) { FaultDrawer_SetCursor(x, y); FaultDrawer_VPrintf(fmt, args); + + va_end(args); } void FaultDrawer_SetDrawerFB(void* fb, u16 w, u16 h) { diff --git a/src/libultra/rmon/sprintf.c b/src/libultra/rmon/sprintf.c index 7658bbd30..446a74702 100644 --- a/src/libultra/rmon/sprintf.c +++ b/src/libultra/rmon/sprintf.c @@ -14,12 +14,15 @@ int vsprintf(char* dst, char* fmt, va_list args) { int sprintf(char* dst, char* fmt, ...) { int ans; - va_list ap; - va_start(ap, fmt); + va_list args; + va_start(args, fmt); - ans = _Printf(&proutSprintf, dst, fmt, ap); + ans = _Printf(&proutSprintf, dst, fmt, args); if (ans > -1) { dst[ans] = 0; } + + va_end(args); + return ans; } From f77cfb9020da043b2a104f9637a0d7873cfac6c9 Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Sat, 25 Sep 2021 14:36:15 +0100 Subject: [PATCH 04/13] Remove `.mdebug` sections by default (#313) * Add RM_MDEBUG to makefile * Add to diff settings to allow use of --source --- Makefile | 13 +++++++++++++ diff_settings.py | 1 + 2 files changed, 14 insertions(+) diff --git a/Makefile b/Makefile index 21d954572..0d0326231 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,8 @@ COMPARE ?= 1 NON_MATCHING ?= 0 # If ORIG_COMPILER is 1, compile with QEMU_IRIX and the original compiler ORIG_COMPILER ?= 0 +# Keep .mdebug section in build +KEEP_MDEBUG ?= 0 ifeq ($(NON_MATCHING),1) CFLAGS := -DNON_MATCHING @@ -68,6 +70,12 @@ LD := $(MIPS_BINUTILS_PREFIX)ld OBJCOPY := $(MIPS_BINUTILS_PREFIX)objcopy OBJDUMP := $(MIPS_BINUTILS_PREFIX)objdump +ifeq ($(KEEP_MDEBUG),0) + RM_MDEBUG = $(OBJCOPY) --remove-section .mdebug $@ +else + RM_MDEBUG = @: +endif + # Check code syntax with host compiler CHECK_WARNINGS := -Wall -Wextra -Wno-format-security -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable -Wno-missing-braces -Wno-int-conversion -Wno-unused-but-set-variable -Wno-unused-label CC_CHECK := gcc -fno-builtin -fsyntax-only -funsigned-char -std=gnu90 -D _LANGUAGE_C -D NON_MATCHING -Iinclude -Isrc -Iassets -Ibuild -include stdarg.h $(CHECK_WARNINGS) @@ -236,6 +244,7 @@ init: build/assets/%.o: assets/%.c $(CC) -I build/ -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< + $(RM_MDEBUG) #### Various Recipes #### @@ -263,23 +272,27 @@ build/src/overlays/%.o: src/overlays/%.c # the following is moved to a separate rule that is only run once when all the required objects have been compiled. $(ZAPD) bovl -eh -i $@ -cfg $< --outputpath $(@D)/$(notdir $(@D))_reloc.s (test -f $(@D)/$(notdir $(@D))_reloc.s && $(AS) $(ASFLAGS) $(@D)/$(notdir $(@D))_reloc.s -o $(@D)/$(notdir $(@D))_reloc.o) || true + $(RM_MDEBUG) build/src/%.o: src/%.c $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< $(CC_CHECK) $< @$(OBJDUMP) -d $@ > $(@:.o=.s) + $(RM_MDEBUG) build/src/libultra/libc/ll.o: src/libultra/libc/ll.c $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< $(CC_CHECK) $< python3 tools/set_o32abi_bit.py $@ @$(OBJDUMP) -d $@ > $(@:.o=.s) + $(RM_MDEBUG) build/src/libultra/libc/llcvt.o: src/libultra/libc/llcvt.c $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< $(CC_CHECK) $< python3 tools/set_o32abi_bit.py $@ @$(OBJDUMP) -d $@ > $(@:.o=.s) + $(RM_MDEBUG) # Build C files from assets build/%.inc.c: %.png diff --git a/diff_settings.py b/diff_settings.py index 45d56dc2b..a6cee9dc8 100755 --- a/diff_settings.py +++ b/diff_settings.py @@ -5,3 +5,4 @@ def apply(config, args): config['myimg'] = 'mm.us.rev1.rom_uncompressed.z64' config['mapfile'] = 'build/mm.map' config['source_directories'] = ['./src','./include'] + config['makeflags'] = ['KEEP_MDEBUG=1'] From bc5c3866d5d7fb993abd5301d96ed76410dd0df4 Mon Sep 17 00:00:00 2001 From: rylieb <31797144+rylieb@users.noreply.github.com> Date: Sat, 25 Sep 2021 07:53:53 -0600 Subject: [PATCH 05/13] Obj_Syokudai (Torch) OK and mostly documented (#306) * Started uncommenting statics, but then realized this actor has BSS, lol. * Import .data and .bss. Run format.sh. * ObjSyokudai_Init OK and mostly documented. * ObjSyokudai_Destroy OK and fully documented. * ObjSyokudai_Draw OK and partially documented. * Good progress on ObjSyokudai_Update, but NOT OK. * Instruction match, but needs regalloc and stack. * Stack is closer now. * Obj_Syokudai OK, no new warnings, ran formatter. * Documented .data and .bss variables. * Final documentation pass before PR. * Add header, fix build errors. * Use COLTYPE_METAL and COLTYPE_WOOD macros. * Apply suggestions from code review engineer124's suggestions. Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Apply suggestions from code review engineer124: WaterBox* instead of UNK_PTR Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c engineer124: AC_HARD -> AC_HIT so Jenkins stops complaining Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Hopefully fix Jenkins via z_bg_lotus WaterBox*. * Rename sp2C to waterBox in BgLotus. * Run format.sh. * Update include/functions.h Change func_800F22C4 param_1 from s8 to s16. Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Change func_801A5CFC param_1 to sfxId in prototype * Document interactions. * Run formatter. * Clarify that posDiff is relative to stick *tip*. * Changed interaction comparisons to better fit enum * snuffTimer enum * Added more #defines. Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> --- include/functions.h | 8 +- include/variables.h | 4 +- spec | 4 +- src/overlays/actors/ovl_Bg_Lotus/z_bg_lotus.c | 4 +- src/overlays/actors/ovl_En_Arrow/z_en_arrow.h | 4 +- .../actors/ovl_En_Firefly/z_en_firefly.c | 2 +- .../actors/ovl_Obj_Syokudai/z_obj_syokudai.c | 299 ++++++++++++++++-- .../actors/ovl_Obj_Syokudai/z_obj_syokudai.h | 50 ++- tools/disasm/variables.txt | 12 +- undefined_syms.txt | 6 + 10 files changed, 351 insertions(+), 42 deletions(-) diff --git a/include/functions.h b/include/functions.h index 367d784ae..e16858aa1 100644 --- a/include/functions.h +++ b/include/functions.h @@ -696,7 +696,7 @@ void func_800B40E0(GlobalContext* globalCtx, Light* light, MtxF* arg2, s32 arg3, void func_800B42F8(Actor* actor, Lights* mapper, GlobalContext* globalCtx); // void func_800B4A98(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); void func_800B4AEC(GlobalContext* globalCtx, Actor* actor, f32 param_3); -void func_800B4B50(Actor* actor, s32 iParm2, GlobalContext* globalCtx); +void func_800B4B50(Actor* actor, Lights* mapper, GlobalContext* globalCtx); void func_800B4EDC(GlobalContext* globalCtx, Vec3f* pzParm2, Vec3f* pzParm3, f32* pfParm4); // void func_800B4F40(TargetContext* targetCtx, s32 param_2, UNK_TYPE4 param_3, UNK_TYPE4 param_4, UNK_TYPE4 param_5); void func_800B4F78(TargetContext* targetCtx, u8 type, GlobalContext* globalCtx); @@ -1110,7 +1110,7 @@ u32 func_800C9E40(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); u32 func_800C9E88(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); // void func_800C9EBC(GlobalContext* globalCtx, CollisionContext* colCtx, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); s32 func_800CA1AC(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox); -void func_800CA1E8(GlobalContext* globalCtx, CollisionContext* colCtx, f32 arg2, f32 arg3, f32* arg4, UNK_PTR arg5); +s32 func_800CA1E8(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox); // void func_800CA22C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); // void func_800CA568(void); // void func_800CA634(void); @@ -1687,7 +1687,7 @@ s16 ActorCutscene_GetLength(s16 index); // void func_800F2178(void); s16 ActorCutscene_GetCurrentCamera(s16 index); // void func_800F21CC(void); -// UNK_TYPE4 func_800F22C4(s16 param_1, Actor* actor); +s32 func_800F22C4(s16 param_1, Actor* actor); void ActorCutscene_SetReturnCamera(s16 index); // void func_800F23E0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); // void func_800F2478(void); @@ -3992,7 +3992,7 @@ UNK_TYPE func_801A51F0(UNK_TYPE arg0); void func_801A5BD0(s32 param_1); // void func_801A5C28(void); // void func_801A5C8C(void); -// void func_801A5CFC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); +void func_801A5CFC(u16 sfxId, Vec3f* param_2, u8 param_3, f32* param_4, f32* param_5, s8* param_6); // void func_801A5DDC(void); // void func_801A5F7C(void); // void func_801A6430(void); diff --git a/include/variables.h b/include/variables.h index 258cec4df..f2fd0f2b4 100644 --- a/include/variables.h +++ b/include/variables.h @@ -1876,8 +1876,8 @@ extern UNK_PTR D_801DB478[7]; // extern UNK_TYPE1 D_801DB49C; // extern UNK_TYPE2 D_801DB4A0; extern UNK_TYPE D_801DB4A4; -// extern UNK_TYPE1 D_801DB4B0; -// extern UNK_TYPE1 D_801DB4B8; +extern f32 D_801DB4B0; +extern s8 D_801DB4B8; // extern UNK_TYPE1 D_801DB4C0; // extern UNK_TYPE1 D_801DB4C4; // extern UNK_TYPE1 D_801DB4C8; diff --git a/spec b/spec index eb6fbaad6..ae8b116fe 100644 --- a/spec +++ b/spec @@ -1075,9 +1075,7 @@ beginseg name "ovl_Obj_Syokudai" compress include "build/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.o" - include "build/data/ovl_Obj_Syokudai/ovl_Obj_Syokudai.data.o" - include "build/data/ovl_Obj_Syokudai/ovl_Obj_Syokudai.bss.o" - include "build/data/ovl_Obj_Syokudai/ovl_Obj_Syokudai.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Syokudai/ovl_Obj_Syokudai_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Bg_Lotus/z_bg_lotus.c b/src/overlays/actors/ovl_Bg_Lotus/z_bg_lotus.c index 55e67d05f..40c60061c 100644 --- a/src/overlays/actors/ovl_Bg_Lotus/z_bg_lotus.c +++ b/src/overlays/actors/ovl_Bg_Lotus/z_bg_lotus.c @@ -165,10 +165,10 @@ void BgLotus_WaitToAppear(BgLotus* this, GlobalContext* globalCtx) { void BgLotus_Update(Actor* thisx, GlobalContext* globalCtx) { BgLotus* this = THIS; s32 pad; - void* sp2C; + WaterBox* waterBox; func_800CA1E8(globalCtx, &globalCtx->colCtx, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.z, - &this->height, &sp2C); + &this->height, &waterBox); this->actionFunc(this, globalCtx); } diff --git a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h index bc31953c8..e022d21a0 100644 --- a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h +++ b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h @@ -9,7 +9,9 @@ typedef void (*EnArrowActionFunc)(struct EnArrow*, GlobalContext*); typedef struct EnArrow { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x130]; + /* 0x0144 */ char unk_144[0x7C]; + /* 0x01C0 */ s32 unk_1C0; + /* 0x01C4 */ char unk_1C4[0xB0]; /* 0x0274 */ EnArrowActionFunc actionFunc; } EnArrow; // size = 0x278 diff --git a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c index 6c2fcb01b..a6297afed 100644 --- a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c +++ b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c @@ -234,7 +234,7 @@ s32 EnFirefly_SeekTorch(EnFirefly* this, GlobalContext* globalCtx) { } while (findTorch != NULL) { - if ((findTorch->actor.id == ACTOR_OBJ_SYOKUDAI) && (findTorch->unk_1DC != 0)) { + if ((findTorch->actor.id == ACTOR_OBJ_SYOKUDAI) && (findTorch->snuffTimer != OBJ_SYOKUDAI_SNUFF_OUT)) { currentDist = Actor_DistanceBetweenActors(&this->actor, &findTorch->actor); if (currentDist < currentMinDist) { currentMinDist = currentDist; diff --git a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c index 92f206b47..997270a6b 100644 --- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c +++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c @@ -1,4 +1,11 @@ +/* + * File: z_obj_syokudai.c + * Overlay: ovl_Obj_Syokudai + * Description: Torch + */ + #include "z_obj_syokudai.h" +#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" #define FLAGS 0x00000410 @@ -9,7 +16,10 @@ void ObjSyokudai_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx); void ObjSyokudai_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +extern Gfx D_060003A0[]; // sObjectSyokudaiTypeSwitchCausesFlameDL +extern Gfx D_06000870[]; // sObjectSyokudaiTypeNoSwitchDL +extern Gfx D_06000B90[]; // sObjectSyokudaiTypeFlameCausesSwitchDL + const ActorInit Obj_Syokudai_InitVars = { ACTOR_OBJ_SYOKUDAI, ACTORCAT_PROP, @@ -22,38 +32,289 @@ const ActorInit Obj_Syokudai_InitVars = { (ActorFunc)ObjSyokudai_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808BCCC0 = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0x00100000, 0x00, 0x00 }, { 0xF6CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sStandColliderInit = { + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x00100000, 0x00, 0x00 }, + { 0xF6CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 12, 45, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808BCCEC = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0x00000000, 0x00, 0x00 }, { 0x00000820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sFlameColliderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x00000000, 0x00, 0x00 }, + { 0x00000820, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 15, 45, 45, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808BCD18[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 800, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_STOP), }; -#endif +static u8 sColTypes[] = { COLTYPE_METAL, COLTYPE_WOOD, COLTYPE_WOOD }; -extern ColliderCylinderInit D_808BCCC0; -extern ColliderCylinderInit D_808BCCEC; -extern InitChainEntry D_808BCD18[]; +static Gfx* sDLists[] = { D_060003A0, D_06000B90, D_06000870 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Syokudai/ObjSyokudai_Init.s") +static s32 sNumLitTorchesInGroup; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Syokudai/ObjSyokudai_Destroy.s") +void ObjSyokudai_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjSyokudai* this = THIS; + s32 pad; + s32 type = OBJ_SYOKUDAI_GET_TYPE(thisx); + s32 switchFlag = OBJ_SYOKUDAI_GET_SWITCH_FLAG(thisx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Syokudai/ObjSyokudai_Update.s") + Actor_ProcessInitChain(thisx, sInitChain); + func_800B4AEC(globalCtx, thisx, 50.0f); + ActorShape_Init(&thisx->shape, 0.0f, func_800B4B50, 1.0f); + Collider_InitAndSetCylinder(globalCtx, &this->standCollider, thisx, &sStandColliderInit); + this->standCollider.base.colType = sColTypes[OBJ_SYOKUDAI_GET_TYPE(thisx)]; + Collider_InitAndSetCylinder(globalCtx, &this->flameCollider, thisx, &sFlameColliderInit); + thisx->colChkInfo.mass = MASS_IMMOVABLE; + Lights_PointGlowSetInfo(&this->lightInfo, thisx->world.pos.x, thisx->world.pos.y + OBJ_SYOKUDAI_GLOW_HEIGHT, + thisx->world.pos.z, 0xFF, 0xFF, 0xB4, -1); + this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Syokudai/ObjSyokudai_Draw.s") + if (OBJ_SYOKUDAI_GET_START_LIT(thisx) || + ((type != OBJ_SYOKUDAI_TYPE_NO_SWITCH || switchFlag != 0x7F) && Flags_GetSwitch(globalCtx, switchFlag))) { + + s32 groupSize = OBJ_SYOKUDAI_GET_GROUP_SIZE(thisx); + + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER; + if (groupSize != 0) { + sNumLitTorchesInGroup = groupSize; + } + } else { + sNumLitTorchesInGroup = 0; + } + this->flameTexScroll = (u32)(Rand_ZeroOne() * OBJ_SYOKUDAI_SNUFF_DEFAULT); + Actor_SetHeight(thisx, 60.0f); +} + +void ObjSyokudai_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjSyokudai* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->standCollider); + Collider_DestroyCylinder(globalCtx, &this->flameCollider); + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode); +} + +void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjSyokudai* this = THIS; + s32 groupSize = OBJ_SYOKUDAI_GET_GROUP_SIZE(thisx); + s32 switchFlag = OBJ_SYOKUDAI_GET_SWITCH_FLAG(thisx); + s32 type = OBJ_SYOKUDAI_GET_TYPE(thisx); + s32 pad0; + WaterBox* waterBox; + f32 waterSurface; + s32 lightRadius = -1; + u8 lightIntensity = 0; + Player* player; + s32 pad1; + + if (this->pendingAction != OBJ_SYOKUDAI_PENDING_ACTION_NONE) { + if (ActorCutscene_GetCurrentIndex() != thisx->cutscene) { + if (ActorCutscene_GetCanPlayNext(thisx->cutscene) != 0) { + ActorCutscene_StartAndSetUnkLinkFields(thisx->cutscene, thisx); + if (this->pendingAction >= OBJ_SYOKUDAI_PENDING_ACTION_CUTSCENE_AND_SWITCH) { + Actor_SetSwitchFlag(globalCtx, switchFlag); + } + } else { + ActorCutscene_SetIntentToPlay(thisx->cutscene); + } + } else if (func_800F22C4(thisx->cutscene, thisx) != 0) { + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER; + this->pendingAction = OBJ_SYOKUDAI_PENDING_ACTION_NONE; + } + } else { + if (func_800CA1E8(globalCtx, &globalCtx->colCtx, thisx->world.pos.x, thisx->world.pos.z, &waterSurface, + &waterBox) && + ((waterSurface - thisx->world.pos.y) > OBJ_SYOKUDAI_FLAME_HEIGHT)) { + + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_OUT; + if (type == OBJ_SYOKUDAI_TYPE_FLAME_CAUSES_SWITCH) { + Actor_UnsetSwitchFlag(globalCtx, switchFlag); + if (groupSize != 0) { + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_GROUP_BY_WATER; + } + } + } else { + s32 interaction = OBJ_SYOKUDAI_INTERACTION_NONE; + u32 flameColliderHurtboxDmgFlags = 0; + player = PLAYER; + + if (OBJ_SYOKUDAI_GET_START_LIT(thisx)) { + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER; + } + if (groupSize != 0) { + if (Flags_GetSwitch(globalCtx, switchFlag)) { + if (this->snuffTimer == OBJ_SYOKUDAI_SNUFF_OUT) { + if (type != OBJ_SYOKUDAI_TYPE_SWITCH_CAUSES_FLAME) { + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER; + } else { + this->pendingAction = OBJ_SYOKUDAI_PENDING_ACTION_CUTSCENE_NO_SWITCH; + } + } else if (this->snuffTimer > OBJ_SYOKUDAI_SNUFF_OUT) { + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER; + } + } else if (this->snuffTimer <= OBJ_SYOKUDAI_SNUFF_NEVER) { + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_DEFAULT; + } + } + if (this->flameCollider.base.acFlags & AC_HIT) { + flameColliderHurtboxDmgFlags = this->flameCollider.info.acHitInfo->toucher.dmgFlags; + if (this->flameCollider.info.acHitInfo->toucher.dmgFlags & 0x820) { + interaction = OBJ_SYOKUDAI_INTERACTION_ARROW_FA; + } + } else if (player->itemActionParam == 7) { + Vec3f stickTipSeparationVec; + + Math_Vec3f_Diff(&player->swordInfo[0].tip, &thisx->world.pos, &stickTipSeparationVec); + stickTipSeparationVec.y -= OBJ_SYOKUDAI_STICK_IGNITION_HEIGHT; + if (SQXYZ(stickTipSeparationVec) < SQ(OBJ_SYOKUDAI_STICK_IGNITION_RADIUS)) { + interaction = OBJ_SYOKUDAI_INTERACTION_STICK; + } + } + if (interaction != OBJ_SYOKUDAI_INTERACTION_NONE) { + if (this->snuffTimer != OBJ_SYOKUDAI_SNUFF_OUT) { + if (interaction <= OBJ_SYOKUDAI_INTERACTION_STICK) { + if (player->unk_B28 == 0) { + player->unk_B28 = 0xD2; + func_8019F1C0(&thisx->projectedPos, NA_SE_EV_FLAME_IGNITION); + } else if (player->unk_B28 < 0xC8) { + player->unk_B28 = 0xC8; + } + } else if (flameColliderHurtboxDmgFlags & 0x20) { + Actor* flameColliderHurtboxActor = this->flameCollider.base.ac; + + if ((flameColliderHurtboxActor->update != NULL) && + (flameColliderHurtboxActor->id == ACTOR_EN_ARROW)) { + + flameColliderHurtboxActor->params = 0; + ((EnArrow*)flameColliderHurtboxActor)->unk_1C0 = 0x800; + } + } + if ((this->snuffTimer > OBJ_SYOKUDAI_SNUFF_NEVER) && + (this->snuffTimer < (OBJ_SYOKUDAI_SNUFF_TIMER_INITIAL(groupSize))) && + (type != OBJ_SYOKUDAI_TYPE_SWITCH_CAUSES_FLAME)) { + + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_TIMER_INITIAL(groupSize); + } + } else if ((type != OBJ_SYOKUDAI_TYPE_SWITCH_CAUSES_FLAME) && + (((interaction >= OBJ_SYOKUDAI_INTERACTION_ARROW_FA) && + (flameColliderHurtboxDmgFlags & 0x800)) || + ((interaction <= OBJ_SYOKUDAI_INTERACTION_STICK) && (player->unk_B28 != 0)))) { + if ((interaction < OBJ_SYOKUDAI_INTERACTION_NONE) && (player->unk_B28 < 0xC8)) { + player->unk_B28 = 0xC8; + } + if (groupSize == 0) { + if ((type == OBJ_SYOKUDAI_TYPE_NO_SWITCH) && (switchFlag == 0x7F)) { + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER; + } else if (thisx->cutscene >= 0) { + this->pendingAction = OBJ_SYOKUDAI_PENDING_ACTION_CUTSCENE_AND_SWITCH; + } else { + Actor_SetSwitchFlag(globalCtx, switchFlag); + this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER; + } + } else { + if (++sNumLitTorchesInGroup >= groupSize) { + this->pendingAction = OBJ_SYOKUDAI_PENDING_ACTION_CUTSCENE_AND_SWITCH; + } else { + this->snuffTimer = + OBJ_SYOKUDAI_SNUFF_TIMER_INITIAL(groupSize) + OBJ_SYOKUDAI_SNUFF_TIMER_JUST_LIT_BONUS; + } + } + func_801A5CFC(NA_SE_EV_FLAME_IGNITION, &thisx->projectedPos, 4, &D_801DB4B0, &D_801DB4B0, + &D_801DB4B8); + } + } + } + } + Collider_UpdateCylinder(thisx, &this->standCollider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->standCollider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->standCollider.base); + Collider_UpdateCylinder(thisx, &this->flameCollider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->flameCollider.base); + if ((this->snuffTimer > OBJ_SYOKUDAI_SNUFF_OUT) && (--this->snuffTimer == OBJ_SYOKUDAI_SNUFF_OUT) && + (type != OBJ_SYOKUDAI_TYPE_SWITCH_CAUSES_FLAME)) { + sNumLitTorchesInGroup--; + } + if (this->snuffTimer != OBJ_SYOKUDAI_SNUFF_OUT) { + s32 pad2; + + if ((this->snuffTimer <= OBJ_SYOKUDAI_SNUFF_NEVER) || (this->snuffTimer >= OBJ_SYOKUDAI_SNUFF_DEFAULT)) { + lightRadius = OBJ_SYOKUDAI_LIGHT_RADIUS_MAX; + } else { + lightRadius = (f32)this->snuffTimer * OBJ_SYOKUDAI_LIGHT_RADIUS_MAX / OBJ_SYOKUDAI_SNUFF_DEFAULT; + } + lightIntensity = Rand_ZeroOne() * 127; + lightIntensity += 128; + func_800B9010(thisx, NA_SE_EV_TORCH - SFX_FLAG); + } + Lights_PointSetColorAndRadius(&this->lightInfo, lightIntensity, lightIntensity * 0.7f, 0, lightRadius); + this->flameTexScroll++; +} + +void ObjSyokudai_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjSyokudai* this = THIS; + s32 pad; + s32 groupSize = OBJ_SYOKUDAI_GET_GROUP_SIZE(thisx); + f32 flameScale; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, sDLists[OBJ_SYOKUDAI_GET_TYPE(thisx)]); + if (this->snuffTimer != OBJ_SYOKUDAI_SNUFF_OUT) { + s32 snuffTimerInitial = OBJ_SYOKUDAI_SNUFF_TIMER_INITIAL(groupSize); + + flameScale = 1.0f; + if (snuffTimerInitial < this->snuffTimer) { + flameScale = (f32)(snuffTimerInitial - this->snuffTimer + OBJ_SYOKUDAI_SNUFF_TIMER_JUST_LIT_BONUS) / + OBJ_SYOKUDAI_SNUFF_TIMER_JUST_LIT_BONUS; + } else if ((this->snuffTimer > OBJ_SYOKUDAI_SNUFF_OUT) && (this->snuffTimer < OBJ_SYOKUDAI_SNUFF_DEFAULT)) { + flameScale = (f32)this->snuffTimer / OBJ_SYOKUDAI_SNUFF_DEFAULT; + } + flameScale *= 0.0027f; + func_8012C2DC(globalCtx->state.gfxCtx); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, + (this->flameTexScroll * -OBJ_SYOKUDAI_SNUFF_DEFAULT) & 0x1FF, 0x20, 0x80)); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 0, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0); + SysMatrix_InsertTranslation(0.0f, OBJ_SYOKUDAI_FLAME_HEIGHT, 0.0f, MTXMODE_APPLY); + Matrix_RotateY(BINANG_ROT180(func_800DFCDC(ACTIVE_CAM) - thisx->shape.rot.y), MTXMODE_APPLY); + Matrix_Scale(flameScale, flameScale, flameScale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_0407D590); + } + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h index c2f0ea4a4..618b86ed5 100644 --- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h +++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h @@ -7,12 +7,54 @@ struct ObjSyokudai; typedef struct ObjSyokudai { /* 0x000 */ Actor actor; - /* 0x144 */ ColliderCylinder colliderCylinder1; - /* 0x190 */ ColliderCylinder colliderCylinder2; - /* 0x1DC */ s16 unk_1DC; - /* 0x1DE */ char unk_1DE[0x16]; + /* 0x144 */ ColliderCylinder standCollider; + /* 0x190 */ ColliderCylinder flameCollider; + /* 0x1DC */ s16 snuffTimer; + /* 0x1DE */ u8 flameTexScroll; + /* 0x1DF */ s8 pendingAction; + /* 0x1E0 */ LightNode* lightNode; + /* 0x1E4 */ LightInfo lightInfo; } ObjSyokudai; // size = 0x1F4 extern const ActorInit Obj_Syokudai_InitVars; +typedef enum { + /* 0 */ OBJ_SYOKUDAI_TYPE_SWITCH_CAUSES_FLAME, + /* 1 */ OBJ_SYOKUDAI_TYPE_FLAME_CAUSES_SWITCH, + /* 2 */ OBJ_SYOKUDAI_TYPE_NO_SWITCH +} ObjSyokudaiTypes; + +typedef enum { + /* -1 */ OBJ_SYOKUDAI_SNUFF_NEVER = -1, + /* 0 */ OBJ_SYOKUDAI_SNUFF_OUT, + /* 1 */ OBJ_SYOKUDAI_SNUFF_GROUP_BY_WATER, + /* 20 */ OBJ_SYOKUDAI_SNUFF_DEFAULT = 20 +} ObjSyokudaiSnuffStates; + +typedef enum { + /* -1 */ OBJ_SYOKUDAI_PENDING_ACTION_CUTSCENE_NO_SWITCH = -1, + /* 0 */ OBJ_SYOKUDAI_PENDING_ACTION_NONE, + /* 1 */ OBJ_SYOKUDAI_PENDING_ACTION_CUTSCENE_AND_SWITCH +} ObjSyokudaiPendingActions; + +typedef enum { + /* -1 */ OBJ_SYOKUDAI_INTERACTION_STICK = -1, + /* 0 */ OBJ_SYOKUDAI_INTERACTION_NONE, + /* 1 */ OBJ_SYOKUDAI_INTERACTION_ARROW_FA +} ObjSyokudaiInteractions; + +#define OBJ_SYOKUDAI_GLOW_HEIGHT 70.0f +#define OBJ_SYOKUDAI_FLAME_HEIGHT 52.0f +#define OBJ_SYOKUDAI_STICK_IGNITION_HEIGHT 67.0f +#define OBJ_SYOKUDAI_STICK_IGNITION_RADIUS 20.0f +#define OBJ_SYOKUDAI_SNUFF_TIMER_JUST_LIT_BONUS 10 +#define OBJ_SYOKUDAI_LIGHT_RADIUS_MAX 250 + +#define OBJ_SYOKUDAI_GET_TYPE(thisx) (thisx->params >> 0xC) +#define OBJ_SYOKUDAI_GET_START_LIT(thisx) (thisx->params & 0x800) +#define OBJ_SYOKUDAI_GET_GROUP_SIZE(thisx) ((thisx->params >> 7) & 0xF) +#define OBJ_SYOKUDAI_GET_SWITCH_FLAG(thisx) (thisx->params & 0x7F) + +#define OBJ_SYOKUDAI_SNUFF_TIMER_INITIAL(groupSize) ((groupSize * 50) + 100) + #endif // Z_OBJ_SYOKUDAI_H diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index a2b28c247..91bfbab47 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -6810,14 +6810,14 @@ 0x808BC000:("D_808BC000","UNK_TYPE1","",0x1), 0x808BC004:("D_808BC004","UNK_TYPE1","",0x1), 0x808BCCA0:("Obj_Syokudai_InitVars","UNK_TYPE1","",0x1), - 0x808BCCC0:("D_808BCCC0","UNK_TYPE1","",0x1), - 0x808BCCEC:("D_808BCCEC","UNK_TYPE1","",0x1), - 0x808BCD18:("D_808BCD18","UNK_TYPE1","",0x1), - 0x808BCD28:("D_808BCD28","UNK_TYPE1","",0x1), - 0x808BCD2C:("D_808BCD2C","UNK_TYPE1","",0x1), + 0x808BCCC0:("sStandColliderInit","UNK_TYPE1","",0x1), + 0x808BCCEC:("sFlameColliderInit","UNK_TYPE1","",0x1), + 0x808BCD18:("sInitChain","UNK_TYPE1","",0x1), + 0x808BCD28:("sColTypes","UNK_TYPE1","",0x1), + 0x808BCD2C:("sDLists","UNK_TYPE1","",0x1), 0x808BCD40:("D_808BCD40","f32","",0x4), 0x808BCD44:("D_808BCD44","f32","",0x4), - 0x808BCDE0:("D_808BCDE0","UNK_TYPE1","",0x1), + 0x808BCDE0:("sNumLitTorchesInGroup","UNK_TYPE1","",0x1), 0x808BD160:("Item_B_Heart_InitVars","UNK_TYPE1","",0x1), 0x808BD180:("D_808BD180","UNK_TYPE1","",0x1), 0x808BD190:("D_808BD190","f32","",0x4), diff --git a/undefined_syms.txt b/undefined_syms.txt index 7fc52d938..bf19c9814 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -4108,6 +4108,12 @@ D_06008B90 = 0x06008B90; D_06000460 = 0x06000460; D_06000E68 = 0x06000E68; +// ovl_Obj_Syokudai + +D_060003A0 = 0x060003A0; +D_06000870 = 0x06000870; +D_06000B90 = 0x06000B90; + // ovl_Obj_Takaraya_Wall D_06000B70 = 0x06000B70; From 456cf789acae16667fd92220dac4c1d58295d140 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sat, 25 Sep 2021 12:47:18 -0300 Subject: [PATCH 06/13] Add `-I.` (#323) * Add `-I.` * IINC --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0d0326231..bc71a02e1 100644 --- a/Makefile +++ b/Makefile @@ -70,6 +70,7 @@ LD := $(MIPS_BINUTILS_PREFIX)ld OBJCOPY := $(MIPS_BINUTILS_PREFIX)objcopy OBJDUMP := $(MIPS_BINUTILS_PREFIX)objdump +IINC := -Iinclude -Isrc -Iassets -Ibuild -I. ifeq ($(KEEP_MDEBUG),0) RM_MDEBUG = $(OBJCOPY) --remove-section .mdebug $@ else @@ -78,7 +79,7 @@ endif # Check code syntax with host compiler CHECK_WARNINGS := -Wall -Wextra -Wno-format-security -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable -Wno-missing-braces -Wno-int-conversion -Wno-unused-but-set-variable -Wno-unused-label -CC_CHECK := gcc -fno-builtin -fsyntax-only -funsigned-char -std=gnu90 -D _LANGUAGE_C -D NON_MATCHING -Iinclude -Isrc -Iassets -Ibuild -include stdarg.h $(CHECK_WARNINGS) +CC_CHECK := gcc -fno-builtin -fsyntax-only -funsigned-char -std=gnu90 -D _LANGUAGE_C -D NON_MATCHING $(IINC) -include stdarg.h $(CHECK_WARNINGS) CPP := cpp ELF2ROM := tools/buildtools/elf2rom @@ -91,7 +92,7 @@ ASFLAGS := -march=vr4300 -32 -Iinclude MIPS_VERSION := -mips2 # we support Microsoft extensions such as anonymous structs, which the compiler does support but warns for their usage. Surpress the warnings with -woff. -CFLAGS += -G 0 -non_shared -Xfullwarn -Xcpluscomm -Iinclude -Isrc -Iassets -Ibuild -I. -Wab,-r4300_mul -woff 624,649,838,712 +CFLAGS += -G 0 -non_shared -Xfullwarn -Xcpluscomm $(IINC) -Wab,-r4300_mul -woff 624,649,838,712 ifeq ($(shell getconf LONG_BIT), 32) # Work around memory allocation bug in QEMU From 039fc4623ecbaf14e3bce46db78efbdb3272c591 Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Sat, 25 Sep 2021 17:22:51 +0100 Subject: [PATCH 07/13] En_Syateki_Man (#269) * En_Syateki_Man * a --- include/functions.h | 8 +- include/z64.h | 2 +- include/z64item.h | 10 +- spec | 3 +- src/overlays/actors/ovl_En_GirlA/z_en_girla.c | 14 +- .../ovl_En_Syateki_Man/z_en_syateki_man.c | 1269 ++++++++++++++++- .../ovl_En_Syateki_Man/z_en_syateki_man.h | 37 +- tools/disasm/functions.txt | 4 +- 8 files changed, 1288 insertions(+), 59 deletions(-) diff --git a/include/functions.h b/include/functions.h index e16858aa1..0948b502e 100644 --- a/include/functions.h +++ b/include/functions.h @@ -2178,7 +2178,7 @@ void func_80115A14(s32 arg0, s16 arg1); // void func_80118BA4(void); // void func_80119030(void); // void func_80119610(void); -// void func_8011B4E0(void); +void func_8011B4E0(GlobalContext* globalCtx, s32 arg1); // void func_8011B5C0(void); // void func_8011B9E0(void); // void func_8011BF70(void); @@ -2238,7 +2238,7 @@ void func_80123D50(GlobalContext* globalCtx, Player* player, UNK_TYPE arg2, UNK_ void func_80123DA4(Player* player); // void func_80123DC0(void); void func_80123E90(GlobalContext* globalCtx, Actor* actor); -// void func_80123F2C(void); +void func_80123F2C(GlobalContext* globalCtx, s32 arg1); // void func_80123F48(void); // void func_80124020(void); u8 Player_GetMask(GlobalContext* globalCtx); @@ -3911,8 +3911,8 @@ void func_801A246C(u8 param_1, u8 param_2); // void func_801A27E8(void); // void func_801A281C(void); void func_801A29D4(UNK_TYPE arg0, f32 arg1, UNK_TYPE arg2); -// void func_801A2BB8(void); -// void func_801A2C20(void); +void func_801A2BB8(s32 arg0); +void func_801A2C20(void); // void func_801A2C44(void); // void func_801A2C88(void); // void func_801A2D54(void); diff --git a/include/z64.h b/include/z64.h index d6f097cfb..3925281a6 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1559,7 +1559,7 @@ struct GlobalContext { /* 0x18784 */ s32 (*damagePlayer)(struct GlobalContext* globalCtx, s32 damage); /* 0x18788 */ void (*talkWithPlayer)(struct GlobalContext* globalCtx, Actor* actor); /* 0x1878C */ void (*unk_1878C)(struct GlobalContext* globalCtx); - /* 0x18790 */ void* unk_18790; //! @TODO: Determine function prototype + /* 0x18790 */ void (*unk_18790)(struct GlobalContext* globalCtx, s16 arg1, Actor* actor); /* 0x18794 */ void* unk_18794; //! @TODO: Determine function prototype /* 0x18798 */ s32 (*setPlayerTalkAnim)(struct GlobalContext* globalCtx, void* talkAnim, s32 arg2); /* 0x1879C */ s16 unk_1879C[10]; diff --git a/include/z64item.h b/include/z64item.h index 80002880a..a5939c0dc 100644 --- a/include/z64item.h +++ b/include/z64item.h @@ -89,9 +89,13 @@ typedef enum { /* 0x1B */ GI_BOMB_BAG_20, /* 0x1C */ GI_BOMB_BAG_30, /* 0x1D */ GI_BOMB_BAG_40, - /* 0x1E */ GI_ARROWS_SMALL, - /* 0x1F */ GI_ARROWS_MEDIUM, - /* 0x20 */ GI_ARROWS_LARGE, + /* 0x1E */ GI_ARROWS_10, + /* 0x1F */ GI_ARROWS_30, + /* 0x20 */ GI_ARROWS_40, + /* 0x21 */ GI_ARROWS_50, + /* 0x22 */ GI_QUIVER_30, + /* 0x23 */ GI_QUIVER_40, + /* 0x24 */ GI_QUIVER_50, /* 0x28 */ GI_NUTS_1 = 0x28, /* 0x2A */ GI_NUTS_10 = 0x2A, /* 0x32 */ GI_SHIELD_HERO = 0x32, diff --git a/spec b/spec index ae8b116fe..0754aca9c 100644 --- a/spec +++ b/spec @@ -2487,8 +2487,7 @@ beginseg name "ovl_En_Syateki_Man" compress include "build/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.o" - include "build/data/ovl_En_Syateki_Man/ovl_En_Syateki_Man.data.o" - include "build/data/ovl_En_Syateki_Man/ovl_En_Syateki_Man.reloc.o" + include "build/src/overlays/actors/ovl_En_Syateki_Man/ovl_En_Syateki_Man_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index 7e7f7e7d4..9473ee313 100644 --- a/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -72,7 +72,7 @@ static ShopItemEntry sShopItemEntries[] = { EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, { OBJECT_GI_BOTTLE_04, GID_FAIRY, func_800B8050, 1, 0X06B6, 0X06B7, GI_FAIRY, EnGirlA_CanBuyFairy, EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, - { OBJECT_GI_ARROW, GID_ARROWS_LARGE, func_800B8050, 50, 0X06BA, 0X06BB, GI_ARROWS_LARGE, EnGirlA_CanBuyArrows, + { OBJECT_GI_ARROW, GID_ARROWS_LARGE, func_800B8050, 50, 0X06BA, 0X06BB, GI_ARROWS_40, EnGirlA_CanBuyArrows, EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, { OBJECT_GI_LIQUID, GID_POTION_GREEN, func_800B8050, 1, 0X06B2, 0X06B3, GI_POTION_GREEN, EnGirlA_CanBuyPotionGreen, EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, @@ -80,7 +80,7 @@ static ShopItemEntry sShopItemEntries[] = { EnGirlA_BuyShieldHero, EnGirlA_BuyFanfare }, { OBJECT_GI_STICK, GID_STICK, NULL, 1, 0X06B4, 0X06B5, GI_STICKS_1, EnGirlA_CanBuyStick, EnGirlA_BuyStick, EnGirlA_BuyFanfare }, - { OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, func_800B8050, 30, 0X06B8, 0X06B9, GI_ARROWS_MEDIUM, EnGirlA_CanBuyArrows, + { OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, func_800B8050, 30, 0X06B8, 0X06B9, GI_ARROWS_30, EnGirlA_CanBuyArrows, EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, { OBJECT_GI_NUTS, GID_NUTS, func_800B8118, 10, 0X06B0, 0X06B1, GI_NUTS_10, EnGirlA_CanBuyNuts, EnGirlA_BuyNuts, EnGirlA_BuyFanfare }, @@ -88,9 +88,9 @@ static ShopItemEntry sShopItemEntries[] = { EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, { OBJECT_GI_BOTTLE_04, GID_FAIRY, func_800B8050, 1, 0X06D3, 0X06D4, GI_FAIRY, EnGirlA_CanBuyFairy, EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, - { OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, func_800B8050, 30, 0X06D5, 0X06D6, GI_ARROWS_MEDIUM, EnGirlA_CanBuyArrows, + { OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, func_800B8050, 30, 0X06D5, 0X06D6, GI_ARROWS_30, EnGirlA_CanBuyArrows, EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, - { OBJECT_GI_ARROW, GID_ARROWS_LARGE, func_800B8050, 50, 0X06D7, 0X06D8, GI_ARROWS_LARGE, EnGirlA_CanBuyArrows, + { OBJECT_GI_ARROW, GID_ARROWS_LARGE, func_800B8050, 50, 0X06D7, 0X06D8, GI_ARROWS_40, EnGirlA_CanBuyArrows, EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, { OBJECT_GI_LIQUID, GID_POTION_GREEN, func_800B8050, 1, 0X06CF, 0X06D0, GI_POTION_GREEN, EnGirlA_CanBuyPotionGreen, EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, @@ -120,19 +120,19 @@ static ShopItemEntry sShopItemEntries[] = { EnGirlA_BuyFanfare }, { OBJECT_GI_SHIELD_2, GID_SHIELD_HERO, func_800B8050, 1, 0X12DB, 0X12DC, GI_SHIELD_HERO, EnGirlA_CanBuyShieldHero, EnGirlA_BuyShieldHero, EnGirlA_BuyFanfare }, - { OBJECT_GI_ARROW, GID_ARROWS_SMALL, func_800B8050, 10, 0X12DD, 0X12DE, GI_ARROWS_SMALL, EnGirlA_CanBuyArrows, + { OBJECT_GI_ARROW, GID_ARROWS_SMALL, func_800B8050, 10, 0X12DD, 0X12DE, GI_ARROWS_10, EnGirlA_CanBuyArrows, EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, { OBJECT_GI_LIQUID, GID_POTION_RED, func_800B8050, 1, 0X12DF, 0X12E0, GI_POTION_RED, EnGirlA_CanBuyPotionRed, EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, { OBJECT_GI_BOMB_1, GID_BOMB, func_800B8050, 10, 0X0BC5, 0X0BC6, GI_BOMBS_10, EnGirlA_CanBuyBombs, EnGirlA_BuyBombs, EnGirlA_BuyFanfare }, - { OBJECT_GI_ARROW, GID_ARROWS_SMALL, func_800B8050, 10, 0X0BC7, 0X0BC8, GI_ARROWS_SMALL, EnGirlA_CanBuyArrows, + { OBJECT_GI_ARROW, GID_ARROWS_SMALL, func_800B8050, 10, 0X0BC7, 0X0BC8, GI_ARROWS_10, EnGirlA_CanBuyArrows, EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, { OBJECT_GI_LIQUID, GID_POTION_RED, func_800B8050, 1, 0X0BC9, 0X0BCA, GI_POTION_RED, EnGirlA_CanBuyPotionRed, EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, { OBJECT_GI_BOMB_1, GID_BOMB, func_800B8050, 10, 0X0BCB, 0X0BCC, GI_BOMBS_10, EnGirlA_CanBuyBombs, EnGirlA_BuyBombs, EnGirlA_BuyFanfare }, - { OBJECT_GI_ARROW, GID_ARROWS_SMALL, func_800B8050, 10, 0X0BCD, 0X0BCE, GI_ARROWS_SMALL, EnGirlA_CanBuyArrows, + { OBJECT_GI_ARROW, GID_ARROWS_SMALL, func_800B8050, 10, 0X0BCD, 0X0BCE, GI_ARROWS_10, EnGirlA_CanBuyArrows, EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, { OBJECT_GI_LIQUID, GID_POTION_RED, func_800B8050, 1, 0X0BCF, 0X0BD0, GI_POTION_RED, EnGirlA_CanBuyPotionRed, EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, 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 ab927fb57..67b0fe886 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 @@ -1,3 +1,9 @@ +/* + * File: z_en_syateki_man.c + * Overlay: ovl_En_Syateki_Man + * Description: Shooting Gallery Man + */ + #include "z_en_syateki_man.h" #define FLAGS 0x08000019 @@ -28,7 +34,16 @@ void func_809C8808(EnSyatekiMan* this, GlobalContext* globalCtx); void func_809C898C(EnSyatekiMan* this, GlobalContext* globalCtx); void func_809C8BF0(EnSyatekiMan* this, GlobalContext* globalCtx); -#if 0 +extern UNK_PTR D_06005AC8; +extern UNK_PTR D_060062C8; +extern AnimationHeader D_0600D2F8; +extern AnimationHeader D_0600D9D0; +extern AnimationHeader D_0600DFEC; +extern FlexSkeletonHeader D_0600E7D0; +extern Gfx D_0600F2D0[]; +extern UNK_PTR D_0600FB90; +extern UNK_PTR D_06010390; + const ActorInit En_Syateki_Man_InitVars = { ACTOR_EN_SYATEKI_MAN, ACTORCAT_NPC, @@ -41,73 +56,1251 @@ const ActorInit En_Syateki_Man_InitVars = { (ActorFunc)EnSyatekiMan_Draw, }; -#endif +static ActorAnimationEntry sAnimations[] = { + { &D_0600D9D0, 1.0f, 0.0f, 0.0f, 0, -8.0f }, + { &D_0600DFEC, 1.0f, 0.0f, 0.0f, 0, -8.0f }, + { &D_0600D2F8, 1.0f, 0.0f, 0.0f, 2, -8.0f }, +}; -extern UNK_TYPE D_060062C8; -extern UNK_TYPE D_0600D2F8; -extern UNK_TYPE D_0600DFEC; -extern UNK_TYPE D_0600F2D0; +static s16 D_809C91C8[] = { + 0x00C1, + 0x0302, + 0x0019, + 0x0026, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C64C0.s") +static EnSyatekiManUnkStruct D_809C91D0[] = { + { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, 0x130 }, + { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, 0x20 }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x0 }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x10 }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x20 }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x30 }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x40 }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x1 }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x11 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x0 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x100 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x200 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x300 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x420 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x520 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x601 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x702 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x801 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x902 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/EnSyatekiMan_Init.s") +static EnSyatekiManUnkStruct D_809C934C[] = { + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x0 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x100 }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x1 }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x11 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x202 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x302 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x3 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x103 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x423 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x204 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x304 }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x424 }, + { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, 0x25 }, + { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, 0x136 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/EnSyatekiMan_Destroy.s") +static EnSyatekiManUnkStruct* D_809C9464[] = { + D_809C91D0, + D_809C934C, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C6720.s") +static s32 D_809C946C[] = { + ARRAY_COUNT(D_809C91D0), + ARRAY_COUNT(D_809C934C), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C6810.s") +static Vec3f D_809C9474 = { 0.0f, 10.0f, 140.0f }; +static Vec3f D_809C9480 = { -20.0f, 20.0f, 198.0f }; +static Vec3f D_809C948C = { -20.0f, 40.0f, 175.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C6848.s") +void func_809C64C0(EnSyatekiMan* this, GlobalContext* globalCtx2, EnSyatekiManUnkStruct arg2[], s32 arg3) { + GlobalContext* globalCtx = globalCtx2; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C6A04.s") + for (i = 0; i < arg3; i++) { + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, arg2[i].index, arg2[i].x, arg2[i].y, + arg2[i].z, 0, 0, 0, arg2[i].variable); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C6C2C.s") +void EnSyatekiMan_Init(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiMan* this = THIS; + s32 pad; + Path* sp34 = &globalCtx->setupPathList[ENSYATEKIMAN_GET_FF00(&this->actor)]; + s32 sp30 = D_809C946C[this->unk_194]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C6E30.s") + this->actor.targetMode = 1; + Actor_SetScale(&this->actor, 0.01f); + if (globalCtx->sceneNum == SCENE_SYATEKI_MORI) { + SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_0600E7D0, &D_0600DFEC, this->jointTable, this->morphTable, 16); + } else { + SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_0600E7D0, &D_0600D9D0, this->jointTable, this->morphTable, 16); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C6F98.s") + this->actor.colChkInfo.cylRadius = 100; + this->actionFunc = func_809C6810; + this->unk_26A = 0; + this->unk_270 = 15; + this->unk_27E = 0; + this->unk_26E = 0; + this->unk_190 = 0; + this->unk_272 = 0; + this->unk_274 = 0; + this->unk_280 = 0; + this->unk_278 = 0; + this->unk_27A = 0; + this->unk_284 = 0; + this->unk_194 = 0; + this->unk_282 = 0; + this->unk_264 = 0; + this->unk_266 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C72D8.s") + if (globalCtx->sceneNum == SCENE_SYATEKI_MORI) { + this->path = sp34; + func_809C64C0(this, globalCtx, D_809C9464[this->unk_194], sp30); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C7380.s") +void EnSyatekiMan_Destroy(Actor* thisx, GlobalContext* globalCtx) { + gSaveContext.weekEventReg[63] &= (u8)~1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C7620.s") +s32 func_809C6720(GlobalContext* globalCtx, Vec3f arg1) { + Player* player = PLAYER; + f32 sp28; + f32 phi_f0; + s16 sp22 = Math_Vec3f_Yaw(&player->actor.world.pos, &arg1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C7990.s") + sp28 = Math_Vec3f_DistXZ(&player->actor.world.pos, &arg1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C7A90.s") + if (sp28 < 5.0f) { + phi_f0 = 10.0f; + } else if (sp28 < 30.0f) { + phi_f0 = 40.0f; + } else { + phi_f0 = 80.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C7C14.s") + globalCtx->actorCtx.unk268 = 1; + func_800B6F20(globalCtx, globalCtx->actorCtx.pad26C, phi_f0, sp22); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C7D14.s") + if (sp28 < 5.0f) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C7EB4.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C7FFC.s") +void func_809C6810(EnSyatekiMan* this, GlobalContext* globalCtx) { + if (globalCtx->sceneNum == SCENE_SYATEKI_MORI) { + this->actionFunc = func_809C6848; + } else if (globalCtx->sceneNum == SCENE_SYATEKI_MIZU) { + this->actionFunc = func_809C72D8; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C80C0.s") +void func_809C6848(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C81D0.s") + if (func_800B84D0(&this->actor, globalCtx)) { + u16 sp22; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C8488.s") + func_800BDC5C(&this->skelAnime, sAnimations, 2); + sp22 = Text_GetFaceReaction(globalCtx, 0x31); + if (sp22 != 0) { + func_801518B0(globalCtx, sp22, &this->actor); + this->unk_284 = sp22; + } else if (player->transformation == PLAYER_FORM_HUMAN) { + if (this->unk_282 == 0) { + this->unk_282 = 1; + func_801518B0(globalCtx, 0xA28, &this->actor); + this->unk_284 = 0xA28; + } else { + func_801518B0(globalCtx, 0xA29, &this->actor); + this->unk_284 = 0xA29; + } + } else { + switch (CURRENT_DAY) { + case 1: + func_801518B0(globalCtx, 0xA38, &this->actor); + this->unk_284 = 0xA38; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C8610.s") + case 2: + func_801518B0(globalCtx, 0xA39, &this->actor); + this->unk_284 = 0xA39; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C8710.s") + case 3: + func_801518B0(globalCtx, 0xA3A, &this->actor); + this->unk_284 = 0xA3A; + break; + } + } + this->actionFunc = func_809C6E30; + } else { + func_800B8614(&this->actor, globalCtx, 120.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C8808.s") + if (player->actor.world.pos.z < 135.0f) { + player->actor.world.pos.z = 135.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C898C.s") +void func_809C6A04(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C8BF0.s") + if (func_80147624(globalCtx)) { + if (globalCtx->msgCtx.choiceIndex == 0) { + if (!CUR_UPG_VALUE(UPG_QUIVER)) { + play_sound(NA_SE_SY_ERROR); + func_801518B0(globalCtx, 0xA30, &this->actor); + this->unk_284 = 0xA30; + } else if (gSaveContext.rupees < 20) { + play_sound(NA_SE_SY_ERROR); + func_801518B0(globalCtx, 0xA31, &this->actor); + this->unk_284 = 0xA31; + if (this->unk_26A == 4) { + gSaveContext.minigameState = 3; + } + this->unk_26A = 3; + } else { + func_8019F208(); + func_801159EC(-20); + gSaveContext.weekEventReg[63] |= 1; + gSaveContext.weekEventReg[63] &= (u8)~2; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_26A = 7; + player->stateFlags1 |= 0x20; + this->actionFunc = func_809C7FFC; + } + } else { + func_8019F230(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C8DE8.s") + switch (CURRENT_DAY) { + case 1: + func_801518B0(globalCtx, 0xA2D, &this->actor); + this->unk_284 = 0xA2D; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/EnSyatekiMan_Update.s") + case 2: + func_801518B0(globalCtx, 0xA2E, &this->actor); + this->unk_284 = 0xA2E; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C8EE4.s") + case 3: + func_801518B0(globalCtx, 0xA2F, &this->actor); + this->unk_284 = 0xA2F; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/func_809C8FAC.s") + if (this->unk_26A == 4) { + gSaveContext.minigameState = 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Man/EnSyatekiMan_Draw.s") + this->unk_26A = 3; + } + } +} + +void func_809C6C2C(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (func_80147624(globalCtx)) { + switch (this->unk_284) { + case 0xA28: + case 0xA29: + func_801518B0(globalCtx, 0xA2A, &this->actor); + this->unk_284 = 0xA2A; + break; + + case 0xA2B: + case 0xA2C: + case 0xA35: + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + player->actor.freezeTimer = 0; + func_80112AFC(globalCtx); + globalCtx->interfaceCtx.hbaAmmo = 80; + func_80123F2C(globalCtx, 80); + this->unk_26A = 1; + this->actionFunc = func_809C80C0; + func_801A2BB8(0x25); + break; + + case 0xA32: + if (gSaveContext.weekEventReg[63] & 2) { + func_801477B4(globalCtx); + player->stateFlags1 &= ~0x20; + gSaveContext.weekEventReg[63] &= (u8)~1; + gSaveContext.weekEventReg[63] &= (u8)~2; + this->actionFunc = func_809C6848; + gSaveContext.minigameState = 3; + this->unk_26A = 0; + } else { + func_801518B0(globalCtx, 0xA33, &this->actor); + this->unk_284 = 0xA33; + } + break; + + case 0xA33: + func_801518B0(globalCtx, 0xA2A, &this->actor); + this->unk_284 = 0xA2A; + this->unk_26A = 4; + break; + + case 0xA34: + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + player->actor.freezeTimer = 0; + gSaveContext.minigameState = 3; + player->stateFlags1 |= 0x20; + this->actionFunc = func_809C7A90; + func_809C7A90(this, globalCtx); + break; + } + } +} + +void func_809C6E30(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (player->stateFlags1 & 0x20) { + player->stateFlags1 |= 0x20; + } + + switch (func_80152498(&globalCtx->msgCtx)) { + case 2: + this->actionFunc = func_809C6848; + this->unk_26A = 0; + break; + + case 4: + func_809C6A04(this, globalCtx); + break; + + case 5: + func_809C6C2C(this, globalCtx); + break; + + case 6: + if (func_80147624(globalCtx)) { + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + player->stateFlags1 &= ~0x20; + gSaveContext.weekEventReg[63] &= (u8)~1; + gSaveContext.weekEventReg[63] &= (u8)~2; + this->actionFunc = func_809C6848; + this->unk_26A = 0; + } + break; + + case 0: + case 1: + case 3: + case 7: + case 8: + case 9: + case 10: + break; + } + + if (this->skelAnime.animCurrentSeg == &D_0600D2F8) { + if (func_801378B8(&this->skelAnime, this->skelAnime.animFrameCount)) { + func_800BDC5C(&this->skelAnime, sAnimations, 0); + } + } +} + +void func_809C6F98(EnSyatekiMan* this, GlobalContext* globalCtx) { + switch (gSaveContext.playerForm) { + case PLAYER_FORM_HUMAN: + Actor_SetAllChestFlag(globalCtx, Actor_GetAllChestFlag(globalCtx) + 1); + if (CURRENT_DAY != 3) { + if (!(this->unk_282 & 1)) { + this->unk_282 |= 1; + func_801518B0(globalCtx, 0x3E8, &this->actor); + this->unk_284 = 0x3E8; + } else { + func_801518B0(globalCtx, 0x3E9, &this->actor); + this->unk_284 = 0x3E9; + } + } else if (!(this->unk_282 & 1)) { + this->unk_282 |= 1; + func_801518B0(globalCtx, 0x3EA, &this->actor); + this->unk_284 = 0x3EA; + } else { + func_801518B0(globalCtx, 0x3EB, &this->actor); + this->unk_284 = 0x3EB; + } + break; + + case PLAYER_FORM_DEKU: + if (CURRENT_DAY != 3) { + if (!(this->unk_282 & 2)) { + this->unk_282 |= 2; + func_801518B0(globalCtx, 0x3EC, &this->actor); + this->unk_284 = 0x3EC; + } else { + func_801518B0(globalCtx, 0x3ED, &this->actor); + this->unk_284 = 0x3ED; + } + } else if (!(this->unk_282 & 2)) { + this->unk_282 |= 2; + func_801518B0(globalCtx, 0x3EE, &this->actor); + this->unk_284 = 0x3EE; + } else { + func_801518B0(globalCtx, 0x3EF, &this->actor); + this->unk_284 = 0x3EF; + } + break; + + case PLAYER_FORM_ZORA: + if (CURRENT_DAY != 3) { + if (!(this->unk_282 & 8)) { + this->unk_282 |= 8; + func_801518B0(globalCtx, 0x3F0, &this->actor); + this->unk_284 = 0x3F0; + } else { + func_801518B0(globalCtx, 0x3F1, &this->actor); + this->unk_284 = 0x3F1; + } + } else if (!(this->unk_282 & 8)) { + this->unk_282 |= 8; + func_801518B0(globalCtx, 0x3F4, &this->actor); + this->unk_284 = 0x3F4; + } else { + func_801518B0(globalCtx, 0x3F5, &this->actor); + this->unk_284 = 0x3F5; + } + break; + + case PLAYER_FORM_GORON: + if (CURRENT_DAY != 3) { + if (!(this->unk_282 & 4)) { + this->unk_282 |= 4; + func_801518B0(globalCtx, 0x3F2, &this->actor); + this->unk_284 = 0x3F2; + } else { + func_801518B0(globalCtx, 0x3F3, &this->actor); + this->unk_284 = 0x3F3; + } + } else if (!(this->unk_282 & 4)) { + this->unk_282 |= 4; + func_801518B0(globalCtx, 0x3F4, &this->actor); + this->unk_284 = 0x3F4; + } else { + func_801518B0(globalCtx, 0x3F5, &this->actor); + this->unk_284 = 0x3F5; + } + break; + } +} + +void func_809C72D8(EnSyatekiMan* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + u16 sp26 = Text_GetFaceReaction(globalCtx, 0x30); + + if (sp26 != 0) { + func_801518B0(globalCtx, sp26, &this->actor); + this->unk_284 = sp26; + } else { + func_809C6F98(this, globalCtx); + } + this->actionFunc = func_809C7990; + } else { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void func_809C7380(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (func_80147624(globalCtx)) { + if (globalCtx->msgCtx.choiceIndex == 0) { + if (!CUR_UPG_VALUE(UPG_QUIVER)) { + play_sound(NA_SE_SY_ERROR); + if (CURRENT_DAY != 3) { + func_801518B0(globalCtx, 0x3F9, &this->actor); + this->unk_284 = 0x3F9; + } else { + func_801518B0(globalCtx, 0x3FA, &this->actor); + this->unk_284 = 0x3FA; + } + } else if (gSaveContext.rupees < 20) { + play_sound(NA_SE_SY_ERROR); + if (CURRENT_DAY != 3) { + func_801518B0(globalCtx, 0x3FB, &this->actor); + this->unk_284 = 0x3FB; + } else { + func_801518B0(globalCtx, 0x3FC, &this->actor); + this->unk_284 = 0x3FC; + } + + if (this->unk_26A == 4) { + player->stateFlags3 &= ~0x400; + gSaveContext.minigameState = 3; + } + this->unk_26A = 3; + } else { + func_8019F208(); + func_801159EC(-20); + this->unk_26A = 2; + if (!(this->unk_282 & 0x10)) { + this->unk_282 |= 0x10; + func_801518B0(globalCtx, 0x3FD, &this->actor); + this->unk_284 = 0x3FD; + } else { + func_801518B0(globalCtx, 0x3FF, &this->actor); + this->unk_284 = 0x3FF; + } + gSaveContext.weekEventReg[63] |= 1; + gSaveContext.weekEventReg[63] &= (u8)~2; + } + } else { + func_8019F230(); + if (CURRENT_DAY != 3) { + func_801518B0(globalCtx, 0x3F7, &this->actor); + this->unk_284 = 0x3F7; + } else { + func_801518B0(globalCtx, 0x3F8, &this->actor); + this->unk_284 = 0x3F8; + } + + if (this->unk_26A == 4) { + player->stateFlags3 &= ~0x400; + gSaveContext.minigameState = 3; + } + this->unk_26A = 3; + } + } +} + +void func_809C7620(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (func_80147624(globalCtx)) { + switch (this->unk_284) { + case 0x3E8: + case 0x3E9: + case 0x3EA: + case 0x3EB: + func_801518B0(globalCtx, 0x3F6, &this->actor); + this->unk_284 = 0x3F6; + break; + + case 0x3EC: + func_801518B0(globalCtx, 0x3ED, &this->actor); + this->unk_284 = 0x3ED; + break; + + case 0x3EE: + func_801518B0(globalCtx, 0x3EF, &this->actor); + this->unk_284 = 0x3EF; + break; + + case 0x3F0: + func_801518B0(globalCtx, 0x3F1, &this->actor); + this->unk_284 = 0x3F1; + break; + + case 0x3F2: + func_801518B0(globalCtx, 0x3F3, &this->actor); + this->unk_284 = 0x3F3; + break; + + case 0x3F4: + func_801518B0(globalCtx, 0x3F5, &this->actor); + this->unk_284 = 0x3F5; + break; + + case 0x3FD: + case 0x3FF: + if (this->unk_26A == 4U) { + if (this->unk_284 == 0x3FD) { + func_801518B0(globalCtx, 0x3FE, &this->actor); + this->unk_284 = 0x3FE; + } else { + func_801518B0(globalCtx, 0x400, &this->actor); + this->unk_284 = 0x400; + } + } else { + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + player->actor.freezeTimer = 0; + this->unk_26A = 7; + player->stateFlags1 |= 0x20; + gSaveContext.weekEventReg[63] |= 1; + gSaveContext.weekEventReg[63] &= (u8)~2; + this->actionFunc = func_809C8710; + } + break; + + case 0x3FE: + case 0x400: + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + player->actor.freezeTimer = 0; + this->unk_27E = 0; + func_80112AFC(globalCtx); + func_80123F2C(globalCtx, 0x63); + this->unk_26A = 1; + func_801A2BB8(0x25); + this->actionFunc = func_809C8808; + break; + + case 0x401: + if (gSaveContext.weekEventReg[63] & 2) { + func_801477B4(globalCtx); + gSaveContext.weekEventReg[63] &= (u8)~1; + gSaveContext.weekEventReg[63] &= (u8)~2; + this->unk_26A = 0; + this->actionFunc = func_809C72D8; + } else { + func_801518B0(globalCtx, 0x402, &this->actor); + this->unk_284 = 0x402; + } + break; + + case 0x403: + if (gSaveContext.weekEventReg[63] & 2) { + func_801477B4(globalCtx); + gSaveContext.weekEventReg[63] &= (u8)~1; + gSaveContext.weekEventReg[63] &= (u8)~2; + this->unk_26A = 0; + this->actionFunc = func_809C72D8; + } else { + func_801518B0(globalCtx, 0x404, &this->actor); + this->unk_284 = 0x404; + } + break; + + case 0x402: + case 0x404: + func_801518B0(globalCtx, 0x3F6, &this->actor); + this->unk_284 = 0x3F6; + this->unk_26A = 4; + break; + + case 0x405: + case 0x406: + case 0x407: + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + player->actor.freezeTimer = 0; + gSaveContext.minigameState = 3; + this->actionFunc = func_809C7D14; + func_809C7D14(this, globalCtx); + break; + } + } +} + +void func_809C7990(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (player->stateFlags1 & 0x20) { + player->stateFlags1 |= 0x20; + } + + switch (func_80152498(&globalCtx->msgCtx)) { + case 2: + this->actionFunc = func_809C72D8; + this->unk_26A = 0; + break; + + case 4: + func_809C7380(this, globalCtx); + break; + + case 5: + func_809C7620(this, globalCtx); + break; + + case 6: + if (func_80147624(globalCtx)) { + gSaveContext.weekEventReg[63] &= (u8)~1; + gSaveContext.weekEventReg[63] &= (u8)~2; + player->stateFlags1 &= ~0x20; + this->actionFunc = func_809C72D8; + this->unk_26A = 0; + } + break; + + case 0: + case 1: + case 3: + case 7: + case 8: + case 9: + case 10: + break; + } +} + +void func_809C7A90(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (Actor_HasParent(&this->actor, globalCtx)) { + if (!(gSaveContext.weekEventReg[59] & 0x10)) { + gSaveContext.weekEventReg[59] |= 0x10; + } else if (!(gSaveContext.weekEventReg[32] & 2) && (this->unk_280 >= 0x884)) { + gSaveContext.weekEventReg[32] |= 2; + } + this->actor.parent = NULL; + this->actionFunc = func_809C7C14; + } else { + if ((CUR_UPG_VALUE(UPG_QUIVER) < 3) && !(gSaveContext.weekEventReg[59] & 0x10)) { + func_800B8A1C(&this->actor, globalCtx, GI_QUIVER_30 + CUR_UPG_VALUE(UPG_QUIVER), 500.0f, 100.0f); + } else if (this->unk_280 < 0x884) { + func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_RED, 500.0f, 100.0f); + } else if (!(gSaveContext.weekEventReg[32] & 2)) { + func_800B8A1C(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); + } else { + func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); + } + + player->actor.shape.rot.y = -0x8000; + player->actor.velocity.z = 0.0f; + player->actor.velocity.x = 0.0f; + player->actor.world.rot.y = player->actor.shape.rot.y; + } +} + +void func_809C7C14(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (func_800B84D0(&this->actor, globalCtx)) { + if ((CURRENT_DAY == 3) && (gSaveContext.time > CLOCK_TIME(12, 00))) { + func_801518B0(globalCtx, 0xA36, &this->actor); + this->unk_284 = 0xA36; + } else { + func_801518B0(globalCtx, 0xA37, &this->actor); + this->unk_284 = 0xA37; + } + player->stateFlags1 &= ~0x20; + this->actor.flags &= ~0x10000; + this->unk_280 = 0; + this->unk_26A = 0; + this->actionFunc = func_809C6E30; + } else { + func_800B85E0(&this->actor, globalCtx, 500.0f, -1); + } +} + +void func_809C7D14(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (Actor_HasParent(&this->actor, globalCtx)) { + if (this->unk_284 == 0x407) { + if (!(gSaveContext.weekEventReg[59] & 0x20)) { + gSaveContext.weekEventReg[59] |= 0x20; + } + } + + if ((this->unk_284 == 0x405) || (this->unk_284 == 0x406)) { + if (!(gSaveContext.weekEventReg[32] & 4)) { + gSaveContext.weekEventReg[32] |= 4; + } + } + this->actor.parent = NULL; + this->actionFunc = func_809C7EB4; + } else { + if (this->unk_284 == 0x407) { + if ((CUR_UPG_VALUE(UPG_QUIVER) < 3) && !(gSaveContext.weekEventReg[59] & 0x20)) { + func_800B8A1C(&this->actor, globalCtx, GI_QUIVER_30 + CUR_UPG_VALUE(UPG_QUIVER), 500.0f, 100.0f); + } else { + func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); + } + } else if (!(gSaveContext.weekEventReg[32] & 4)) { + func_800B8A1C(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); + } else { + func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_GOLD, 500.0f, 100.0f); + } + + player->actor.shape.rot.y = -0x8000; + player->actor.velocity.z = 0.0f; + player->actor.velocity.x = 0.0f; + player->actor.world.rot.y = player->actor.shape.rot.y; + } +} + +void func_809C7EB4(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (CURRENT_DAY != 3) { + if ((func_80152498(&globalCtx->msgCtx) == 6) && func_80147624(globalCtx)) { + player->stateFlags1 &= ~0x20; + this->unk_280 = 0; + this->unk_26A = 0; + gSaveContext.weekEventReg[63] &= (u8)~1; + gSaveContext.weekEventReg[63] &= (u8)~2; + this->actionFunc = func_809C6810; + } + } else if (func_800B84D0(&this->actor, globalCtx)) { + func_801518B0(globalCtx, 0x408, &this->actor); + this->unk_284 = 0x408; + player->stateFlags1 &= ~0x20; + this->actor.flags &= ~0x10000; + this->unk_280 = 0; + this->unk_26A = 0; + this->actionFunc = func_809C7990; + } else { + func_800B85E0(&this->actor, globalCtx, 500.0f, -1); + } +} + +void func_809C7FFC(EnSyatekiMan* this, GlobalContext* globalCtx) { + Player* player = PLAYER; + + if (func_809C6720(globalCtx, D_809C9474)) { + player->stateFlags1 |= 0x20; + this->unk_26A = 2; + if (this->unk_282 != 2) { + this->unk_282 = 2; + func_801518B0(globalCtx, 0xA2B, &this->actor); + this->unk_284 = 0xA2B; + } else { + func_801518B0(globalCtx, 0xA2C, &this->actor); + this->unk_284 = 0xA2C; + } + this->actionFunc = func_809C6E30; + } +} + +void func_809C80C0(EnSyatekiMan* this, GlobalContext* globalCtx) { + static s16 D_809C9498 = 30; + Player* player = PLAYER; + + if (D_809C9498 > 0) { + player->actor.world.pos = D_809C9474; + player->actor.shape.rot.y = -0x8000; + player->actor.world.rot.y = player->actor.shape.rot.y; + globalCtx->unk_18790(globalCtx, -0x8000, &this->actor); + D_809C9498--; + } else { + D_809C9498 = 30; + this->unk_27E = 0; + this->unk_280 = 0; + player->stateFlags1 &= ~0x20; + Audio_PlayActorSound2(&this->actor, NA_SE_SY_FOUND); + this->unk_272 = 0x1F; + this->unk_274 = 0; + this->unk_276 = 0; + this->unk_26C = 0; + this->unk_278 = 0; + this->unk_27A = 0; + this->unk_27C = 0; + this->unk_26E = 0; + func_8010E9F0(1, 100); + this->actor.draw = NULL; + this->actionFunc = func_809C81D0; + } +} + +void func_809C81D0(EnSyatekiMan* this, GlobalContext* globalCtx) { + static s16 D_809C949C = 0; + Player* player = PLAYER; + + if (((this->unk_272 == 0) || (this->unk_26C > 140)) && (D_809C949C == 0) && (this->unk_27C < 4)) { + D_809C949C = 1; + this->unk_26C = 0; + Audio_PlayActorSound2(&this->actor, NA_SE_SY_FOUND); + this->unk_274 = D_809C91C8[this->unk_27E]; + if (this->unk_27E == 3) { + this->unk_27E = 0; + } else { + this->unk_27E++; + } + } else if ((this->unk_274 == 0) && (this->unk_272 == 0) && (D_809C949C == 1) && (this->unk_27C < 4)) { + if (this->unk_27A < 3) { + this->unk_27A = 0; + } + this->unk_26C = 0; + D_809C949C = 0; + this->unk_27C++; + if (this->unk_27C < 4) { + this->unk_272 = 31; + } + } + + if (this->unk_27A == 3) { + this->unk_27A = 0; + this->unk_276 |= 1; + } + + if (this->unk_278 == 10) { + this->unk_278 = 0; + this->unk_276 |= 2; + } + + this->unk_26C++; + if (gSaveContext.unk_3DE0[1] == 0) { + gSaveContext.unk_3DE0[1] = 0; + gSaveContext.unk_3DD0[1] = 5; + this->actor.draw = EnSyatekiMan_Draw; + this->unk_27E = 0; + this->unk_27C = 0; + player->stateFlags1 |= 0x20; + D_809C949C = 0; + func_801A2C20(); + this->actionFunc = func_809C8488; + } else if ((this->unk_27C == 4) && (this->unk_276 == 0) && (this->unk_26E == 2)) { + this->actor.draw = EnSyatekiMan_Draw; + this->unk_27E = 0; + this->unk_27C = 0; + player->stateFlags1 |= 0x20; + D_809C949C = 0; + func_801A2C20(); + this->unk_26A = 5; + if (this->unk_280 == 0x848) { + func_8011B4E0(globalCtx, 2); + gSaveContext.unk_3DD0[1] = 6; + this->actionFunc = func_809C8610; + } else { + gSaveContext.unk_3DD0[1] = 5; + this->actionFunc = func_809C8488; + } + } +} + +void func_809C8488(EnSyatekiMan* this, GlobalContext* globalCtx) { + if ((this->unk_26A == 1) || (this->unk_26A == 5)) { + this->unk_190 = 0; + this->unk_272 = 0; + this->unk_274 = 0; + this->unk_276 = 0; + if (this->unk_270 <= 0) { + if ((s32)((gSaveContext.roomInf[127][6] & 0xFFFF0000) >> 0x10) < this->unk_280) { + gSaveContext.roomInf[127][6] = ((gSaveContext.roomInf[127][6]) & 0xFFFF) | ((u16)this->unk_280 << 0x10); + } + this->unk_270 = 15; + if (this->unk_280 >= 0x848) { + func_801518B0(globalCtx, 0xA34, &this->actor); + this->unk_284 = 0xA34; + this->unk_26A = 6; + } else if (this->unk_280 >= 0x7D0) { + if (gSaveContext.weekEventReg[63] & 2) { + gSaveContext.weekEventReg[63] &= (u8)~1; + gSaveContext.weekEventReg[63] &= (u8)~2; + this->unk_26A = 0; + gSaveContext.minigameState = 3; + this->actionFunc = func_809C6848; + return; + } + func_801518B0(globalCtx, 0xA35, &this->actor); + this->unk_284 = 0xA35; + this->unk_26A = 4; + this->unk_280 = 0; + } else { + func_801518B0(globalCtx, 0xA32, &this->actor); + this->unk_284 = 0xA32; + this->unk_26A = 6; + } + this->actionFunc = func_809C6E30; + } else { + this->unk_270--; + } + } + + if (this->unk_270 < 5) { + globalCtx->unk_1887C = -10; + } +} + +void func_809C8610(EnSyatekiMan* this, GlobalContext* globalCtx) { + static s32 D_809C94A0 = 0; + Player* player = PLAYER; + + player->stateFlags1 |= 0x20; + if (globalCtx->interfaceCtx.unk_286 == 0) { + if (gSaveContext.unk_3DE0[1] == 0) { + gSaveContext.unk_3DE0[1] = 0; + gSaveContext.unk_3DD0[1] = 5; + this->unk_27E = 0; + this->unk_27C = 0; + this->actionFunc = func_809C8488; + D_809C94A0 = 0; + } else if (D_809C94A0 > 10) { + gSaveContext.unk_3E88[1] += 100; + globalCtx->interfaceCtx.unk_25C += 10; + this->unk_280 += 10; + Audio_PlayActorSound2(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + D_809C94A0 = 0; + } else { + D_809C94A0++; + } + } +} + +void func_809C8710(EnSyatekiMan* this, GlobalContext* globalCtx) { + Vec3f sp24; + + if (gSaveContext.playerForm == PLAYER_FORM_FIERCE_DEITY) { + sp24 = D_809C9480; + } else { + sp24 = D_809C948C; + } + + if (func_809C6720(globalCtx, sp24)) { + if (this->unk_284 == 0x3FD) { + func_801518B0(globalCtx, 0x3FE, &this->actor); + this->unk_284 = 0x3FE; + } else { + func_801518B0(globalCtx, 0x400, &this->actor); + this->unk_284 = 0x400; + } + this->unk_26A = 2; + this->actionFunc = func_809C7990; + } +} + +void func_809C8808(EnSyatekiMan* this, GlobalContext* globalCtx) { + static s16 D_809C94A4 = 30; + Player* player = PLAYER; + + if (D_809C94A4 == 30) { + if (player->transformation == PLAYER_FORM_FIERCE_DEITY) { + player->actor.world.pos = D_809C9480; + } else { + player->actor.world.pos = D_809C948C; + } + player->actor.prevPos = player->actor.world.pos; + player->actor.shape.rot.y = -0x8000; + player->actor.world.rot.y = player->actor.shape.rot.y; + globalCtx->unk_18790(globalCtx, -0x8000, &this->actor); + player->stateFlags1 |= 0x20; + D_809C94A4--; + } else if (D_809C94A4 > 0) { + player->actor.shape.rot.y = -0x8000; + player->actor.world.rot.y = player->actor.shape.rot.y; + D_809C94A4--; + } else if (D_809C94A4 == 0) { + player->stateFlags1 &= ~0x20; + this->unk_280 = 0; + this->unk_27E = 0; + this->unk_26C = 70; + this->unk_26E = 0; + D_809C94A4 = 30; + func_8010E9F0(1, 75); + this->actor.draw = NULL; + this->actionFunc = func_809C898C; + } +} + +void func_809C898C(EnSyatekiMan* this, GlobalContext* globalCtx) { + static const s32 D_809C94D0[] = { + 0x00000111, 0x00000650, 0x00010025, 0x00011011, 0x00000984, 0x00004050, 0x00010211, 0x00022015, + 0x00026984, 0x00012852, 0x00011999, 0x00022895, 0x0000056A, 0x0002A451, 0x00004115, + }; + static s32 D_809C94A8 = 0; + Player* player = PLAYER; + s32 sp30; + s32 pad; + u64 sp20; + + sp20 = gSaveContext.unk_3DE0[1]; + sp30 = (sp20 * 0.1f) + 1.0f; + + if (sp30 < 0x2EF) { + s32 temp; + + // clang-format off + if (D_809C94A8 == 0) { + sp20 = gSaveContext.unk_3DE0[1]; temp = sp20 % 0x1F4; + } else { + sp20 = gSaveContext.unk_3DE0[1]; temp = (sp20 + 250) % 0x1F4; + } + //clang-format on + + if (temp < 100) { + this->unk_26C = 0x50; + } + + if (this->unk_26E != 0) { + if (this->unk_26E == 2) { + gSaveContext.unk_3E18[1] -= 250; + D_809C94A8 = (D_809C94A8 + 25) % 50; + } + this->unk_26E = 0; + } + + if (this->unk_26C == 0) { + this->unk_26C++; + } + + if ((D_809C94A8 == (sp30 % 50)) && (this->unk_26C >= 70)) { + if (this->unk_27E < 15) { + this->unk_190 = D_809C94D0[this->unk_27E++]; + Audio_PlayActorSound2(&this->actor, NA_SE_SY_FOUND); + this->unk_26C = 0; + } + } + + if (gSaveContext.unk_3DE0[1] == 0) { + this->unk_27E = 0; + this->unk_26C = 80; + gSaveContext.unk_3DE0[1] = 0; + gSaveContext.unk_3DD0[1] = 5; + player->stateFlags1 |= 0x20; + D_809C94A8 = 0; + this->actor.draw = EnSyatekiMan_Draw; + func_801A2C20(); + this->actionFunc = func_809C8BF0; + if (this->unk_280 == 50) { + func_801A3098(0x922); + func_8011B4E0(globalCtx, 1); + } + } + } +} + +void func_809C8BF0(EnSyatekiMan* this, GlobalContext* globalCtx) { + if (this->unk_26A == 1) { + this->unk_190 = 0; + if ((this->unk_270 <= 0) && (globalCtx->interfaceCtx.unk_286 == 0)) { + Actor_SetAllChestFlag(globalCtx, this->unk_280); + this->unk_270 = 15; + if (((s32)(gSaveContext.roomInf[127][6] & 0xFFFF) < this->unk_280) || (this->unk_280 == 50)) { + if ((s32)(gSaveContext.roomInf[127][6] & 0xFFFF) < this->unk_280) { + if (!(gSaveContext.weekEventReg[59] & 0x20)) { + func_801518B0(globalCtx, 0x407, &this->actor); + this->unk_284 = 0x407; + } else if (this->unk_280 == 50) { + func_801518B0(globalCtx, 0x405, &this->actor); + this->unk_284 = 0x405; + } else { + func_801518B0(globalCtx, 0x407, &this->actor); + this->unk_284 = 0x407; + } + } else if (this->unk_280 == 50) { + func_801518B0(globalCtx, 0x406, &this->actor); + this->unk_284 = 0x406; + } + gSaveContext.roomInf[127][6] = (gSaveContext.roomInf[127][6] & 0xFFFF0000) | (this->unk_280 & 0xFFFF); + this->unk_26A = 6; + } else { + if (CURRENT_DAY != 3) { + func_801518B0(globalCtx, 0x401, &this->actor); + this->unk_284 = 0x401; + } else { + func_801518B0(globalCtx, 0x403, &this->actor); + this->unk_284 = 0x403; + } + this->unk_26A = 4; + } + this->actionFunc = func_809C7990; + } else { + this->unk_270--; + } + } + + if (this->unk_270 < 5) { + globalCtx->unk_1887C = -10; + } +} + +void func_809C8DE8(EnSyatekiMan* this) { + switch (this->unk_266) { + case 1: + this->unk_264 = 2; + break; + + case 2: + this->unk_264 = 1; + break; + + case 40: + this->unk_266 = 0; + + default: + this->unk_264 = 0; + break; + } + + this->unk_266++; +} + +void EnSyatekiMan_Update(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiMan* this = THIS; + + this->actionFunc(this, globalCtx); + func_809C8DE8(this); + this->actor.focus.pos.y = 70.0f; + Actor_SetHeight(&this->actor, 70.0f); + if (this->unk_26A != 1) { + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + func_800E9250(globalCtx, &this->actor, &this->unk_258, &this->unk_25E, this->actor.focus.pos); + } +} + +s32 EnSyatekiMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnSyatekiMan* this = THIS; + + if ((globalCtx->sceneNum == SCENE_SYATEKI_MIZU) && (limbIndex == 15)) { + *dList = D_0600F2D0; + } + + if (limbIndex == 15) { + SysMatrix_InsertTranslation(3000.0f, 0.0f, 0.0f, MTXMODE_APPLY); + SysMatrix_InsertZRotation_s(this->unk_258.x, MTXMODE_APPLY); + SysMatrix_InsertXRotation_s(this->unk_258.y, MTXMODE_APPLY); + SysMatrix_InsertTranslation(-3000.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } else if (limbIndex == 8) { + SysMatrix_InsertXRotation_s(-this->unk_25E.y, MTXMODE_APPLY); + } + + return false; +} + +void EnSyatekiMan_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnSyatekiMan* this = THIS; + Vec3f sp18 = { 1600.0f, 0.0f, 0.0f }; + + if (limbIndex == 15) { + SysMatrix_MultiplyVector3fByState(&sp18, &this->actor.focus.pos); + } +} + +void EnSyatekiMan_Draw(Actor* thisx, GlobalContext* globalCtx) { + static UNK_PTR D_809C94B8[] = { + &D_06005AC8, + &D_060062C8, + &D_060062C8, + }; + EnSyatekiMan* this = THIS; + s32 pad; + + if (globalCtx->sceneNum == SCENE_SYATEKI_MIZU) { + D_809C94B8[0] = &D_0600FB90; + D_809C94B8[1] = &D_06010390; + D_809C94B8[2] = &D_06010390; + } else { + D_809C94B8[0] = &D_06005AC8; + D_809C94B8[1] = &D_060062C8; + D_809C94B8[2] = &D_060062C8; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C5B0(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_809C94B8[this->unk_264])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_809C94B8[this->unk_264])); + + SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount, + EnSyatekiMan_OverrideLimbDraw, EnSyatekiMan_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h index a80b2b304..80f2a1068 100644 --- a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h +++ b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h @@ -7,11 +7,44 @@ struct EnSyatekiMan; typedef void (*EnSyatekiManActionFunc)(struct EnSyatekiMan*, GlobalContext*); +#define ENSYATEKIMAN_GET_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) + +typedef struct { + /* 0x00 */ s16 index; + /* 0x04 */ f32 x; + /* 0x08 */ f32 y; + /* 0x0C */ f32 z; + /* 0x10 */ s32 variable; +} EnSyatekiManUnkStruct; + typedef struct EnSyatekiMan { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnSyatekiManActionFunc actionFunc; - /* 0x018C */ char unk_18C[0xFC]; + /* 0x018C */ Path* path; + /* 0x0190 */ s32 unk_190; + /* 0x0194 */ s32 unk_194; + /* 0x0198 */ Vec3s jointTable[16]; + /* 0x01F8 */ Vec3s morphTable[16]; + /* 0x0258 */ Vec3s unk_258; + /* 0x025E */ Vec3s unk_25E; + /* 0x0264 */ s16 unk_264; + /* 0x0266 */ s16 unk_266; + /* 0x0268 */ UNK_TYPE1 unk268[0x2]; + /* 0x026A */ s16 unk_26A; + /* 0x026C */ s16 unk_26C; + /* 0x026E */ s16 unk_26E; + /* 0x0270 */ s16 unk_270; + /* 0x0272 */ s16 unk_272; + /* 0x0274 */ s16 unk_274; + /* 0x0276 */ s16 unk_276; + /* 0x0278 */ s16 unk_278; + /* 0x027A */ s16 unk_27A; + /* 0x027C */ s16 unk_27C; + /* 0x027E */ s16 unk_27E; + /* 0x0280 */ s16 unk_280; + /* 0x0282 */ s16 unk_282; + /* 0x0284 */ s16 unk_284; } EnSyatekiMan; // size = 0x288 extern const ActorInit En_Syateki_Man_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index eba62a5cd..8ba8afa25 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -9113,8 +9113,8 @@ 0x809C8BF0:("func_809C8BF0",), 0x809C8DE8:("func_809C8DE8",), 0x809C8E44:("EnSyatekiMan_Update",), - 0x809C8EE4:("func_809C8EE4",), - 0x809C8FAC:("func_809C8FAC",), + 0x809C8EE4:("EnSyatekiMan_OverrideLimbDraw",), + 0x809C8FAC:("EnSyatekiMan_PostLimbDraw",), 0x809C9008:("EnSyatekiMan_Draw",), 0x809C9A60:("BgIcicle_Init",), 0x809C9B54:("BgIcicle_Destroy",), From c72b5788a3fcb13d099880d5fb552af232142266 Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Mon, 27 Sep 2021 22:41:07 +0100 Subject: [PATCH 08/13] sys_math, cosf OK and documented, sinf, coss, sins documented (#289) * OK, data imported, document * spec * Match cosf, document sinf and cosf * Some more documentation, switch fu back * Format * Little more documentation * Document coss too * Move macros * Review, add some .s * Fix headers, review --- include/convert.h | 2 + include/functions.h | 6 +-- include/macros.h | 5 ++- include/math.h | 3 +- include/variables.h | 2 +- spec | 1 - src/code/sys_math.c | 92 ++++++++++++++++++++++++++++++++++++++---- src/libultra/gu/cosf.c | 71 +++++++++++++++++++++++++++++++- src/libultra/gu/coss.c | 5 ++- src/libultra/gu/sinf.c | 88 ++++++++++++++++++++-------------------- src/libultra/gu/sins.c | 8 +++- tools/disasm/files.txt | 2 +- 12 files changed, 221 insertions(+), 64 deletions(-) diff --git a/include/convert.h b/include/convert.h index 31bdb034f..456e4b198 100644 --- a/include/convert.h +++ b/include/convert.h @@ -1,6 +1,8 @@ #ifndef _ULTRA64_CONVERT_H_ #define _ULTRA64_CONVERT_H_ +#include "stdint.h" + #define OS_CLOCK_RATE 62500000LL #define OS_CPU_COUNTER (OS_CLOCK_RATE*3/4) diff --git a/include/functions.h b/include/functions.h index 0948b502e..aba291a28 100644 --- a/include/functions.h +++ b/include/functions.h @@ -3269,9 +3269,9 @@ void Check_ClearRGBA16(s16* buffer); // void Check_DrawRegionLockErrorMessage(void); // void Check_ExpansionPak(void); // void Check_RegionIsSupported(void); -f32 func_80179300(f32 param_1); -f32 func_80179400(s32 param_1); -f32 pow_int(f32 x, s32 pow); +f32 func_80179300(f32 n); +f32 func_80179400(s32 n); +f32 pow_int(f32 base, s32 exp); f32 sin_rad(f32 rad); f32 cos_rad(f32 rad); f32 Rand_ZeroFloat(f32 scale); diff --git a/include/macros.h b/include/macros.h index 36af1534b..e0e6c8e7c 100644 --- a/include/macros.h +++ b/include/macros.h @@ -1,8 +1,9 @@ #ifndef _MACROS_H_ #define _MACROS_H_ -#include "convert.h" #include "stdint.h" +#include "convert.h" +#include "z64.h" #define ARRAY_COUNT(arr) (s32)(sizeof(arr) / sizeof(arr[0])) #define ARRAY_COUNTU(arr) (u32)(sizeof(arr) / sizeof(arr[0])) @@ -116,6 +117,8 @@ extern GraphicsContext* __gfxCtx; #define CLAMP_MAX(x, max) ((x) > (max) ? (max) : (x)) #define CLAMP_MIN(x, min) ((x) < (min) ? (min) : (x)) +#define ROUND(x) (s32)(((x) >= 0.0) ? ((x) + 0.5) : ((x) - 0.5)) + #define SWAP(type, a, b) \ { \ type _temp = (a); \ diff --git a/include/math.h b/include/math.h index 316bc5710..20fa352fa 100644 --- a/include/math.h +++ b/include/math.h @@ -12,12 +12,11 @@ #define DEGTORAD(x) ((x) * (M_PI / 180.0f)) typedef union { + f64 d; struct { u32 hi; u32 lo; } word; - - f64 d; } du; typedef union { diff --git a/include/variables.h b/include/variables.h index f2fd0f2b4..c6fb55982 100644 --- a/include/variables.h +++ b/include/variables.h @@ -1670,7 +1670,7 @@ extern PadMgr* padmgrContext; // extern UNK_TYPE4 controllerInputsCaptured; // extern UNK_TYPE4 D_801D1538; extern UNK_PTR D_801D1540; -extern f32 D_801D1570[13]; +// extern f32 sFactorialTbl[13]; extern Vec3f D_801D15B0; extern Vec3s D_801D15BC; extern RSPMatrix D_801D1DE0; diff --git a/spec b/spec index 0754aca9c..6b028302d 100644 --- a/spec +++ b/spec @@ -633,7 +633,6 @@ beginseg include "build/src/code/sys_math.o" include "build/src/code/sys_math3d.o" include "build/data/code/sys_math3d.bss.o" - include "build/data/code/code_801D1570.data.o" include "build/data/code/code_801D15B0.data.o" include "build/src/code/sys_math_atan.o" include "build/src/code/sys_matrix.o" diff --git a/src/code/sys_math.c b/src/code/sys_math.c index 4142cd598..9b274c7e2 100644 --- a/src/code/sys_math.c +++ b/src/code/sys_math.c @@ -1,15 +1,93 @@ +/** + * Maths library: two factorials, integer power, wrappers for libultra's sins and coss (the main ones used), and some + * random functions moved from OoT's z_actor + */ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math/func_80179300.s") +static f32 sFactorialTbl[] = { 1.0f, 1.0f, 2.0f, 6.0f, 24.0f, 120.0f, 720.0f, + 5040.0f, 40320.0f, 362880.0f, 3628800.0f, 39916800.0f, 479001600.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math/func_80179400.s") +// Rename to Math_FactorialF +/** + * Takes a float, returns the factorial of it(s trunctation), iteratively + * Unused + */ +f32 func_80179300(f32 n) { + f32 ret = 1.0f; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math/pow_int.s") + //! @bug No check for negative argument. Will return 1.0f if the argument truncates to a negative int. + for (i = n; i > 1; i--) { + ret *= i; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math/sin_rad.s") +// Rename to Math_Factorial +/** + * Takes an int and returns its factorial as a float. Uses the lookup table for n <= 12. + * Unused + */ +f32 func_80179400(s32 n) { + f32 ret; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math/cos_rad.s") + //! @bug No check for negative argument. Will read the array out-of-bounds if the argument is negative. + //! (The OoT version does an unsigned check instead, which will return sFactorialTbl[12] for a negative argument.) + if (n > 12) { + ret = sFactorialTbl[12]; + for (i = 13; i <= n; i++) { + ret *= i; + } + } else { + ret = sFactorialTbl[n]; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math/Rand_ZeroFloat.s") +// Rename to Math_PowF +/** + * Returns base^{exp} if exp is nonnegative and 1.0f otherwise. + * Unused + */ +f32 pow_int(f32 base, s32 exp) { + f32 ret = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math/randPlusMinusPoint5Scaled.s") + while (exp > 0) { + exp--; + ret *= base; + } + + return ret; +} + +// Rename to Math_SinF +/** + * Takes an angle in radians and returns the sine. + */ +f32 sin_rad(f32 rad) { + return sins(RADF_TO_BINANG(rad)) * SHT_MINV; +} + +// Rename to Math_CosF +/** + * Takes an angle in radians and returns the cosine. + */ +f32 cos_rad(f32 rad) { + return coss(RADF_TO_BINANG(rad)) * SHT_MINV; +} + +/** + * Returns a pseudo-random floating-point number between 0.0f and scale. Originally in z_actor in OoT. + */ +f32 Rand_ZeroFloat(f32 scale) { + return Rand_ZeroOne() * scale; +} + +// Rename to Rand_CenteredFloat +/** + * Returns a pseudo-random floating-point number between (- scale / 2) and (scale / 2). Originally in z_actor in OoT. + */ +f32 randPlusMinusPoint5Scaled(f32 scale) { + return Rand_Centered() * scale; +} diff --git a/src/libultra/gu/cosf.c b/src/libultra/gu/cosf.c index c5af1c907..72d154d70 100644 --- a/src/libultra/gu/cosf.c +++ b/src/libultra/gu/cosf.c @@ -1,3 +1,70 @@ -#include "global.h" +#include "math.h" +#include "macros.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/cosf/__cosf.s") +// A slightly tweaked form of the coefficients of the Maclaurin series of sine up to x^9 +// [https://mathworld.wolfram.com/MaclaurinSeries.html]. +// The commented versions do not match. +static const du P[] = { + { 1.0 }, // 1 + { -0.16666659550427756 }, // -1/3! = 1/6 + { 0.008333066246082155 }, // 1/5! = 1/120 + { -0.0001980960290193795 }, // -1/7! = -1/5040 + { 0.000002605780637968037 }, // 1/9! = 1/362880 +}; + +static const du rpi = { 1 / 3.14159265358979323846 }; // 1/M_PI, "reciprocal of pi" + +static const du pihi = { 3.1415926218032837 }; + +static const du pilo = { 3.178650954705639E-8 }; // pihi + pilo is the closest double to pi + +static const fu zero = { 0x00000000 }; + +/** + * Computes the cosine of a float, returning a float. It essentially computes sin(x+pi/2) by the same method as __sinf, + * without as many size checks. + */ +f32 __cosf(f32 x) { + f32 absx; + f64 dx; // x promoted to double + f64 xSq; // square of dx + f64 polyApprox; // Most of Maclaurin polynomial of sin(x) of degree 9 + f64 dn; // n promoted to double + s32 n; // number of multiples of pi away from the first half-period + f64 result; + s32 ix = *(s32*)&x; // Type-pun x into an s32, i.e. its IEEE-754 hex representation + s32 xpt = (ix >> 22); // Obtain the exponent of x (actually 2 * exponent + 127) + + xpt &= 0x1FF; // Remove the sign bit + + // |x| < 2^{28} (beyond this range, floats are too sparse to make the trig functions useable) + if (xpt < 310) { + absx = (x > 0) ? x : -x; + dx = absx; + + dn = dx * rpi.d + 0.5; + n = ROUND(dn); + dn = n; + + dn -= 0.5; + + dx -= dn * pihi.d; + dx -= dn * pilo.d; + + xSq = SQ(dx); + polyApprox = ((P[4].d * xSq + P[3].d) * xSq + P[2].d) * xSq + P[1].d; + result = dx + (dx * xSq) * polyApprox; // Actual Maclaurin polynomial for sin(x) + + if (n % 2 == 0) { + return (f32)result; + } + return -(f32)result; + } + + // if x is NaN + if (x != x) { + return __libm_qnan_f; + } + + return zero.f; +} diff --git a/src/libultra/gu/coss.c b/src/libultra/gu/coss.c index 466c36505..ebed28405 100644 --- a/src/libultra/gu/coss.c +++ b/src/libultra/gu/coss.c @@ -1,5 +1,8 @@ #include "global.h" -short coss(unsigned short x) { +/** + * Compute the sine of a hex angle and return a short, using the formula cos(x) = sin(x+pi). + */ +s16 coss(u16 x) { return sins(x + 0x4000); } diff --git a/src/libultra/gu/sinf.c b/src/libultra/gu/sinf.c index 01923221c..5f3455ec5 100644 --- a/src/libultra/gu/sinf.c +++ b/src/libultra/gu/sinf.c @@ -1,77 +1,79 @@ #include "math.h" +#include "macros.h" +// A slightly tweaked form of the coefficients of the Maclaurin series of sine up to x^9 +// [https://mathworld.wolfram.com/MaclaurinSeries.html]. +// The commented versions do not match. static const du P[] = { - { 0x3FF00000, 0x00000000 }, { 0xBFC55554, 0xBC83656D }, { 0x3F8110ED, 0x3804C2A0 }, - { 0xBF29F6FF, 0xEEA56814 }, { 0x3EC5DBDF, 0x0E314BFE }, + { 1.0 }, // 1 + { -0.16666659550427756 }, // -1/3! = 1/6 + { 0.008333066246082155 }, // 1/5! = 1/120 + { -0.0001980960290193795 }, // -1/7! = -1/5040 + { 0.000002605780637968037 }, // 1/9! = 1/362880 }; -static const du rpi = { 0x3FD45F30, 0x6DC9C883 }; +static const du rpi = { 1 / 3.14159265358979323846 }; // 1/M_PI, "reciprocal of pi" -static const du pihi = { 0x400921FB, 0x50000000 }; +static const du pihi = { 3.1415926218032837 }; -static const du pilo = { 0x3E6110B4, 0x611A6263 }; +static const du pilo = { 3.178650954705639E-8 }; // pihi + pilo is the closest double to pi static const fu zero = { 0x00000000 }; -extern float __libm_qnan_f; +/** + * Returns the sine of a float as a float, using the Maclaurin series and shifting. + */ +f32 __sinf(f32 x) { + f64 dx; // x promoted to double + f64 xSq; // square of dx + f64 polyApprox; // Most of Maclaurin polynomial of sin(x) of degree 9 + f64 dn; // n promoted to double + s32 n; // number of multiples of pi away from the first half-period + f64 result; + s32 ix = *(s32*)&x; // Type-pun x into an s32, i.e. its IEEE-754 hex representation + s32 xpt = (ix >> 22); // Obtain the exponent of x (actually 2 * exponent + 127) -float __sinf(float x) { - double dx; // double x - double xsq; // x squared - double poly; - double dn; - int n; - double result; - int ix; // int x - int xpt; - - ix = *(int*)&x; - xpt = (ix >> 22) & 0x1FF; + xpt &= 0x1FF; // Remove the sign bit + // |x| < 1 if (xpt < 255) { dx = x; + + // |x| > 2^{-12}: for x smaller in magnitude than this, sin(x) - x is too small for a float to register the + // error if (xpt >= 230) { - xsq = dx * dx; + xSq = SQ(dx); + polyApprox = ((P[4].d * xSq + P[3].d) * xSq + P[2].d) * xSq + P[1].d; - poly = (((((P[4].d * xsq) + P[3].d) * xsq) + P[2].d) * xsq) + P[1].d; - - result = ((dx * xsq) * poly) + dx; - - return result; - } else { - return x; + result = dx + (dx * xSq) * polyApprox; + return (f32)result; } + return x; } + // |x| < 2^{28} (beyond this range, floats are too sparse to make the trig functions useable) if (xpt < 310) { dx = x; - dn = dx * rpi.d; - - if (dn >= 0) { - n = dn + 0.5; - } else { - n = dn - 0.5; - } - + n = ROUND(dn); dn = n; + // Bring x to the first half-period where the Maclaurin polynomial can be used dx -= dn * pihi.d; dx -= dn * pilo.d; - xsq = dx * dx; + xSq = SQ(dx); + polyApprox = ((P[4].d * xSq + P[3].d) * xSq + P[2].d) * xSq + P[1].d; + result = dx + (dx * xSq) * polyApprox; // Actual Maclaurin polynomial for sin(x) - poly = (((((P[4].d * xsq) + P[3].d) * xsq) + P[2].d) * xsq) + P[1].d; - - result = ((dx * xsq) * poly) + dx; - - if ((n & 0x1) == 0) { - return result; - } else { - return -(float)result; + // add a minus sign if x is an odd number of multiples of pi away from the first half-period + if (n % 2 == 0) { + return (f32)result; } + return -(f32)result; } + // if x is NaN if (x != x) { return __libm_qnan_f; } diff --git a/src/libultra/gu/sins.c b/src/libultra/gu/sins.c index 6dd5f23fc..69b3b7e39 100644 --- a/src/libultra/gu/sins.c +++ b/src/libultra/gu/sins.c @@ -77,8 +77,12 @@ static s16 sintable[0x400] = { 0x7FFE, 0x7FFF, }; -short sins(unsigned short x) { - short val; +/** + * Compute the sine of a hex angle and return a short, using a lookup table for the first quadrant, extrapolating to the + * others using the equivalents of sin(pi-x) = sin(x) and sin(pi+x) = -sin(x). + */ +s16 sins(u16 x) { + s16 val; x >>= 4; if ((x & 0x400) != 0) { diff --git a/tools/disasm/files.txt b/tools/disasm/files.txt index c67e0b7a7..eb4be6eb3 100644 --- a/tools/disasm/files.txt +++ b/tools/disasm/files.txt @@ -561,7 +561,7 @@ 0x801D1520 : "graph", 0x801D1530 : "padmgr", 0x801D1540 : "speed_meter", - 0x801D1570 : "", + 0x801D1570 : "sys_math", 0x801D15B0 : "", 0x801D15D0 : "sys_math_atan", 0x801D1DE0 : "sys_matrix", From 1362615cc6bc264654f4efc619c98cf53723adf3 Mon Sep 17 00:00:00 2001 From: rylieb <31797144+rylieb@users.noreply.github.com> Date: Mon, 27 Sep 2021 15:41:36 -0600 Subject: [PATCH 09/13] Add ctags "tags" files to .gitignore for vim users (#328) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fbaba047c..e2078e841 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ __pycache__/ CMakeLists.txt cmake-build-debug venv/ +tags # Project-specific ignores *.z64 From f642ed6eef04369fca72f106d87ff2c6f6475066 Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Tue, 28 Sep 2021 01:07:09 +0100 Subject: [PATCH 10/13] boot_0x80086760 OK and documented (#288) * boot_80086760 OK, added fp header, resplit data * Some more documentation, data imported with unions * Sweep data under the rug * Move the fp header properly * Format * include/fp.h header guards Co-authored-by: Anghelo Carvajal * Engineer's review * Fix typo Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Rename header * while (true) Co-authored-by: Anghelo Carvajal Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> --- include/fixed_point.h | 34 ++++++ spec | 2 +- src/boot_O2/boot_80086760.c | 209 +++++++++++++++++++++++++++++++++--- tools/disasm/files.txt | 1 + tools/disasm/variables.txt | 4 +- 5 files changed, 235 insertions(+), 15 deletions(-) create mode 100644 include/fixed_point.h diff --git a/include/fixed_point.h b/include/fixed_point.h new file mode 100644 index 000000000..bb7e96494 --- /dev/null +++ b/include/fixed_point.h @@ -0,0 +1,34 @@ +#ifndef FIXED_POINT_H +#define FIXED_POINT_H +#include "ultra64.h" + +extern f32 qNaN0x3FFFFF; +extern f32 qNaN0x10000; +extern f32 sNaN0x3FFFFF; + +f32 floorf(f32 x); +f64 floor(f64 x); +s32 lfloorf(f32 x); +s32 lfloor(f64 x); + +f32 ceilf(f32 x); +f64 ceil(f64 x); +s32 lceilf(f32 x); +s32 lceil(f64 x); + +f32 truncf(f32 x); +f64 trunc(f64 x); +s32 ltruncf(f32 x); +s32 ltrunc(f64 x); + +f32 nearbyintf(f32 x); +f64 nearbyint(f64 x); +s32 lnearbyintf(f32 x); +s32 lnearbyint(f64 x); + +f32 roundf(f32 x); +f64 round(f64 x); +s32 lroundf(f32 x); +s32 lround(f64 x); + +#endif diff --git a/spec b/spec index 6b028302d..41c7d61f8 100644 --- a/spec +++ b/spec @@ -43,8 +43,8 @@ beginseg include "build/data/boot/boot_800862E0.data.o" include "build/src/boot_O2/padsetup.o" include "build/src/boot_O2/boot_80086760.o" - include "build/data/boot/boot_80086760.bss.o" include "build/asm/boot/fp.text.o" + include "build/data/boot/fp.data.o" include "build/src/boot_O2/system_malloc.o" include "build/src/boot_O2/rand.o" include "build/src/boot_O2/__osMalloc.o" diff --git a/src/boot_O2/boot_80086760.c b/src/boot_O2/boot_80086760.c index b68013370..1a9b37453 100644 --- a/src/boot_O2/boot_80086760.c +++ b/src/boot_O2/boot_80086760.c @@ -1,27 +1,210 @@ +/** + * MathF library + * Contains tangent function, wrappers for a number of the handwritten functions in fp, and a suite of arctangents + */ #include "global.h" +#include "fixed_point.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_80086760.s") +extern f32 func_80086C70(f32 x); +extern f32 func_80086CA8(f32 x); +extern f32 func_80086D50(f32 x); +extern f32 func_80086CE0(f32 x); +extern f32 func_80086D18(f32 x); -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_80086794.s") +s32 gUseAtanContFrac; -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_800867B4.s") +/** + * Tangent function computed using libultra __sinf and __cosf + */ +// Math_FTanF +f32 func_80086760(f32 x) { + return __sinf(x) / __cosf(x); +} -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_800867D4.s") +// Unused +// Math_FFloorF +f32 func_80086794(f32 x) { + func_80086C70(x); +} -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_800867F4.s") +// Unused +// Math_FCeilF +f32 func_800867B4(f32 x) { + func_80086CA8(x); +} -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_80086814.s") +// Unused +// Math_FRoundF +f32 func_800867D4(f32 x) { + func_80086D50(x); +} -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_80086834.s") +// Unused +// Math_FTruncF +f32 func_800867F4(f32 x) { + func_80086CE0(x); +} -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_80086880.s") +// Math_FNearbyIntF +f32 func_80086814(f32 x) { + func_80086D18(x); +} -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_800869A4.s") +/** + * Arctangent approximation using a Maclaurin series [https://mathworld.wolfram.com/MaclaurinSeries.html] + * (one quadrant, i.e. |x| < 1) + */ +// Math_FAtanTaylorQF +f32 func_80086834(f32 x) { + // Coefficients of Maclaurin series of arctangent + static const f32 coeffs[] = { + -1.0f / 3, +1.0f / 5, -1.0f / 7, +1.0f / 9, -1.0f / 11, +1.0f / 13, -1.0f / 15, +1.0f / 17, 0.0f, + }; -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_80086AF0.s") + f32 poly = x; + f32 sq = SQ(x); + f32 exp = x * sq; + const f32* c = coeffs; + f32 term; -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_80086B30.s") + // Calculate the series until adding more terms does not change the float + while (true) { + term = *c++ * exp; + if (poly + term == poly) { + break; + } + poly += term; + exp *= sq; + } -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_80086C18.s") + return poly; +} -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_80086760/func_80086C48.s") +/** + * Extends previous arctangent function to the rest of the real numbers. + * Uses the formulae arctan(x) = pi/2 - arctan(1/x) + * and arctan(x) = pi/4 - arctan( (1-x)/(1+x) ) + * to extend the range in which the series computed by func_80086834 is a good approximation + */ +// Math_FAtanTaylorF +f32 func_80086880(f32 x) { + f32 t; + f32 q; + + if (x > 0.0f) { + t = x; + } else if (x < 0.0f) { + t = -x; + } else if (x == 0.0f) { + return 0.0f; + } else { + return qNaN0x10000; + } + + if (t <= M_SQRT2 - 1.0f) { + return func_80086834(x); + } + + if (t >= M_SQRT2 + 1.0f) { + q = M_PI / 2 - func_80086834(1.0f / t); + } else { // in the interval (\sqrt{2} - 1, \sqrt{2} + 1) + q = M_PI / 4 - func_80086834((1.0f - t) / (1.0f + t)); + } + + if (x > 0.0f) { + return q; + } else { + return -q; + } +} + +/** + * Arctangent approximation using a continued fraction + * Cf. https://en.wikipedia.org/wiki/Gauss%27s_continued_fraction#The_series_2F1_2 , + * https://dlmf.nist.gov/4.25#E4 + */ +// Math_FAtanContFracF +f32 func_800869A4(f32 x) { + s32 sector; + f32 z; + f32 conv; + f32 sq; + s32 i; + + if (x >= -1.0f && x <= 1.0f) { + sector = 0; + } else if (x > 1.0f) { + sector = 1; + x = 1.0f / x; + } else if (x < -1.0f) { + sector = -1; + x = 1.0f / x; + } else { + return qNaN0x10000; + } + + // Builds the continued fraction from the innermost fraction out + sq = SQ(x); + conv = 0.0f; + z = 8.0f; + for (i = 8; i != 0; i--) { + conv = SQ(z) * sq / (2.0f * z + 1.0f + conv); + z -= 1.0f; + } + conv = x / (1.0f + conv); + + if (sector == 0) { + return conv; + } else if (sector > 0) { + return M_PI / 2 - conv; + } else { + return -M_PI / 2 - conv; + } +} + +// Math_FAtanF +/** + * Single-argument arctangent, only used by the two-argument function. + * Nothing else sets the bss variable gUseAtanContFrac, so the Maclaurin series is always used + */ +f32 func_80086AF0(f32 x) { + if (!gUseAtanContFrac) { + return func_80086880(x); + } else { + return func_800869A4(x); + } +} + +// Math_FAtan2F +/** + * Main two-argument arctangent function + */ +f32 func_80086B30(f32 y, f32 x) { + if (x == 0.0f) { + if (y == 0.0f) { + return 0.0f; + } else if (y > 0.0f) { + return M_PI / 2; + } else if (y < 0.0f) { + return -M_PI / 2; + } else { + return qNaN0x10000; + } + } else if (x >= 0.0f) { + return func_80086AF0(y / x); + } else if (y < 0.0f) { + return func_80086AF0(y / x) - M_PI; + } else { + return M_PI - func_80086AF0(-(y / x)); + } +} + +// Math_FAsinF +f32 func_80086C18(f32 x) { + return func_80086B30(x, sqrtf(1.0f - SQ(x))); +} + +// Math_FAcosF +f32 func_80086C48(f32 x) { + return M_PI / 2 - func_80086C18(x); +} diff --git a/tools/disasm/files.txt b/tools/disasm/files.txt index eb4be6eb3..ed536b318 100644 --- a/tools/disasm/files.txt +++ b/tools/disasm/files.txt @@ -257,6 +257,7 @@ 0x80096C40 : "stackcheck", 0x80096C50 : "gfxprint", 0x80097500 : "boot_800862E0", + 0x80097520 : "fp", 0x80097530 : "rand", 0x80097540 : "vimodeHpf", 0x800975E0 : "sins", diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 91bfbab47..cc79d6fe8 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -36,7 +36,9 @@ 0x80096CF0:("sGfxPrintUnkData","u8","[8]",0x8), 0x80096CF8:("sGfxPrintFontData","u8","[0x800]",0x800), 0x80097500:("D_80097500","UNK_TYPE4","",0x4), - 0x80097524:("D_80097524","UNK_TYPE4","",0x4), + 0x80097520:("qNaN0x3FFFFF","f32","",0x4), + 0x80097524:("qNaN0x10000","f32","",0x4), + 0x80097528:("sNaN0x3FFFFF","f32","",0x4), 0x80097530:("sRandInt","u32","",0x4), 0x80097540:("osViModeNtscHpf1","OSViMode","",0x50), 0x80097590:("osViModePalLan1","OSViMode","",0x50), From de4cf63f63109519d1ec876cb7217422ee244d09 Mon Sep 17 00:00:00 2001 From: emilybrooks Date: Mon, 27 Sep 2021 17:21:08 -0700 Subject: [PATCH 11/13] obj_aqua OK (#321) * setup * almost done * only 3 floating point registers swapped * forgot newline * Audio_PlaySoundAtPosition * review suggestions * missed a hex number * matched func_80ACBDFC --- include/functions.h | 2 +- spec | 3 +- src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c | 279 ++++++++++++++++-- src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.h | 8 +- 4 files changed, 256 insertions(+), 36 deletions(-) diff --git a/include/functions.h b/include/functions.h index aba291a28..cc6513381 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1108,7 +1108,7 @@ u32 func_800C9D8C(CollisionContext* param_1, CollisionPoly* param_2, s32 param_3 u32 func_800C9E18(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); u32 func_800C9E40(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); u32 func_800C9E88(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -// void func_800C9EBC(GlobalContext* globalCtx, CollisionContext* colCtx, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); +s32 func_800C9EBC(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox, s32* bgId); s32 func_800CA1AC(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox); s32 func_800CA1E8(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox); // void func_800CA22C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); diff --git a/spec b/spec index 41c7d61f8..6c9cb749c 100644 --- a/spec +++ b/spec @@ -3584,8 +3584,7 @@ beginseg name "ovl_Obj_Aqua" compress include "build/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.o" - include "build/data/ovl_Obj_Aqua/ovl_Obj_Aqua.data.o" - include "build/data/ovl_Obj_Aqua/ovl_Obj_Aqua.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Aqua/ovl_Obj_Aqua_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c index f0ea044c8..5c0aa5cb1 100644 --- a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c +++ b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_aqua.c + * Overlay: ovl_Obj_Aqua + * Description: Water poured out of a bottle + */ + #include "z_obj_aqua.h" #define FLAGS 0x00000010 @@ -9,11 +15,14 @@ void ObjAqua_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjAqua_Update(Actor* thisx, GlobalContext* globalCtx); void ObjAqua_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80ACBC70(ObjAqua* this); +void func_80ACBDCC(ObjAqua* this); void func_80ACBC8C(ObjAqua* this, GlobalContext* globalCtx); void func_80ACBD48(ObjAqua* this, GlobalContext* globalCtx); void func_80ACBDFC(ObjAqua* this, GlobalContext* globalCtx); -#if 0 +void func_80ACBD34(ObjAqua* this); + const ActorInit Obj_Aqua_InitVars = { ACTOR_OBJ_AQUA, ACTORCAT_ITEMACTION, @@ -26,55 +35,263 @@ const ActorInit Obj_Aqua_InitVars = { (ActorFunc)ObjAqua_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80ACC2C0 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_OTHER, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_OTHER, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_NONE, + }, { 6, 10, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80ACC2EC[] = { - ICHAIN_VEC3S(shape.rot, 0, ICHAIN_CONTINUE), - ICHAIN_VEC3S(world.rot, 0, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(gravity, -900, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -4000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 300, ICHAIN_CONTINUE), +static InitChainEntry sInitChain[] = { + ICHAIN_VEC3S(shape.rot, 0, ICHAIN_CONTINUE), ICHAIN_VEC3S(world.rot, 0, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(gravity, -900, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(minVelocityY, -4000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 300, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 300, ICHAIN_STOP), }; -#endif +Vec3f D_80ACC308 = { 1.0f / 1000.0f, 7.0f / 10000.0f, 1.0f / 1000.0f }; +Vec3f D_80ACC314 = { 8.6f / 1000.0f, 8.0f / 10000.0f, 8.6f / 1000.0f }; +Vec3f D_80ACC320 = { 1.0f / 100.0f, 2.6f / 1000.0f, 1.0f / 100.0f }; -extern ColliderCylinderInit D_80ACC2C0; -extern InitChainEntry D_80ACC2EC[]; +extern Gfx D_0407D590[]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACB6A0.s") +void func_80ACB6A0(ObjAqua* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp58; + s32 angleOffset = 0; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACB7F4.s") + sp58.y = this->actor.world.pos.y + this->actor.yDistToWater; + for (i = 0; i < 4; i++) { + sp58.x = this->actor.world.pos.x + Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + angleOffset) * 8.0f; + sp58.z = this->actor.world.pos.z + Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + angleOffset) * 8.0f; + EffectSsGSplash_Spawn(globalCtx, &sp58, NULL, NULL, 0, 120); + angleOffset += 0x4000; + } + sp58.x = this->actor.world.pos.x; + sp58.z = this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp58, NULL, NULL, 0, 300); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACB940.s") +void func_80ACB7F4(ObjAqua* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f effectPos; + s32 angleOffset = 0; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACBA10.s") + effectPos.y = this->actor.floorHeight; + for (i = 0; i < 4; i++) { + effectPos.x = (this->actor.world.pos.x + Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + angleOffset) * 8.0f); + effectPos.z = (this->actor.world.pos.z + Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + angleOffset) * 8.0f); + EffectSsGSplash_Spawn(globalCtx, &effectPos, NULL, NULL, 0, 120); + angleOffset += 0x4000; + } + effectPos.x = this->actor.world.pos.x; + effectPos.z = this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &effectPos, NULL, NULL, 0, 300); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACBA60.s") +void func_80ACB940(ObjAqua* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f effectPos; + Vec3f effectVel; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/ObjAqua_Init.s") + effectVel.x = Rand_ZeroOne() - 0.5f; + effectVel.y = 2.0f; + effectVel.z = Rand_ZeroOne() - 0.5f; + effectPos.x = this->actor.world.pos.x + (effectVel.x * 40.0f); + effectPos.y = this->actor.world.pos.y; + effectPos.z = this->actor.world.pos.z + (effectVel.z * 40.0f); + EffectSsIceSmoke_Spawn(globalCtx, &effectPos, &effectVel, &D_801D15B0, (s32)(Rand_ZeroOne() * 24.0f) + 70); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/ObjAqua_Destroy.s") +void func_80ACBA10(ObjAqua* this) { + s32 pad; + MtxF sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACBC70.s") + func_800C0094(this->actor.floorPoly, this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, + &sp2C); + func_8018219C(&sp2C, &this->actor.shape.rot, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACBC8C.s") +s32 func_80ACBA60(ObjAqua* this, GlobalContext* globalCtx) { + s32 pad; + WaterBox* waterBox; + f32 ySurface; + s32 bgId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACBD34.s") + if (func_800C9EBC(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &ySurface, + &waterBox, &bgId) && + (this->actor.world.pos.y < ySurface)) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACBD48.s") +void ObjAqua_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjAqua* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACBDCC.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actor.scale.x = 0.0009f; + this->actor.scale.y = 0.0005f; + this->actor.scale.z = 0.0009f; + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 60.0f); + if (1) {}; + this->actor.shape.shadowAlpha = 140; + this->alpha = 255; + if (func_80ACBA60(this, globalCtx)) { + for (i = 0; i < 8; i++) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, -4.0f, 4.0f, 4.0f, + (Rand_ZeroOne() * 0.09f) + 0.03f); + } + func_80ACBDCC(this); + } else { + func_80ACBC70(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/func_80ACBDFC.s") +void ObjAqua_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjAqua* this = THIS; + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/ObjAqua_Update.s") +void func_80ACBC70(ObjAqua* this) { + this->counter = 200; + this->actionFunc = func_80ACBC8C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Aqua/ObjAqua_Draw.s") +void func_80ACBC8C(ObjAqua* this, GlobalContext* globalCtx) { + if (this->actor.bgCheckFlags & 0x21) { + if (this->actor.bgCheckFlags & 1) { + func_80ACB7F4(this, globalCtx); + func_80ACBA10(this); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOTTLE_WATERING); + func_80ACBD34(this); + } else { + func_80ACB6A0(this, globalCtx); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 0x28, NA_SE_EV_BOMB_DROP_WATER); + Actor_MarkForDeath(&this->actor); + } + } else if (this->counter <= 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80ACBD34(ObjAqua* this) { + this->actionFunc = func_80ACBD48; +} + +void func_80ACBD48(ObjAqua* this, GlobalContext* globalCtx) { + if ((AQUA_HOT(&this->actor) == 1) && (this->alpha > 90)) { + func_80ACB940(this, globalCtx); + } + if (this->alpha > 5) { + this->alpha -= 5; + } else { + this->alpha = 0; + } + if (this->actor.shape.shadowAlpha > 2) { + this->actor.shape.shadowAlpha -= 2; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80ACBDCC(ObjAqua* this) { + this->actor.gravity = -0.1f; + this->counter = 40; + this->alpha = 140; + this->actionFunc = func_80ACBDFC; +} + +void func_80ACBDFC(ObjAqua* this, GlobalContext* globalCtx) { + s32 pad; + f32 temp = this->counter; + + this->alpha = (s32)(temp * 3.25f) + 10; + this->actor.shape.shadowAlpha = this->alpha; + this->unk_198 += 1000; + if (AQUA_HOT(&this->actor) == 1) { + f32 temp_f2 = this->actor.scale.x * 10000.0f; + + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, temp_f2 * -0.5f, temp_f2, temp_f2, + (Rand_ZeroOne() * 0.1f) + 0.03f); + } + if (this->counter <= 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void ObjAqua_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjAqua* this = THIS; + s32 pad; + + if (this->counter > 0) { + this->counter--; + } + this->actionFunc(this, globalCtx); + if (this->actor.update) { + if (this->actionFunc == func_80ACBC8C) { + Math_Vec3f_StepTo(&this->actor.scale, &D_80ACC308, 0.00006f); + } else if (this->actionFunc == func_80ACBD48) { + Math_Vec3f_StepTo(&this->actor.scale, &D_80ACC314, 0.00095f); + } else { + Math_Vec3f_StepTo(&this->actor.scale, &D_80ACC320, 0.0004f); + } + this->actor.velocity.y *= 0.9f; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 12.0f, 4.0f, 0.0f, 5); + if (this->actionFunc != func_80ACBDFC) { + Collider_UpdateCylinder(&this->actor, &this->collider); + this->collider.dim.radius = this->actor.scale.x * 3000.0f; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } +} + +void ObjAqua_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjAqua* this = THIS; + s32 framesTemp; + s32 pad; + s16 yaw = func_800DFCDC(globalCtx->cameraPtrs[globalCtx->activeCamera]) + 0x8000; + s32 actionFuncTemp = this->actionFunc == func_80ACBDFC; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + framesTemp = ((globalCtx->gameplayFrames & 0x7FFFFFFF) * -0xA) & 0x1FF; + if (actionFuncTemp) { + framesTemp >>= 1; + } + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, framesTemp, 0x20, 0x80)); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 170, 255, 255, this->alpha); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 150, 255, 0); + if (actionFuncTemp) { + s16 rotation = Math_SinS(this->unk_198) * 8000.0f; + + SysMatrix_InsertZRotation_s(rotation, 1); + Matrix_Scale(1.3f, 1.0f, 1.0f, 1); + SysMatrix_InsertZRotation_s(rotation * -1, 1); + Matrix_Scale(10.0f / 13.0f, 1.0f, 1.0f, 1); + } + Matrix_RotateY(yaw, 1); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_0407D590); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.h b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.h index dec966f0a..0c8bdc714 100644 --- a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.h +++ b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.h @@ -3,15 +3,19 @@ #include "global.h" +#define AQUA_HOT(thisx) ((thisx)->params & 1) + struct ObjAqua; typedef void (*ObjAquaActionFunc)(struct ObjAqua*, GlobalContext*); typedef struct ObjAqua { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4C]; + /* 0x0144 */ ColliderCylinder collider; /* 0x0190 */ ObjAquaActionFunc actionFunc; - /* 0x0194 */ char unk_194[0x8]; + /* 0x0194 */ s16 counter; + /* 0x0196 */ u8 alpha; + /* 0x0198 */ s16 unk_198; } ObjAqua; // size = 0x19C extern const ActorInit Obj_Aqua_InitVars; From a6d26c82f23c6176c4f32fe0351425829d3ca01e Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Tue, 28 Sep 2021 02:00:55 +0100 Subject: [PATCH 12/13] afterprenmi.c OK (#297) --- src/libultra/os/afterprenmi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libultra/os/afterprenmi.c b/src/libultra/os/afterprenmi.c index 4c61fe0bf..b59814763 100644 --- a/src/libultra/os/afterprenmi.c +++ b/src/libultra/os/afterprenmi.c @@ -1,3 +1,6 @@ +#include "ultra64.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/afterprenmi/osAfterPreNMI.s") +s32 osAfterPreNMI(void) { + return __osSpSetPc(0); +} From 14ad66b4ed6079872fc4c546007a150ae658f3aa Mon Sep 17 00:00:00 2001 From: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Date: Tue, 28 Sep 2021 02:29:30 +0100 Subject: [PATCH 13/13] `ovl_title` OK (#311) * OK, asset XML made and symbols imported * Missed a GLOBAL_ASM * Remove data from spec * engineer's review * Correct arg * Un-format functions.h * Hopefully fix it --- assets/xml/static/nintendo_rogo_static.xml | 8 + include/functions.h | 28 +-- spec | 6 +- src/overlays/gamestates/ovl_title/z_title.c | 178 +++++++++++++++++++- src/overlays/gamestates/ovl_title/z_title.h | 21 ++- 5 files changed, 204 insertions(+), 37 deletions(-) create mode 100644 assets/xml/static/nintendo_rogo_static.xml diff --git a/assets/xml/static/nintendo_rogo_static.xml b/assets/xml/static/nintendo_rogo_static.xml new file mode 100644 index 000000000..ff6fc56fc --- /dev/null +++ b/assets/xml/static/nintendo_rogo_static.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/include/functions.h b/include/functions.h index cc6513381..e9a0074da 100644 --- a/include/functions.h +++ b/include/functions.h @@ -789,7 +789,7 @@ void func_800B75A0(CollisionPoly* param_1, Vec3f* param_2, s16* param_3); // UNK_TYPE4 func_800B7678(GlobalContext* globalCtx, Actor* param_2, s32 param_3, u32 param_4); void Actor_UpdateBgCheckInfo(GlobalContext* globalCtx, Actor* actor, f32 wallCheckHeight, f32 wallCheckRadius, f32 ceilingCheckHeight, u32 flags); // void func_800B7E04(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); -s32 func_800B7FE0(f32* param_1, f32* param_2, f32* param_3, GraphicsContext* gfxCtx); +Hilite* func_800B7FE0(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx); // void func_800B8018(void); void func_800B8050(Actor* actor, GlobalContext* globalCtx, s32 iParm3); void func_800B8118(Actor* actor, GlobalContext* globalCtx, s32 iParm3); @@ -1775,7 +1775,7 @@ void func_800FB320(GlobalContext* globalCtx, u8 param_2); void func_800FBF3C(GlobalContext* globalCtx); // void func_800FC158(void); // void func_800FC3DC(void); -// void func_800FC444(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE1 param_6); +void func_800FC444(GraphicsContext* gfxCtx, u8 arg1, u8 arg2, u8 arg3, u8 arg4, UNK_TYPE arg5); // void func_800FC64C(void); // void func_800FD2B4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); void func_800FD538(Color_RGB8* param_1, Color_RGB8* param_2, f32 param_3, Vec3s* param_4); @@ -2831,8 +2831,8 @@ void func_80146580(s32 param_1, SramContext* param_2, s32 param_3); // void func_80146628(void); // void func_80146AA0(void); // void func_80146DF8(void); -// void func_80146E40(void); -void Sram_Alloc(GameState* gamestate, SramContext* iParm2); +void func_80146E40(GameState* gameState, SramContext* sramCtx); +void Sram_Alloc(GameState* gamestate, SramContext* sramCtx); // void func_80146EBC(SramContext* param_1, UNK_TYPE4 param_2, UNK_TYPE4 param_3); // void func_80146EE8(void); // void func_80146F5C(void); @@ -2918,18 +2918,18 @@ void func_8015E7EC(GlobalContext* globalCtx, UNK_PTR puParm2); // void func_80160B40(void); // void func_80160B80(void); // void func_80160BC0(void); -void ShrinkWindow_SetLetterboxTarget(s8 target); -// s32 ShrinkWindow_GetLetterboxTarget(void); -void ShrinkWindow_SetLetterboxMagnitude(s8 magnitude); +void ShrinkWindow_SetLetterboxTarget(s32 target); +s32 ShrinkWindow_GetLetterboxTarget(void); +void ShrinkWindow_SetLetterboxMagnitude(s32 magnitude); s32 ShrinkWindow_GetLetterboxMagnitude(void); -void ShrinkWindow_SetPillarboxTarget(s8 target); -// s32 ShrinkWindow_GetPillarboxTarget(void); -void ShrinkWindow_SetPillarboxMagnitude(u8 magnitude); -// s32 ShrinkWindow_GetPillarboxMagnitude(void); -// void ShrinkWindow_Init(void); +void ShrinkWindow_SetPillarboxTarget(s32 target); +s32 ShrinkWindow_GetPillarboxTarget(void); +void ShrinkWindow_SetPillarboxMagnitude(s32 magnitude); +s32 ShrinkWindow_GetPillarboxMagnitude(void); +void ShrinkWindow_Init(void); void ShrinkWindow_Fini(void); void ShrinkWindow_Step(s32 framerateDivisor); -void ShrinkWindow_Draw(GlobalContext* globalCtx); +void ShrinkWindow_Draw(GraphicsContext* gfxCtx); // void func_80161180(void); // void func_8016119C(void); // void func_8016122C(void); @@ -3186,7 +3186,7 @@ void func_80174AA0(ListAlloc* alloc); // void func_80174B20(void); void func_80174BA0(ListAlloc* alloc); void Main(void* arg); -// u32 Padmgr_GetControllerBitmask(void); +u32 Padmgr_GetControllerBitmask(void); // void func_80174F24(void); // void func_80174F44(void); // void func_80174F7C(void); diff --git a/spec b/spec index 6c9cb749c..0eb4cdf1f 100644 --- a/spec +++ b/spec @@ -697,8 +697,7 @@ beginseg compress address 0x80800000 include "build/src/overlays/gamestates/ovl_title/z_title.o" - include "build/data/ovl_title/ovl_title.data.o" - include "build/data/ovl_title/ovl_title.reloc.o" + include "build/src/overlays/gamestates/ovl_title/ovl_title_reloc.o" endseg beginseg @@ -8881,7 +8880,8 @@ beginseg name "nintendo_rogo_static" compress romalign 0x1000 - include "build/baserom/nintendo_rogo_static.o" + include "build/assets/static/nintendo_rogo_static/nintendo_rogo_static.o" + number 1 endseg beginseg diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c index 0d67be592..83e3f487a 100644 --- a/src/overlays/gamestates/ovl_title/z_title.c +++ b/src/overlays/gamestates/ovl_title/z_title.c @@ -1,22 +1,182 @@ /* * File: z_title.c * Overlay: ovl_title - * Description: + * Description: Nintendo 64 logo shown on startup */ #include "z_title.h" +#include "overlays/gamestates/ovl_opening/z_opening.h" +#include "static/nintendo_rogo_static/nintendo_rogo_static.h" -extern UNK_TYPE D_01002720; +void Title_UpdateCounters(TitleContext* this) { + if ((this->coverAlpha == 0) && (this->visibleDuration != 0)) { + this->timer--; + this->visibleDuration--; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_title/Title_UpdateCounters.s") + if (this->timer == 0) { + this->timer = 400; + } + } else { + this->coverAlpha += this->addAlpha; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_title/Title_RenderView.s") + if (this->coverAlpha <= 0) { + this->coverAlpha = 0; + this->addAlpha = 12; + } else if (this->coverAlpha >= 255) { + this->coverAlpha = 255; + this->exit = true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_title/Title_Draw.s") + this->uls = this->ult & 0x7F; + this->ult++; +} -void Title_Main(GameState* thisx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_title/Title_Main.s") +void Title_RenderView(TitleContext* this, f32 x, f32 y, f32 z) { + View* view = &this->view; + Vec3f eye; + Vec3f at; + Vec3f up; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_title/Title_Destroy.s") + eye.x = x; + eye.y = y; + eye.z = z; + up.x = up.z = 0.0f; + at.x = at.y = at.z = 0.0f; + up.y = 1.0f; + func_8013F0D0(view, 30.0f, 10.0f, 12800.0f); + View_SetViewOrientation(view, &eye, &at, &up); + View_RenderView(view, 0xF); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_title/Title_Init.s") +void Title_Draw(GameState* thisx) { + static s16 titleRotation = 0; + static Lights1 sTitleLights = gdSPDefLights1(100, 100, 100, 255, 255, 255, 69, 69, 69); + TitleContext* this = (TitleContext*)thisx; + u16 y; + u16 idx; + Vec3f lightDir; + Vec3f object; + Vec3f eye; + s32 pad[2]; + + OPEN_DISPS(this->gameState.gfxCtx); + + lightDir.x = 69.0f; + lightDir.y = 69.0f; + lightDir.z = 69.0f; + + object.x = 0.0f; + object.y = 0.0f; + object.z = 0.0f; + + eye.x = -4949.148f; + eye.y = 4002.5417f; + eye.z = 1119.0837f; + + func_800B7FE0(&object, &eye, &lightDir, this->gameState.gfxCtx); + + gSPSetLights1(POLY_OPA_DISP++, sTitleLights); + + Title_RenderView(this, 0.0f, 150.0f, 300.0f); + func_8012C28C(this->gameState.gfxCtx); + SysMatrix_InsertTranslation(-53.0f, -5.0f, 0.0f, MTXMODE_NEW); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + SysMatrix_InsertRotation(0, titleRotation, 0, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(this->gameState.gfxCtx), G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, gNintendo64LogoNDL); + + func_8012C628(this->gameState.gfxCtx); + + gDPPipeSync(POLY_OPA_DISP++); + gDPSetCycleType(POLY_OPA_DISP++, G_CYC_2CYCLE); + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_XLU_SURF2, G_RM_OPA_CI | CVG_DST_WRAP); + gDPSetCombineLERP(POLY_OPA_DISP++, TEXEL1, PRIMITIVE, ENV_ALPHA, TEXEL0, 0, 0, 0, TEXEL0, PRIMITIVE, ENVIRONMENT, + COMBINED, ENVIRONMENT, COMBINED, 0, PRIMITIVE, 0); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 170, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 255, 128); + gDPLoadMultiBlock(POLY_OPA_DISP++, gNintendo64LogoTextShineTex, 0x100, 1, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, 2, 11); + + for (idx = 0, y = 94; idx < 16; idx++, y += 2) { + gDPLoadTextureBlock(POLY_OPA_DISP++, &((u8*)gNintendo64LogoTextTex)[0x180 * idx], G_IM_FMT_I, G_IM_SIZ_8b, 192, + 2, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + + gDPSetTileSize(POLY_OPA_DISP++, 1, this->uls, (this->ult & 0x7F) - idx * 4, 0, 0); + gSPTextureRectangle(POLY_OPA_DISP++, 388, y << 2, 1156, (y + 2) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + } + + func_800FC444(this->gameState.gfxCtx, 0, 0, 0, this->coverAlpha, 2); + + titleRotation += 300; + + CLOSE_DISPS(this->gameState.gfxCtx); +} + +void Title_Main(GameState* thisx) { + TitleContext* this = (TitleContext*)thisx; + + func_8012CF0C(this->gameState.gfxCtx, 1, 1, 0, 0, 0); + + OPEN_DISPS(this->gameState.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x01, this->staticSegment); + + Title_UpdateCounters(this); + Title_Draw(&this->gameState); + if (this->exit) { + gSaveContext.seqIndex = 0xFF; + gSaveContext.nightSeqIndex = 0xFF; + gSaveContext.gameMode = 1; + + { + GameState* gameState = &this->gameState; + gameState->running = false; + } + SET_NEXT_GAMESTATE(&this->gameState, Opening_Init, OpeningContext); + } + + CLOSE_DISPS(this->gameState.gfxCtx); +} + +void Title_Destroy(GameState* thisx) { + TitleContext* this = (TitleContext*)thisx; + + func_80146E40(&this->gameState, &this->sramCtx); + ShrinkWindow_Fini(); + CIC6105_Nop80081828(); +} + +void Title_Init(GameState* thisx) { + TitleContext* this = (TitleContext*)thisx; + uintptr_t segmentSize = + (uintptr_t)_nintendo_rogo_staticSegmentRomEnd - (uintptr_t)_nintendo_rogo_staticSegmentRomStart; + + this->staticSegment = THA_AllocEndAlign16(&this->gameState.heap, segmentSize); + DmaMgr_SendRequest0(this->staticSegment, (uintptr_t)_nintendo_rogo_staticSegmentRomStart, segmentSize); + + Game_SetFramerateDivisor(thisx, 1); + SysMatrix_StateAlloc(thisx); + ShrinkWindow_Init(); + View_Init(&this->view, thisx->gfxCtx); + + thisx->main = Title_Main; + thisx->destroy = Title_Destroy; + this->exit = false; + + if (!(Padmgr_GetControllerBitmask() & 1)) { + gSaveContext.fileNum = 0xFEDC; + } else { + gSaveContext.fileNum = 0xFF; + } + + gSaveContext.unk_3F3F = 1; + Sram_Alloc(thisx, &this->sramCtx); + this->ult = 0; + this->timer = 20; + this->coverAlpha = 255; + this->addAlpha = -12; + this->visibleDuration = 60; +} diff --git a/src/overlays/gamestates/ovl_title/z_title.h b/src/overlays/gamestates/ovl_title/z_title.h index a3005f004..7f2f34425 100644 --- a/src/overlays/gamestates/ovl_title/z_title.h +++ b/src/overlays/gamestates/ovl_title/z_title.h @@ -1,5 +1,5 @@ -#ifndef _Z64_TITLE_H_ -#define _Z64_TITLE_H_ +#ifndef Z64_TITLE_H +#define Z64_TITLE_H #include "global.h" @@ -7,18 +7,17 @@ void Title_Init(GameState* thisx); void Title_Destroy(GameState* thisx); typedef struct { - /* 0x000 */ GameState state; + /* 0x000 */ GameState gameState; /* 0x0A4 */ u8* staticSegment; /* 0x0A8 */ View view; /* 0x210 */ SramContext sramCtx; - /* 0x238 */ s16 mode; - /* 0x23A */ s16 timer; - /* 0x23C */ s16 coverAlpha; - /* 0x23E */ s16 addAlpha; - /* 0x240 */ s16 visibleDuration; - /* 0x242 */ s16 ult; - /* 0x244 */ s16 uls; - /* 0x246 */ u8 exit; + /* 0x238 */ s16 timer; + /* 0x23A */ s16 coverAlpha; + /* 0x23C */ s16 addAlpha; + /* 0x23E */ s16 visibleDuration; + /* 0x240 */ s16 ult; + /* 0x242 */ s16 uls; + /* 0x244 */ u8 exit; } TitleContext; // size = 0x248 #endif