diff --git a/config/RSBE01_02/splits.txt b/config/RSBE01_02/splits.txt index 0d69ad4..f1b8153 100644 --- a/config/RSBE01_02/splits.txt +++ b/config/RSBE01_02/splits.txt @@ -131,6 +131,14 @@ sora/st/module.cpp: .text start:0x80043B18 end:0x80043B6C .data start:0x8042AEB0 end:0x8042B598 +sora/ut/ut_nw.cpp: + .text start:0x80043B6C end:0x80043E1C + .sdata2 start:0x805A17E0 end:0x805A17E8 + +sora/ut/ut_relocate.cpp: + .text start:0x80043E1C end:0x80044214 + .data start:0x8042B598 end:0x8042B5FC + sora/ut/ut_list.cpp: .text start:0x800448F8 end:0x80044AD0 diff --git a/config/RSBE01_02/symbols.txt b/config/RSBE01_02/symbols.txt index a56260b..5d73338 100644 --- a/config/RSBE01_02/symbols.txt +++ b/config/RSBE01_02/symbols.txt @@ -6,7 +6,7 @@ __init_registers = .init:0x800041A8; // type:function size:0x90 scope:local __init_data = .init:0x80004238; // type:function size:0xA8 scope:local __init_hardware = .init:0x800042E0; // type:function size:0x24 scope:global __flush_cache = .init:0x80004304; // type:function size:0x34 scope:global -memcpy__FPvPvUl = .init:0x80004338; // type:function size:0x50 scope:global +memcpy = .init:0x80004338; // type:function size:0x50 scope:global __fill_mem = .init:0x80004388; // type:function size:0xB4 scope:global memset = .init:0x8000443C; // type:function size:0x30 scope:global fn_8000446C = .init:0x8000446C; // type:function size:0x30 @@ -2885,7 +2885,7 @@ vlRotateFix__FP5Vec3fQ212vlRotateAxis4Enumf = .text:0x8003E244; // type:function setIdentity__6MatrixFv = .text:0x8003E35C; // type:function size:0x2C fn_8003E388 = .text:0x8003E388; // type:function size:0x34 fn_8003E3BC = .text:0x8003E3BC; // type:function size:0x5C -fn_8003E418 = .text:0x8003E418; // type:function size:0x54 +mulPos__6MatrixFPC5Vec3fP5Vec3f = .text:0x8003E418; // type:function size:0x54 fn_8003E46C = .text:0x8003E46C; // type:function size:0x54 fn_8003E4C0 = .text:0x8003E4C0; // type:function size:0xF4 fn_8003E5B4 = .text:0x8003E5B4; // type:function size:0x128 @@ -2983,11 +2983,11 @@ nwSMGetGlobalRotation__FPCQ34nw4r3g3d12ScnMdlSimpleUl = .text:0x80043CB0; // typ nwSMSetVisibility__FPQ34nw4r3g3d12ScnMdlSimpleb = .text:0x80043D20; // type:function size:0x40 nwSMSetNodeVisibility__FPQ34nw4r3g3d6ScnMdlUlb = .text:0x80043D60; // type:function size:0x4C nwSMSetNodeVisibility__FPQ34nw4r3g3d6ScnMdllPCUlb = .text:0x80043DAC; // type:function size:0x70 -__ct__10utRelocateFPvUl = .text:0x80043E1C; // type:function size:0x150 +__ct__10utRelocateFPUcUl = .text:0x80043E1C; // type:function size:0x150 __dt__10utRelocateFv = .text:0x80043F6C; // type:function size:0x40 -getPublicAddress__10utRelocateFPCc = .text:0x80043FAC; // type:function size:0x90 -fn_8004403C = .text:0x8004403C; // type:function size:0xC8 -fn_80044104 = .text:0x80044104; // type:function size:0x110 +getPublicAddress__10utRelocateCFPCc = .text:0x80043FAC; // type:function size:0x90 +locateExtern__10utRelocateFPCcPv = .text:0x8004403C; // type:function size:0xC8 +resolveReference__10utRelocateFPC10utRelocate = .text:0x80044104; // type:function size:0x110 fn_80044214 = .text:0x80044214; // type:function size:0x34 fn_80044248 = .text:0x80044248; // type:function size:0x118 fn_80044360 = .text:0x80044360; // type:function size:0x29C @@ -7890,9 +7890,9 @@ fn_801B0440 = .text:0x801B0440; // type:function size:0x78 fn_801B04B8 = .text:0x801B04B8; // type:function size:0x68 __ct__Q44nw4r3g3d6ScnMdl15CopiedMatAccessFPQ34nw4r3g3d6ScnMdlUl = .text:0x801B0520; // type:function size:0x280 fn_801B07A0 = .text:0x801B07A0; // type:function size:0x80 -fn_801B0820 = .text:0x801B0820; // type:function size:0x7C +SetVisibility__Q44nw4r3g3d6ScnMdl15CopiedVisAccessFb = .text:0x801B0820; // type:function size:0x7C fn_801B089C = .text:0x801B089C; // type:function size:0xD0 -fn_801B096C = .text:0x801B096C; // type:function size:0xBC +__ct__Q44nw4r3g3d6ScnMdl15CopiedVisAccessFPQ34nw4r3g3d6ScnMdlUl = .text:0x801B096C; // type:function size:0xBC fn_801B0A28 = .text:0x801B0A28; // type:function size:0x118 fn_801B0B40 = .text:0x801B0B40; // type:function size:0xB2C fn_801B166C = .text:0x801B166C; // type:function size:0x174 diff --git a/configure.py b/configure.py index cd3dd44..6117f09 100755 --- a/configure.py +++ b/configure.py @@ -316,6 +316,8 @@ def MatchingFor(*versions): Object(Matching, "sora/mt/mt_prng.cpp", extra_cflags=["-RTTI off"]), Object(Matching, "sora/mt/mt_prng_log.cpp"), Object(Matching, "sora/st/module.cpp"), + Object(Matching, "sora/ut/ut_nw.cpp"), + Object(NonMatching, "sora/ut/ut_relocate.cpp"), Object(Matching, "sora/ut/ut_list.cpp"), Object(Matching, "sora/ip/ip_human.cpp"), Object(NonMatching, "sora/ip/ip_network_producer.cpp"), diff --git a/include/lib/BrawlHeaders b/include/lib/BrawlHeaders index b634fd9..8675125 160000 --- a/include/lib/BrawlHeaders +++ b/include/lib/BrawlHeaders @@ -1 +1 @@ -Subproject commit b634fd920254df2c31c092b985e387e5b0ff91ef +Subproject commit 86751254e622c81382ccac62083d475e3a6f763e diff --git a/src/sora/ty/ty_fig_listmng.cpp b/src/sora/ty/ty_fig_listmng.cpp index 51cc475..3ec5d39 100644 --- a/src/sora/ty/ty_fig_listmng.cpp +++ b/src/sora/ty/ty_fig_listmng.cpp @@ -48,7 +48,7 @@ bool tyFigListDataManager::isLoadFinish() { // "m_bySeries-2" and "m_byKind-2", then adding back the 2 when // dereferencing, but this would still result in UB void tyFigListDataManager::setData(void* fileBuf, u32 fileSz) { - utRelocate object(fileBuf, fileSz); + utRelocate object(reinterpret_cast(fileBuf), fileSz); m_data = static_cast(object.getPublicAddress("tyDataList")); m_count = 0; while (m_data[m_count].id >= 0) { diff --git a/src/sora/ut/ut_nw.cpp b/src/sora/ut/ut_nw.cpp new file mode 100644 index 0000000..be83cde --- /dev/null +++ b/src/sora/ut/ut_nw.cpp @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include +#include +#include + +Vec3f nwSMGetGlobalPosition(const nw4r::g3d::ScnMdlSimple* scnMdl, u32 nodeId, const Vec3f* pos) { + Vec3f res; + Matrix mtx(true); + scnMdl->GetScnMtxPos(&mtx, nw4r::g3d::ScnObj::MTX_WORLD, nodeId); + if (0.0f != pos->m_x || 0.0f != pos->m_y || 0.0f != pos->m_z) { + mtx.mulPos(pos, &res); + } else { + float z = mtx.m[2][3]; + float y = mtx.m[1][3]; + float x = mtx.m[0][3]; + res.m_x = x; + res.m_y = y; + res.m_z = z; + } + return res; +} + +Vec3f nwSMGetGlobalPosition(const nw4r::g3d::ScnMdlSimple* scnMdl, u32 nodeId) { + Vec3f res; + Matrix mtx(true); + scnMdl->GetScnMtxPos(&mtx, nw4r::g3d::ScnObj::MTX_WORLD, nodeId); + float z = mtx.m[2][3]; + float y = mtx.m[1][3]; + float x = mtx.m[0][3]; + res.m_x = x; + res.m_y = y; + res.m_z = z; + return res; +} + +Vec3f nwSMGetLocalPosition(const nw4r::g3d::ScnMdlSimple* scnMdl, u32 nodeId) { + Vec3f res; + Matrix mtx(true); + scnMdl->GetScnMtxPos(&mtx, nw4r::g3d::ScnObj::MTX_LOCAL, nodeId); + float z = mtx.m[2][3]; + float y = mtx.m[1][3]; + float x = mtx.m[0][3]; + res.m_x = x; + res.m_y = y; + res.m_z = z; + return res; +} + +Vec3f nwSMGetGlobalRotation(const nw4r::g3d::ScnMdlSimple* scnMdl, u32 nodeId) { + Vec3f res; + Matrix mtx(true); + scnMdl->GetScnMtxPos(&mtx, nw4r::g3d::ScnObj::MTX_WORLD, nodeId); + mtx.getRotate(&res); + res.m_x = 57.29578f * res.m_x; + res.m_y = 57.29578f * res.m_y; + res.m_z = 57.29578f * res.m_z; + return res; +} + +void nwSMSetVisibility(nw4r::g3d::ScnMdlSimple* scnMdl, bool vis) { + if (vis) { + scnMdl->SetScnObjOption(0x10001, 0); + } else { + scnMdl->SetScnObjOption(0x10001, 1); + } +} + +void nwSMSetNodeVisibility(nw4r::g3d::ScnMdl* scnMdl, u32 nodeId, bool vis) { + nw4r::g3d::ScnMdl::CopiedVisAccess cva(scnMdl, nodeId); + cva.SetVisibility(vis); +} + +void nwSMSetNodeVisibility(nw4r::g3d::ScnMdl* scnMdl, s32 numIds, const u32* nodeIds, bool vis) { + for (s32 i = 0; i < numIds; i++) { + nw4r::g3d::ScnMdl::CopiedVisAccess cva(scnMdl, nodeIds[i]); + cva.SetVisibility(vis); + } +} diff --git a/src/sora/ut/ut_relocate.cpp b/src/sora/ut/ut_relocate.cpp new file mode 100644 index 0000000..26a5a9f --- /dev/null +++ b/src/sora/ut/ut_relocate.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#include + +// NONMATCHING regswap +utRelocate::utRelocate(u8* fileBuf, u32 fileSz) { + m_dataStart = nullptr; + m_relStart = nullptr; + m_symtabStart = nullptr; + m_importStart = nullptr; + m_strtabStart = nullptr; + std::memcpy(&m_hdr, fileBuf, sizeof(m_hdr)); + if (m_hdr.fileSz != fileSz) { + OSReport("utRelocate: byte-order mismatch! Please check data format\n"); + } + + u32 fp = sizeof(m_hdr); + if (m_hdr.dataSz) { + m_dataStart = fileBuf + sizeof(m_hdr); + fp = m_hdr.dataSz + sizeof(m_hdr); + } + + if (m_hdr.nRels) { + m_relStart = reinterpret_cast(fileBuf + fp); + fp += m_hdr.nRels * sizeof(m_relStart[0]); + } + + if (m_hdr.nSymbols) { + m_symtabStart = reinterpret_cast(fileBuf + fp); + fp += m_hdr.nSymbols * sizeof(m_symtabStart[0]); + } + + if (m_hdr.nImports) { + m_importStart = reinterpret_cast(fileBuf + fp); + fp += m_hdr.nImports * sizeof(m_importStart[0]); + } + + if (fp < m_hdr.fileSz) { + m_strtabStart = reinterpret_cast(fileBuf + fp); + } + + if (!m_hdr.isAbsolute) { + // Resolve all internal relocations + for (u32 i = 0; i < m_hdr.nRels; i++) { + u8* datap = m_dataStart; + u32 offset = reinterpret_cast(datap); + *reinterpret_cast(&datap[m_relStart[i]]) += offset; + } + reinterpret_cast(fileBuf)->isAbsolute = true; + } +} + +utRelocate::~utRelocate() { } + +void* utRelocate::getPublicAddress(const char* symName) const { + const DATSymbol* sym; + for (u32 i = 0; i < m_hdr.nSymbols; i++) { + sym = m_symtabStart; + if (!std::strcmp(m_strtabStart + sym[i].name, symName)) { + return m_dataStart + sym[i].offset; + } + } + return nullptr; +} + +static const u32 EndMarker = 0xFFFFFFFF; + +// Resolve all references to externName within this module to addr +void utRelocate::locateExtern(const char* externName, void* addr) { + u32 nextOffset = EndMarker; + for (u32 i = 0; i < m_hdr.nImports; i++) { + if (!std::strcmp(externName, m_strtabStart + m_importStart[i].name)) { + nextOffset = m_importStart[i].offset; + break; + } + } + if (nextOffset == EndMarker) { + return; + } else { + while (nextOffset != EndMarker && nextOffset < m_hdr.dataSz) { + void** ref = reinterpret_cast(m_dataStart + nextOffset); + nextOffset = reinterpret_cast(*ref); + *ref = addr; + } + } +} + +// NONMATCHING regswaps +// Resolve all undefined references in this utRelocate against +// the symbols defined in other +void utRelocate::resolveReference(const utRelocate* other) { + for (s32 i = 0; i < m_hdr.nImports; i++) { + const char* importName = getImportName(i, m_hdr.nImports); + if (importName) { + void* addr = reinterpret_cast(other->getPublicAddress(importName)); + if (!addr) { + OSReport("utRelocate: not found symbol! ->[%s] \n", importName); + } + locateExtern(importName, addr); + } + } +}