diff options
Diffstat (limited to 'include/JSystem/JMath')
| -rw-r--r-- | include/JSystem/JMath/JMATrigonometric.h | 136 | ||||
| -rw-r--r-- | include/JSystem/JMath/JMath.h | 263 | ||||
| -rw-r--r-- | include/JSystem/JMath/random.h | 51 |
3 files changed, 450 insertions, 0 deletions
diff --git a/include/JSystem/JMath/JMATrigonometric.h b/include/JSystem/JMath/JMATrigonometric.h new file mode 100644 index 00000000..2b162c56 --- /dev/null +++ b/include/JSystem/JMath/JMATrigonometric.h @@ -0,0 +1,136 @@ +#ifndef JMATRIGONOMETRIC_H +#define JMATRIGONOMETRIC_H + +#include "dolphin/types.h" +#include "utility.h" + +template<typename T> +struct TAngleConstant_; + +/** + * @ingroup jsystem-jmath + * + */ +template<> +struct TAngleConstant_<f32> { + static f32 RADIAN_DEG090() { return 1.5707964f; } + static f32 RADIAN_DEG180() { return 3.1415927f; } + static f32 RADIAN_DEG360() { return 6.2831855f; } + static f32 RADIAN_TO_DEGREE_FACTOR() { return 180.0f / RADIAN_DEG180(); } +}; + +/** + * @ingroup jsystem-jmath + * + */ +template<int N, typename T> +struct TSinCosTable { + std::pair<T, T> table[1 << N]; + + T sinShort(s16 v) const { return table[(u16)v >> (16U - N)].first; } + T cosShort(s16 v) const { return table[(u16)v >> (16U - N)].second; } + + inline T sinLap(T v) { + if (v < (T)0.0) { + return -table[(u16)(-(T)(1 << N) * v) & ((1 << N) - 1)].first; + } + return table[(u16)((T)(1 << N) * v) & ((1 << N) - 1)].first; + } + + inline T sinDegree(T degree) { + if (degree < (T)0.0) { + return -table[(u16)(-((T)(1 << N) / (T)360.0) * degree) & ((1 << N) - 1)].first; + } + return table[(u16)(((T)(1 << N) / (T)360.0) * degree) & ((1 << N) - 1)].first; + } + + inline T cosDegree(T degree) { + if (degree < (T)0.0) { + degree = -degree; + } + return table[(u16)(((T)(1 << N) / (T)360.0) * degree) & ((1 << N) - 1)].second; + } + + inline T sinRadian(T radian) { + if (radian < (T)0.0) { + return -table[(u16)(-(T)(1 << N) / TAngleConstant_<T>::RADIAN_DEG360() * radian) & ((1 << N) - 1)].first; + } + return table[(u16)((T)(1 << N) / TAngleConstant_<T>::RADIAN_DEG360() * radian) & ((1 << N) - 1)].first; + } +}; + +/** + * @ingroup jsystem-jmath + * + */ +struct TAtanTable { + f32 table[1025]; + u8 pad[0x1C]; +}; + +/** + * @ingroup jsystem-jmath + * + */ +struct TAsinAcosTable { + f32 table[1025]; + u8 pad[0x1C]; + + f32 acos_(f32 x) { + if (x >= 1.0f) { + return 0.0f; + } else if (x <= -1.0f) { + return TAngleConstant_<f32>::RADIAN_DEG180(); + } else if (x < 0.0f) { + return table[(u32)(-x * 1023.5f)] + TAngleConstant_<f32>::RADIAN_DEG090(); + } else { + return TAngleConstant_<f32>::RADIAN_DEG090() - table[(u32)(x * 1023.5f)]; + } + } + + f32 acosDegree(f32 x) { + return acos_(x) * TAngleConstant_<f32>::RADIAN_TO_DEGREE_FACTOR(); + } +}; + +namespace JMath { +extern TSinCosTable<13, f32> sincosTable_; +extern TAtanTable atanTable_; +extern TAsinAcosTable asinAcosTable_; + +inline f32 acosDegree(f32 x) { + return asinAcosTable_.acosDegree(x); +} +}; // namespace JMath + +inline f32 JMASCosShort(s16 v) { + return JMath::sincosTable_.cosShort(v); +} +inline f32 JMASinShort(s16 v) { + return JMath::sincosTable_.sinShort(v); +} + +inline f32 JMASCos(s16 v) { + return JMASCosShort(v); +} +inline f32 JMASSin(s16 v) { + return JMASinShort(v); +} + +inline f32 JMASinLap(f32 v) { + return JMath::sincosTable_.sinLap(v); +} + +inline f32 JMASinDegree(f32 degree) { + return JMath::sincosTable_.sinDegree(degree); +} + +inline f32 JMACosDegree(f32 degree) { + return JMath::sincosTable_.cosDegree(degree); +} + +inline f32 JMASinRadian(f32 radian) { + return JMath::sincosTable_.sinRadian(radian); +} + +#endif /* JMATRIGONOMETRIC_H */ diff --git a/include/JSystem/JMath/JMath.h b/include/JSystem/JMath/JMath.h new file mode 100644 index 00000000..eb7932e8 --- /dev/null +++ b/include/JSystem/JMath/JMath.h @@ -0,0 +1,263 @@ +#ifndef JMATH_H +#define JMATH_H + +#include "dolphin/mtx.h" +#include "math.h" + +void JMAMTXApplyScale(const Mtx, Mtx, f32, f32, f32); +void JMAEulerToQuat(s16 param_0, s16 param_1, s16 param_2, Quaternion* param_3); +void JMAQuatLerp(const Quaternion*, const Quaternion*, f32, Quaternion*); +void JMAFastVECNormalize(register const Vec* src, register Vec* dst); +void JMAVECScaleAdd(register const Vec* vec1, register const Vec* vec2, register Vec* dst, + register f32 scale); + +inline int JMAAbs(int value) { + return __abs(value); +} + +inline f32 JMAFastReciprocal(f32 value) { + return __fres(value); +} + +inline float __frsqrtes(register double f) { + register float out; + // clang-format off +#ifdef __MWERKS__ + asm { + frsqrte out, f + } +#endif + // clang-format on + return out; +} + +inline f32 JMAFastSqrt(register f32 input) { + if (input > 0.0f) { + register f32 out; +#ifdef __MWERKS__ + asm { + frsqrte out, input + } +#endif + return out * input; + } else { + return input; + } +} + +inline f32 JMAHermiteInterpolation(register f32 p1, register f32 p2, register f32 p3, + register f32 p4, register f32 p5, register f32 p6, + register f32 p7) { + register f32 ff25; + register f32 ff31; + register f32 ff30; + register f32 ff29; + register f32 ff28; + register f32 ff27; + register f32 ff26; + // clang-format off +#ifdef __MWERKS__ + asm { + fsubs ff31, p1, p2 + fsubs ff30, p5, p2 + fdivs ff29, ff31, ff30 + fmuls ff28,ff29,ff29 + fadds ff25,ff29,ff29 + fsubs ff27,ff28,ff29 + fsubs ff30, p3, p6 + fmsubs ff26,ff25,ff27,ff28 + fmadds ff25,p4,ff27,p4 + fmadds ff26,ff26,ff30,p3 + fmadds ff25,p7,ff27,ff25 + fmsubs ff25,ff29,p4,ff25 + fnmsubs ff25,ff31,ff25,ff26 + + } +#endif + // clang-format on + return ff25; +} + +namespace JMath { + +inline f32 fastReciprocal(f32 value) { + return JMAFastReciprocal(value); +} + +inline void gekko_ps_copy3(register void* dst, register const void* src) { + register f32 src0; + register f32 src1; +#ifdef __MWERKS__ + asm { + psq_l src0, 0(src), 0, 0 + lfs src1, 8(src) + psq_st src0, 0(dst), 0, 0 + stfs src1, 8(dst) + }; +#endif +} + +inline void gekko_ps_copy6(register void* dst, register const void* src) { + register f32 src0; + register f32 src1; + register f32 src2; +#ifdef __MWERKS__ + asm { + psq_l src0, 0(src), 0, 0 + psq_l src1, 8(src), 0, 0 + psq_l src2, 16(src), 0, 0 + psq_st src0, 0(dst), 0, 0 + psq_st src1, 8(dst), 0, 0 + psq_st src2, 16(dst), 0, 0 + }; +#endif +} + +inline void gekko_ps_copy12(register void* dst, register const void* src) { + register f32 src0; + register f32 src1; + register f32 src2; + register f32 src3; + register f32 src4; + register f32 src5; +#ifdef __MWERKS__ + asm { + psq_l src0, 0(src), 0, 0 + psq_l src1, 8(src), 0, 0 + psq_l src2, 16(src), 0, 0 + psq_l src3, 24(src), 0, 0 + psq_l src4, 32(src), 0, 0 + psq_l src5, 40(src), 0, 0 + psq_st src0, 0(dst), 0, 0 + psq_st src1, 8(dst), 0, 0 + psq_st src2, 16(dst), 0, 0 + psq_st src3, 24(dst), 0, 0 + psq_st src4, 32(dst), 0, 0 + psq_st src5, 40(dst), 0, 0 + }; +#endif +} + +inline void gekko_ps_copy16(register void* dst, register const void* src) { + register f32 src0; + register f32 src1; + register f32 src2; + register f32 src3; + register f32 src4; + register f32 src5; + register f32 src6; + register f32 src7; +#ifdef __MWERKS__ + asm { + psq_l src0, 0(src), 0, 0 + psq_l src1, 8(src), 0, 0 + psq_l src2, 16(src), 0, 0 + psq_l src3, 24(src), 0, 0 + psq_l src4, 32(src), 0, 0 + psq_l src5, 40(src), 0, 0 + psq_l src6, 48(src), 0, 0 + psq_l src7, 56(src), 0, 0 + psq_st src0, 0(dst), 0, 0 + psq_st src1, 8(dst), 0, 0 + psq_st src2, 16(dst), 0, 0 + psq_st src3, 24(dst), 0, 0 + psq_st src4, 32(dst), 0, 0 + psq_st src5, 40(dst), 0, 0 + psq_st src6, 48(dst), 0, 0 + psq_st src7, 56(dst), 0, 0 + }; +#endif +} + +}; // namespace JMath + +namespace JMathInlineVEC { + inline void C_VECAdd(register const Vec* a, register const Vec* b, register Vec* ab) { + register f32 axy; + register f32 bxy; + register f32 az; + register f32 sumz; + register f32 bz; + #ifdef __MWERKS__ + asm { + psq_l axy, 0(a), 0, 0 + psq_l bxy, 0(b), 0, 0 + ps_add bxy, axy, bxy + psq_st bxy, 0(ab), 0, 0 + psq_l az, 8(a), 1, 0 + psq_l bz, 8(b), 1, 0 + ps_add sumz, az, bz + psq_st sumz, 8(ab), 1, 0 + } + #endif + } + + inline void C_VECSubtract(register const Vec* a, register const Vec* b, register Vec* ab) { + register f32 axy; + register f32 bxy; + register f32 az; + register f32 subz; + register f32 bz; + #ifdef __MWERKS__ + asm { + psq_l axy, 0(a), 0, 0 + psq_l bxy, 0(b), 0, 0 + ps_sub bxy, axy, bxy + psq_st bxy, 0(ab), 0, 0 + psq_l az, 8(a), 1, 0 + psq_l bz, 8(b), 1, 0 + ps_sub subz, az, bz + psq_st subz, 8(ab), 1, 0 + } + #endif + } + + inline f32 C_VECSquareMag(register const Vec* v) { + register f32 x_y; + register f32 z; + register f32 res; + #ifdef __MWERKS__ + asm { + psq_l x_y, 0(v), 0, 0 + ps_mul x_y, x_y, x_y + lfs z, 8(v) + ps_madd res, z, z, x_y + ps_sum0 res, res, x_y, x_y + } + #endif + return res; + } + + inline f32 C_VECDotProduct(register const Vec *a, register const Vec *b) { + register f32 res; + register f32 thisyz; + register f32 otheryz; + register f32 otherxy; + register f32 thisxy; +#ifdef __MWERKS__ + asm { + psq_l thisyz, 4(a), 0, 0 + psq_l otheryz, 4(b), 0, 0 + ps_mul thisyz, thisyz, otheryz + psq_l thisxy, 0(a), 0, 0 + psq_l otherxy, 0(b), 0, 0 + ps_madd otheryz, thisxy, otherxy, thisyz + ps_sum0 res, otheryz, thisyz, thisyz + }; +#endif + return res; + } +}; + +template<typename T> +inline T JMAMax(T param_0, T param_1) { + T ret; + if (param_0 > param_1) { + ret = param_0; + } else { + ret = param_1; + } + return ret; +} + +#endif /* JMATH_H */ diff --git a/include/JSystem/JMath/random.h b/include/JSystem/JMath/random.h new file mode 100644 index 00000000..cfb8ecc1 --- /dev/null +++ b/include/JSystem/JMath/random.h @@ -0,0 +1,51 @@ +#ifndef RANDOM_H +#define RANDOM_H + +#include "dolphin/types.h" + +namespace JMath { + +/** + * @ingroup jsystem-jmath + * + */ +struct TRandom_fast_ { + u32 value; + + TRandom_fast_(u32 value); + u32 get(void) { + value = (value * 0x19660d) + 0x3c6ef35f; + return value; + } + + u32 get_bit32(void) { return this->get(); } + + // due to the float constant, having this function inlined adds that float to data, + // making it not match + float get_ufloat_1(void) { + // !@bug UB: in C++ it's not legal to read from an union member other + // than the last one that was written to. + union { + f32 f; + u32 s; + } out; + out.s = (this->get() >> 9) | 0x3f800000; + return out.f - 1; + } + + void setSeed(u32 seed) { value = seed; } +}; + +template <class RandomT> +class TRandom_ : public RandomT { +public: + TRandom_(u32 value) : RandomT(value) {} + + u8 get_uint8(u8 param_0) { + return get_ufloat_1() * param_0; + } +}; + +} // namespace JMath + +#endif /* RANDOM_H */ |
