diff --git a/config/RSBE01_02/splits.txt b/config/RSBE01_02/splits.txt index 65ed5bbbf..c1a7b8325 100644 --- a/config/RSBE01_02/splits.txt +++ b/config/RSBE01_02/splits.txt @@ -147,6 +147,10 @@ sora/mt/mt_prng.cpp: .sbss start:0x805A00B8 end:0x805A00C0 .sdata2 start:0x805A1748 end:0x805A176C +sora/mt/mt_trig.cpp: + .text start:0x8003FD5C end:0x8003FFC4 + .sdata2 start:0x805A1770 end:0x805A179C + sora/mt/mt_prng_log.cpp: .text start:0x8004392C end:0x80043B18 .ctors start:0x80406514 end:0x80406518 diff --git a/config/RSBE01_02/symbols.txt b/config/RSBE01_02/symbols.txt index 6ccc07256..a99b26f69 100644 --- a/config/RSBE01_02/symbols.txt +++ b/config/RSBE01_02/symbols.txt @@ -31850,7 +31850,7 @@ lbl_805A1780 = .sdata2:0x805A1780; // type:object size:0x4 align:4 data:float lbl_805A1784 = .sdata2:0x805A1784; // type:object size:0x4 align:4 data:float lbl_805A1788 = .sdata2:0x805A1788; // type:object size:0x4 align:4 data:float lbl_805A1790 = .sdata2:0x805A1790; // type:object size:0x8 align:8 data:double -lbl_805A1798 = .sdata2:0x805A1798; // type:object size:0x8 align:4 data:float +lbl_805A1798 = .sdata2:0x805A1798; // type:object size:0x4 align:4 data:float lbl_805A17A0 = .sdata2:0x805A17A0; // type:object size:0x8 align:4 data:float lbl_805A17A8 = .sdata2:0x805A17A8; // type:object size:0x4 align:4 data:float lbl_805A17AC = .sdata2:0x805A17AC; // type:object size:0x4 align:4 data:float diff --git a/configure.py b/configure.py index 0e13ceba8..f45733120 100755 --- a/configure.py +++ b/configure.py @@ -198,7 +198,7 @@ "-maxerrors 1", "-nosyspath", "-RTTI off", - "-fp_contract on", + "-fp_contract off", "-str reuse", "-enc SJIS", "-i include", @@ -320,6 +320,7 @@ def MatchingFor(*versions): Object(Matching, "sora/gf/gf_resource_loader.cpp"), Object(NonMatching, "sora/mt/mt_vector_old.cpp"), Object(Matching, "sora/mt/mt_prng.cpp", extra_cflags=["-RTTI off"]), + Object(NonMatching, "sora/mt/mt_trig.cpp"), Object(Matching, "sora/mt/mt_prng_log.cpp"), Object(Matching, "sora/st/module.cpp"), Object(Matching, "sora/ut/ut_nw.cpp"), diff --git a/src/sora/mt/mt_trig.cpp b/src/sora/mt/mt_trig.cpp new file mode 100644 index 000000000..fc8921119 --- /dev/null +++ b/src/sora/mt/mt_trig.cpp @@ -0,0 +1,64 @@ +#include + +// pi/2 +#define HALF_PI 1.5707964f +// 2^24 / (2*pi) +#define RAD_TO_FIXED_PT 2670176.8f +// (2*pi) / 2^24 +#define FIXED_PT_TO_RAD 3.7450704e-7f + +// Quarter-turn and reduce range to [0, 2^24) +static inline s32 reduceRange(s32 fixedPtAngle) { + return (fixedPtAngle + 0x400000) & 0x00FFFFFF; +} + +// Fit to range [-2^22, 2^22), i.e. [-pi/2, pi/2) +static inline s32 fitToRange(s32 theta) { + if (theta > 0x800000) + theta = 0x1000000 - theta; + theta -= 0x400000; + + return theta; +} + +// 9th order Taylor polynomial approximation of sin(x) +static inline float taylor(float x) { + const float C1 = 1.0f; // 1 + const float C2 = -0.16666657f; // -1/3! + const float C3 = 0.0083330255f; // 1/5! + const float C4 = -0.00019807414f; // -1/7! + const float C5 = 0.000002601887f; // 1/9! + return x * (C1 + ((x * x) * (C2 + ((x * x) * (C3 + ((x * x) * (C4 + (C5 * (x * x))))))))); +} + +float mtSinf(float angle) { + return taylor(FIXED_PT_TO_RAD * fitToRange(reduceRange((RAD_TO_FIXED_PT * angle)))); +} + +float mtCosf(float angle) { + return mtSinf(angle + HALF_PI); +} + +// NONMATCHING regswaps - should simply interleave calls to mtCosf and mtSinf +void mtSinCosf(float rad, float* sinOut, float* cosOut) { + s32 s0 = RAD_TO_FIXED_PT * rad; + s32 c0 = RAD_TO_FIXED_PT * (rad + HALF_PI); + + s32 s1 = reduceRange(s0); + s32 c1 = reduceRange(c0); + + s32 c2 = fitToRange(s1); + s32 s2 = fitToRange(c1); + + float s3 = s2; + float c3 = c2; + + float c4 = FIXED_PT_TO_RAD * c3; + float s4 = FIXED_PT_TO_RAD * s3; + + float s5 = taylor(s4); + float c5 = taylor(c4); + + *sinOut = s5; + *cosOut = c5; +}