diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 90cb6779..f0c6a0d3 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -360,6 +360,7 @@ toBeSorted/area_math.cpp: toBeSorted/deg_angle_util.cpp: .text start:0x80067280 end:0x80067B14 align:16 + .sdata2 start:0x805779B0 end:0x805779E8 d/d_reset.cpp: .text start:0x80067B20 end:0x80068FD0 align:16 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 3edde39f..8910b507 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -2906,26 +2906,26 @@ __ct__7mVec2_cFv = .text:0x80067280; // type:function size:0x4 fn_80067290 = .text:0x80067290; // type:function size:0xA8 fn_80067340 = .text:0x80067340; // type:function size:0xC0 fn_80067400 = .text:0x80067400; // type:function size:0x80 -fn_80067480 = .text:0x80067480; // type:function size:0x38 -fn_800674C0 = .text:0x800674C0; // type:function size:0x3C -fn_80067500 = .text:0x80067500; // type:function size:0x10 -fn_80067510 = .text:0x80067510; // type:function size:0x3C -fn_80067550 = .text:0x80067550; // type:function size:0x18 -fn_80067570 = .text:0x80067570; // type:function size:0x28 -fn_800675A0 = .text:0x800675A0; // type:function size:0x28 -fn_800675D0 = .text:0x800675D0; // type:function size:0x88 -fn_80067660 = .text:0x80067660; // type:function size:0x4 -fn_80067670 = .text:0x80067670; // type:function size:0x10 -fn_80067680 = .text:0x80067680; // type:function size:0x24 -fn_800676B0 = .text:0x800676B0; // type:function size:0x3C -fn_800676F0 = .text:0x800676F0; // type:function size:0x3C -fn_80067730 = .text:0x80067730; // type:function size:0xF8 -fn_80067830 = .text:0x80067830; // type:function size:0x58 -fn_80067890 = .text:0x80067890; // type:function size:0x120 -fn_800679B0 = .text:0x800679B0; // type:function size:0xB0 -fn_80067A60 = .text:0x80067A60; // type:function size:0x34 -fn_80067AA0 = .text:0x80067AA0; // type:function size:0x3C -fn_80067AE0 = .text:0x80067AE0; // type:function size:0x34 +adjust__7dDegreeFf = .text:0x80067480; // type:function size:0x38 +canonicalize__7dDegreeFf = .text:0x800674C0; // type:function size:0x3C +rotate180F__7dDegreeCFv = .text:0x80067500; // type:function size:0x10 +rotate180__7dDegreeFv = .text:0x80067510; // type:function size:0x3C +abs__7dDegreeCFv = .text:0x80067550; // type:function size:0x18 +sin__7dDegreeCFv = .text:0x80067570; // type:function size:0x28 +cos__7dDegreeCFv = .text:0x800675A0; // type:function size:0x28 +tan__7dDegreeCFv = .text:0x800675D0; // type:function size:0x88 +tan2__7dDegreeCFv = .text:0x80067660; // type:function size:0x4 +toRad__7dDegreeCFv = .text:0x80067670; // type:function size:0x10 +toIdx__7dDegreeFv = .text:0x80067680; // type:function size:0x24 +__ct__6dPolarFfff = .text:0x800676B0; // type:function size:0x3C +__ct__6dPolarFRC7mVec3_c = .text:0x800676F0; // type:function size:0x3C +canonicalize__6dPolarFv = .text:0x80067730; // type:function size:0xF8 +Set__6dPolarFfff = .text:0x80067830; // type:function size:0x58 +setCartesian__6dPolarFRC7mVec3_c = .text:0x80067890; // type:function size:0x120 +toCartesian__6dPolarCFv = .text:0x800679B0; // type:function size:0xB0 +SetR__6dPolarFf = .text:0x80067A60; // type:function size:0x34 +SetU__6dPolarFf = .text:0x80067AA0; // type:function size:0x3C +SetV__6dPolarFf = .text:0x80067AE0; // type:function size:0x34 CreateInstance__Q26dReset8Manage_cFPQ23EGG4Heap = .text:0x80067B20; // type:function size:0x4C GetInstance__Q26dReset8Manage_cFv = .text:0x80067B70; // type:function size:0x8 __ct__Q26dReset8Manage_cFPQ23EGG4Heap = .text:0x80067B80; // type:function size:0x84 @@ -17289,7 +17289,7 @@ clear__9cListMg_cFv = .text:0x802E0A10; // type:function size:0x40 cM__rad2s = .text:0x802E0A50; // type:function size:0x5C cM__U_GetAtanTable = .text:0x802E0AB0; // type:function size:0x34 atan2s__2cMFff = .text:0x802E0AF0; // type:function size:0x1BC -cM__atan2f = .text:0x802E0CB0; // type:function size:0x48 +atan2f__2cMFff = .text:0x802E0CB0; // type:function size:0x48 cM__initRnd = .text:0x802E0D00; // type:function size:0x8 rnd__2cMFv = .text:0x802E0D10; // type:function size:0x8 rndInt__2cMFi = .text:0x802E0D20; // type:function size:0x58 diff --git a/include/c/c_math.h b/include/c/c_math.h index ba284408..914eff24 100644 --- a/include/c/c_math.h +++ b/include/c/c_math.h @@ -8,6 +8,8 @@ namespace cM { s16 atan2s(f32, f32); +f32 atan2f(f32, f32); + void initRnd(s32); f32 rnd(); int rndInt(int max); diff --git a/include/m/m_angle.h b/include/m/m_angle.h index ab5e1997..393a047a 100644 --- a/include/m/m_angle.h +++ b/include/m/m_angle.h @@ -98,8 +98,12 @@ struct mAng { return rad * sRadToAng; } - static f32 ang2deg_c(f32 rad) { - return rad * sAngToDeg; + static f32 ang2deg_c(f32 ang) { + return ang * sAngToDeg; + } + + static f32 rad2deg_c(f32 rad) { + return rad * sRadToDeg; } static f32 rad2deg(f32 rad) { @@ -124,6 +128,10 @@ struct mAng { return rad * (65536.0f / (2.f * M_PI)); } + static f32 deg2rad_c(f32 deg) { + return deg * sDegToRad; + } + s16 mVal; private: diff --git a/include/toBeSorted/deg_angle_util.h b/include/toBeSorted/deg_angle_util.h new file mode 100644 index 00000000..cb2406a6 --- /dev/null +++ b/include/toBeSorted/deg_angle_util.h @@ -0,0 +1,65 @@ +#ifndef TOBESORTED_DEG_ANGLE_UTIL_H +#define TOBESORTED_DEG_ANGLE_UTIL_H + +#include "common.h" +#include "m/m_vec.h" + +struct dDegree { +public: + /** Wraps a degree angle so that value is within [-180.0f; 180.0f] */ + static f32 adjust(f32 value); + /** Canonicalizes a degree angle so that value is within [-180.0f; 180.0f) */ + static f32 canonicalize(f32 value); + + f32 rotate180F() const; + void rotate180(); + f32 abs() const; + + f32 sin() const; + f32 cos() const; + f32 tan() const; + f32 tan2() const; + f32 toRad() const; + s16 toIdx(); // can't be const... + + void Set(f32 v) { + value = adjust(v); + } + + f32 operator-(const dDegree &other) const { + return value - other.value; + } + + f32 operator+(const dDegree &other) const { + return value + other.value; + } + + dDegree() : value(0.0f) {} + dDegree(f32 value) : value(adjust(value)) {} + dDegree(const dDegree &other) : value(other.value) {} + + /* 0x0 */ f32 value; +}; + +struct dPolar { +public: + dPolar(f32 r, f32 u, f32 v); + dPolar(const mVec3_c &v); + + dPolar *canonicalize(); + + void Set(f32 r, f32 u, f32 v); + + void setCartesian(const mVec3_c &v); + mVec3_c toCartesian() const; + + f32 SetR(f32 r); + f32 SetU(f32 u); + f32 SetV(f32 v); + + /* 0x0 */ f32 R; + /* 0x4 */ dDegree U; + /* 0x8 */ dDegree V; +}; + +#endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h index 31411d2c..0ec47d8b 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h @@ -90,6 +90,9 @@ extern inline float sqrtf(float x) { return x; } +#if 1 +double sqrt(double); +#else extern inline double sqrt(double x) { if (x > 0.0) { double guess = __frsqrte(x); /* returns an approximation to */ @@ -106,6 +109,7 @@ extern inline double sqrt(double x) { return HUGE_VALF; } +#endif inline float atan2f(float y, float x) { return (float)atan2(y, x); diff --git a/src/toBeSorted/deg_angle_util.cpp b/src/toBeSorted/deg_angle_util.cpp new file mode 100644 index 00000000..4bad9213 --- /dev/null +++ b/src/toBeSorted/deg_angle_util.cpp @@ -0,0 +1,157 @@ +#include "toBeSorted/deg_angle_util.h" + +#include "c/c_math.h" +#include "common.h" +#include "m/m_angle.h" +#include "m/m_vec.h" +#include "math.h" + +#include + +f32 dDegree::adjust(f32 value) { + while (value < -180.0f) { + value += 360.0f; + } + + while (value > 180.0f) { + value -= 360.0f; + } + + return value; +} + +f32 dDegree::canonicalize(f32 value) { + while (value < -180.0f) { + value += 360.0f; + } + + while (value >= 180.0f) { + value -= 360.0f; + } + + return value; +} + +f32 dDegree::rotate180F() const { + return adjust(value + 180.0f); +} + +void dDegree::rotate180() { + value = adjust(value + 180.0f); +} + +f32 dDegree::abs() const { + f32 v = value; + if (v < 0.0f) { + v = -v; + } + return v; +} + +f32 dDegree::sin() const { + return std::sinf(toRad()); +} + +f32 dDegree::cos() const { + return std::cosf(toRad()); +} + +f32 dDegree::tan() const { + f32 c = cos(); + f32 s = sin(); + if (cM::isZero(c)) { + return s > 0.0f ? INFINITY : -INFINITY; + } + return s / c; +} + +f32 dDegree::tan2() const { + return tan(); +} + +f32 dDegree::toRad() const { + return mAng::deg2rad_c(value); +} + +s16 dDegree::toIdx() { + return mAng::fromDeg(value); +} + +dPolar::dPolar(f32 r, f32 u, f32 v) { + Set(r, u, v); +} + +dPolar::dPolar(const mVec3_c &v) { + setCartesian(v); +} + +dPolar *dPolar::canonicalize() { + // NONMATCHING - redundant stack copies + if (R < 0.0f) { + R = -R; + + U.Set(-U.value); + V.Set(V.rotate180F()); + } + + if (U.value < -90.0f) { + U.Set(U.value + 180.0f); + V.Set(V.rotate180F()); + } else if (U.value > 90.0f) { + U.Set(U - 180.0f); + V.Set(V.rotate180F()); + } + return this; +} + +void dPolar::Set(f32 r, f32 u, f32 v) { + R = r; + U.Set(u); + V.Set(v); + canonicalize(); +} + +void dPolar::setCartesian(const mVec3_c &v) { + f32 x = v.x; + f32 y = v.y; + f32 z = v.z; + + f64 magXZSq = (f64)(z * z) + (f64)(x * x); + f64 magSq = magXZSq + (f64)(y * y); + + f32 magXZ = (magXZSq > 0.0) ? (f32)sqrt(magXZSq) : 0.f; + R = (magSq > 0.0) ? (f32)sqrt(magSq) : 0.f; + U.Set(mAng::rad2deg_c(M_PI / 2 - cM::atan2f(magXZ, y))); + V.Set(mAng::rad2deg_c(cM::atan2f(x, z))); + canonicalize(); +} + +mVec3_c dPolar::toCartesian() const { + f32 cosU = U.cos(); + f32 sinU = U.sin(); + f32 cosV = V.cos(); + f32 sinV = V.sin(); + + f32 x = sinV * (R * cosU); + f32 z = cosV * (R * cosU); + f32 y = R * sinU; + + return mVec3_c(x, y, z); +} + +f32 dPolar::SetR(f32 r) { + R = r; + canonicalize(); + return R; +} + +f32 dPolar::SetU(f32 u) { + U.Set(u); + canonicalize(); + return U.value; +} + +f32 dPolar::SetV(f32 v) { + V.Set(v); + return V.value; +}