Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions UnleashedRecomp/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

52 changes: 52 additions & 0 deletions UnleashedRecomp/patches/misc_patches.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "misc_patches.h"
#include <api/SWA.h>
#include <ui/game_window.h>
#include <user/achievement_manager.h>
Expand Down Expand Up @@ -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>
// <TerrainInfoFile>terrain</TerrainInfoFile>
// <GIAtlas>1</GIAtlas>
// </Terrain>
// <Terrain>
// <RigidBodyContainer>collision</RigidBodyContainer>
// <IsCollisionRender>false</IsCollisionRender>
// </Terrain>
//
// 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;
}
3 changes: 3 additions & 0 deletions UnleashedRecomp/patches/misc_patches.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

static bool g_singleTerrainBlockXml = false;
16 changes: 16 additions & 0 deletions UnleashedRecompLib/config/SWA.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading