Map CSD structures by full path.

This commit is contained in:
Skyth 2025-01-03 10:13:22 +03:00
parent 95bd71a23e
commit f8c6f5172e
2 changed files with 141 additions and 0 deletions

View file

@ -66,3 +66,139 @@ bool MotionBlurMidAsmHook()
{
return Config::MotionBlur != EMotionBlur::Off;
}
// These are here for now to not recompile basically all of the project.
namespace Chao::CSD
{
struct Cast
{
SWA_INSERT_PADDING(0x144);
};
struct CastLink
{
be<uint32_t> ChildCastIndex;
be<uint32_t> SiblingCastIndex;
};
struct CastNode
{
be<uint32_t> CastCount;
xpointer<Cast> pCasts;
be<uint32_t> RootCastIndex;
xpointer<CastLink> pCastLinks;
};
struct CastIndex
{
xpointer<const char> pCastName;
be<uint32_t> CastNodeIndex;
be<uint32_t> CastIndex;
};
struct Scene
{
SWA_INSERT_PADDING(0x24);
be<uint32_t> CastNodeCount;
xpointer<CastNode> pCastNodes;
be<uint32_t> CastCount;
xpointer<CastIndex> pCastIndices;
};
struct SceneIndex
{
xpointer<const char> pSceneName;
be<uint32_t> SceneIndex;
};
struct SceneNodeIndex
{
xpointer<const char> pSceneNodeName;
be<uint32_t> SceneNodeIndex;
};
struct SceneNode
{
be<uint32_t> SceneCount;
xpointer<xpointer<Scene>> pScenes;
xpointer<SceneIndex> pSceneIndices;
be<uint32_t> SceneNodeCount;
xpointer<SceneNode> pSceneNodes;
xpointer<SceneNodeIndex> pSceneNodeIndices;
};
struct Project
{
xpointer<SceneNode> pRootNode;
};
}
static std::map<const void*, XXH64_hash_t> g_paths;
static void EmplacePath(const void* key, const std::string_view& value)
{
g_paths.emplace(key, XXH3_64bits(value.data(), value.size()));
}
static void TraverseCast(Chao::CSD::Scene* scene, uint32_t castNodeIndex, Chao::CSD::CastNode* castNode, uint32_t castIndex, const std::string& parentPath)
{
if (castIndex == ~0)
return;
TraverseCast(scene, castNodeIndex, castNode, castNode->pCastLinks[castIndex].SiblingCastIndex, parentPath);
std::string path = parentPath;
for (size_t i = 0; i < scene->CastCount; i++)
{
auto& index = scene->pCastIndices[i];
if (index.CastNodeIndex == castNodeIndex && index.CastIndex == castIndex)
{
path += index.pCastName;
break;
}
}
EmplacePath(&castNode->pCasts[castIndex], path);
path += "/";
TraverseCast(scene, castNodeIndex, castNode, castNode->pCastLinks[castIndex].ChildCastIndex, path);
}
static void TraverseScene(Chao::CSD::Scene* scene, std::string path)
{
EmplacePath(scene, path);
path += "/";
for (size_t i = 0; i < scene->CastNodeCount; i++)
{
auto& castNode = scene->pCastNodes[i];
TraverseCast(scene, i, &castNode, castNode.RootCastIndex, path);
}
}
static void TraverseSceneNode(Chao::CSD::SceneNode* sceneNode, std::string path)
{
EmplacePath(sceneNode, path);
path += "/";
for (size_t i = 0; i < sceneNode->SceneCount; i++)
{
auto& sceneIndex = sceneNode->pSceneIndices[i];
TraverseScene(sceneNode->pScenes[sceneIndex.SceneIndex], path + sceneIndex.pSceneName.get());
}
for (size_t i = 0; i < sceneNode->SceneNodeCount; i++)
{
auto& sceneNodeIndex = sceneNode->pSceneNodeIndices[i];
TraverseSceneNode(&sceneNode->pSceneNodes[sceneNodeIndex.SceneNodeIndex], path + sceneNodeIndex.pSceneNodeName.get());
}
}
void MakeCsdProjectMidAsmHook(PPCRegister& r3, PPCRegister& r29)
{
uint8_t* base = g_memory.base;
auto csdProject = reinterpret_cast<Chao::CSD::CProject*>(base + PPC_LOAD_U32(PPC_LOAD_U32(r3.u32 + 16) + 4));
auto name = reinterpret_cast<const char*>(base + PPC_LOAD_U32(r29.u32));
TraverseSceneNode(csdProject->m_pResource->pRootNode, name);
}

View file

@ -590,3 +590,8 @@ jump_address = 0x82B723BC
name = "DisableDLCIconMidAsmHook"
address = 0x825756B0
jump_address_on_true = 0x825756E0
[[midasm_hook]]
name = "MakeCsdProjectMidAsmHook"
address = 0x825E4120
registers = ["r3", "r29"]