diff --git a/soh/soh/Enhancements/stairs.cpp b/soh/soh/Enhancements/stairs.cpp index 0475d53dd..87cd679f9 100644 --- a/soh/soh/Enhancements/stairs.cpp +++ b/soh/soh/Enhancements/stairs.cpp @@ -18,6 +18,9 @@ static const std::vector stairActorTable = { #undef DEFINE_ACTOR_UNSET #undef DEFINE_ACTOR +size_t stairsAllocSize = 0x1D4790 - 0x26960 - 0x2200 - (0x55 * 0x60) - (3 * (48 * 16) / 2) - (4 * (32 * 32 * 4)) - 0x1000 - (20 * sizeof(MtxF)); +Arena sStairsArena; + // using sizes from the debug rom std::unordered_map actorOverlaySizes = { { ACTOR_PLAYER, 0x0}, @@ -507,6 +510,17 @@ size_t Stairs_GetOverlaySize(u16 id) { return actorOverlaySizes[id]; } +size_t Stairs_GetSize() { + return stairsAllocSize; +} + +s32 Stairs_DecreaseSize(size_t size) { + if (size > stairsAllocSize) { + return false; + } + stairsAllocSize -= size; + return true; +} void* StairsArena_Malloc(size_t size) { void* ptr = __osMalloc(&sStairsArena, size); @@ -647,6 +661,7 @@ void StairsArena_Cleanup() { mallocRPtrMap.clear(); absolutePtr = nullptr; absoluteSpaceFlag = 0; + stairsAllocSize = 0x1D4790 - 0x26960 - 0x2200 - (0x55 * 0x60) - (3 * (48 * 16) / 2) - (4 * (32 * 32 * 4)) - 0x1000 - (20 * sizeof(MtxF)); } u8 StairsArena_IsInitalized() { diff --git a/soh/soh/Enhancements/stairs.h b/soh/soh/Enhancements/stairs.h index 29225799f..8875bdbe9 100644 --- a/soh/soh/Enhancements/stairs.h +++ b/soh/soh/Enhancements/stairs.h @@ -3,14 +3,14 @@ #include "global.h" -// This value is based on the ZeldaArena size created on play init with default GameAlloc size -#define STAIRS_ALLOC_SIZE 560064 #define STAIRS_ACTOROVL_ABSOLUTE_SPACE_SIZE 0x27A0 #define STAIRS_ACTOROVL_ALLOC_ABSOLUTE (1 << 0) #define STAIRS_ACTOROVL_ALLOC_PERSISTENT (1 << 1) -Arena sStairsArena; +// This value is based on the ZeldaArena size created on play init with default GameAlloc size +// #define STAIRS_ALLOC_SIZE 560064 +// #define STAIRS_ALLOC_SIZE 0x88BC0 #ifdef __cplusplus extern "C" { @@ -24,6 +24,9 @@ s32 Stairs_GetAbsoluteSpace(); s32 Stairs_UnregisterAbsoluteSpace(); size_t Stairs_GetOverlaySize(u16 id); +size_t Stairs_GetSize(); +s32 Stairs_DecreaseSize(size_t size); + void* StairsArena_Malloc(size_t size); void* StairsArena_MallocR(size_t size); void* StairsArena_Realloc(void* ptr, size_t newSize); diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 7c1f51cf1..b32cb97c2 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -1467,7 +1467,8 @@ extern std::shared_ptr mValueViewerWindow; void DrawDeveloperToolsMenu() { if (ImGui::BeginMenu("Developer Tools")) { ImGui::BeginDisabled(CVarGetInteger("gDisableChangingSettings", 0)); - + UIWidgets::EnhancementCheckbox("Stairs heap display", "gStairsDisplay"); + UIWidgets::Tooltip("Visualises the stair heap"); UIWidgets::EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled"); UIWidgets::Tooltip("Enables Debug Mode, allowing you to select maps with L + R + Z, noclip with L + D-pad Right, and open the debug menu with L on the pause screen"); if (CVarGetInteger("gDebugEnabled", 0)) { diff --git a/soh/src/code/z_bgcheck.c b/soh/src/code/z_bgcheck.c index 4acc68e55..d42abd7b3 100644 --- a/soh/src/code/z_bgcheck.c +++ b/soh/src/code/z_bgcheck.c @@ -4,6 +4,8 @@ #include #include +#include "soh/Enhancements/stairs.h" + #define SS_NULL 0xFFFF // bccFlags @@ -2453,6 +2455,7 @@ void SSNodeList_Alloc(PlayState* play, SSNodeList* this, s32 tblMax, s32 numPoly assert(this->tbl != NULL); this->polyCheckTbl = GAMESTATE_ALLOC_MC(&play->state, numPolys); + Stairs_DecreaseSize(numPolys); assert(this->polyCheckTbl != NULL); } diff --git a/soh/src/code/z_construct.c b/soh/src/code/z_construct.c index b95902cc5..991efb5aa 100644 --- a/soh/src/code/z_construct.c +++ b/soh/src/code/z_construct.c @@ -2,6 +2,8 @@ #include #include +#include "soh/Enhancements/stairs.h" + void func_80110990(PlayState* play) { Map_Destroy(play); } @@ -35,6 +37,7 @@ void func_801109B0(PlayState* play) { osSyncPrintf("常駐PARAMETERセグメント=%x\n", parameterSize); interfaceCtx->parameterSegment = GAMESTATE_ALLOC_MC(&play->state, parameterSize); + Stairs_DecreaseSize(parameterSize); osSyncPrintf("parameter->parameterSegment=%x\n", interfaceCtx->parameterSegment); diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index c160a0ce3..5a55a2b0a 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -478,9 +478,10 @@ void Play_Init(GameState* thisx) { //play->state.gfxCtx = NULL; uintptr_t zAlloc; uintptr_t stairsAlloc; - uintptr_t stairsAllocAligned; uintptr_t zAllocAligned; + uintptr_t stairsAllocAligned; size_t zAllocSize; + size_t stairsAllocSize; Player* player; s32 playerStartCamId; s32 i; @@ -671,10 +672,11 @@ void Play_Init(GameState* thisx) { D_801614B0.a = 0; Flags_UnsetAllEnv(play); - // Stairs Heap - stairsAlloc = GAMESTATE_ALLOC_MC(&play->state, STAIRS_ALLOC_SIZE); + // Stairs Heap + stairsAllocSize = Stairs_GetSize(); + stairsAlloc = GAMESTATE_ALLOC_MC(&play->state, stairsAllocSize); stairsAllocAligned = (stairsAlloc + 8) & ~0xF; - StairsArena_Init(stairsAllocAligned, STAIRS_ALLOC_SIZE - stairsAllocAligned + stairsAlloc); + StairsArena_Init(stairsAllocAligned, stairsAllocSize - stairsAllocAligned + stairsAlloc); osSyncPrintf("ZELDA ALLOC SIZE=%x\n", THA_GetSize(&play->state.tha)); zAllocSize = THA_GetSize(&play->state.tha); zAlloc = GAMESTATE_ALLOC_MC(&play->state, zAllocSize); @@ -794,6 +796,11 @@ void Play_Update(PlayState* play) { ZeldaArena_Display(); } + if (CVarGetInteger("gStairs", 1) && CVarGetInteger("gStairsDisplay", 0)) { + // todo: implement drawing + StairsArena_Display(); + } + if ((HREG(80) == 18) && (HREG(81) < 0)) { HREG(81) = 0; osSyncPrintf("object_exchange_rom_address %u\n", gObjectTableSize); diff --git a/soh/src/code/z_room.c b/soh/src/code/z_room.c index 772978f09..74a0d98be 100644 --- a/soh/src/code/z_room.c +++ b/soh/src/code/z_room.c @@ -5,6 +5,7 @@ #include "global.h" #include "vt.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" +#include "soh/Enhancements/stairs.h" #include #include @@ -564,6 +565,7 @@ u32 func_80096FE8(PlayState* play, RoomContext* roomCtx) { // "Room buffer size=%08x(%5.1fK)" osSyncPrintf("部屋バッファサイズ=%08x(%5.1fK)\n", maxRoomSize, maxRoomSize / 1024.0f); roomCtx->bufPtrs[0] = GAMESTATE_ALLOC_MC(&play->state, maxRoomSize); + Stairs_DecreaseSize(maxRoomSize); // "Room buffer initial pointer=%08x" osSyncPrintf("部屋バッファ開始ポインタ=%08x\n", roomCtx->bufPtrs[0]); roomCtx->bufPtrs[1] = (void*)((intptr_t)roomCtx->bufPtrs[0] + maxRoomSize); diff --git a/soh/src/code/z_scene.c b/soh/src/code/z_scene.c index 1702dc3d9..f900d1949 100644 --- a/soh/src/code/z_scene.c +++ b/soh/src/code/z_scene.c @@ -3,6 +3,8 @@ #include "soh/ActorDB.h" #include +#include "soh/Enhancements/stairs.h" + RomFile sNaviMsgFiles[]; s32 Object_Spawn(ObjectContext* objectCtx, s16 objectId) { @@ -71,6 +73,7 @@ void Object_InitBank(PlayState* play, ObjectContext* objectCtx) { objectCtx->spaceStart = objectCtx->status[0].segment = GAMESTATE_ALLOC_MC(&play->state, spaceSize); + Stairs_DecreaseSize(spaceSize); objectCtx->spaceEnd = (void*)((uintptr_t)objectCtx->spaceStart + spaceSize); objectCtx->mainKeepIndex = Object_Spawn(objectCtx, OBJECT_GAMEPLAY_KEEP); diff --git a/soh/src/code/z_vr_box.c b/soh/src/code/z_vr_box.c index ff2622187..73a657b88 100644 --- a/soh/src/code/z_vr_box.c +++ b/soh/src/code/z_vr_box.c @@ -71,6 +71,8 @@ #include "assets/textures/skyboxes/vr_holy1_static.h" #include "assets/textures/skyboxes/vr_holy1_pal_static.h" +#include "soh/Enhancements/stairs.h" + u32 D_8012AC90[4] = { 0x00000000, @@ -605,6 +607,13 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) { u8 sp40; // imageIdx2 uintptr_t start; s32 phi_v1; + + // todo: figure out correct 'size' rather than 0x10000 (which is far too large) + if (skyboxId == SKYBOX_NORMAL_SKY || skyboxId == SKYBOX_OVERCAST_SUNSET || skyboxId == SKYBOX_CUTSCENE_MAP) { + // Stairs_DecreaseSize(0x10000 * 4); + } else { + // Stairs_DecreaseSize(0x10000 * 2); + } switch (skyboxId) { @@ -968,23 +977,28 @@ void Skybox_Init(GameState* state, SkyboxContext* skyboxCtx, s16 skyboxId) { if (skyboxCtx->unk_140 != 0) { skyboxCtx->dListBuf = GAMESTATE_ALLOC_MC(state, 8 * 150 * sizeof(Gfx)); assert(skyboxCtx->dListBuf != NULL); + Stairs_DecreaseSize(8 * 150 * sizeof(Gfx)); skyboxCtx->roomVtx = GAMESTATE_ALLOC_MC(state, 256 * sizeof(Vtx)); assert(skyboxCtx->roomVtx != NULL); + Stairs_DecreaseSize(256 * sizeof(Vtx)); func_800AEFC8(skyboxCtx, skyboxId); } else { skyboxCtx->dListBuf = GAMESTATE_ALLOC_MC(state, 12 * 150 * sizeof(Gfx)); assert(skyboxCtx->dListBuf != NULL); + Stairs_DecreaseSize(12 * 150 * sizeof(Gfx)); if (skyboxId == SKYBOX_CUTSCENE_MAP) { skyboxCtx->roomVtx = GAMESTATE_ALLOC_MC(state, 192 * sizeof(Vtx)); assert(skyboxCtx->roomVtx != NULL); + Stairs_DecreaseSize(192 * sizeof(Gfx)); func_800AF178(skyboxCtx, 6); } else { skyboxCtx->roomVtx = GAMESTATE_ALLOC_MC(state, 160 * sizeof(Vtx)); assert(skyboxCtx->roomVtx != NULL); + Stairs_DecreaseSize(160 * sizeof(Vtx)); func_800AF178(skyboxCtx, 5); }