diff --git a/include/functions.h b/include/functions.h index 65d1b8b18d..e11a962633 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1087,7 +1087,7 @@ s32 Camera_ChangeMode(Camera* camera, s16 mode); // void func_800DF86C(void); // void func_800DF8EC(void); s32 Camera_ChangeSetting(Camera* camera, s16 setting); -u32 Camera_ChangeDataIdx(Camera* camera, u32 camDataIdx); +s32 Camera_ChangeDataIdx(Camera* camera, s32 camDataIdx); // void func_800DFC1C(void); // void func_800DFC40(void); s32 Camera_GetInputDirYaw(Camera* camera); @@ -1097,7 +1097,7 @@ s16 Camera_GetCamDirYaw(Camera* camera); void Camera_AddQuake(Camera* camera, s32 arg1, s16 y, s32 countdown); s32 Camera_SetViewParam(Camera* camera, s32 viewFlag, void* param); // UNK_TYPE4 func_800DFEF0(s32 param_1, u16 param_2); -// UNK_TYPE4 func_800DFF18(Camera* iParm1, UNK_TYPE2 uParm2); +void func_800DFF18(Camera* camera, s32 arg1); // UNK_TYPE4 func_800DFF34(s32 param_1); // UNK_TYPE4 func_800DFF44(void); s16 Camera_SetFlags(Camera* iParm1, s16 flags); @@ -1431,13 +1431,13 @@ void Font_LoadMessageBoxEndIcon(Font* font, u16 icon); void Font_LoadOrderedFont(Font* font); // void func_800F5090(void); // void func_800F50D4(void); -void Kankyo_Init(PlayState* play, EnvironmentContext* envCtx); +void Kankyo_Init(PlayState* play, EnvironmentContext* envCtx, s32 arg2); u32 func_800F5954(u8* param_1, u32 param_2, u32 param_3, u8 param_4, u8 param_5); f32 Environment_LerpWeight(u16 max, u16 min, u16 val); // void func_800F5B10(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); // void func_800F5CD0(void); void func_800F6834(PlayState* play, s32 waterLightsIndex); -// void func_800F694C(void); +void func_800F694C(PlayState* play); // void func_800F6A04(void); // void func_800F6A40(void); // void func_800F6AB8(void); @@ -1622,7 +1622,7 @@ void* ZeldaArena_Calloc(u32 num, size_t size); void ZeldaArena_GetSizes(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); s32 ZeldaArena_Check(); void ZeldaArena_Init(void* start, size_t size); -void ZeldaArena_Cleanup(); +void ZeldaArena_Cleanup(void); u8 ZeldaArena_IsInitialized(); // void func_80102E40(void); // void func_80102E90(void); @@ -1829,7 +1829,7 @@ void Interface_ChangeAlpha(u16 param_1); // void func_8010F1A8(void); // void func_80110038(void); // void func_80111CB4(void); -// void func_801129E4(void); +void func_801129E4(PlayState* play); void func_80112AFC(PlayState* play); void Interface_LoadItemIconImpl(PlayState* play, u8 btn); void Interface_LoadItemIcon(PlayState* play, u8 btn); @@ -1887,7 +1887,7 @@ void func_8011C808(PlayState* play); // void func_80121000(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE1 param_8, UNK_TYPE1 param_9, UNK_TYPE1 param_10, UNK_TYPE4 param_11, UNK_TYPE4 param_12, UNK_TYPE4 param_13, UNK_TYPE4 param_14); // void func_80121064(void); // void func_801210E0(void); -// void func_80121F94(void); +void func_80121F94(PlayState* play); void func_80121FC4(PlayState* play); Path* Path_GetByIndex(PlayState* play, s16 index, s16 max); f32 Path_OrientAndGetDistSq(Actor* actor, Path* path, s16 waypoint, s16* yaw); @@ -2352,8 +2352,8 @@ void func_80140900(void* arg0); void func_80140CE0(void* arg0); void func_80140D04(void* arg0); void func_80140D10(void* arg0, Gfx** gfx, u32 arg2); -void func_80140E80(void* param_1); -// void func_80140EA0(void); +void func_80140E80(Struct_80140E80* arg0); +void func_80140EA0(Struct_80140E80* arg0); // void func_80140EAC(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_80141008(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_8014116C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); @@ -2487,18 +2487,18 @@ void* KaleidoManager_FaultAddrConvFunc(void* address, void* param); void KaleidoManager_LoadOvl(KaleidoMgrOverlay* ovl); void KaleidoManager_ClearOvl(KaleidoMgrOverlay* ovl); void KaleidoManager_Init(PlayState* play); -void KaleidoManager_Destroy(); +void KaleidoManager_Destroy(void); void* KaleidoManager_GetRamAddr(void* vram); void KaleidoScopeCall_LoadPlayer(void); void KaleidoScopeCall_Init(PlayState* play); void KaleidoScopeCall_Destroy(PlayState* play); void KaleidoScopeCall_Update(PlayState* play); void KaleidoScopeCall_Draw(PlayState* play); -// void func_80163C90(void); -// void func_80163D80(void); +void func_80163C90(PlayStruct_18BF0* arg0); +void func_80163D80(PlayStruct_18BF0* arg0, PlayState* play); // void func_80163DC0(void); // void func_8016418C(void); -// void func_8016424C(void); +void func_8016424C(FbDemoStruct* this); // void func_801642D8(void); // void func_80164438(void); // void func_8016454C(void); @@ -2506,13 +2506,14 @@ void KaleidoScopeCall_Draw(PlayState* play); // void func_801647AC(void); // UNK_TYPE4 func_801647B8(void); // void TransitionFade_Start(void); -void* TransitionFade_Init(void* param_1); -// void TransitionFade_Destroy(void); +void* TransitionFade_Init(TransitionFade* arg0); +void TransitionFade_Destroy(TransitionFade* arg0); // void TransitionFade_Update(void); // void TransitionFade_Draw(void); // void TransitionFade_IsDone(void); -// void TransitionFade_SetColor(void); -// void TransitionFade_SetType(void); +void TransitionFade_SetColor(TransitionFade* arg0, u32 color); +void TransitionFade_SetType(TransitionFade* arg0, s32 arg1); +void TransitionFade_Start(TransitionFade* arg0); // void TransitionCircle_Start(void); // void TransitionCircle_Init(void); // void TransitionCircle_Destroy(void); @@ -2553,7 +2554,7 @@ void func_80167DE4(PlayState* play); // void func_80167F0C(void); void Play_Draw(PlayState* play); void func_80168DAC(PlayState* play); -void Play_Main(PlayState* play); +void Play_Main(GameState* thisx); s32 Play_InCsMode(PlayState* play); f32 func_80169100(PlayState* play, MtxF* mtx, CollisionPoly** arg2, s32* arg3, Vec3f* feetPosPtr); // void func_801691F0(void); @@ -2603,8 +2604,8 @@ void Play_Init(GameState* gameState); // void func_8016F1A8(void); // void func_8016F4EC(void); void func_8016F5A8(PlayState* play, s8* pcParm2, Input* iParm3); -// void func_8016FC78(void); -// void func_8016FC98(void); +void func_8016FC78(HiresoStruct* this); +void func_8016FC98(HiresoStruct* this); void PreRender_SetValuesSave(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf, void* cvg); void PreRender_Init(PreRender* this); void PreRender_SetValues(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf); @@ -2776,7 +2777,7 @@ void SpeedMeter_DrawAllocEntries(void* displayList, GraphicsContext* gfxCtx, Gam void func_801780F0(Mtx* param_1, f32 param_2, f32 param_3, f32 param_4, f32 param_5, f32 param_6, f32 param_7); // void func_801781EC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); void func_8017842C(MtxF* arg0, f32 arg1, f32 arg2, f32 arg3, s16 arg4, f32 arg5, f32 arg6, f32 arg7, f32 arg8, f32 arg9, f32 arg10); -// void func_80178750(void); +void func_80178750(void); // void func_80178818(void); void func_80178978(void); // void func_801789D4(void); @@ -3283,7 +3284,7 @@ void func_801A3CD8(s8 param_1); // void func_801A3CF4(void); void func_801A3D98(s8 audioSetting); // void func_801A3E38(void); -// void func_801A3EC0(void); +void func_801A3EC0(u8 arg0); void Audio_SetCutsceneFlag(u8 flag); // void func_801A3F6C(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_801A3FB4(void); diff --git a/include/z64.h b/include/z64.h index ec51a3a8c3..1eafccde0e 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1088,6 +1088,24 @@ typedef struct { /* 0x0 */ u16 state; } GameOverContext; // size = 0x2 +typedef struct { + /* 0x000 */ s16 unk_00; + /* 0x002 */ s8 unk_02; + /* 0x003 */ char unk03[0x5]; + /* 0x008 */ s32 unk_08; + /* 0x00C */ char unk0C[0x224]; + /* 0x230 */ void (*unk_230)(s32*); + /* 0x234 */ void (*unk_234)(s32*); + /* 0x238 */ void (*unk_238)(s32*, u8); + /* 0x23C */ char unk23C[0x4]; + /* 0x240 */ void (*unk_240)(s32*); + /* 0x244 */ void (*unk_244)(s32*, s32); + /* 0x248 */ void (*unk_248)(s32*, u32); // RGBA8 colour? + /* 0x24C */ void (*unk_24C)(s32*, u32); // RGBA8 colour? + /* 0x250 */ s32 (*unk_250)(s32*); + /* 0x254 */ char unk254[0x4]; +} PlayStruct_18BF0; // size = 0x258 TransitionContext? + struct PlayState { /* 0x00000 */ GameState state; /* 0x000A4 */ s16 sceneNum; @@ -1169,13 +1187,50 @@ struct PlayState { /* 0x18B49 */ u8 unk_18B49; /* 0x18B4A */ u8 transitionMode; /* 0x18B4C */ PreRender pauseBgPreRender; - /* 0x18B9C */ char unk_18B9C[0x2B8]; + /* 0x18B9C */ char unk_18B9C[0x54]; + /* 0x18BF0 */ PlayStruct_18BF0 unk_18BF0; + /* 0x18E48 */ TransitionFade unk_18E48; /* 0x18E54 */ SceneTableEntry* loadedScene; - /* 0x18E58 */ char unk_18E58[0x10]; - /* 0x18E68 */ s32 unk_18E68; + /* 0x18E58 */ UNK_PTR unk_18E58; + /* 0x18E5C */ UNK_PTR unk_18E5C; + /* 0x18E60 */ UNK_PTR unk_18E60; + /* 0x18E64 */ void* unk_18E64; + /* 0x18E68 */ void* unk_18E68; /* 0x18E6C */ char unk_18E6C[0x3EC]; }; // size = 0x19258 +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ char unk_01[0x3F]; + /* 0x40 */ void* unk_40; + /* 0x44 */ u32 unk_44; + /* 0x48 */ u32 unk_48; + /* 0x4C */ DmaRequest unk_4C; + /* 0x6C */ OSMesgQueue unk_6C; + /* 0x84 */ OSMesg unk_84[1]; + /* 0x88 */ void* unk_88; + /* 0x8C */ uintptr_t unk_8C; + /* 0x90 */ size_t unk_90; + /* 0x94 */ s32 unk_94; + /* 0x98 */ s32 unk_98; + /* 0x9C */ s32 unk_9C; + /* 0xA0 */ char unk_A0[0x4]; + /* 0xA4 */ s32 unk_A4; + /* 0xA8 */ s32 unk_A8; +} HiresoStruct; // size = 0xAC + +typedef struct { + /* 0x00 */ char unk_00[0xDC]; +} FbDemoStruct; // size = 0xDC + +typedef struct { + /* 0x00 */ u8 mode; + /* 0x04 */ f32 scale; + /* 0x08 */ f32 lodProportion; // expected to be between 0.0f and 1.0f + /* 0x0C */ Color_RGBA8_u32 primColor; + /* 0x10 */ Color_RGBA8_u32 envColor; +} Struct_80140E80; // size = 0x14 + typedef struct { /* 0x00 */ s32 unk0; /* 0x04 */ s32 unk4; diff --git a/include/z64save.h b/include/z64save.h index 6b77e29686..882a334bd1 100644 --- a/include/z64save.h +++ b/include/z64save.h @@ -121,7 +121,7 @@ typedef struct SavePlayerData { } SavePlayerData; // size = 0x28 typedef struct Save { - /* 0x0000 */ u32 entrance; // "scene_no" + /* 0x0000 */ s32 entrance; // "scene_no" /* 0x0004 */ u8 equippedMask; // "player_mask" /* 0x0005 */ u8 isFirstCycle; // "opening_flag" /* 0x0006 */ u8 unk_06; diff --git a/include/z64scene.h b/include/z64scene.h index 6a0808b559..20573958f6 100644 --- a/include/z64scene.h +++ b/include/z64scene.h @@ -342,6 +342,7 @@ typedef struct { /* 0xA */ u8 unk_A; /* 0xB */ u8 drawConfig; /* 0xC */ u8 unk_C; + /* 0xD */ u8 unk_D; } SceneTableEntry; // size = 0x10 typedef struct { diff --git a/include/z64transition.h b/include/z64transition.h index 9630b4a3ff..bb63e90663 100644 --- a/include/z64transition.h +++ b/include/z64transition.h @@ -16,7 +16,12 @@ typedef struct { } TransitionInit; // size = 0x24 typedef struct { - /* 0x0 */ char unk_0[0xC]; + /* 0x00 */ s8 unk_00; + /* 0x01 */ s8 unk_01; + /* 0x02 */ s8 unk_02; + /* 0x04 */ Color_RGBA8_u32 unk_04; + /* 0x08 */ s16 unk_08; + /* 0x0A */ char unk_0A[0x2]; } TransitionFade; // size = 0xC extern const TransitionInit TransitionFade_InitVars; diff --git a/spec b/spec index e17d3af91b..169ef792bc 100644 --- a/spec +++ b/spec @@ -556,7 +556,6 @@ beginseg include "build/data/code/z_fbdemo_circle.data.o" include "build/src/code/z_overlay.o" include "build/src/code/z_play.o" - include "build/data/code/z_play.data.o" include "build/data/code/z_play.bss.o" include "build/src/code/z_play_hireso.o" include "build/data/code/z_play_hireso.data.o" diff --git a/src/code/z_play.c b/src/code/z_play.c index c24a45b516..b073216d87 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -1,17 +1,50 @@ #include "global.h" +#include "overlays/gamestates/ovl_daytelop/z_daytelop.h" +#include "overlays/gamestates/ovl_opening/z_opening.h" + +s32 gDbgCamEnabled = false; +u8 D_801D0D54 = 0; + +// bss +extern s16 D_801F6C10; +extern Input D_801F6C18; +extern FbDemoStruct D_801F6C30; +extern u16* D_801F6D0C; +extern s32 D_801F6D10; +extern VisMono D_801F6D18; +extern Color_RGBA8 D_801F6D30; +extern Struct_80140E80 D_801F6D38; +extern Struct_80140E80* D_801F6D4C; +extern HiresoStruct D_801F6D50; +extern u8 D_801F6DFC; +extern s8 D_801F6DFD; #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80165460.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80165608.s") +void func_80165608(void) { + SREG(91) = 0; + SREG(93) = 0; + D_801F6DFD = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80165630.s") +void func_80165630(void) { + SREG(91) = 0; + SREG(93) = 0; + D_801F6DFD = 0; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80165658.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016566C.s") +void func_8016566C(u32 arg0) { + SREG(90) = arg0; + SREG(91) = 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80165690.s") +void func_80165690(void) { + SREG(91) = 0; +} +void func_801656A4(u8* arg0, u16* arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7); #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801656A4.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80165DB8.s") @@ -22,27 +55,248 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80165E04.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80165E1C.s") +void func_80165E1C(PreRender* prerender) { + PreRender_ApplyFilters(prerender); + func_801656A4(D_80780000, prerender->fbufSave, 0x140, 0x50, 0x40, 0xEF, 0xAF, 8); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80165E7C.s") +s32 func_80165E7C(PlayState* this, s32 arg1) { + s32 phi_v1 = arg1; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80165EC0.s") + if (arg1 == 0x14) { + if (!gSaveContext.save.isNight) { + phi_v1 = TRANS_TYPE_03; + } else { + phi_v1 = TRANS_TYPE_02; + } + } + if (phi_v1 != arg1) { + this->transitionType = phi_v1; + } + return phi_v1; +} + +void func_80165EC0(PlayState* this, s32 arg1) { + PlayStruct_18BF0* ptr = &this->unk_18BF0; + s32 sp20; + + bzero(ptr, sizeof(this->unk_18BF0)); + + sp20 = -1; + if (arg1 & 0x40) { + sp20 = 3; + } else if ((arg1 & 0x78) == 0x20) { + sp20 = 4; + } else if (!(arg1 & 0x60)) { + switch (arg1) { + case 1: + sp20 = 1; + break; + case 0: + case 8: + sp20 = 2; + break; + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 13: + case 17: + case 18: + case 19: + sp20 = 0; + break; + case 9: + case 10: + this->transitionMode = TRANS_MODE_04; + break; + case 11: + this->transitionMode = TRANS_MODE_10; + break; + case 12: + this->transitionMode = TRANS_MODE_07; + break; + case 14: + this->transitionMode = TRANS_MODE_12; + break; + case 15: + this->transitionMode = TRANS_MODE_14; + break; + case 16: + this->transitionMode = TRANS_MODE_16; + break; + case 21: + sp20 = 5; + break; + case 22: + sp20 = 6; + break; + default: + sp20 = -1; + __assert("../z_play.c", 1420); + } + } else { + sp20 = -1; + __assert("../z_play.c", 1423); + } + + ptr->unk_00 = arg1; + ptr->unk_02 = sp20; + if (sp20 != -1) { + func_80163C90(ptr); + } +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/D_801DFA18.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80166060.s") +void func_80166060(PlayState* this) { + if (this->unk_18BF0.unk_02 != -1) { + func_80163D80(&this->unk_18BF0, this); + } + this->unk_18BF0.unk_00 = -1; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801660B8.s") +Gfx* func_801660B8(PlayState* this, Gfx* gfx) { + s32 phi_v1 = this->lightCtx.unkC * 0.078125f; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Destroy.s") + return Gfx_SetFogWithSync(gfx, this->lightCtx.unk7, this->lightCtx.unk8, this->lightCtx.unk9, 0, + this->lightCtx.unkA, phi_v1 <= 1000 ? 1000 : phi_v1); +} + +void Play_Destroy(GameState* thisx) { + PlayState* this = (PlayState*)thisx; + GraphicsContext* gfxCtx = this->state.gfxCtx; + + if (D_801F6DFC != 0) { + MsgEvent_SendNullTask(); + func_80178750(); + gfxCtx->curFrameBuffer = (u16*)SysCfb_GetFbPtr(gfxCtx->framebufferIdx % 2); + gfxCtx->zbuffer = SysCfb_GetZBuffer(); + gfxCtx->viMode = D_801FBB88; + gfxCtx->viConfigFeatures = gViConfigFeatures; + gfxCtx->xScale = gViConfigXScale; + gfxCtx->yScale = gViConfigYScale; + gfxCtx->updateViMode = 1; + D_801F6DFC = 0; + } + func_8016FC98(&D_801F6D50); + this->state.gfxCtx->callback = NULL; + this->state.gfxCtx->callbackParam = 0; + func_80165630(); + if (SREG(94) != 0) { + PreRender_ApplyFiltersSlowlyDestroy(&this->pauseBgPreRender); + SREG(94) = 0; + } + SREG(89) = 0; + PreRender_Destroy(&this->pauseBgPreRender); + this->unk_18E58 = NULL; + this->unk_18E5C = NULL; + this->unk_18E60 = NULL; + this->unk_18E64 = NULL; + this->unk_18E68 = NULL; + Effect_DestroyAll(this); + EffectSS_Clear(this); + CollisionCheck_DestroyContext(this, &this->colChkCtx); + if (D_801F6D10 == 3) { + func_8016424C(&D_801F6C30); + D_801F6D10 = 0; + } + if ((this->transitionMode == TRANS_MODE_03) || (D_801D0D54 != 0)) { + this->unk_18BF0.unk_234(&this->unk_18BF0.unk_08); + func_80166060(this); + this->transitionMode = TRANS_MODE_OFF; + } + ShrinkWindow_Destroy(); + TransitionFade_Destroy(&this->unk_18E48); + VisMono_Destroy(&D_801F6D18); + func_80140EA0(D_801F6D4C); + D_801F6D4C = NULL; + if (gSaveContext.save.weekEventReg[0x5C] & 0x80) { + Actor_CleanupContext(&this->actorCtx, this); + } + gSaveContext.save.weekEventReg[0x5C] &= (u8)~0x80; + func_80121F94(this); + KaleidoScopeCall_Destroy(this); + KaleidoManager_Destroy(); + ZeldaArena_Cleanup(); +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801663C4.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80166644.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801668B4.s") +f32 func_801668B4(PlayState* this, Vec3f* arg1, s32* arg2) { + Player* player = GET_PLAYER(this); + f32 sp38 = player->actor.world.pos.y; + WaterBox* sp34; + s32 sp30; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80166968.s") + if (!WaterBox_GetSurfaceImpl(this, &this->colCtx, arg1->x, arg1->z, &sp38, &sp34, &sp30)) { + return BGCHECK_Y_MIN; + } + + if (sp38 < arg1->y) { + return BGCHECK_Y_MIN; + } + + *arg2 = WaterBox_GetLightSettingIndex(&this->colCtx, sp34); + return sp38; +} + +void func_80166968(PlayState* this, Camera* camera) { + static s16 D_801D0D58 = -1; + static s16 D_801D0D5C = 0; + s32 pad; + s32 sp28; + Player* player = GET_PLAYER(this); + + D_801D0D5C = camera->stateFlags & CAM_STATE_UNDERWATER; + if (func_801668B4(this, &camera->eye, &sp28) != BGCHECK_Y_MIN) { + s16 temp; + + if (D_801D0D5C == 0) { + Camera_SetFlags(camera, CAM_STATE_UNDERWATER); + D_801D0D58 = -1; + Distortion_SetType(0x10); + Distortion_SetCountdown(0x50); + } + func_801A3EC0(0x20); + func_800F6834(this, sp28); + if ((D_801D0D58 == -1) || (Quake_GetCountdown(D_801D0D58) == 0xA)) { + s16 quake = Quake_Add(camera, 5); + + D_801D0D58 = quake; + if (quake != 0) { + Quake_SetSpeed(D_801D0D58, 0x226); + Quake_SetQuakeValues(D_801D0D58, 1, 1, 0xB4, 0); + Quake_SetCountdown(D_801D0D58, 1000); + } + } + if (player->stateFlags3 & PLAYER_STATE3_8000) { + Distortion_SetType(8); + Distortion_ClearType(4); + } else { + Distortion_SetType(4); + Distortion_ClearType(8); + } + } else { + if (D_801D0D5C != 0) { + Camera_ClearFlags(camera, 0x100); + } + Distortion_ClearType(4); + Distortion_ClearType(0x10); + Distortion_ClearType(8); + if (D_801D0D58 != 0) { + Quake_RemoveFromIdx(D_801D0D58); + } + func_800F694C(this); + func_801A3EC0(0); + } +} + +Input* D_801D0D60 = NULL; #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80166B30.s") @@ -56,6 +310,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80168DAC.s") +void Play_Main(GameState* thisx); #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Main.s") s32 Play_InCsMode(PlayState* this) { @@ -66,13 +321,53 @@ s32 Play_InCsMode(PlayState* this) { #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801691F0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_LoadScene.s") +void* Play_LoadScene(PlayState* this, RomFile* entry) { + size_t size = entry->vromEnd - entry->vromStart; + void* sp18 = THA_AllocEndAlign16(&this->state.heap, size); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016927C.s") + DmaMgr_SendRequest0(sp18, entry->vromStart, size); + return sp18; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801692C4.s") +void func_8016927C(PlayState* this, s16 skyboxId) { + func_801434E4(&this->state, &this->skyboxCtx, skyboxId); + Kankyo_Init(this, &this->envCtx, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_SceneInit.s") +void func_801692C4(PlayState* this, s32 spawn) { + this->curSpawn = spawn; + this->linkActorEntry = NULL; + this->actorCsCamList = NULL; + this->setupEntranceList = NULL; + this->setupExitList = NULL; + this->unk_18868 = NULL; + this->setupPathList = NULL; + this->sceneMaterialAnims = NULL; + this->roomCtx.unk74 = NULL; + this->numSetupActors = 0; + Object_InitBank(&this->state, &this->objectCtx); + LightContext_Init(this, &this->lightCtx); + Door_InitContext(&this->state, &this->doorCtx); + Room_Init(this, &this->roomCtx); + gSaveContext.worldMapArea = 0; + Scene_ProcessHeader(this, this->sceneSegment); + func_8016927C(this, this->skyboxId); +} + +void Play_SceneInit(PlayState* this, s32 scene, s32 spawn) { + s32 pad; + SceneTableEntry* sp1C = &gSceneTable[scene]; + + sp1C->unk_D = 0; + this->loadedScene = sp1C; + this->sceneNum = scene; + this->sceneConfig = sp1C->drawConfig; + this->sceneSegment = Play_LoadScene(this, &sp1C->segment); + sp1C->unk_D = 0; + gSegments[0x02] = VIRTUAL_TO_PHYSICAL(this->sceneSegment); + func_801692C4(this, spawn); + Room_AllocateAndLoad(this, &this->roomCtx); +} void Play_GetScreenPos(PlayState* this, Vec3f* worldPos, Vec3f* screenPos) { f32 invW; @@ -500,8 +795,7 @@ s32 Play_IsDebugCamEnabled(void) { } // A mapping from playerActorCsIds to sGlobalCamDataSettings indices. -extern s16 D_801D0D64[]; -// s16 D_801D0D64[] = { -3, -2, -4, -5, -7, -11, -8, -9, -6, -16 }; +s16 D_801D0D64[] = { -3, -2, -4, -5, -7, -11, -8, -9, -6, -16 }; // Used by Player /** @@ -546,4 +840,283 @@ void func_8016A268(GameState* thisx, s16 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg MREG(68) = arg5; } +#ifdef NON_MATCHING +// a1/a2 reg swap around Entrance_GetSpawnNum +void Play_Init(GameState* thisx) { + PlayState* this = (PlayState*)thisx; + GraphicsContext* gfxCtx = this->state.gfxCtx; + s32 pad; + s32 pad2; + s32 sp94; + Player* player; + s32 spawn; + s32 i; + u8 sp87; + u32 temp_v0_12; + s32 scene; + s16 params; + + if ((gSaveContext.respawnFlag == -4) || (gSaveContext.respawnFlag == -0x63)) { + if (gSaveContext.eventInf[2] & 0x80) { + gSaveContext.eventInf[2] &= (u8)~0x80; + this->state.running = false; + { + GameState* state = &this->state; + + SET_NEXT_GAMESTATE(state, Daytelop_Init, DaytelopContext); + } + return; + } + + gSaveContext.unk_3CA7 = 1; + if (gSaveContext.respawnFlag == ~0x62) { + gSaveContext.respawnFlag = 2; + } + } else { + gSaveContext.unk_3CA7 = 0; + } + + if (gSaveContext.save.entrance == -1) { + gSaveContext.save.entrance = 0; + this->state.running = false; + { + GameState* state = &this->state; + + SET_NEXT_GAMESTATE(state, Opening_Init, OpeningContext); + } + return; + } + + if ((gSaveContext.nextCutsceneIndex == 0xFFEF) || (gSaveContext.nextCutsceneIndex == 0xFFF0)) { + scene = gSaveContext.save.entrance >> 9; + spawn = (gSaveContext.save.entrance >> 4) & 0x1F; + + if (gSaveContext.save.weekEventReg[33] & 0x80) { + if (scene == ENTR_SCENE_MOUNTAIN_VILLAGE_WINTER) { + scene = ENTR_SCENE_MOUNTAIN_VILLAGE_SPRING; + } else if (scene == ENTR_SCENE_GORON_VILLAGE_WINTER) { + scene = ENTR_SCENE_GORON_VILLAGE_SPRING; + } else if (scene == ENTR_SCENE_PATH_TO_GORON_VILLAGE_WINTER) { + scene = ENTR_SCENE_PATH_TO_GORON_VILLAGE_SPRING; + } else if ((scene == ENTR_SCENE_SNOWHEAD) || (scene == ENTR_SCENE_PATH_TO_SNOWHEAD) || + (scene == ENTR_SCENE_PATH_TO_MOUNTAIN_VILLAGE) || (scene == ENTR_SCENE_GORON_SHRINE) || + (scene == ENTR_SCENE_GORON_RACETRACK)) { + gSaveContext.nextCutsceneIndex = 0xFFF0; + } + } + + if (gSaveContext.save.weekEventReg[20] & 2) { + if (scene == ENTR_SCENE_SOUTHERN_SWAMP_POISONED) { + scene = ENTR_SCENE_SOUTHERN_SWAMP_CLEARED; + } else if (scene == ENTR_SCENE_WOODFALL) { + gSaveContext.nextCutsceneIndex = 0xFFF1; + } + } + + if ((gSaveContext.save.weekEventReg[52] & 0x20) && (scene == ENTR_SCENE_IKANA_CANYON)) { + gSaveContext.nextCutsceneIndex = 0xFFF2; + } + + if ((gSaveContext.save.weekEventReg[55] & 0x80) && + ((scene == ENTR_SCENE_GREAT_BAY_COAST) || (scene == ENTR_SCENE_ZORA_CAPE))) { + gSaveContext.nextCutsceneIndex = 0xFFF0; + } + + if (INV_CONTENT(ITEM_OCARINA) != ITEM_OCARINA) { + if ((scene == ENTR_SCENE_TERMINA_FIELD) && + (((void)0, gSaveContext.save.entrance) != ENTRANCE(TERMINA_FIELD, 10))) { + gSaveContext.nextCutsceneIndex = 0xFFF4; + } + } + gSaveContext.save.entrance = Entrance_Create(scene, spawn, ((void)0, gSaveContext.save.entrance) & 0xF); + } + + GameState_Realloc(&this->state, 0); + KaleidoManager_Init(this); + ShrinkWindow_Init(); + View_Init(&this->view, gfxCtx); + func_801A3EC0(0); + Quake_Init(); + Distortion_Init(this); + + for (i = 0; i < ARRAY_COUNT(this->cameraPtrs); i++) { + this->cameraPtrs[i] = NULL; + } + + Camera_Init(&this->mainCamera, &this->view, &this->colCtx, this); + Camera_ChangeStatus(&this->mainCamera, 7); + + for (i = 0; i < ARRAY_COUNT(this->subCameras); i++) { + Camera_Init(&this->subCameras[i], &this->view, &this->colCtx, this); + Camera_ChangeStatus(&this->subCameras[i], 0x100); + } + + this->cameraPtrs[CAM_ID_MAIN] = &this->mainCamera; + this->cameraPtrs[CAM_ID_MAIN]->uid = CAM_ID_MAIN; + this->activeCamId = CAM_ID_MAIN; + + func_800DFF18(&this->mainCamera, 0x7F); + Sram_Alloc(&this->state, &this->sramCtx); + func_801AAAA0(this); + Message_Init(this); + GameOver_Init(this); + SoundSource_InitAll(this); + EffFootmark_Init(this); + Effect_Init(this); + EffectSS_Init(this, 100); + CollisionCheck_InitContext(this, &this->colChkCtx); + AnimationContext_Reset(&this->animationCtx); + Cutscene_Init(this, &this->csCtx); + + if (gSaveContext.nextCutsceneIndex != 0xFFEF) { + gSaveContext.save.cutscene = gSaveContext.nextCutsceneIndex; + gSaveContext.nextCutsceneIndex = 0xFFEF; + } + + if (gSaveContext.save.cutscene == 0xFFFD) { + gSaveContext.save.cutscene = 0; + } + + if (gSaveContext.nextDayTime != 0xFFFF) { + gSaveContext.save.time = gSaveContext.nextDayTime; + gSaveContext.skyboxTime = gSaveContext.nextDayTime; + } + + if ((gSaveContext.save.time >= CLOCK_TIME(18, 0)) || (gSaveContext.save.time < CLOCK_TIME(6, 30))) { + gSaveContext.save.isNight = true; + } else { + gSaveContext.save.isNight = false; + } + + func_800EDDB0(this); + + if (((gSaveContext.gameMode != 0) && (gSaveContext.gameMode != 1)) || (gSaveContext.save.cutscene >= 0xFFF0)) { + gSaveContext.unk_3DC0 = 0; + func_80115D5C(&this->state); + gSaveContext.sceneSetupIndex = (gSaveContext.save.cutscene & 0xF) + 1; + gSaveContext.save.cutscene = 0; + } else { + gSaveContext.sceneSetupIndex = 0; + } + + sp87 = gSaveContext.sceneSetupIndex; + + Play_SceneInit( + this, + Entrance_GetSceneNumAbsolute(((void)0, gSaveContext.save.entrance) + ((void)0, gSaveContext.sceneSetupIndex)), + Entrance_GetSpawnNum(((void)0, gSaveContext.save.entrance) + ((void)0, gSaveContext.sceneSetupIndex))); + KaleidoScopeCall_Init(this); + func_80121FC4(this); + + if (gSaveContext.nextDayTime != 0xFFFF) { + if (gSaveContext.nextDayTime == 0x8000) { + gSaveContext.save.day++; + gSaveContext.save.daysElapsed++; + gSaveContext.dogIsLost = true; + gSaveContext.nextDayTime = -2; + } else { + gSaveContext.nextDayTime = -3; + } + } + + func_80165608(); + + SREG(94) = 0; + SREG(89) = 0; + + PreRender_Init(&this->pauseBgPreRender); + PreRender_SetValuesSave(&this->pauseBgPreRender, D_801FBBCC, D_801FBBCE, NULL, NULL, NULL); + PreRender_SetValues(&this->pauseBgPreRender, D_801FBBCC, D_801FBBCE, NULL, NULL); + + this->unk_18E64 = D_801FBB90; + this->unk_18E5C = D_80780000; + this->unk_18E68 = D_80784600; + this->unk_18E58 = D_80784600; + this->unk_18E60 = D_80784600; + D_801F6D10 = 0; + this->transitionMode = TRANS_MODE_OFF; + D_801D0D54 = 0; + + FrameAdvance_Init(&this->frameAdvCtx); + Rand_Seed(osGetTime()); + Matrix_Init(&this->state); + + this->state.main = Play_Main; + this->state.destroy = Play_Destroy; + + this->transitionTrigger = TRANS_TRIGGER_END; + this->unk_18876 = 0; + this->bgCoverAlpha = 0; + this->unk_18845 = 0; + this->unk_18844 = 0; + + if (gSaveContext.gameMode != 1) { + if (gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT) { + this->transitionType = + (Entrance_GetTransitionFlags(((void)0, gSaveContext.save.entrance) + sp87) >> 7) & 0x7F; + } else { + this->transitionType = gSaveContext.nextTransitionType; + gSaveContext.nextTransitionType = 0xFF; + } + } else { + this->transitionType = TRANS_TYPE_02; + } + + TransitionFade_Init(&this->unk_18E48); + TransitionFade_SetType(&this->unk_18E48, 3); + TransitionFade_SetColor(&this->unk_18E48, 0xA0A0A0FF); + TransitionFade_Start(&this->unk_18E48); + VisMono_Init(&D_801F6D18); + + D_801F6D30.a = 0; + D_801F6D4C = &D_801F6D38; + func_80140E80(D_801F6D4C); + D_801F6D4C->lodProportion = 0.0f; + D_801F6D4C->mode = 1; + D_801F6D4C->primColor.r = 0; + D_801F6D4C->primColor.g = 0; + D_801F6D4C->primColor.b = 0; + D_801F6D4C->primColor.a = 0; + D_801F6D4C->envColor.r = 0; + D_801F6D4C->envColor.g = 0; + D_801F6D4C->envColor.b = 0; + D_801F6D4C->envColor.a = 0; + EnvFlags_UnsetAll(this); + THA_GetSize(&this->state.heap); + sp94 = THA_GetSize(&this->state.heap); + temp_v0_12 = (u32)THA_AllocEndAlign16(&this->state.heap, sp94); + ZeldaArena_Init(((temp_v0_12 + 8) & ~0xF), (sp94 - ((temp_v0_12 + 8) & ~0xF)) + temp_v0_12); + Actor_InitContext(this, &this->actorCtx, this->linkActorEntry); + + while (Room_HandleLoadCallbacks(this, &this->roomCtx) == 0) {} + + if ((CURRENT_DAY != 0) && ((this->roomCtx.currRoom.unk3 == 1) || (this->roomCtx.currRoom.unk3 == 5))) { + Actor_Spawn(&this->actorCtx, this, 0x15A, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0); + } + + player = GET_PLAYER(this); + + Camera_InitPlayerSettings(&this->mainCamera, player); + gDbgCamEnabled = false; + + if ((player->actor.params & 0xFF) != 0xFF) { + Camera_ChangeDataIdx(&this->mainCamera, player->actor.params & 0xFF); + } + + func_800F15D8(&this->mainCamera); + func_801129E4(this); + func_800FB758(this); + gSaveContext.seqIndex = this->soundCtx.seqIndex; + gSaveContext.nightSeqIndex = this->soundCtx.nightSeqIndex; + AnimationContext_Update(this, &this->animationCtx); + func_800EDBE0(this); + gSaveContext.respawnFlag = 0; + D_801F6DFC = 0; + func_8016FC78(&D_801F6D50); +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Init.s") +#endif + +// play_hireso need to confirm still +u16 D_801D0D78[] = { 0, 0, 0, 0 }; diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index eaca8ea4bf..5d8d45c340 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -2131,7 +2131,7 @@ 0x801D0D5C:("D_801D0D5C","UNK_TYPE2","",0x2), 0x801D0D60:("D_801D0D60","Input*","",0x4), 0x801D0D64:("D_801D0D64","s16","[10]",0x14), - 0x801D0D7A:("D_801D0D7A","UNK_TYPE1","",0x1), + 0x801D0D78:("D_801D0D78","u16","[4]",0x4), 0x801D0D80:("D_801D0D80","UNK_TYPE1","",0x1), 0x801D11F4:("D_801D11F4","UNK_TYPE1","",0x1), 0x801D1230:("D_801D1230","UNK_TYPE1","",0x1),