diff --git a/UnleashedRecomp/app.cpp b/UnleashedRecomp/app.cpp index b298ebc3..d82e9c5b 100644 --- a/UnleashedRecomp/app.cpp +++ b/UnleashedRecomp/app.cpp @@ -89,9 +89,6 @@ PPC_FUNC(sub_822C1130) if (Config::EnableObjectCollisionDebugView) *SWA::SGlobals::ms_IsObjectCollisionRender = true; - if (Config::EnableStageCollisionDebugView) - *SWA::SGlobals::ms_IsCollisionRender = true; - __imp__sub_822C1130(ctx, base); } diff --git a/UnleashedRecomp/patches/misc_patches.cpp b/UnleashedRecomp/patches/misc_patches.cpp index ec4e1a8b..de1ef8eb 100644 --- a/UnleashedRecomp/patches/misc_patches.cpp +++ b/UnleashedRecomp/patches/misc_patches.cpp @@ -1,3 +1,4 @@ +#include "misc_patches.h" #include #include #include @@ -193,3 +194,54 @@ PPC_FUNC(sub_824EE620) ctx.r3.u32 = PersistentStorageManager::ShouldDisplayDLCMessage(true); } + +bool StageCollisionDebugViewMidAsmHook(PPCRegister& r27) +{ + if (Config::EnableStageCollisionDebugView) + { + r27.u32 = true; + return true; + } + + return false; +} + +// The game is set up so that after parsing the Stage.set.xml it checks if TerrainInfoFile is found or not. +// Based on the result of that it will either draw terrain or debug collision (if enabled). +// +// The XMLs in the game are populated like this generally speaking: +// +// terrain +// 1 +// +// +// collision +// false +// +// +// In some cases however, the information in these two Terrain blocks is combined into one block, +// which makes the logic checking TerrainInfoFile's contents only fire once, and with success only, as such +// the logic for drawing collision will never execute. +// +// To combat this we check if both types returned with some value from the XML file, which indicates that its +// a single Terrain block, and if so we store that information so we can later on re-use to manually fire the +// logic controlling the drawing of the debug collision view. +void StageCollisionDebugViewStoreXmlTypeMidAsmHook(PPCRegister& r1) +{ + uint8_t* base = g_memory.base; + + const char* rigidBodyContainer = (const char*)(base + PPC_LOAD_U32(r1.u32 + 108)); + const char* terrainInfoFile = (const char*)(base + PPC_LOAD_U32(r1.u32 + 132)); + if (*rigidBodyContainer != '\0' && *terrainInfoFile != '\0') + { + g_singleTerrainBlockXml = true; + } +} + +bool StageCollisionDebugViewSingleTerrainBlockXmlMidAsmHook() +{ + bool runCollisionViewDrawLogic = g_singleTerrainBlockXml; + g_singleTerrainBlockXml = false; + + return runCollisionViewDrawLogic; +} diff --git a/UnleashedRecomp/patches/misc_patches.h b/UnleashedRecomp/patches/misc_patches.h new file mode 100644 index 00000000..c1d8ee5f --- /dev/null +++ b/UnleashedRecomp/patches/misc_patches.h @@ -0,0 +1,3 @@ +#pragma once + +static bool g_singleTerrainBlockXml = false; diff --git a/UnleashedRecompLib/config/SWA.toml b/UnleashedRecompLib/config/SWA.toml index eb871b8a..4bb30544 100644 --- a/UnleashedRecompLib/config/SWA.toml +++ b/UnleashedRecompLib/config/SWA.toml @@ -1141,3 +1141,19 @@ registers = ["r3"] name = "EndingTextPositionMidAsmHook" address = 0x82580168 registers = ["r31", "f13"] + +[[midasm_hook]] +name = "StageCollisionDebugViewMidAsmHook" +address = 0x825648F8 +registers = ["r27"] +jump_address_on_true = 0x825648FC + +[[midasm_hook]] +name = "StageCollisionDebugViewStoreXmlTypeMidAsmHook" +address = 0x8256422C +registers = ["r1"] + +[[midasm_hook]] +name = "StageCollisionDebugViewSingleTerrainBlockXmlMidAsmHook" +address = 0x82564B00 +jump_address_on_true = 0x82564764