From 4fbb3366f23e53f415d28d62993cc05953b4574e Mon Sep 17 00:00:00 2001 From: 2gifts Date: Fri, 25 Sep 2026 21:52:37 -0400 Subject: [PATCH] Match nw4r math_arithmetic Co-Authored-By: Claude Opus 5.5 --- config/RSBE01_02/splits.txt | 5 + config/RSBE01_02/symbols.txt | 24 +- configure.py | 1 + src/nw4r/math/math_arithmetic.cpp | 350 ++++++++++++++++++++++++++++++ 4 files changed, 368 insertions(+), 12 deletions(-) create mode 100644 src/nw4r/math/math_arithmetic.cpp diff --git a/config/RSBE01_02/splits.txt b/config/RSBE01_02/splits.txt index afd89c83d..a430b5d29 100644 --- a/config/RSBE01_02/splits.txt +++ b/config/RSBE01_02/splits.txt @@ -337,6 +337,11 @@ sora/st/st_data_container_multi.cpp: sora/st/st_data_container_magic.cpp: .sdata start:0x8059E860 end:0x8059E864 +nw4r/math/math_arithmetic.cpp: + .text start:0x80162188 end:0x801622C4 + .data start:0x80464828 end:0x80465138 + .sdata2 start:0x805A2BF0 end:0x805A2C10 + Runtime.PPCEABI.H/__init_cpp_exceptions.cpp: .text start:0x803F1A08 end:0x803F1A78 .ctors start:0x804064E0 end:0x804064E4 rename:.ctors$10 diff --git a/config/RSBE01_02/symbols.txt b/config/RSBE01_02/symbols.txt index fedea1b01..3c99ecaa8 100644 --- a/config/RSBE01_02/symbols.txt +++ b/config/RSBE01_02/symbols.txt @@ -6684,9 +6684,9 @@ fn_80160E3C = .text:0x80160E3C; // type:function size:0x120 fn_80160F5C = .text:0x80160F5C; // type:function size:0xA5C fn_801619B8 = .text:0x801619B8; // type:function size:0x74C fn_80162104 = .text:0x80162104; // type:function size:0x84 -fn_80162188 = .text:0x80162188; // type:function size:0x8C -fn_80162214 = .text:0x80162214; // type:function size:0x8C -fn_801622A0 = .text:0x801622A0; // type:function size:0x24 +FExp__Q34nw4r4math6detailFf = .text:0x80162188; // type:function size:0x8C +FLog__Q34nw4r4math6detailFf = .text:0x80162214; // type:function size:0x8C +FrSqrt__Q24nw4r4mathFf = .text:0x801622A0; // type:function size:0x24 fn_801622C4 = .text:0x801622C4; // type:function size:0x68 fn_8016232C = .text:0x8016232C; // type:function size:0x58 fn_80162384 = .text:0x80162384; // type:function size:0x6C @@ -26258,8 +26258,8 @@ lbl_80464710 = .data:0x80464710; // type:object size:0x58 lbl_80464768 = .data:0x80464768; // type:object size:0x10 data:4byte lbl_80464778 = .data:0x80464778; // type:object size:0x58 lbl_804647D0 = .data:0x804647D0; // type:object size:0x58 -lbl_80464828 = .data:0x80464828; // type:object size:0x108 -lbl_80464930 = .data:0x80464930; // type:object size:0x808 +expTable__Q34nw4r4math6detail = .data:0x80464828; // type:object size:0x108 scope:local +logTable__Q34nw4r4math6detail = .data:0x80464930; // type:object size:0x808 scope:local lbl_80465138 = .data:0x80465138; // type:object size:0x108 lbl_80465240 = .data:0x80465240; // type:object size:0x18 lbl_80465258 = .data:0x80465258; // type:object size:0x20 @@ -32998,13 +32998,13 @@ lbl_805A2BD8 = .sdata2:0x805A2BD8; // type:object size:0x4 align:4 data:float lbl_805A2BDC = .sdata2:0x805A2BDC; // type:object size:0x4 align:4 data:float lbl_805A2BE0 = .sdata2:0x805A2BE0; // type:object size:0x8 align:8 data:double lbl_805A2BE8 = .sdata2:0x805A2BE8; // type:object size:0x8 align:4 data:float -lbl_805A2BF0 = .sdata2:0x805A2BF0; // type:object size:0x4 align:4 data:float -lbl_805A2BF4 = .sdata2:0x805A2BF4; // type:object size:0x4 align:4 data:float -lbl_805A2BF8 = .sdata2:0x805A2BF8; // type:object size:0x4 align:4 data:float -lbl_805A2BFC = .sdata2:0x805A2BFC; // type:object size:0x4 align:4 data:float -lbl_805A2C00 = .sdata2:0x805A2C00; // type:object size:0x4 align:4 data:float -lbl_805A2C04 = .sdata2:0x805A2C04; // type:object size:0x4 align:4 data:float -lbl_805A2C08 = .sdata2:0x805A2C08; // type:object size:0x8 align:4 data:float +@716 = .sdata2:0x805A2BF0; // type:object size:0x4 align:4 data:float scope:local +@717 = .sdata2:0x805A2BF4; // type:object size:0x4 align:4 data:float scope:local +@718 = .sdata2:0x805A2BF8; // type:object size:0x4 align:4 data:float scope:local +@738 = .sdata2:0x805A2BFC; // type:object size:0x4 align:4 data:float scope:local +@739 = .sdata2:0x805A2C00; // type:object size:0x4 align:4 data:float scope:local +@741 = .sdata2:0x805A2C04; // type:object size:0x4 align:4 data:float scope:local +@742 = .sdata2:0x805A2C08; // type:object size:0x4 align:4 data:float scope:local lbl_805A2C10 = .sdata2:0x805A2C10; // type:object size:0x4 align:4 data:float lbl_805A2C14 = .sdata2:0x805A2C14; // type:object size:0x4 align:4 data:float lbl_805A2C18 = .sdata2:0x805A2C18; // type:object size:0x4 align:4 data:float diff --git a/configure.py b/configure.py index d44984a5b..a881cbbba 100755 --- a/configure.py +++ b/configure.py @@ -361,6 +361,7 @@ def MatchingFor(*versions): Object(Matching, "sora/st/st_data_container.cpp"), Object(Matching, "sora/st/st_data_container_multi.cpp"), Object(Matching, "sora/st/st_data_container_magic.cpp"), + Object(Matching, "nw4r/math/math_arithmetic.cpp", extra_cflags=["-RTTI off"]), ], }, # Common REL units diff --git a/src/nw4r/math/math_arithmetic.cpp b/src/nw4r/math/math_arithmetic.cpp new file mode 100644 index 000000000..f9de31ddd --- /dev/null +++ b/src/nw4r/math/math_arithmetic.cpp @@ -0,0 +1,350 @@ +#include + +namespace nw4r { +namespace math { +namespace detail { + +struct InterpolationEntry { // Name unknown + f32 unk00; + f32 unk04; +}; + +static InterpolationEntry expTable[33] = { // Name unknown + { 0.5f, 0.0221368913f }, + { 0.522136867f, 0.0231169742f }, + { 0.545253873f, 0.0241404511f }, + { 0.56939429f, 0.0252092406f }, + { 0.594603539f, 0.0263253488f }, + { 0.620928884f, 0.027490871f }, + { 0.648419797f, 0.028707996f }, + { 0.677127779f, 0.0299790073f }, + { 0.707106769f, 0.0313062929f }, + { 0.738413095f, 0.0326923393f }, + { 0.771105409f, 0.0341397524f }, + { 0.805245161f, 0.0356512479f }, + { 0.840896428f, 0.0372296646f }, + { 0.878126085f, 0.038877964f }, + { 0.917004049f, 0.0405992381f }, + { 0.957603276f, 0.0423967205f }, + { 1.0f, 0.0442737825f }, + { 1.04427373f, 0.0462339483f }, + { 1.09050775f, 0.0482809022f }, + { 1.13878858f, 0.0504184812f }, + { 1.18920708f, 0.0526506975f }, + { 1.24185777f, 0.0549817421f }, + { 1.29683959f, 0.057415992f }, + { 1.35425556f, 0.0599580146f }, + { 1.41421354f, 0.0626125857f }, + { 1.47682619f, 0.0653846785f }, + { 1.54221082f, 0.0682795048f }, + { 1.61049032f, 0.0713024959f }, + { 1.68179286f, 0.0744593292f }, + { 1.75625217f, 0.077755928f }, + { 1.8340081f, 0.0811984763f }, + { 1.91520655f, 0.084793441f }, + { 2.0f, 0.088547565f }, +}; + +static InterpolationEntry logTable[257] = { // Name unknown + { 0.0f, 0.00389863993f }, + { 0.00389863993f, 0.00388349988f }, + { 0.00778213982f, 0.00386847695f }, + { 0.0116506172f, 0.00385356904f }, + { 0.015504187f, 0.00383877591f }, + { 0.0193429627f, 0.00382409594f }, + { 0.0231670588f, 0.00380952796f }, + { 0.0269765873f, 0.00379507104f }, + { 0.0307716597f, 0.00378072308f }, + { 0.0345523804f, 0.00376648293f }, + { 0.038318865f, 0.00375235011f }, + { 0.0420712158f, 0.00373832206f }, + { 0.0458095372f, 0.00372439902f }, + { 0.0495339334f, 0.00371057889f }, + { 0.0532445163f, 0.00369686191f }, + { 0.0569413751f, 0.00368324504f }, + { 0.0606246218f, 0.00366972899f }, + { 0.0642943531f, 0.00365631096f }, + { 0.0679506585f, 0.00364299095f }, + { 0.0715936497f, 0.00362976803f }, + { 0.0752234235f, 0.00361664011f }, + { 0.078840062f, 0.00360360811f }, + { 0.0824436694f, 0.00359066809f }, + { 0.0860343352f, 0.00357782096f }, + { 0.0896121562f, 0.00356506603f }, + { 0.0931772217f, 0.0035524019f }, + { 0.0967296287f, 0.00353982695f }, + { 0.100269452f, 0.00352734094f }, + { 0.103796795f, 0.00351494201f }, + { 0.107311733f, 0.00350263109f }, + { 0.110814363f, 0.00349040492f }, + { 0.114304774f, 0.00347826397f }, + { 0.117783032f, 0.003466208f }, + { 0.121249244f, 0.00345423492f }, + { 0.124703482f, 0.00344234402f }, + { 0.128145829f, 0.00343053509f }, + { 0.131576359f, 0.00341880694f }, + { 0.134995162f, 0.00340715796f }, + { 0.138402328f, 0.00339558907f }, + { 0.141797915f, 0.00338409794f }, + { 0.145182014f, 0.00337268389f }, + { 0.148554698f, 0.00336134806f }, + { 0.151916042f, 0.00335008698f }, + { 0.155266136f, 0.00333890109f }, + { 0.158605024f, 0.00332778995f }, + { 0.161932826f, 0.00331675308f }, + { 0.165249571f, 0.00330578792f }, + { 0.168555364f, 0.0032948961f }, + { 0.171850264f, 0.00328407506f }, + { 0.175134331f, 0.00327332504f }, + { 0.178407654f, 0.00326264603f }, + { 0.181670308f, 0.00325203501f }, + { 0.184922338f, 0.00324149407f }, + { 0.188163832f, 0.00323102111f }, + { 0.191394851f, 0.00322061498f }, + { 0.194615468f, 0.0032102759f }, + { 0.197825745f, 0.00320000295f }, + { 0.201025739f, 0.00318979495f }, + { 0.204215541f, 0.00317965308f }, + { 0.207395196f, 0.00316957501f }, + { 0.210564762f, 0.00315956003f }, + { 0.21372433f, 0.00314960908f }, + { 0.216873944f, 0.00313972007f }, + { 0.220013663f, 0.00312989298f }, + { 0.223143548f, 0.0031201269f }, + { 0.226263672f, 0.00311042205f }, + { 0.229374096f, 0.00310077798f }, + { 0.232474878f, 0.00309119304f }, + { 0.235566065f, 0.003081667f }, + { 0.238647744f, 0.00307219895f }, + { 0.241719931f, 0.00306279003f }, + { 0.244782731f, 0.00305343699f }, + { 0.247836158f, 0.00304414192f }, + { 0.250880301f, 0.0030349039f }, + { 0.25391522f, 0.00302572106f }, + { 0.256940931f, 0.0030165941f }, + { 0.259957522f, 0.00300752092f }, + { 0.262965053f, 0.00299850293f }, + { 0.265963554f, 0.00298953895f }, + { 0.268953085f, 0.00298062805f }, + { 0.271933705f, 0.00297177001f }, + { 0.274905473f, 0.00296296505f }, + { 0.27786845f, 0.00295421202f }, + { 0.280822664f, 0.00294550997f }, + { 0.283768177f, 0.00293686008f }, + { 0.286705047f, 0.00292826002f }, + { 0.289633304f, 0.00291971001f }, + { 0.292553008f, 0.00291121006f }, + { 0.295464218f, 0.00290275994f }, + { 0.298366964f, 0.00289435801f }, + { 0.301261336f, 0.00288600498f }, + { 0.304147333f, 0.00287769991f }, + { 0.307025045f, 0.00286944211f }, + { 0.309894472f, 0.00286123203f }, + { 0.312755704f, 0.00285306899f }, + { 0.31560877f, 0.00284495205f }, + { 0.318453729f, 0.00283688097f }, + { 0.321290612f, 0.002828856f }, + { 0.324119478f, 0.00282087596f }, + { 0.326940358f, 0.00281294109f }, + { 0.32975328f, 0.00280505093f }, + { 0.332558334f, 0.002797205f }, + { 0.33535555f, 0.00278940191f }, + { 0.338144958f, 0.00278164307f }, + { 0.340926588f, 0.00277392706f }, + { 0.343700528f, 0.00276625296f }, + { 0.34646678f, 0.00275862194f }, + { 0.349225402f, 0.00275103305f }, + { 0.351976424f, 0.00274348608f }, + { 0.354719907f, 0.00273598009f }, + { 0.357455879f, 0.00272851507f }, + { 0.360184401f, 0.0027210901f }, + { 0.362905502f, 0.00271370611f }, + { 0.365619212f, 0.00270636193f }, + { 0.368325561f, 0.00269905711f }, + { 0.371024609f, 0.00269179209f }, + { 0.373716414f, 0.00268456503f }, + { 0.376400977f, 0.00267737801f }, + { 0.379078358f, 0.00267022895f }, + { 0.381748587f, 0.0026631169f }, + { 0.384411693f, 0.00265604397f }, + { 0.387067735f, 0.00264900806f }, + { 0.389716744f, 0.00264200894f }, + { 0.39235875f, 0.002635048f }, + { 0.394993812f, 0.00262812199f }, + { 0.39762193f, 0.002621233f }, + { 0.400243163f, 0.00261438102f }, + { 0.402857542f, 0.00260756304f }, + { 0.405465096f, 0.00260078209f }, + { 0.408065885f, 0.00259403489f }, + { 0.410659939f, 0.00258732401f }, + { 0.413247257f, 0.00258064689f }, + { 0.4158279f, 0.002574004f }, + { 0.418401897f, 0.00256739603f }, + { 0.420969307f, 0.0025608209f }, + { 0.423530102f, 0.00255427998f }, + { 0.426084399f, 0.0025477719f }, + { 0.42863217f, 0.00254129712f }, + { 0.431173474f, 0.00253485609f }, + { 0.43370831f, 0.00252844603f }, + { 0.436236769f, 0.00252206903f }, + { 0.43875885f, 0.00251572509f }, + { 0.441274554f, 0.00250941189f }, + { 0.443783969f, 0.00250312989f }, + { 0.446287096f, 0.00249688001f }, + { 0.448783994f, 0.00249066111f }, + { 0.451274633f, 0.00248447293f }, + { 0.453759104f, 0.00247831596f }, + { 0.456237435f, 0.00247218902f }, + { 0.458709627f, 0.00246609189f }, + { 0.46117571f, 0.00246002595f }, + { 0.463635743f, 0.00245398888f }, + { 0.466089725f, 0.00244798209f }, + { 0.468537718f, 0.00244200393f }, + { 0.47097972f, 0.0024360551f }, + { 0.473415762f, 0.00243013492f }, + { 0.475845903f, 0.00242424407f }, + { 0.478270143f, 0.00241838093f }, + { 0.480688542f, 0.00241254596f }, + { 0.48310107f, 0.0024067401f }, + { 0.485507816f, 0.00240096194f }, + { 0.487908781f, 0.00239521102f }, + { 0.490303993f, 0.00238948711f }, + { 0.492693484f, 0.00238379091f }, + { 0.495077252f, 0.00237812195f }, + { 0.497455388f, 0.00237248f }, + { 0.499827862f, 0.00236686505f }, + { 0.502194762f, 0.00236127595f }, + { 0.504556f, 0.0023557141f }, + { 0.506911695f, 0.00235017692f }, + { 0.509261906f, 0.00234466698f }, + { 0.511606574f, 0.00233918196f }, + { 0.513945758f, 0.00233372301f }, + { 0.516279459f, 0.00232828991f }, + { 0.518607736f, 0.00232288102f }, + { 0.520930648f, 0.00231749797f }, + { 0.523248136f, 0.00231214007f }, + { 0.52556026f, 0.00230680592f }, + { 0.527867079f, 0.00230149692f }, + { 0.530168593f, 0.0022962119f }, + { 0.532464802f, 0.00229095202f }, + { 0.534755766f, 0.00228571496f }, + { 0.537041485f, 0.00228050305f }, + { 0.539321959f, 0.00227531395f }, + { 0.541597307f, 0.00227014907f }, + { 0.543867409f, 0.002265007f }, + { 0.546132445f, 0.00225988799f }, + { 0.548392355f, 0.00225479202f }, + { 0.55064714f, 0.00224972004f }, + { 0.552896857f, 0.00224466994f }, + { 0.555141509f, 0.0022396429f }, + { 0.557381153f, 0.00223463797f }, + { 0.559615791f, 0.00222965493f }, + { 0.561845422f, 0.00222469494f }, + { 0.564070165f, 0.00221975707f }, + { 0.566289902f, 0.00221483991f }, + { 0.568504751f, 0.00220994605f }, + { 0.570714653f, 0.0022050729f }, + { 0.572919726f, 0.00220022094f }, + { 0.575119972f, 0.00219539111f }, + { 0.57731539f, 0.00219058106f }, + { 0.57950592f, 0.0021857929f }, + { 0.581691742f, 0.00218102592f }, + { 0.583872795f, 0.00217627897f }, + { 0.58604902f, 0.0021715539f }, + { 0.588220596f, 0.00216684793f }, + { 0.590387464f, 0.00216216291f }, + { 0.592549622f, 0.00215749792f }, + { 0.594707131f, 0.00215285295f }, + { 0.596859932f, 0.00214822893f }, + { 0.599008203f, 0.00214362401f }, + { 0.601151824f, 0.00213903794f }, + { 0.603290856f, 0.00213447306f }, + { 0.605425298f, 0.00212992611f }, + { 0.60755527f, 0.00212539895f }, + { 0.609680653f, 0.00212089205f }, + { 0.611801565f, 0.00211640308f }, + { 0.613917947f, 0.00211193296f }, + { 0.616029859f, 0.00210748194f }, + { 0.61813736f, 0.00210305001f }, + { 0.62024039f, 0.00209863693f }, + { 0.62233907f, 0.00209424202f }, + { 0.624433279f, 0.00208986504f }, + { 0.626523137f, 0.00208550598f }, + { 0.628608644f, 0.00208116602f }, + { 0.6306898f, 0.00207684399f }, + { 0.632766664f, 0.00207254011f }, + { 0.634839237f, 0.002068253f }, + { 0.636907458f, 0.00206398405f }, + { 0.638971448f, 0.00205973303f }, + { 0.641031206f, 0.002055499f }, + { 0.643086672f, 0.00205128291f }, + { 0.645137966f, 0.00204708404f }, + { 0.647185028f, 0.00204290194f }, + { 0.649227977f, 0.00203873706f }, + { 0.651266694f, 0.00203458895f }, + { 0.653301299f, 0.00203045807f }, + { 0.655331731f, 0.00202634302f }, + { 0.65735805f, 0.00202224497f }, + { 0.659380317f, 0.00201816391f }, + { 0.66139847f, 0.00201409892f }, + { 0.663412571f, 0.00201005093f }, + { 0.665422618f, 0.002006019f }, + { 0.667428672f, 0.0020020029f }, + { 0.669430673f, 0.00199800311f }, + { 0.67142868f, 0.00199401891f }, + { 0.673422694f, 0.00199005008f }, + { 0.675412714f, 0.00198609801f }, + { 0.677398801f, 0.00198216108f }, + { 0.679381013f, 0.00197823998f }, + { 0.681359231f, 0.00197433401f }, + { 0.683333576f, 0.00197044411f }, + { 0.685303986f, 0.00196656911f }, + { 0.687270582f, 0.00196270901f }, + { 0.689233303f, 0.00195886404f }, + { 0.69119215f, 0.00195503491f }, + { 0.693147182f, 0.00195121998f }, +}; + +f32 FExp(f32 x) { + s16 exponent = F32ToS16(x * (1.0f / NW4R_MATH_LN_2)); + f32 remainder = x - NW4R_MATH_LN_2 * S16ToF32(exponent); + f32 position = (NW4R_MATH_LN_2 + remainder) * (16.0f / NW4R_MATH_LN_2); + u16 index = F32ToU16(position); + f32 fraction = position - U16ToF32(index); + f32 value = expTable[index].unk00 + fraction * expTable[index].unk04; + u32 bits = F32AsU32(value) + (static_cast(exponent) << 23); + return U32AsF32(bits & 0x7FFFFFFF); +} + +f32 FLog(f32 x) { + s16 exponent = FGetExpPart(x); + f32 mantissa = FGetMantPart(x); + f32 exponentValue = S16ToF32(exponent); + f32 position = 256.0f * (mantissa - 1.0f); + u16 index = F32ToU16(position); + f32 fraction = position - U16ToF32(index); + f32 logarithm = logTable[index].unk00 + fraction * logTable[index].unk04; + return logarithm + NW4R_MATH_LN_2 * exponentValue; +} + +} // namespace detail + +f32 FrSqrt(register f32 x) { + register f32 estimate; + asm { + frsqrte estimate, x + } + register f32 half = 0.5f; + register f32 three = 3.0f; + register f32 squared; + asm { + fmuls squared, estimate, estimate + fmuls estimate, estimate, half + fnmsubs squared, squared, x, three + fmuls estimate, squared, estimate + } + return estimate; +} + +} // namespace math +} // namespace nw4r