summaryrefslogtreecommitdiff
path: root/include/JSystem/JMath
diff options
context:
space:
mode:
Diffstat (limited to 'include/JSystem/JMath')
-rw-r--r--include/JSystem/JMath/JMATrigonometric.h136
-rw-r--r--include/JSystem/JMath/JMath.h263
-rw-r--r--include/JSystem/JMath/random.h51
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 */