diff options
| author | robojumper <robojumper@gmail.com> | 2025-04-27 07:13:47 +0200 |
|---|---|---|
| committer | robojumper <robojumper@gmail.com> | 2025-04-27 07:13:47 +0200 |
| commit | c1a0264e6ac151f3a884bc32126de192eede19c7 (patch) | |
| tree | 1649757ae5c7b47b87f17ef69760b4a359a8d46d /include | |
| parent | 5df26c52fcc06e017f2cf525264d4f7563715e05 (diff) | |
Initial import of JParticle + JSUList from TP
Diffstat (limited to 'include')
27 files changed, 3080 insertions, 0 deletions
diff --git a/include/JSystem/JGeometry.h b/include/JSystem/JGeometry.h new file mode 100644 index 00000000..5ae2e827 --- /dev/null +++ b/include/JSystem/JGeometry.h @@ -0,0 +1,508 @@ +#ifndef JGEOMETRY_H +#define JGEOMETRY_H + +#include "dolphin/mtx.h" +#include "math.h" +#include "JSystem/JMath/JMath.h" + +namespace JGeometry { + +template<typename T> +struct TUtil { + static inline T clamp(T v, T min, T max) { + if (v < min) { + return min; + } + if (v > max) { + return max; + } + return v; + } +}; + +template<> +struct TUtil<f32> { + static inline f32 clamp(f32 v, f32 min, f32 max) { + if (v < min) { + return min; + } + if (v > max) { + return max; + } + return v; + } + static inline f32 epsilon() { return 32.0f * FLT_EPSILON; } + static inline f32 PI() { return 3.1415927f; } + static inline f32 inv_sqrt(f32 x) { + if (x <= 0.0f) { + return x; + } + f32 root = __frsqrte(x); + root = 0.5f * root * (3.0f - x * (root * root)); + return root; + } +}; + +template<> +struct TUtil<double> { + static inline double epsilon() { return 32.0f * FLT_EPSILON; } + static inline double one() { return 1.0; } + static inline double atan2(double x, double y) { return ::atan2(x, y); } + static inline double asin(double x) { return ::asin(x); } + static inline double halfPI() { return 1.5707963267948966; } +}; + +template <typename T> +struct TVec3 { + T x; + T y; + T z; + + void set(const TVec3& other) { + x = other.x; + y = other.y; + z = other.z; + } +}; + +template <> +struct TVec3<double> { + double x, y, z; + + void set(double x_, double y_, double z_) { + x = x_; + y = y_; + z = z_; + } + + inline TVec3<double>& operator*=(double b) { + scale(b); + return *this; + } + + void scale(double b) { + x *= b; + y *= b; + z *= b; + } +}; + +template <> +struct TVec3<s16> { + s16 x, y, z; + + TVec3() {} + + TVec3(s16 x, s16 y, s16 z) { + set(x, y, z); + } + + TVec3& operator=(const TVec3& b) { + // Force copies to use lwz/lha + *((s32*)this) = *((s32*)&b); + z = b.z; + return *this; + } + + void set(s16 x_, s16 y_, s16 z_) { + x = x_; + y = y_; + z = z_; + } +}; + +inline void setTVec3f(const f32* vec_a, f32* vec_b) { + const register f32* v_a = vec_a; + register f32* v_b = vec_b; + + register f32 a_x; + register f32 b_x; + +#ifdef __MWERKS__ + asm { + psq_l a_x, 0(v_a), 0, 0 + lfs b_x, 8(v_a) + psq_st a_x, 0(v_b), 0, 0 + stfs b_x, 8(v_b) + }; +#endif +} + +// Until we figure out TVec3 ctors +inline void setTVec3f(const Vec& vec_a, Vec& vec_b) { + setTVec3f(&vec_a.x, &vec_b.x); +} + +inline float fsqrt_step(float mag) { + f32 root = __frsqrte(mag); + return 0.5f * root * (3.0f - mag * (root * root)); +} + +inline void mulInternal(register const f32* a, register const f32* b, register float* dst) { + register f32 a_x_y; + register f32 b_x_y; + register f32 x_y; + register f32 za; + register f32 zb; + register f32 z; +#ifdef __MWERKS__ + asm { + psq_l a_x_y, 0(a), 0, 0 + psq_l b_x_y, 0(b), 0, 0 + ps_mul x_y, a_x_y, b_x_y + psq_st x_y, 0(dst), 0, 0 + }; + dst[2] = a[2] * b[2]; +#endif +} + +template <> +struct TVec3<f32> : public Vec { + inline TVec3(const Vec& i_vec) { + setTVec3f(&i_vec.x, &x); + } + + inline TVec3(const TVec3<f32>& i_vec) { + setTVec3f(&i_vec.x, &x); + } + + template<class U> + TVec3(U x, U y, U z) { + set(x, y, z); + } + + TVec3() {} + + operator Vec*() { return (Vec*)&x; } + operator const Vec*() const { return (Vec*)&x; } + + template<class U> + void set(const TVec3<U>& other) { + x = other.x; + y = other.y; + z = other.z; + } + + void set(const Vec& other) { + x = other.x; + y = other.y; + z = other.z; + } + + template<class U> + void set(U x_, U y_, U z_) { + x = x_; + y = y_; + z = z_; + } + + inline void add(const TVec3<f32>& b) { + JMathInlineVEC::C_VECAdd((Vec*)&x, (Vec*)&b.x, (Vec*)&x); + } + + void zero() { x = y = z = 0.0f; } + + void mul(const TVec3<f32>& a, const TVec3<f32>& b) { + mulInternal(&a.x, &b.x, &this->x); + } + + inline void mul(const TVec3<f32>& a) { + mul(*this, a); + } + + inline TVec3<f32>& operator=(const Vec& b) { + setTVec3f(&b.x, &this->x); + return *this; + } + + inline TVec3<f32>& operator=(const TVec3<f32>& b) { + set(b.x, b.y, b.z); + return *this; + } + + inline TVec3<f32>& operator+=(const TVec3<f32>& b) { + add(b); + return *this; + } + + inline TVec3<f32> operator+(const TVec3<f32>& b) { + TVec3<f32> a = *this; + a += b; + return a; + } + + // inline TVec3<f32> operator+(const TVec3<f32>& b) { + // TVec3<f32> res(*(Vec*)this); + // res += b; + // return res; + // } + + f32 squared() const { + return JMathInlineVEC::C_VECSquareMag((Vec*)&x); + } + + f32 normalize() { + f32 sq = squared(); + if (sq <= TUtil<f32>::epsilon()) { + return 0.0f; + } + f32 inv_norm = TUtil<f32>::inv_sqrt(sq); + scale(inv_norm); + return inv_norm * sq; + } + + void normalize(const TVec3<f32>& other) { + f32 sq = other.squared(); + if (sq <= TUtil<f32>::epsilon()) { + zero(); + return; + } + f32 norm; + if (sq <= 0.0f) { + norm = sq; + } else { + norm = fsqrt_step(sq); + } + scale(norm, other); + } + + f32 length() const { + return VECMag((Vec*)this); + } + + void scale(register f32 sc) { + register f32 z; + register f32 x_y; + register f32* dst = &x; + register f32 zres; +#ifdef __MWERKS__ + asm { + psq_l x_y, 0(dst), 0, 0 + psq_l z, 8(dst), 1, 0 + ps_muls0 x_y, x_y, sc + psq_st x_y, 0(dst), 0, 0 + ps_muls0 zres, z, sc + psq_st zres, 8(dst), 1, 0 + }; +#endif + } + + void scale(register f32 sc, const TVec3<f32>& other) { + register const f32* src = &other.x; + register f32 z; + register f32 x_y; + register f32* dst = &x; + register f32 zres; +#ifdef __MWERKS__ + asm { + psq_l x_y, 0(src), 0, 0 + psq_l z, 8(src), 1, 0 + ps_muls0 x_y, x_y, sc + psq_st x_y, 0(dst), 0, 0 + ps_muls0 zres, z, sc + psq_st zres, 8(dst), 1, 0 + }; +#endif + } + + void scaleAdd(register f32 sc, const TVec3<f32>& a, const TVec3<f32>& b) { + JMAVECScaleAdd(&a, &b, this, sc); + } + + void negateInternal(TVec3<f32>* dst) { + register f32* rdst = &dst->x; + const register f32* src = &x; + register f32 x_y; + register f32 z; +#ifdef __MWERKS__ + asm { + psq_l x_y, 0(src), 0, 0 + ps_neg x_y, x_y + psq_st x_y, 0(rdst), 0, 0 + lfs z, 8(src) + fneg z, z + stfs z, 8(rdst) + }; +#endif + } + + void negate() { + negateInternal(this); + } + + void sub(const TVec3<f32>& b) { + JMathInlineVEC::C_VECSubtract((Vec*)&x, (Vec*)&b.x, (Vec*)&x); + } + + void sub(const TVec3<f32>& a, const TVec3<f32>& b) { + JMathInlineVEC::C_VECSubtract((Vec*)&a.x, (Vec*)&b.x, (Vec*)&x); + } + + bool isZero() const { + return squared() <= TUtil<f32>::epsilon(); + } + + void cross(const TVec3<f32>& a, const TVec3<f32>& b) { + VECCrossProduct(a, b, *this); + } + + f32 setLength(f32 len) { + f32 sq = squared(); + if (sq <= TUtil<f32>::epsilon()) { + return 0.0f; + } + f32 inv_norm = TUtil<f32>::inv_sqrt(sq); + scale(inv_norm * len); + return inv_norm * sq; + } + + f32 setLength(const TVec3<f32>& other, f32 len) { + f32 sq = other.squared(); + if (sq <= TUtil<f32>::epsilon()) { + zero(); + return 0.0f; + } + f32 inv_norm = TUtil<f32>::inv_sqrt(sq); + scale(inv_norm * len, other); + return inv_norm * sq; + } + + f32 dot(const TVec3<f32>& other) const { + return JMathInlineVEC::C_VECDotProduct(this, &other); + } + + void cubic(const TVec3<f32>& param_1, const TVec3<f32>& param_2, const TVec3<f32>& param_3, + const TVec3<f32>& param_4, f32 param_5) { + f32 fVar5 = param_5 * param_5; + f32 fVar6 = fVar5 * param_5; + f32 fVar8 = 1.0f + (2.0f * fVar6 - 3.0f * fVar5); + f32 fVar9 = -2.0f * fVar6 + 3.0f * fVar5; + f32 fVar7 = param_5 + (fVar6 - 2.0f * fVar5); + f32 fVar4 = fVar6 - fVar5; + x = fVar8 * param_1.x + fVar9 * param_4.x + fVar7 * param_2.x + fVar4 * param_3.x; + y = fVar8 * param_1.y + fVar9 * param_4.y + fVar7 * param_2.y + fVar4 * param_3.y; + z = fVar8 * param_1.z + fVar9 * param_4.z + fVar7 * param_2.z + fVar4 * param_3.z; + } +}; + +template <typename T> +struct TVec2 { + TVec2() {} + TVec2(T v) { set(v); } + TVec2(T x, T y) { set(x, y); } + + void set(T v) { y = x = v; } + + void set(T x, T y) { + this->x = x; + this->y = y; + } + + void set(const TVec2& other) { + x = other.x; + y = other.y; + } + + void setMin(const TVec2<f32>& min) { + if (x >= min.x) + x = min.x; + if (y >= min.y) + y = min.y; + } + + void setMax(const TVec2<f32>& max) { + if (x <= max.x) + x = max.x; + if (y <= max.y) + y = max.y; + } + + void add(const TVec2<T>& other) { + x += other.x; + y += other.y; + } + + bool isAbove(const TVec2<T>& other) const { + return (x >= other.x) && (y >= other.y) ? true : false; + } + + f32 dot(const TVec2<T>& other) const { + return x * other.x + y * other.y; + } + + f32 squared() const { + return dot(*this); + } + + f32 length() const { + f32 sqr = squared(); + if (sqr <= 0.0f) { + return sqr; + } + sqr *= fsqrt_step(sqr); + return sqr; + } + + T x; + T y; +}; + +template <class T> +struct TBox { + TBox() : i(), f() {} + TBox(const TBox& other) : i(other.i), f(other.f) {} + + T i, f; +}; + +// clang-format off +template<> struct TBox<TVec2<f32> > { + f32 getWidth() const { return f.x - i.x; } + f32 getHeight() const { return f.y - i.y; } + + bool isValid() const { return f.isAbove(i); } + + void addPos(f32 x, f32 y) { + addPos(TVec2<f32>(x, y)); + } + + void addPos(const TVec2<f32>& pos) { + i.add(pos); + f.add(pos); + } + + bool intersect(const TBox<TVec2<f32> >& other) { + i.setMax(other.i); + f.setMin(other.f); + return isValid(); + } + + TVec2<f32> i, f; +}; + +template <typename T> +struct TBox2 : TBox<TVec2<T> > { + TBox2() {} + TBox2(const TVec2<f32>& i, const TVec2<f32>& f) { set(i, f); } + TBox2(f32 x0, f32 y0, f32 x1, f32 y1) { set(x0, y0, x1, y1); } + + void absolute() { + if (!this->isValid()) { + TBox2<T> box(*this); + this->i.setMin(box.i); + this->i.setMin(box.f); + this->f.setMax(box.i); + this->f.setMax(box.f); + } + } + + void set(const TBox2& other) { set(other.i, other.f); } + void set(const TVec2<f32>& i, const TVec2<f32>& f) { this->i.set(i), this->f.set(f); } + void set(f32 x0, f32 y0, f32 x1, f32 y1) { this->i.set(x0, y0); this->f.set(x1, y1); } +}; + +// clang-format on + +} // namespace JGeometry + +#endif 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 */ diff --git a/include/JSystem/JParticle/JPABaseShape.h b/include/JSystem/JParticle/JPABaseShape.h new file mode 100644 index 00000000..3ebff452 --- /dev/null +++ b/include/JSystem/JParticle/JPABaseShape.h @@ -0,0 +1,210 @@ +#ifndef JPABASESHAPE_H +#define JPABASESHAPE_H + +#include <dolphin/gx.h> + +class JPAEmitterWorkData; +class JPABaseParticle; +class JKRHeap; + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPABaseShapeData { + // Common header. + /* 0x00 */ u8 mMagic[4]; + /* 0x04 */ u32 mSize; + + /* 0x08 */ u32 mFlags; + /* 0x0C */ s16 mClrPrmAnmOffset; + /* 0x0E */ s16 mClrEnvAnmOffset; + /* 0x10 */ f32 mBaseSizeX; + /* 0x14 */ f32 mBaseSizeY; + /* 0x18 */ u16 mBlendModeCfg; + /* 0x1A */ u8 mAlphaCompareCfg; + /* 0x1B */ u8 mAlphaRef0; + /* 0x1C */ u8 mAlphaRef1; + /* 0x1D */ u8 mZModeCfg; + /* 0x1E */ u8 mTexFlg; + /* 0x1F */ u8 mTexAnmNum; + /* 0x20 */ u8 mTexIdx; + /* 0x21 */ u8 mClrFlg; + /* 0x22 */ u8 mClrPrmKeyNum; + /* 0x23 */ u8 mClrEnvKeyNum; + /* 0x24 */ s16 mClrAnmFrmMax; + /* 0x26 */ GXColor mClrPrm; + /* 0x2A */ GXColor mClrEnv; + /* 0x2E */ u8 mAnmRndm; + /* 0x2F */ u8 mClrAnmRndmMask; + /* 0x30 */ u8 mTexAnmRndmMask; +}; + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPABaseShape { +public: + /* 8027A6DC */ JPABaseShape(u8 const*, JKRHeap*); + /* 8027A7E8 */ void setGX(JPAEmitterWorkData*) const; + + static GXBlendMode st_bm[3]; + static GXBlendFactor st_bf[10]; + static GXLogicOp st_lo[16]; + static GXCompare st_c[8]; + static GXAlphaOp st_ao[4]; + static GXTevColorArg st_ca[6][4]; + static GXTevAlphaArg st_aa[2][4]; + + GXBlendMode getBlendMode() const { return st_bm[mpData->mBlendModeCfg & 0x03]; } + GXBlendFactor getBlendSrc() const { return st_bf[(mpData->mBlendModeCfg >> 2) & 0x0F]; } + GXBlendFactor getBlendDst() const { return st_bf[(mpData->mBlendModeCfg >> 6) & 0x0F]; } + GXLogicOp getLogicOp() const { return st_lo[(mpData->mBlendModeCfg >> 10) & 0x0F]; } + GXBool getZCompLoc() const { return (GXBool)((mpData->mZModeCfg >> 5) & 0x01); } + + GXBool getZEnable() const { return (GXBool)(mpData->mZModeCfg & 0x01); } + GXCompare getZCmp() const { return st_c[(mpData->mZModeCfg >> 1) & 0x07]; } + GXBool getZUpd() const { return (GXBool)((mpData->mZModeCfg >> 4) & 0x01); } + + GXCompare getAlphaCmp0() const { return st_c[mpData->mAlphaCompareCfg & 0x07]; } + u8 getAlphaRef0() const { return mpData->mAlphaRef0; } + GXAlphaOp getAlphaOp() const { return st_ao[(mpData->mAlphaCompareCfg >> 3) & 0x03]; } + GXCompare getAlphaCmp1() const { return st_c[(mpData->mAlphaCompareCfg >> 5) & 0x07]; } + u8 getAlphaRef1() const { return mpData->mAlphaRef1; } + + const GXTevColorArg* getTevColorArg() const { return st_ca[(mpData->mFlags >> 0x0F) & 0x07]; } + const GXTevAlphaArg* getTevAlphaArg() const { return st_aa[(mpData->mFlags >> 0x12) & 0x01]; } + + u32 getType() const { return (mpData->mFlags >> 0) & 0x0F; } + u32 getDirType() const { return (mpData->mFlags >> 4) & 0x07; } + u32 getRotType() const { return (mpData->mFlags >> 7) & 0x07; } + u32 getBasePlaneType() const { return (mpData->mFlags >> 10) & 0x01; } + u32 getTilingS() const { return (mpData->mFlags >> 25) & 0x01; } + u32 getTilingT() const { return (mpData->mFlags >> 26) & 0x01; } + BOOL isGlblClrAnm() const { return mpData->mFlags & 0x00001000; } + BOOL isGlblTexAnm() const { return mpData->mFlags & 0x00004000; } + BOOL isPrjTex() const { return mpData->mFlags & 0x00100000; } + bool isDrawFwdAhead() const { return !!(mpData->mFlags & 0x00200000); } + bool isDrawPrntAhead() const { return !!(mpData->mFlags & 0x00400000); } + bool isClipOn() const { return !!(mpData->mFlags & 0x00800000); } + BOOL isTexCrdAnm() const { return mpData->mFlags & 0x01000000; } + bool isNoDrawParent() const { return !!(mpData->mFlags & 0x08000000); } + bool isNoDrawChild() const { return !!(mpData->mFlags & 0x10000000); } + + BOOL isPrmAnm() const { return mpData->mClrFlg & 0x02; } + BOOL isEnvAnm() const { return mpData->mClrFlg & 0x08; } + u8 getClrAnmType() const { return (mpData->mClrFlg >> 4) & 0x07; } + s16 getClrAnmMaxFrm() const { return mpData->mClrAnmFrmMax; } + void getPrmClr(GXColor* dst) { *dst = mpData->mClrPrm; } + void getPrmClr(s16 idx, GXColor* dst) { *dst = mpPrmClrAnmTbl[idx]; } + void getEnvClr(GXColor* dst) { *dst = mpData->mClrEnv; } + void getEnvClr(s16 idx, GXColor* dst) { *dst = mpEnvClrAnmTbl[idx]; } + + BOOL isTexAnm() const { return mpData->mTexFlg & 0x01; } + u8 getTexAnmType() const { return (mpData->mTexFlg >> 2) & 0x07; } + u32 getTexIdx() const { return mpData->mTexIdx; } + u8 getTexIdx(u8 idx) const { return mpTexIdxAnimTbl[idx]; } + + f32 getBaseSizeX() const { return mpData->mBaseSizeX; } + f32 getBaseSizeY() const { return mpData->mBaseSizeY; } + u8 getClrLoopOfstMask() const { return mpData->mClrAnmRndmMask; } + u32 getClrLoopOfst(u32 param_1) const { return getClrLoopOfstMask() & param_1; } + u8 getTexLoopOfstMask() const { return mpData->mTexAnmRndmMask; } + u32 getTexLoopOfst(u8 param_1) const { return getTexLoopOfstMask() & param_1; } + u8 getLoopOfstValue() const { return mpData->mAnmRndm; } + + f32 getIncTransX() const { return ((f32*)mpTexCrdMtxAnmTbl)[5]; } + f32 getInitTransX() const { return ((f32*)mpTexCrdMtxAnmTbl)[0]; } + f32 getIncTransY() const { return ((f32*)mpTexCrdMtxAnmTbl)[6]; } + f32 getInitTransY() const { return ((f32*)mpTexCrdMtxAnmTbl)[1]; } + f32 getIncScaleX() const { return ((f32*)mpTexCrdMtxAnmTbl)[7]; } + f32 getInitScaleX() const { return ((f32*)mpTexCrdMtxAnmTbl)[2]; } + f32 getIncScaleY() const { return ((f32*)mpTexCrdMtxAnmTbl)[8]; } + f32 getInitScaleY() const { return ((f32*)mpTexCrdMtxAnmTbl)[3]; } + f32 getIncRot() const { return ((f32*)mpTexCrdMtxAnmTbl)[9]; } + f32 getInitRot() const { return ((f32*)mpTexCrdMtxAnmTbl)[4]; } + u8 getTexAnmKeyNum() const { return mpData->mTexAnmNum; } + +public: + /* 0x00 */ const JPABaseShapeData* mpData; + /* 0x04 */ const void* mpTexCrdMtxAnmTbl; + /* 0x08 */ const u8* mpTexIdxAnimTbl; + /* 0x0C */ GXColor* mpPrmClrAnmTbl; + /* 0x10 */ GXColor* mpEnvClrAnmTbl; +}; + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPAClrAnmKeyData { + /* 0x0 */ s16 index; + /* 0x2 */ GXColor color; +}; + +void JPACalcTexIdxNormal(JPAEmitterWorkData*); +void JPACalcTexIdxRepeat(JPAEmitterWorkData*); +void JPACalcTexIdxReverse(JPAEmitterWorkData*); +void JPACalcTexIdxMerge(JPAEmitterWorkData*); +void JPACalcTexIdxRandom(JPAEmitterWorkData*); +void JPACalcPrm(JPAEmitterWorkData*); +void JPACalcEnv(JPAEmitterWorkData*); +void JPACalcClrIdxNormal(JPAEmitterWorkData*); +void JPACalcClrIdxRepeat(JPAEmitterWorkData*); +void JPACalcClrIdxReverse(JPAEmitterWorkData*); +void JPACalcClrIdxMerge(JPAEmitterWorkData*); +void JPACalcClrIdxRandom(JPAEmitterWorkData*); + +void JPACalcTexIdxNormal(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcTexIdxRepeat(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcTexIdxReverse(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcTexIdxMerge(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcTexIdxRandom(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcPrm(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcEnv(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcClrIdxNormal(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcClrIdxRepeat(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcClrIdxReverse(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcClrIdxMerge(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcClrIdxRandom(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcColorCopy(JPAEmitterWorkData*, JPABaseParticle*); + +void JPADrawStripe(JPAEmitterWorkData*); +void JPADrawStripeX(JPAEmitterWorkData*); +void JPADrawEmitterCallBackB(JPAEmitterWorkData*); +void JPALoadTex(JPAEmitterWorkData*); +void JPALoadTexAnm(JPAEmitterWorkData*); +void JPAGenTexCrdMtxIdt(JPAEmitterWorkData*); +void JPAGenCalcTexCrdMtxAnm(JPAEmitterWorkData*); +void JPAGenTexCrdMtxAnm(JPAEmitterWorkData*); +void JPAGenTexCrdMtxPrj(JPAEmitterWorkData*); +void JPALoadPosMtxCam(JPAEmitterWorkData*); +void JPASetLineWidth(JPAEmitterWorkData*); +void JPASetPointSize(JPAEmitterWorkData*); +void JPARegistPrm(JPAEmitterWorkData*); +void JPARegistEnv(JPAEmitterWorkData*); +void JPARegistPrmEnv(JPAEmitterWorkData*); + +void JPADrawPoint(JPAEmitterWorkData*, JPABaseParticle*); +void JPADrawLine(JPAEmitterWorkData*, JPABaseParticle*); +void JPADrawRotBillboard(JPAEmitterWorkData*, JPABaseParticle*); +void JPADrawBillboard(JPAEmitterWorkData*, JPABaseParticle*); +void JPADrawRotDirection(JPAEmitterWorkData*, JPABaseParticle*); +void JPADrawDirection(JPAEmitterWorkData*, JPABaseParticle*); +void JPADrawRotation(JPAEmitterWorkData*, JPABaseParticle*); +void JPADrawDBillboard(JPAEmitterWorkData*, JPABaseParticle*); +void JPADrawRotYBillboard(JPAEmitterWorkData*, JPABaseParticle*); +void JPADrawYBillboard(JPAEmitterWorkData*, JPABaseParticle*); +void JPADrawParticleCallBack(JPAEmitterWorkData*, JPABaseParticle*); +void JPALoadTexAnm(JPAEmitterWorkData*, JPABaseParticle*); +void JPASetPointSize(JPAEmitterWorkData*, JPABaseParticle*); +void JPASetLineWidth(JPAEmitterWorkData*, JPABaseParticle*); +void JPALoadCalcTexCrdMtxAnm(JPAEmitterWorkData*, JPABaseParticle*); +void JPARegistAlpha(JPAEmitterWorkData*, JPABaseParticle*); +void JPARegistEnv(JPAEmitterWorkData*, JPABaseParticle*); +void JPARegistAlphaEnv(JPAEmitterWorkData*, JPABaseParticle*); +void JPARegistPrmAlpha(JPAEmitterWorkData*, JPABaseParticle*); +void JPARegistPrmAlphaEnv(JPAEmitterWorkData*, JPABaseParticle*); + +#endif /* JPABASESHAPE_H */ diff --git a/include/JSystem/JParticle/JPAChildShape.h b/include/JSystem/JParticle/JPAChildShape.h new file mode 100644 index 00000000..2761a567 --- /dev/null +++ b/include/JSystem/JParticle/JPAChildShape.h @@ -0,0 +1,89 @@ +#ifndef JPACHILDSHAPE_H +#define JPACHILDSHAPE_H + +#include <dolphin/gx.h> + +class JPAEmitterWorkData; +class JPABaseParticle; + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPAChildShapeData { + // Common header. + /* 0x00 */ u8 mMagic[4]; + /* 0x04 */ u32 mSize; + + /* 0x08 */ u32 mFlags; + /* 0x0C */ f32 mPosRndm; + /* 0x10 */ f32 mBaseVel; + /* 0x14 */ f32 mBaseVelRndm; + /* 0x18 */ f32 mVelInfRate; + /* 0x1C */ f32 mGravity; + /* 0x20 */ f32 mScaleX; + /* 0x24 */ f32 mScaleY; + /* 0x28 */ f32 mInheritScale; + /* 0x2C */ f32 mInheritAlpha; + /* 0x30 */ f32 mInheritRGB; + /* 0x34 */ GXColor mPrmClr; + /* 0x38 */ GXColor mEnvClr; + /* 0x3C */ f32 mTiming; + /* 0x40 */ s16 mLife; + /* 0x42 */ s16 mRate; + /* 0x44 */ u8 mStep; + /* 0x45 */ u8 mTexIdx; + /* 0x46 */ s16 mRotSpeed; +}; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPAChildShape { +public: + /* 8027B038 */ JPAChildShape(u8 const*); + + f32 getPosRndm() const { return mpData->mPosRndm; } + f32 getBaseVel() const { return mpData->mBaseVel; } + f32 getBaseVelRndm() const { return mpData->mBaseVelRndm; } + f32 getVelInhRate() const { return mpData->mVelInfRate; } + f32 getGravity() const { return mpData->mGravity; } + f32 getScaleX() const { return mpData->mScaleX; } + f32 getScaleY() const { return mpData->mScaleY; } + f32 getScaleInhRate() const { return mpData->mInheritScale; } + f32 getAlphaInhRate() const { return mpData->mInheritAlpha; } + f32 getColorInhRate() const { return mpData->mInheritRGB; } + void getPrmClr(GXColor* dst) const { *dst = mpData->mPrmClr; } + u8 getPrmAlpha() const { return mpData->mPrmClr.a; } + void getEnvClr(GXColor* dst) const { *dst = mpData->mEnvClr; } + f32 getTiming() const { return mpData->mTiming; } + s16 getLife() const { return mpData->mLife; } + s16 getRate() const { return mpData->mRate; } + u8 getStep() const { return mpData->mStep; } + u8 getTexIdx() const { return mpData->mTexIdx; } + s16 getRotInitSpeed() const { return mpData->mRotSpeed; } + u32 getType() const { return mpData->mFlags & 0xF; } + u32 getDirType() const { return (mpData->mFlags >> 4) & 7; } + u32 getRotType() const { return (mpData->mFlags >> 7) & 7; } + u32 getBasePlaneType() const { return (mpData->mFlags >> 10) & 1; } + + BOOL isScaleInherited() const { return mpData->mFlags & 0x10000; } + BOOL isAlphaInherited() const { return mpData->mFlags & 0x20000; } + BOOL isColorInherited() const { return mpData->mFlags & 0x40000; } + BOOL isClipOn() const { return mpData->mFlags & 0x100000; } + BOOL isFieldAffected() const { return mpData->mFlags & 0x200000; } + BOOL isScaleOutOn() const { return mpData->mFlags & 0x400000; } + BOOL isAlphaOutOn() const { return mpData->mFlags & 0x800000; } + BOOL isRotateOn() const { return mpData->mFlags & 0x1000000; } + +public: + /* 0x00 */ const JPAChildShapeData* mpData; +}; + +void JPARegistChildPrmEnv(JPAEmitterWorkData*); + +void JPACalcChildAlphaOut(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcChildScaleOut(JPAEmitterWorkData*, JPABaseParticle*); + +#endif /* JPACHILDSHAPE_H */ diff --git a/include/JSystem/JParticle/JPADrawInfo.h b/include/JSystem/JParticle/JPADrawInfo.h new file mode 100644 index 00000000..061783af --- /dev/null +++ b/include/JSystem/JParticle/JPADrawInfo.h @@ -0,0 +1,29 @@ +#ifndef JPADRAWINFO_H +#define JPADRAWINFO_H + +#include "dolphin/mtx.h" + +/** + * @ingroup jsystem-jparticle + * + */ +class JPADrawInfo { +public: + JPADrawInfo(Mtx param_0, f32 fovY, f32 aspect) { + MTXCopy(param_0, mCamMtx); + C_MTXLightPerspective(mPrjMtx, fovY, aspect, 0.5f, -0.5f, 0.5f, 0.5f); + } + + JPADrawInfo(Mtx param_0, f32 top, f32 bottom, f32 left, f32 right) { + MTXCopy(param_0, mCamMtx); + C_MTXLightOrtho(mPrjMtx, top, bottom, left, right, 0.5f, 0.5f, 0.5f, 0.5f); + } + + Mtx mCamMtx; + Mtx mPrjMtx; + + void getCamMtx(Mtx dst) const { MTXCopy(mCamMtx, dst); } + void getPrjMtx(Mtx dst) const { MTXCopy(mPrjMtx, dst); } +}; + +#endif diff --git a/include/JSystem/JParticle/JPADynamicsBlock.h b/include/JSystem/JParticle/JPADynamicsBlock.h new file mode 100644 index 00000000..fc175ff6 --- /dev/null +++ b/include/JSystem/JParticle/JPADynamicsBlock.h @@ -0,0 +1,109 @@ +#ifndef JPADYNAMICSBLOCK_H +#define JPADYNAMICSBLOCK_H + +#include "JSystem/JGeometry.h" + +#include "dolphin/types.h" + +class JPAEmitterWorkData; + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPADynamicsBlockData { + // Common header. + /* 0x00 */ u8 mMagic[4]; + /* 0x04 */ u32 mSize; + + /* 0x08 */ u32 mFlags; + /* 0x0C */ u32 mResUserWork; + /* 0x10 */ JGeometry::TVec3<f32> mEmitterScl; + /* 0x1C */ JGeometry::TVec3<f32> mEmitterTrs; + /* 0x28 */ JGeometry::TVec3<f32> mEmitterDir; + /* 0x34 */ f32 mInitialVelOmni; + /* 0x38 */ f32 mInitialVelAxis; + /* 0x3C */ f32 mInitialVelRndm; + /* 0x40 */ f32 mInitialVelDir; + /* 0x44 */ f32 mSpread; + /* 0x48 */ f32 mInitialVelRatio; + /* 0x4C */ f32 mRate; + /* 0x50 */ f32 mRateRndm; + /* 0x54 */ f32 mLifeTimeRndm; + /* 0x58 */ f32 mVolumeSweep; + /* 0x5C */ f32 mVolumeMinRad; + /* 0x60 */ f32 mAirResist; + /* 0x64 */ f32 mMoment; + /* 0x68 */ JGeometry::TVec3<s16> mEmitterRot; + /* 0x6E */ s16 mMaxFrame; + /* 0x70 */ s16 mStartFrame; + /* 0x72 */ s16 mLifeTime; + /* 0x74 */ u16 mVolumeSize; + /* 0x76 */ u16 mDivNumber; + /* 0x78 */ u8 mRateStep; + /* 0x7C */ u32 field_0x7c; +}; + +typedef void (*JPADynamicsCalcVolumeFunc)(JPAEmitterWorkData*); + +enum { + JPADynFlag_FixedDensity = 0x01, + JPADynFlag_FixedInterval = 0x02, + JPADynFlag_InheritScale = 0x04, + JPADynFlag_FollowEmtr = 0x08, + JPADynFlag_FollowEmtrChld = 0x10, +}; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPADynamicsBlock { +public: + /* 8027BB18 */ JPADynamicsBlock(u8 const*); + /* 8027BB4C */ void init(); + /* 8027BBE8 */ void create(JPAEmitterWorkData*); + + void calc(JPAEmitterWorkData* work) { mpCalcVolumeFunc(work); } + + s16 getStartFrame() const { return mpData->mStartFrame; } + u32 getResUserWork() const { return mpData->mResUserWork; } + u32 getFlag() const { return mpData->mFlags; } + u32 getVolumeType() const { return (mpData->mFlags >> 8) & 0x07; } + u16 getDivNumber() const { return mpData->mDivNumber; } + f32 getRateRndm() const { return mpData->mRateRndm; } + void getEmitterScl(JGeometry::TVec3<f32>* vec) const { + vec->set(mpData->mEmitterScl.x, mpData->mEmitterScl.y, mpData->mEmitterScl.z); + } + void getEmitterTrs(JGeometry::TVec3<f32>* vec) const { + vec->set(mpData->mEmitterTrs.x, mpData->mEmitterTrs.y, mpData->mEmitterTrs.z); + } + void getEmitterDir(JGeometry::TVec3<f32>* vec) const { + vec->set(mpData->mEmitterDir.x, mpData->mEmitterDir.y, mpData->mEmitterDir.z); + } + void getEmitterRot(JGeometry::TVec3<s16>* vec) const { + vec->set(mpData->mEmitterRot.x, mpData->mEmitterRot.y, mpData->mEmitterRot.z); + } + s16 getMaxFrame() { return mpData->mMaxFrame; } + s16 getLifetime() { return mpData->mLifeTime; } + u16 getVolumeSize() { return mpData->mVolumeSize; } + f32 getRate() { return mpData->mRate; } + u8 getRateStep() { return mpData->mRateStep; } + f32 getVolumeSweep() { return mpData->mVolumeSweep; } + f32 getVolumeMinRad() { return mpData->mVolumeMinRad; } + f32 getInitVelOmni() { return mpData->mInitialVelOmni; } + f32 getInitVelAxis() { return mpData->mInitialVelAxis; } + f32 getInitVelDir() { return mpData->mInitialVelDir; } + f32 getInitVelDirSp() { return mpData->mSpread; } + f32 getInitVelRndm() { return mpData->mInitialVelRndm; } + f32 getInitVelRatio() const { return mpData->mInitialVelRatio; } + f32 getAirRes() { return mpData->mAirResist; } + f32 getLifetimeRndm() const { return mpData->mLifeTimeRndm; } + f32 getMomentRndm() const { return mpData->mMoment; } + +public: + /* 0x00 */ const JPADynamicsBlockData* mpData; + /* 0x04 */ JPADynamicsCalcVolumeFunc mpCalcVolumeFunc; +}; + +#endif /* JPADYNAMICSBLOCK_H */ diff --git a/include/JSystem/JParticle/JPAEmitter.h b/include/JSystem/JParticle/JPAEmitter.h new file mode 100644 index 00000000..063b7c1f --- /dev/null +++ b/include/JSystem/JParticle/JPAEmitter.h @@ -0,0 +1,272 @@ +#ifndef JPAEMITTER_H +#define JPAEMITTER_H + +#include <dolphin/gx.h> +#include "JSystem/JParticle/JPAResource.h" +#include "JSystem/JParticle/JPAList.h" +#include "JSystem/JParticle/JPARandom.h" +#include "JSystem/JParticle/JPAMath.h" +#include "JSystem/JParticle/JPADynamicsBlock.h" +#include "JSystem/JSupport/JSUList.h" + +class JPAResourceManager; +class JPABaseEmitter; +class JPAEmitterManager; +class JPAParticleCallBack; + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPAEmitterWorkData { + struct JPAVolumeCalcData { + /* 0x00 */ JGeometry::TVec3<f32> mVolumePos; + /* 0x0C */ JGeometry::TVec3<f32> mVelOmni; + /* 0x18 */ JGeometry::TVec3<f32> mVelAxis; + }; + + JPAEmitterWorkData() : mRndm(0) {} + + /* 0x00 */ JPABaseEmitter* mpEmtr; + /* 0x04 */ JPAResource* mpRes; + /* 0x08 */ JPAResourceManager* mpResMgr; + /* 0x0C */ JPARandom mRndm; + /* 0x10 */ JPAVolumeCalcData mVolumeCalcData; + /* 0x34 */ f32 mVolumeSize; + /* 0x38 */ f32 mVolumeMinRad; + /* 0x3C */ f32 mVolumeSweep; + /* 0x40 */ s32 mEmitCount; + /* 0x44 */ s32 mVolumeEmitIdx; + /* 0x48 */ Mtx mDirectionMtx; + /* 0x78 */ Mtx mRotationMtx; + /* 0xA8 */ Mtx mGlobalRot; + /* 0xD8 */ Mtx mGlobalSR; + /* 0x108 */ JGeometry::TVec3<f32> mEmitterPos; + /* 0x114 */ JGeometry::TVec3<f32> mGlobalScl; + /* 0x120 */ JGeometry::TVec3<f32> mGlobalEmtrDir; + /* 0x12C */ JGeometry::TVec3<f32> mPublicScale; + /* 0x138 */ JGeometry::TVec3<f32> mGlobalPos; + /* 0x144 */ JGeometry::TVec2<f32> mGlobalPtclScl; + /* 0x14C */ JGeometry::TVec2<f32> mPivot; + /* 0x154 */ Mtx mYBBCamMtx; + /* 0x184 */ Mtx mPosCamMtx; + /* 0x1B4 */ Mtx mPrjMtx; + /* 0x1E4 */ JPAList<JPABaseParticle>* mpAlivePtcl; + /* 0x1E8 */ JPANode<JPABaseParticle>* mpCurNode; + /* 0x1EC */ s32 mVolumeAngleNum; + /* 0x1F0 */ s32 mVolumeAngleMax; + /* 0x1F4 */ s32 mVolumeX; + /* 0x1F8 */ s32 mDivNumber; + /* 0x1FC */ f32 mScaleAnm; + /* 0x200 */ u32 mDirType; + /* 0x204 */ u32 mRotType; + /* 0x208 */ u32 mPlaneType; + /* 0x20C */ u32 mDLType; + /* 0x210 */ u32 mPrjType; + /* 0x214 */ s16 mClrKeyFrame; + /* 0x216 */ u8 mDrawCount; +}; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPAEmitterCallBack { +public: + virtual ~JPAEmitterCallBack() = 0; + /* 80050368 */ virtual void execute(JPABaseEmitter*) {} + /* 80050374 */ virtual void executeAfter(JPABaseEmitter*) {} + /* 8005036C */ virtual void draw(JPABaseEmitter*) {} + /* 80050370 */ virtual void drawAfter(JPABaseEmitter*) {} + + /* 8027E6A4 */ //~JPAEmitterCallBack(); +}; + +enum { + JPAEmtrStts_StopEmit = 0x01, + JPAEmtrStts_StopCalc = 0x02, + JPAEmtrStts_StopDraw = 0x04, + JPAEmtrStts_EnableDeleteEmitter = 0x08, + JPAEmtrStts_FirstEmit = 0x10, + JPAEmtrStts_RateStepEmit = 0x20, + JPAEmtrStts_Immortal = 0x40, + JPAEmtrStts_Delete = 0x100, +}; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPABaseEmitter { +public: + /* 8027E5EC */ ~JPABaseEmitter() {} + /* 8027E64C */ JPABaseEmitter() : mLink(this), mRndm(0) {} + /* 8027E6EC */ void init(JPAEmitterManager*, JPAResource*); + /* 8027EDD4 */ bool processTillStartFrame(); + /* 8027EE14 */ bool processTermination(); + /* 8027EEB0 */ void calcEmitterGlobalPosition(JGeometry::TVec3<f32>*) const; + /* 8027EC60 */ void deleteAllParticle(); + /* 8027EB60 */ JPABaseParticle* createChild(JPABaseParticle*); + /* 8027EA40 */ JPABaseParticle* createParticle(); + /* 8027EF30 */ u32 getCurrentCreateNumber() const; + /* 8027EF40 */ u8 getDrawCount() const; + /* 8027EF50 */ bool loadTexture(u8, GXTexMapID); + + void initStatus(u32 status) { mStatus = status; } + void setStatus(u32 status) { mStatus |= status; } + void clearStatus(u32 status) { mStatus &= ~status; } + u32 checkStatus(u32 status) const { return (mStatus & status); } + bool checkFlag(u32 flag) const { return !!(mpRes->getDyn()->getFlag() & flag); } + u8 getResourceManagerID() const { return mResMgrID; } + u8 getGroupID() const { return mGroupID; } + u8 getDrawTimes() const { return mDrawTimes; } + void setRate(f32 rate) { mRate = rate; } + void setDirectionalSpeed(f32 i_speed) { mDirSpeed = i_speed; } + void setRandomDirectionSpeed(f32 i_speed) { mRndmDirSpeed = i_speed; } + void setEmitterCallBackPtr(JPAEmitterCallBack* ptr) { mpEmtrCallBack = ptr; } + void setGlobalRTMatrix(const Mtx m) { JPASetRMtxTVecfromMtx(m, mGlobalRot, &mGlobalTrs); } + void setGlobalSRTMatrix(const Mtx m) { + JPASetRMtxSTVecfromMtx(m, mGlobalRot, &mGlobalScl, &mGlobalTrs); + + // set is actually used here in debug + mGlobalPScl.x = mGlobalScl.x; + mGlobalPScl.y = mGlobalScl.y; + } + void setGlobalTranslation(f32 x, f32 y, f32 z) { mGlobalTrs.set(x, y, z); } + void setGlobalTranslation(const JGeometry::TVec3<f32>& trs) { mGlobalTrs.set(trs); } + void getLocalTranslation(JGeometry::TVec3<f32>& vec) { vec.set(mLocalTrs); } + void setGlobalRotation(const JGeometry::TVec3<s16>& rot) { + JPAGetXYZRotateMtx(rot.x, rot.y, rot.z, mGlobalRot); + } + void getGlobalTranslation(JGeometry::TVec3<f32>* out) const { out->set(mGlobalTrs); } + void setGlobalDynamicsScale(const JGeometry::TVec3<f32>& i_scale) { mGlobalScl.set(i_scale); } + void setGlobalAlpha(u8 alpha) { mGlobalPrmClr.a = alpha; } + u8 getGlobalAlpha() { return mGlobalPrmClr.a; } + void getGlobalPrmColor(GXColor& color) { color = mGlobalPrmClr; } + void setGlobalPrmColor(u8 r, u8 g, u8 b) { mGlobalPrmClr.r = r; mGlobalPrmClr.g = g; mGlobalPrmClr.b = b; } + void setGlobalEnvColor(u8 r, u8 g, u8 b) { mGlobalEnvClr.r = r; mGlobalEnvClr.g = g; mGlobalEnvClr.b = b; } + void setVolumeSize(u16 size) { mVolumeSize = size; } + void setLifeTime(s16 lifetime) { mLifeTime = lifetime; } + void setAwayFromCenterSpeed(f32 i_speed) { mAwayFromCenterSpeed = i_speed; } + void setAwayFromAxisSpeed(f32 i_speed) { mAwayFromAxisSpeed = i_speed; } + void setSpread(f32 i_spread) { mSpread = i_spread; } + void setLocalTranslation(const JGeometry::TVec3<f32>& i_trans) { mLocalTrs.set(i_trans); } + void setLocalRotation(const JGeometry::TVec3<s16>& i_rot) { mLocalRot.set(i_rot.x * 0.005493248f, i_rot.y * 0.005493248f, i_rot.z * 0.005493248f); } + void setRateStep(u8 i_step) { mRateStep = i_step; } + + void setGlobalParticleHeightScale(f32 height) { + mGlobalPScl.y = height; + } + void setGlobalParticleScale(const JGeometry::TVec3<f32>& scale) { + mGlobalPScl.set(scale.x, scale.y); + } + void setGlobalParticleScale(f32 scaleX, f32 scaleY) { + mGlobalPScl.set(scaleX, scaleY); + } + void getGlobalParticleScale(JGeometry::TVec3<f32>& scale) { + scale.set(mGlobalPScl.x, mGlobalPScl.y, 1.0f); + } + void setGlobalScale(const JGeometry::TVec3<f32>& scale) { + mGlobalScl.set(scale); + mGlobalPScl.set(scale.x ,scale.y); + } + void setGlobalSRTMatrix(const MtxP matrix) { + JPASetRMtxSTVecfromMtx(matrix, mGlobalRot, &mGlobalScl, &mGlobalTrs); + mGlobalPScl.set(mGlobalScl.x, mGlobalScl.y); + } + void setDirection(const JGeometry::TVec3<f32>& direction) { + mLocalDir.set(direction); + } + + void setLocalScale(const JGeometry::TVec3<f32>& scale) { + mLocalScl.set(scale); + } + + f32 get_r_f() { return mRndm.get_rndm_f(); } + f32 get_r_zp() { return mRndm.get_rndm_zp(); } + f32 get_r_zh() { return mRndm.get_rndm_zh(); } + s16 get_r_ss() { return mRndm.get_rndm_ss(); } + + void stopCreateParticle() { setStatus(JPAEmtrStts_StopEmit); } + void playCreateParticle() { clearStatus(JPAEmtrStts_StopEmit); } + void becomeImmortalEmitter() { setStatus(JPAEmtrStts_Immortal); } + void becomeContinuousParticle() { mMaxFrame = 0; } + void becomeDeleteEmitter() { setStatus(JPAEmtrStts_Delete); } + void becomeInvalidEmitter() { + stopCreateParticle(); + mMaxFrame = 1; + } + + void quitImmortalEmitter() { clearStatus(JPAEmtrStts_Immortal); } + void stopCalcEmitter() { setStatus(JPAEmtrStts_StopCalc); } + void playCalcEmitter() { clearStatus(JPAEmtrStts_StopCalc); } + void stopDrawParticle() { setStatus(JPAEmtrStts_StopDraw); } + void playDrawParticle() { clearStatus(JPAEmtrStts_StopDraw); } + + u32 getUserWork() { return mpUserWork; } + void setUserWork(u32 userWork) { mpUserWork = userWork; } + u32 getParticleNumber() { + return mAlivePtclBase.getNum() + mAlivePtclChld.getNum(); + } + bool isEnableDeleteEmitter() { + return checkStatus(JPAEmtrStts_EnableDeleteEmitter) && getParticleNumber() == 0; + } + void setDrawTimes(u8 drawTimes) { mDrawTimes = drawTimes; } + void setParticleCallBackPtr(JPAParticleCallBack* cb) { mpPtclCallBack = cb; } + JPAParticleCallBack* getParticleCallBackPtr() { return mpPtclCallBack; } + JPAEmitterCallBack* getEmitterCallBackPtr() const { return mpEmtrCallBack; } + u32 getAge() const { return mTick; } + +public: + /* 0x00 */ JGeometry::TVec3<f32> mLocalScl; + /* 0x0C */ JGeometry::TVec3<f32> mLocalTrs; + /* 0x18 */ JGeometry::TVec3<f32> mLocalDir; + /* 0x24 */ s32 mMaxFrame; + /* 0x28 */ f32 mRate; + /* 0x2C */ f32 mVolumeSweep; + /* 0x30 */ f32 mVolumeMinRad; + /* 0x34 */ f32 mAwayFromCenterSpeed; + /* 0x38 */ f32 mAwayFromAxisSpeed; + /* 0x3C */ f32 mDirSpeed; + /* 0x40 */ f32 mSpread; + /* 0x44 */ f32 mRndmDirSpeed; + /* 0x48 */ f32 mAirResist; + /* 0x4C */ JGeometry::TVec3<s16> mLocalRot; + /* 0x52 */ s16 mLifeTime; + /* 0x54 */ u16 mVolumeSize; + /* 0x56 */ u8 mRateStep; + /* 0x58 */ JSULink<JPABaseEmitter> mLink; + /* 0x68 */ Mtx mGlobalRot; + /* 0x98 */ JGeometry::TVec3<f32> mGlobalScl; + /* 0xA4 */ JGeometry::TVec3<f32> mGlobalTrs; + /* 0xB0 */ JGeometry::TVec2<f32> mGlobalPScl; + /* 0xB8 */ GXColor mGlobalPrmClr; + /* 0xBC */ GXColor mGlobalEnvClr; + /* 0xC0 */ s32 mpUserWork; + /* 0xC4 */ JPARandom mRndm; + /* 0xC8 */ JPAList<JPABaseParticle> mAlivePtclBase; + /* 0xD4 */ JPAList<JPABaseParticle> mAlivePtclChld; + /* 0xE0 */ JPAList<JPABaseParticle>* mpPtclPool; + /* 0xE4 */ JPAEmitterManager* mpEmtrMgr; + /* 0xE8 */ JPAResource* mpRes; + /* 0xEC */ JPAEmitterCallBack* mpEmtrCallBack; + /* 0xF0 */ JPAParticleCallBack* mpPtclCallBack; + /* 0xF4 */ volatile u32 mStatus; + /* 0xF8 */ f32 mEmitCount; + /* 0xFC */ f32 mScaleOut; + /* 0x100 */ u32 mTick; + /* 0x104 */ s16 mWaitTime; + /* 0x106 */ s16 mRateStepTimer; + /* 0x108 */ GXColor mPrmClr; + /* 0x10C */ GXColor mEnvClr; + /* 0x110 */ u8 mDrawTimes; + /* 0x111 */ u8 mTexAnmIdx; + /* 0x112 */ u8 mGroupID; + /* 0x113 */ u8 mResMgrID; +}; + +enum { + JPAPtclStts_Invisible = 0x08, +}; + +#endif /* JPAEMITTER_H */ diff --git a/include/JSystem/JParticle/JPAEmitterManager.h b/include/JSystem/JParticle/JPAEmitterManager.h new file mode 100644 index 00000000..5cd69a28 --- /dev/null +++ b/include/JSystem/JParticle/JPAEmitterManager.h @@ -0,0 +1,49 @@ +#ifndef JPAEMITTERMANAGER_H +#define JPAEMITTERMANAGER_H + +#include "dolphin/types.h" +#include "JSystem/JParticle/JPAList.h" +#include "JSystem/JParticle/JPADrawInfo.h" +#include "JSystem/JSupport/JSUList.h" +#include "JSystem/JGeometry.h" + +class JPAEmitterCallBack; +class JPAParticleCallBack; +class JPABaseEmitter; +class JPAResourceManager; +class JPABaseParticle; +class JKRHeap; +struct JPAEmitterWorkData; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPAEmitterManager { +public: + /* 8027DCA0 */ JPAEmitterManager(u32, u32, JKRHeap*, u8, u8); + /* 8027DEBC */ JPABaseEmitter* createSimpleEmitterID(JGeometry::TVec3<f32> const&, u16, u8, u8, + JPAEmitterCallBack*, JPAParticleCallBack*); + /* 8027DFA0 */ void calc(u8); + /* 8027E028 */ void draw(JPADrawInfo const*, u8); + /* 8027E220 */ void forceDeleteAllEmitter(); + /* 8027E278 */ void forceDeleteGroupEmitter(u8); + /* 8027E2D8 */ void forceDeleteEmitter(JPABaseEmitter*); + /* 8027E344 */ void entryResourceManager(JPAResourceManager*, u8); + /* 8027E354 */ void clearResourceManager(u8); + /* 8027E3F4 */ void calcYBBCam(); + JPAResourceManager* getResourceManager(u16 idx) { return pResMgrAry[idx]; } + +public: + /* 0x00 */ JSUList<JPABaseEmitter>* pEmtrUseList; + /* 0x04 */ JSUList<JPABaseEmitter> mFreeEmtrList; + /* 0x10 */ JPAList<JPABaseParticle> mPtclPool; + /* 0x1C */ JPAResourceManager** pResMgrAry; + /* 0x20 */ JPAEmitterWorkData* pWd; + /* 0x24 */ u32 emtrNum; + /* 0x28 */ u32 ptclNum; + /* 0x2C */ u8 gidMax; + /* 0x2D */ u8 ridMax; +}; + +#endif /* JPAEMITTERMANAGER_H */ diff --git a/include/JSystem/JParticle/JPAExTexShape.h b/include/JSystem/JParticle/JPAExTexShape.h new file mode 100644 index 00000000..b202cc9d --- /dev/null +++ b/include/JSystem/JParticle/JPAExTexShape.h @@ -0,0 +1,45 @@ +#ifndef JPAEXTEXSHAPE_H +#define JPAEXTEXSHAPE_H + +#include "dolphin/types.h" + +class JPAEmitterWorkData; + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPAExTexShapeData { + // Common header. + /* 0x00 */ u8 mMagic[4]; + /* 0x04 */ u32 mSize; + + /* 0x08 */ u32 mFlags; + /* 0x0C */ f32 mIndTexMtx[2][3]; + /* 0x24 */ s8 mExpScale; + /* 0x25 */ s8 mIndTexIdx; + /* 0x26 */ s8 mSecTexIdx; +}; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPAExTexShape { +public: + /* 8027B13C */ JPAExTexShape(u8 const*); + + const f32* getIndTexMtx() const { return &mpData->mIndTexMtx[0][0]; } + s8 getExpScale() const { return mpData->mExpScale; } + u8 getIndTexIdx() const { return mpData->mIndTexIdx; } + u8 getSecTexIdx() const { return mpData->mSecTexIdx; } + bool isUseIndirect() const { return !!(mpData->mFlags & 0x01); } + bool isUseSecTex() const { return !!(mpData->mFlags & 0x0100); } + +public: + const JPAExTexShapeData* mpData; +}; + +void JPALoadExTex(JPAEmitterWorkData*); + +#endif /* JPAEXTEXSHAPE_H */ diff --git a/include/JSystem/JParticle/JPAExtraShape.h b/include/JSystem/JParticle/JPAExtraShape.h new file mode 100644 index 00000000..dbf46363 --- /dev/null +++ b/include/JSystem/JParticle/JPAExtraShape.h @@ -0,0 +1,112 @@ +#ifndef JPAEXTRASHAPE_H +#define JPAEXTRASHAPE_H + +#include "dolphin/types.h" + +class JPAEmitterWorkData; +class JPABaseParticle; + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPAExtraShapeData { + // Common header. + /* 0x00 */ u8 mMagic[4]; + /* 0x04 */ u32 mSize; + + /* 0x08 */ u32 mFlags; + /* 0x0C */ f32 mScaleInTiming; + /* 0x10 */ f32 mScaleOutTiming; + /* 0x14 */ f32 mScaleInValueX; + /* 0x18 */ f32 mScaleOutValueX; + /* 0x1C */ f32 mScaleInValueY; + /* 0x20 */ f32 mScaleOutValueY; + /* 0x24 */ f32 mScaleOutRandom; + /* 0x28 */ s16 mScaleAnmCycleX; + /* 0x2A */ s16 mScaleAnmCycleY; + /* 0x2C */ f32 mAlphaInTiming; + /* 0x30 */ f32 mAlphaOutTiming; + /* 0x34 */ f32 mAlphaInValue; + /* 0x38 */ f32 mAlphaBaseValue; + /* 0x3C */ f32 mAlphaOutValue; + /* 0x40 */ f32 mAlphaWaveFrequency; + /* 0x44 */ f32 mAlphaWaveRandom; + /* 0x48 */ f32 mAlphaWaveAmplitude; + /* 0x4C */ f32 mRotateAngle; + /* 0x50 */ f32 mRotateAngleRandom; + /* 0x54 */ f32 mRotateSpeed; + /* 0x58 */ f32 mRotateSpeedRandom; + /* 0x5C */ f32 mRotateDirection; +}; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPAExtraShape { +public: + /* 8027AD88 */ JPAExtraShape(u8 const*); + /* 8027ADBC */ void init(); + + f32 getScaleInTiming() const { return mpData->mScaleInTiming; } + f32 getScaleOutTiming() const { return mpData->mScaleOutTiming; } + f32 getScaleInValueX() const { return mpData->mScaleInValueX; } + f32 getScaleInValueY() const { return mpData->mScaleInValueY; } + f32 getScaleOutValueX() const { return mpData->mScaleOutValueX; } + f32 getScaleOutValueY() const { return mpData->mScaleOutValueY; } + f32 getScaleRndm() const { return mpData->mScaleOutRandom; } + s16 getScaleAnmCycleX() const { return mpData->mScaleAnmCycleX; } + s16 getScaleAnmCycleY() const { return mpData->mScaleAnmCycleY; } + f32 getAlphaInTiming() const { return mpData->mAlphaInTiming; } + f32 getAlphaOutTiming() const { return mpData->mAlphaOutTiming; } + f32 getAlphaInValue() const { return mpData->mAlphaInValue; } + f32 getAlphaOutValue() const { return mpData->mAlphaOutValue; } + f32 getAlphaBaseValue() const { return mpData->mAlphaBaseValue; } + f32 getAlphaFreq() const { return mpData->mAlphaWaveFrequency; } + f32 getAlphaFreqRndm() const { return mpData->mAlphaWaveRandom; } + f32 getAlphaAmp() const { return mpData->mAlphaWaveAmplitude; } + f32 getRotateInitAngle() const { return mpData->mRotateAngle; } + f32 getRotateRndmAngle() const { return mpData->mRotateAngleRandom; } + f32 getRotateInitSpeed() const { return mpData->mRotateSpeed; } + f32 getRotateRndmSpeed() const { return mpData->mRotateSpeedRandom; } + f32 getRotateDirection() const { return mpData->mRotateDirection; } + f32 getScaleIncRateX() const { return mScaleIncRateX; } + f32 getScaleDecRateX() const { return mScaleDecRateX; } + f32 getScaleIncRateY() const { return mScaleIncRateY; } + f32 getScaleDecRateY() const { return mScaleDecRateY; } + f32 getAlphaIncRate() const { return mAlphaIncRate; } + f32 getAlphaDecRate() const { return mAlphaDecRate; } + + BOOL isEnableScaleAnm() const { return mpData->mFlags & 1; } + BOOL isScaleXYDiff() const { return mpData->mFlags & 2; } + u32 getScaleAnmTypeX() const { return (mpData->mFlags >> 8) & 3; } + u32 getScaleAnmTypeY() const { return (mpData->mFlags >> 10) & 3; } + u32 getScaleCenterX() const { return (mpData->mFlags >> 12) & 3; } + u32 getScaleCenterY() const { return (mpData->mFlags >> 14) & 3; } + BOOL isEnableAlphaAnm() const { return mpData->mFlags & 0x10000; } + BOOL isEnableAlphaFlick() const { return mpData->mFlags & 0x20000; } + BOOL isEnableRotateAnm() const { return mpData->mFlags & 0x1000000; } + +private: + /* 0x00 */ const JPAExtraShapeData* mpData; + /* 0x04 */ f32 mAlphaIncRate; + /* 0x08 */ f32 mAlphaDecRate; + /* 0x0C */ f32 mScaleIncRateX; + /* 0x10 */ f32 mScaleIncRateY; + /* 0x14 */ f32 mScaleDecRateX; + /* 0x18 */ f32 mScaleDecRateY; +}; + +void JPACalcAlphaFlickAnm(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcAlphaAnm(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcScaleX(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcScaleY(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcScaleCopy(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcScaleAnmNormal(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcScaleAnmRepeatX(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcScaleAnmReverseX(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcScaleAnmRepeatY(JPAEmitterWorkData*, JPABaseParticle*); +void JPACalcScaleAnmReverseY(JPAEmitterWorkData*, JPABaseParticle*); + +#endif /* JPAEXTRASHAPE_H */ diff --git a/include/JSystem/JParticle/JPAFieldBlock.h b/include/JSystem/JParticle/JPAFieldBlock.h new file mode 100644 index 00000000..2031ba26 --- /dev/null +++ b/include/JSystem/JParticle/JPAFieldBlock.h @@ -0,0 +1,174 @@ +#ifndef JPAFIELDBLOCK_H +#define JPAFIELDBLOCK_H + +#include "JSystem/JGeometry.h" +#include "dolphin/types.h" + +class JKRHeap; +class JPAEmitterWorkData; +class JPABaseParticle; +class JPAFieldBlock; + +class JPAFieldBase { +public: + /* 8027BDEC */ void calcAffect(JPAFieldBlock*, JPABaseParticle*); + /* 8027BF18 */ f32 calcFadeAffect(JPAFieldBlock*, f32) const; + + /* 8027D3AC */ virtual ~JPAFieldBase() {} + /* 80276A8C */ virtual void prepare(JPAEmitterWorkData*, JPAFieldBlock*) {} + virtual void calc(JPAEmitterWorkData*, JPAFieldBlock*, JPABaseParticle*) = 0; + + /* 0x04 */ JGeometry::TVec3<f32> mAccel; +}; + +class JPAFieldVortex : public JPAFieldBase { +public: + /* 8027C56C */ void prepare(JPAEmitterWorkData*, JPAFieldBlock*); + /* 8027C674 */ void calc(JPAEmitterWorkData*, JPAFieldBlock*, JPABaseParticle*); + /* 8027D564 */ ~JPAFieldVortex() {} + + /* 0x10 */ JGeometry::TVec3<f32> field_0x10; + /* 0x1C */ f32 field_0x1c; + /* 0x20 */ f32 field_0x20; +}; + +class JPAFieldSpin : public JPAFieldBase { +public: + /* 8027CE64 */ void prepare(JPAEmitterWorkData*, JPAFieldBlock*); + /* 8027CFA8 */ void calc(JPAEmitterWorkData*, JPAFieldBlock*, JPABaseParticle*); + /* 8027D3F4 */ ~JPAFieldSpin() {} + + /* 0x10 */ JGeometry::TVec3<f32> field_0x10; + /* 0x1C */ JGeometry::TVec3<f32> field_0x1c; + /* 0x28 */ JGeometry::TVec3<f32> field_0x28; +}; + +class JPAFieldRandom : public JPAFieldBase { +public: + /* 8027CCCC */ void calc(JPAEmitterWorkData*, JPAFieldBlock*, JPABaseParticle*); + /* 8027D4AC */ ~JPAFieldRandom() {} +}; + +class JPAFieldNewton : public JPAFieldBase { +public: + /* 8027C36C */ void prepare(JPAEmitterWorkData*, JPAFieldBlock*); + /* 8027C3E0 */ void calc(JPAEmitterWorkData*, JPAFieldBlock*, JPABaseParticle*); + /* 8027D5C0 */ ~JPAFieldNewton() {} + + /* 0x10 */ JGeometry::TVec3<f32> mDir; + /* 0x1C */ f32 mCutoff; +}; + +class JPAFieldMagnet : public JPAFieldBase { +public: + /* 8027C24C */ void prepare(JPAEmitterWorkData*, JPAFieldBlock*); + /* 8027C29C */ void calc(JPAEmitterWorkData*, JPAFieldBlock*, JPABaseParticle*); + /* 8027D61C */ ~JPAFieldMagnet() {} + + /* 0x10 */ JGeometry::TVec3<f32> mDir; +}; + +class JPAFieldGravity : public JPAFieldBase { +public: + /* 8027BFB4 */ void prepare(JPAEmitterWorkData*, JPAFieldBlock*); + /* 8027C054 */ void calc(JPAEmitterWorkData*, JPAFieldBlock*, JPABaseParticle*); + /* 8027D6D4 */ ~JPAFieldGravity() {} +}; + +class JPAFieldDrag : public JPAFieldBase { +public: + /* 8027CDE4 */ void calc(JPAEmitterWorkData*, JPAFieldBlock*, JPABaseParticle*); + /* 8027D450 */ ~JPAFieldDrag() {} +}; + +class JPAFieldConvection : public JPAFieldBase { +public: + /* 8027C814 */ void prepare(JPAEmitterWorkData*, JPAFieldBlock*); + /* 8027CA94 */ void calc(JPAEmitterWorkData*, JPAFieldBlock*, JPABaseParticle*); + /* 8027D508 */ ~JPAFieldConvection() {} + + /* 0x10 */ JGeometry::TVec3<f32> field_0x10; + /* 0x1C */ JGeometry::TVec3<f32> field_0x1c; + /* 0x28 */ JGeometry::TVec3<f32> field_0x28; +}; + +class JPAFieldAir : public JPAFieldBase { +public: + /* 8027C07C */ void prepare(JPAEmitterWorkData*, JPAFieldBlock*); + /* 8027C1B8 */ void calc(JPAEmitterWorkData*, JPAFieldBlock*, JPABaseParticle*); + /* 8027D678 */ ~JPAFieldAir() {} +}; + +// unknown name +class JPAFieldBlockData { +public: + /* 0x00 */ u8 mMagic[4]; + /* 0x04 */ u32 mSize; + /* 0x08 */ u32 mFlags; + /* 0x0C */ JGeometry::TVec3<f32> mPos; + /* 0x18 */ JGeometry::TVec3<f32> mDir; + /* 0x24 */ f32 mMag; + /* 0x28 */ f32 mMagRndm; + /* 0x2C */ f32 mVal1; + /* 0x30 */ f32 mFadeInTime; + /* 0x34 */ f32 mFadeOutTime; + /* 0x38 */ f32 mEnTime; + /* 0x3C */ f32 mDisTime; + /* 0x40 */ u8 mCycle; +}; + +class JPAFieldBlock { +public: + /* 8027D088 */ JPAFieldBlock(u8 const*, JKRHeap*); + /* 8027D0C0 */ void init(JKRHeap*); + + u32 getType() { return mpData->mFlags & 0xF; } + u32 getAddType() { return (mpData->mFlags >> 8) & 3; } + u32 getSttFlag() { return mpData->mFlags >> 16; } + bool checkStatus(u16 flag) { return flag & getSttFlag(); } + f32 getMagRndm() const { return mpData->mMagRndm; } + f32 getVal1() const { return mpData->mVal1; } + f32 getFadeInTime() { return mpData->mFadeInTime; } + f32 getFadeOutTime() { return mpData->mFadeOutTime; } + f32 getEnTime() { return mpData->mEnTime; } + f32 getDisTime() { return mpData->mDisTime; } + u8 getCycle() { return mpData->mCycle; } + f32 getFadeInRate() { return mFadeInRate; } + f32 getFadeOutRate() { return mFadeOutRate; } + JGeometry::TVec3<f32>& getPos() { return mPos; } + JGeometry::TVec3<f32>& getDir() { return mDir; } + f32 getMag() const { return mMag; } + void getPosOrig(JGeometry::TVec3<f32>* pos) { pos->set(mpData->mPos); } + void getDirOrig(JGeometry::TVec3<f32>* dir) { dir->set(mpData->mDir); } + f32 getMagOrig() { return mpData->mMag; } + void initOpParam() { + getPosOrig(&mPos); + getDirOrig(&mDir); + mMag = getMagOrig(); + } + void prepare(JPAEmitterWorkData* work) { mpField->prepare(work, this); } + void calc(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { mpField->calc(work, this, ptcl); } + +private: + /* 0x00 */ const JPAFieldBlockData* mpData; + /* 0x04 */ JPAFieldBase* mpField; + /* 0x08 */ f32 mFadeInRate; + /* 0x0C */ f32 mFadeOutRate; + /* 0x10 */ JGeometry::TVec3<f32> mPos; + /* 0x1C */ JGeometry::TVec3<f32> mDir; + /* 0x28 */ f32 mMag; + + enum Type { + /* 0x0 */ FIELD_GRAVITY, + /* 0x1 */ FIELD_AIR, + /* 0x2 */ FIELD_MAGNET, + /* 0x3 */ FIELD_NEWTON, + /* 0x4 */ FIELD_VORTEX, + /* 0x5 */ FIELD_RANDOM, + /* 0x6 */ FIELD_DRAG, + /* 0x7 */ FIELD_CONVECTION, + /* 0x8 */ FIELD_SPIN, + }; +}; + +#endif /* JPAFIELDBLOCK_H */ diff --git a/include/JSystem/JParticle/JPAKeyBlock.h b/include/JSystem/JParticle/JPAKeyBlock.h new file mode 100644 index 00000000..3d79e854 --- /dev/null +++ b/include/JSystem/JParticle/JPAKeyBlock.h @@ -0,0 +1,21 @@ +#ifndef JPAKEYBLOCK_H +#define JPAKEYBLOCK_H + +#include "dolphin/types.h" + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPAKeyBlock { + /* 8027D730 */ JPAKeyBlock(u8 const*); + /* 8027D740 */ f32 calc(f32); + + u8 getID() { return mDataStart[8]; } + + const u8* mDataStart; + const f32* field_0x4; +}; + + +#endif /* JPAKEYBLOCK_H */ diff --git a/include/JSystem/JParticle/JPAList.h b/include/JSystem/JParticle/JPAList.h new file mode 100644 index 00000000..ab2e5a7f --- /dev/null +++ b/include/JSystem/JParticle/JPAList.h @@ -0,0 +1,131 @@ +#ifndef JPALIST_H +#define JPALIST_H + +#include "dolphin/types.h" + +/** + * @ingroup jsystem-jparticle + * + */ +template <class T> +struct JPANode { + JPANode() : mpPrev(NULL), mpNext(NULL) { + } + ~JPANode() {} + JPANode<T>* getPrev() { return mpPrev; } + JPANode<T>* getNext() { return mpNext; } + T* getObject() { return &mData; } + + /* 0x00 */ JPANode<T>* mpPrev; + /* 0x04 */ JPANode<T>* mpNext; + /* 0x08 */ T mData; +}; + +/** + * @ingroup jsystem-jparticle + * + */ +template <class T> +struct JPAList { + /* 0x00 */ JPANode<T>* mpFirst; + /* 0x04 */ JPANode<T>* mpLast; + /* 0x08 */ u32 mNum; + + JPAList() : mpFirst(NULL), mpLast(NULL), mNum() {} + ~JPAList() {} + + JPANode<T>* getEnd() { return NULL; } + JPANode<T>* getFirst() const { return mpFirst; } + JPANode<T>* getLast() const { return mpLast; } + u32 getNum() const { return mNum; } + + void push_front(JPANode<T>* node) { + if (mpFirst != NULL) { + node->mpPrev = NULL; + node->mpNext = mpFirst; + mpFirst->mpPrev = node; + mpFirst = node; + } else { + mpLast = node; + mpFirst = node; + node->mpPrev = NULL; + node->mpNext = NULL; + } + + mNum++; + } + + void push_back(JPANode<T>* node) { + if (mpLast != NULL) { + node->mpPrev = mpLast; + node->mpNext = NULL; + mpLast->mpNext = node; + mpLast = node; + } else { + mpFirst = node; + mpLast = node; + node->mpNext = node->mpPrev = NULL; + } + + mNum++; + } + + JPANode<T>* pop_front() { + JPANode<T>* ret = NULL; + + if (mNum == 1) { + ret = mpFirst; + mpLast = NULL; + mpFirst = NULL; + mNum--; + } else if (mNum) { + ret = mpFirst; + ret->mpNext->mpPrev = NULL; + mpFirst = ret->mpNext; + mNum--; + } + + return ret; + } + + JPANode<T>* pop_back() { + JPANode<T>* ret = NULL; + + if (mNum == 1) { + ret = mpLast; + mpLast = NULL; + mpFirst = NULL; + mNum--; + } else if (mNum) { + ret = mpLast; + ret->mpPrev->mpNext = NULL; + mpLast = ret->mpPrev; + mNum--; + } + + return ret; + } + + JPANode<T>* erase(JPANode<T>* node) { + if (node->mpNext != NULL && node->mpPrev != NULL) { + node->mpPrev->mpNext = node->mpNext; + node->mpNext->mpPrev = node->mpPrev; + mNum--; + } else if (node->mpNext != NULL) { + node->mpNext->mpPrev = NULL; + mpFirst = node->mpNext; + mNum--; + } else if (node->mpPrev != NULL) { + node->mpPrev->mpNext = NULL; + mpLast = node->mpPrev; + mNum--; + } else { + mpLast = NULL; + mpFirst = NULL; + mNum--; + } + return node; + } +}; + +#endif diff --git a/include/JSystem/JParticle/JPAMath.h b/include/JSystem/JParticle/JPAMath.h new file mode 100644 index 00000000..68701359 --- /dev/null +++ b/include/JSystem/JParticle/JPAMath.h @@ -0,0 +1,16 @@ +#ifndef JPAMATH_H +#define JPAMATH_H + +#include "dolphin/mtx.h" +#include "JSystem/JGeometry.h" + +void JPAGetDirMtx(JGeometry::TVec3<f32> const& param_0, f32 (*param_1)[4]); +void JPAGetYZRotateMtx(s16 angleY, s16 angleZ, f32 (*param_2)[4]); +void JPAGetXYZRotateMtx(s16 x, s16 y, s16 z, Mtx dst); +void JPASetRMtxTVecfromMtx(f32 const (*param_0)[4], f32 (*param_1)[4], + JGeometry::TVec3<f32>* param_2); +f32 JPACalcKeyAnmValue(f32 param_0, u16 param_1, f32 const* param_2); +void JPASetRMtxSTVecfromMtx(f32 const (*param_0)[4], f32 (*param_1)[4], + JGeometry::TVec3<f32>* param_2, JGeometry::TVec3<f32>* param_3); + +#endif /* JPAMATH_H */ diff --git a/include/JSystem/JParticle/JPAParticle.h b/include/JSystem/JParticle/JPAParticle.h new file mode 100644 index 00000000..2e67f8e8 --- /dev/null +++ b/include/JSystem/JParticle/JPAParticle.h @@ -0,0 +1,93 @@ +#ifndef JPAPARTICLE_H +#define JPAPARTICLE_H + +#include <dolphin/gx.h> +#include "JSystem/JGeometry.h" + +class JKRHeap; +class JPABaseEmitter; +class JPABaseParticle; +class JPAEmitterCallBack; +class JPAEmitterManager; +class JPAParticleCallBack; +class JPAResourceManager; +struct JPAEmitterWorkData; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPABaseParticle { +public: + ~JPABaseParticle() {} + /* 8027EFEC */ void init_p(JPAEmitterWorkData*); + /* 8027F8C8 */ void init_c(JPAEmitterWorkData*, JPABaseParticle*); + /* 8027FFD0 */ bool calc_p(JPAEmitterWorkData*); + /* 80280260 */ bool calc_c(JPAEmitterWorkData*); + /* 802804C8 */ bool canCreateChild(JPAEmitterWorkData*); + /* 80280548 */ f32 getWidth(JPABaseEmitter const*) const; + /* 80280568 */ f32 getHeight(JPABaseEmitter const*) const; + int getAge() { return mAge; } + void setOffsetPosition(const JGeometry::TVec3<f32>& pos) { mOffsetPosition.set(pos); } + void setOffsetPosition(f32 x, f32 y, f32 z) { mOffsetPosition.set(x, y, z); } + void getOffsetPosition(JGeometry::TVec3<f32>& pos) { pos.set(mOffsetPosition); } + u16 getRotateAngle() const { return mRotateAngle; } + void getGlobalPosition(JGeometry::TVec3<f32>& pos) const { pos.set(mPosition); } + f32 getParticleScaleX() const { return mParticleScaleX; } + f32 getParticleScaleY() const { return mParticleScaleY; } + void setStatus(u32 flag) { mStatus |= flag; } + u32 checkStatus(u32 flag) { return mStatus & flag; } + void initStatus(u32 status) { mStatus = status; } + void setInvisibleParticleFlag() { setStatus(8); } + void setDeleteParticleFlag() { setStatus(2); } + void getVelVec(JGeometry::TVec3<f32>& vec) const { vec.set(mVelocity); } + void getLocalPosition(JGeometry::TVec3<f32>& vec) const { vec.set(mLocalPosition); } + void getBaseAxis(JGeometry::TVec3<f32>& vec) const { vec.set(mBaseAxis); } + +public: + /* 0x00 */ JGeometry::TVec3<f32> mPosition; + /* 0x0C */ JGeometry::TVec3<f32> mLocalPosition; + /* 0x18 */ JGeometry::TVec3<f32> mOffsetPosition; + /* 0x24 */ JGeometry::TVec3<f32> mVelocity; + /* 0x30 */ JGeometry::TVec3<f32> mVelType1; + /* 0x3C */ JGeometry::TVec3<f32> mVelType0; + /* 0x48 */ JGeometry::TVec3<f32> mVelType2; + /* 0x54 */ JGeometry::TVec3<f32> mBaseAxis; + /* 0x60 */ f32 mParticleScaleX; + /* 0x64 */ f32 mParticleScaleY; + /* 0x68 */ f32 mScaleOut; + /* 0x6C */ f32 mAlphaWaveRandom; + /* 0x70 */ f32 mMoment; + /* 0x74 */ f32 mDrag; + /* 0x78 */ u32 field_0x78; + /* 0x7C */ u32 mStatus; + /* 0x80 */ s16 mAge; + /* 0x82 */ s16 mLifeTime; + /* 0x84 */ f32 mTime; + /* 0x88 */ u16 mRotateAngle; + /* 0x8A */ s16 mRotateSpeed; + /* 0x8C */ GXColor mPrmClr; + /* 0x90 */ GXColor mEnvClr; + /* 0x94 */ u8 mTexAnmIdx; + /* 0x95 */ u8 mAnmRandom; + /* 0x96 */ u8 mPrmColorAlphaAnm; +}; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPAParticleCallBack { +public: + JPAParticleCallBack() {} + virtual ~JPAParticleCallBack() = 0; + virtual void execute(JPABaseEmitter*, JPABaseParticle*) {} + virtual void draw(JPABaseEmitter*, JPABaseParticle*) {} +}; + +// not sure where this belongs +static inline u32 COLOR_MULTI(u32 a, u32 b) { + return ((a * (b + 1)) * 0x10000) >> 24; +} + +#endif /* JPAPARTICLE_H */ diff --git a/include/JSystem/JParticle/JPARandom.h b/include/JSystem/JParticle/JPARandom.h new file mode 100644 index 00000000..5ffb276d --- /dev/null +++ b/include/JSystem/JParticle/JPARandom.h @@ -0,0 +1,43 @@ +#ifndef JPARANDOM_H +#define JPARANDOM_H + +#include "dolphin/types.h" + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPARandom { +public: + JPARandom() { mSeed = 0; } + JPARandom(u32 seed) { mSeed = seed; } + ~JPARandom() {} + void set_seed(u32 seed) { mSeed = seed; } + + u32 get_rndm_u() { return mSeed = mSeed * 0x19660du + 0x3c6ef35fu; } + + f32 get_rndm_f() { + union { + u32 u; + f32 f; + } a; + a.u = ((get_rndm_u() >> 9) | 0x3f800000); + return a.f - 1.0f; + } + + f32 get_rndm_zp() { + f32 f = get_rndm_f(); + return (f + f) - 1.0f; + } + + f32 get_rndm_zh() { + return get_rndm_f() - 0.5f; + } + + s16 get_rndm_ss() { return (s16)(get_rndm_u() >> 16); } + +public: + u32 mSeed; +}; + +#endif diff --git a/include/JSystem/JParticle/JPAResource.h b/include/JSystem/JParticle/JPAResource.h new file mode 100644 index 00000000..4b953233 --- /dev/null +++ b/include/JSystem/JParticle/JPAResource.h @@ -0,0 +1,81 @@ +#ifndef JPARESOURCE_H +#define JPARESOURCE_H + +#include "dolphin/types.h" + +class JKRHeap; +class JPAEmitterWorkData; +class JPABaseEmitter; +class JPABaseParticle; + +class JPABaseShape; +class JPAExtraShape; +class JPAChildShape; +class JPAExTexShape; +class JPADynamicsBlock; +class JPAFieldBlock; +class JPAKeyBlock; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPAResource { +public: + /* 80274010 */ JPAResource(); + /* 80274080 */ void init(JKRHeap*); + /* 802755E8 */ bool calc(JPAEmitterWorkData*, JPABaseEmitter*); + /* 80275A94 */ void draw(JPAEmitterWorkData*, JPABaseEmitter*); + /* 80275B74 */ void drawP(JPAEmitterWorkData*); + /* 80275EB0 */ void drawC(JPAEmitterWorkData*); + /* 802761A8 */ void setPTev(); + /* 8027642C */ void setCTev(JPAEmitterWorkData*); + /* 8027658C */ void calc_p(JPAEmitterWorkData*, JPABaseParticle*); + /* 80276608 */ void calc_c(JPAEmitterWorkData*, JPABaseParticle*); + /* 80276684 */ void calcField(JPAEmitterWorkData*, JPABaseParticle*); + /* 80276700 */ void calcKey(JPAEmitterWorkData*); + /* 80276840 */ void calcWorkData_c(JPAEmitterWorkData*); + /* 80276A0C */ void calcWorkData_d(JPAEmitterWorkData*); + + JPABaseShape* getBsp() const { return mpBaseShape; } + JPAExtraShape* getEsp() const { return mpExtraShape; } + JPAChildShape* getCsp() const { return mpChildShape; } + JPAExTexShape* getEts() const { return mpExTexShape; } + JPADynamicsBlock* getDyn() const { return mpDynamicsBlock; } + + u32 getTexIdx(u32 idx) const { return mpTDB1[idx]; } + u16 getUsrIdx() const { return mUsrIdx; } + +public: + typedef void (*EmitterFunc)(JPAEmitterWorkData*); + typedef void (*ParticleFunc)(JPAEmitterWorkData*, JPABaseParticle*); + /* 0x00 */ EmitterFunc* mpCalcEmitterFuncList; + /* 0x04 */ EmitterFunc* mpDrawEmitterFuncList; + /* 0x08 */ EmitterFunc* mpDrawEmitterChildFuncList; + /* 0x0C */ ParticleFunc* mpCalcParticleFuncList; + /* 0x10 */ ParticleFunc* mpDrawParticleFuncList; + /* 0x14 */ ParticleFunc* mpCalcParticleChildFuncList; + /* 0x18 */ ParticleFunc* mpDrawParticleChildFuncList; + + /* 0x1C */ JPABaseShape* mpBaseShape; + /* 0x20 */ JPAExtraShape* mpExtraShape; + /* 0x24 */ JPAChildShape* mpChildShape; + /* 0x28 */ JPAExTexShape* mpExTexShape; + /* 0x2C */ JPADynamicsBlock* mpDynamicsBlock; + /* 0x30 */ JPAFieldBlock** mpFieldBlocks; + /* 0x34 */ JPAKeyBlock** mpKeyBlocks; + /* 0x38 */ u16 const* mpTDB1; + /* 0x3C */ u16 mUsrIdx; + /* 0x3E */ u8 mFieldBlockNum; + /* 0x3F */ u8 mKeyBlockNum; + /* 0x40 */ u8 mTDB1Num; + /* 0x41 */ u8 mpCalcEmitterFuncListNum; + /* 0x42 */ u8 mpDrawEmitterFuncListNum; + /* 0x43 */ u8 mpDrawEmitterChildFuncListNum; + /* 0x44 */ u8 mpCalcParticleFuncListNum; + /* 0x45 */ u8 mpDrawParticleFuncListNum; + /* 0x46 */ u8 mpCalcParticleChildFuncListNum; + /* 0x47 */ u8 mpDrawParticleChildFuncListNum; +}; + +#endif /* JPARESOURCE_H */ diff --git a/include/JSystem/JParticle/JPAResourceLoader.h b/include/JSystem/JParticle/JPAResourceLoader.h new file mode 100644 index 00000000..10ff1e38 --- /dev/null +++ b/include/JSystem/JParticle/JPAResourceLoader.h @@ -0,0 +1,14 @@ +#ifndef JPARESOURCELOADER_H +#define JPARESOURCELOADER_H + +#include "dolphin/types.h" + +class JPAResourceManager; + +class JPAResourceLoader { +public: + /* 8027D8A0 */ JPAResourceLoader(u8 const*, JPAResourceManager*); + /* 8027D8E0 */ void load_jpc(u8 const*, JPAResourceManager*); +}; + +#endif /* JPARESOURCELOADER_H */ diff --git a/include/JSystem/JParticle/JPAResourceManager.h b/include/JSystem/JParticle/JPAResourceManager.h new file mode 100644 index 00000000..2820c810 --- /dev/null +++ b/include/JSystem/JParticle/JPAResourceManager.h @@ -0,0 +1,36 @@ +#ifndef JPARESOURCEMANAGER_H +#define JPARESOURCEMANAGER_H + +#include "JSystem/JParticle/JPATexture.h" + +class JKRHeap; +class JPAResource; +struct ResTIMG; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPAResourceManager { +public: + /* 80273E10 */ JPAResourceManager(void const*, JKRHeap*); + /* 80273E68 */ JPAResource* getResource(u16) const; + /* 80273EA8 */ bool checkUserIndexDuplication(u16) const; + /* 80273EEC */ const ResTIMG* swapTexture(ResTIMG const*, char const*); + /* 80273F8C */ void registRes(JPAResource*); + /* 80273FAC */ void registTex(JPATexture*); + /* 80273FCC */ u32 getResUserWork(u16) const; + + void load(u16 idx, GXTexMapID texMapID) { mpTexArr[idx]->load(texMapID); } + +public: + /* 0x00 */ JKRHeap* mpHeap; + /* 0x04 */ JPAResource** mpResArr; + /* 0x08 */ JPATexture** mpTexArr; + /* 0x0C */ u16 mResMax; + /* 0x0E */ u16 mResNum; + /* 0x10 */ u16 mTexMax; + /* 0x12 */ u16 mTexNum; +}; + +#endif /* JPARESOURCEMANAGER_H */ diff --git a/include/JSystem/JParticle/JPATexture.h b/include/JSystem/JParticle/JPATexture.h new file mode 100644 index 00000000..19b3bed7 --- /dev/null +++ b/include/JSystem/JParticle/JPATexture.h @@ -0,0 +1,36 @@ +#ifndef JPATEXTURE_H +#define JPATEXTURE_H + +#include "JSystem/JUtility/JUTTexture.h" + +/** + * @ingroup jsystem-jparticle + * + */ +struct JPATextureData { + // Probably magic / size / flags up top here, but they're unused. + /* 0x00 */ char field_0x00[0x0C]; + /* 0x0C */ char mName[0x14]; + /* 0x20 */ ResTIMG mResTIMG; +}; + +/** + * @ingroup jsystem-jparticle + * + */ +class JPATexture { +public: + JPATexture(u8 const*); + virtual ~JPATexture(); + + void load(GXTexMapID texMapID) { mTexture.load(texMapID); } + + JUTTexture* getJUTTexture() { return &mTexture; } + const char* getName() const { return mpData->mName; } + +public: + JUTTexture mTexture; + const JPATextureData* mpData; +}; + +#endif /* JPATEXTURE_H */ diff --git a/include/JSystem/JSupport/JSUList.h b/include/JSystem/JSupport/JSUList.h new file mode 100644 index 00000000..884b8b9b --- /dev/null +++ b/include/JSystem/JSupport/JSUList.h @@ -0,0 +1,254 @@ +#ifndef JSULIST_H +#define JSULIST_H + +#include "dolphin/types.h" + +template <typename T> +class JSUList; + +// +// Link +// + +class JSUPtrList; + +/** +* @ingroup jsystem-jsupport +* +*/ +class JSUPtrLink { +public: + JSUPtrLink(void* object); + ~JSUPtrLink(); + + void* getObjectPtr() const { return mObject; } + + JSUPtrList* getList() const { return mList; } + + JSUPtrLink* getNext() const { return mNext; } + + JSUPtrLink* getPrev() const { return mPrev; } + +public: + void* mObject; + JSUPtrList* mList; + JSUPtrLink* mPrev; + JSUPtrLink* mNext; +}; + +/** +* @ingroup jsystem-jsupport +* +*/ +template <typename T> +class JSULink : public JSUPtrLink { +public: + JSULink(T* object) : JSUPtrLink((void*)object) {} + + T* getObject() const { return static_cast<T*>(mObject); } + + JSUList<T>* getSupervisor() const { return static_cast<JSUList<T>*>(this->getList()); } + + JSULink<T>* getNext() const { return static_cast<JSULink*>(mNext); } + + JSULink<T>* getPrev() const { return static_cast<JSULink*>(mPrev); } +}; + +// +// List +// + +/** +* @ingroup jsystem-jsupport +* +*/ +class JSUPtrList { +public: + JSUPtrList() { this->initiate(); } + JSUPtrList(bool init); + ~JSUPtrList(); + + void initiate(); + void setFirst(JSUPtrLink* first); + bool append(JSUPtrLink* ptr); + bool prepend(JSUPtrLink* ptr); + bool insert(JSUPtrLink* before, JSUPtrLink* ptr); + bool remove(JSUPtrLink* ptr); + JSUPtrLink* getNthLink(u32 i) const; + + JSUPtrLink* getFirstLink() const { return mHead; } + + JSUPtrLink* getLastLink() const { return mTail; } + + u32 getNumLinks() const { return mLength; } + +private: + JSUPtrLink* mHead; + JSUPtrLink* mTail; + u32 mLength; +}; + +/** +* @ingroup jsystem-jsupport +* +*/ +template <typename T> +class JSUList : public JSUPtrList { +public: + JSUList() : JSUPtrList() {} + JSUList(bool init) : JSUPtrList(init) {} + + ~JSUList() {} + + bool append(JSULink<T>* link) { return this->JSUPtrList::append((JSUPtrLink*)link); } + + bool prepend(JSULink<T>* link) { return this->JSUPtrList::prepend((JSUPtrLink*)link); } + + bool insert(JSULink<T>* before, JSULink<T>* link) { + return this->JSUPtrList::insert((JSUPtrLink*)before, (JSUPtrLink*)link); + } + + bool remove(JSULink<T>* link) { return this->JSUPtrList::remove((JSUPtrLink*)link); } + + JSULink<T>* getFirst() const { return (JSULink<T>*)getFirstLink(); } + + JSULink<T>* getLast() const { return (JSULink<T>*)getLastLink(); } + + JSULink<T>* getNth(int index) { return (JSULink<T>*)getNthLink(index); } + + JSULink<T>* getEnd() const { return NULL; } + + u32 getNumLinks() const { return this->JSUPtrList::getNumLinks(); } +}; + +/** +* @ingroup jsystem-jsupport +* +*/ +template <typename T> +class JSUListIterator { +public: + JSUListIterator() : mLink(NULL) {} + JSUListIterator(JSULink<T>* link) : mLink(link) {} + JSUListIterator(JSUList<T>* list) : mLink(list->getFirst()) {} + + JSUListIterator<T>& operator=(JSULink<T>* link) { + this->mLink = link; + return *this; + } + + T* getObject() { return this->mLink->getObject(); } + + bool operator==(JSULink<T> const* other) const { return this->mLink == other; } + bool operator!=(JSULink<T> const* other) const { return this->mLink != other; } + bool operator==(JSUListIterator<T> const& other) const { return this->mLink == other.mLink; } + bool operator!=(JSUListIterator<T> const& other) const { return this->mLink != other.mLink; } + + JSUListIterator<T> operator++(int) { + JSUListIterator<T> prev = *this; + this->mLink = this->mLink->getNext(); + return prev; + } + + JSUListIterator<T>& operator++() { + this->mLink = this->mLink->getNext(); + return *this; + } + + JSUListIterator<T> operator--(int) { + JSUListIterator<T> prev = *this; + this->mLink = this->mLink->getPrev(); + return prev; + } + + JSUListIterator<T>& operator--() { + this->mLink = this->mLink->getPrev(); + return *this; + } + + T& operator*() { return *this->getObject(); } + + T* operator->() const { return mLink->getObject(); } + +// private: + JSULink<T>* mLink; +}; + +// +// Tree +// + +/** +* @ingroup jsystem-jsupport +* +*/ +template <typename T> +class JSUTree : public JSUList<T>, public JSULink<T> { +public: + JSUTree(T* owner) : JSUList<T>(), JSULink<T>(owner) {} + ~JSUTree() {} + + bool appendChild(JSUTree<T>* child) { return this->append(child); } + + bool removeChild(JSUTree<T>* child) { return this->remove(child); } + + bool insertChild(JSUTree<T>* before, JSUTree<T>* child) { return this->insert(before, child); } + + JSUTree<T>* getEndChild() const { return NULL; } + + JSUTree<T>* getFirstChild() const { return (JSUTree<T>*)this->getFirst(); } + + JSUTree<T>* getLastChild() const { return (JSUTree<T>*)this->getLast(); } + + JSUTree<T>* getNextChild() const { return (JSUTree<T>*)this->getNext(); } + + JSUTree<T>* getPrevChild() const { return (JSUTree<T>*)this->getPrev(); } + + u32 getNumChildren() const { return this->getNumLinks(); } + + T* getObject() const { return (T*)this->getObjectPtr(); } + + JSUTree<T>* getParent() const { return (JSUTree<T>*)this->getList(); } +}; + +/** +* @ingroup jsystem-jsupport +* +*/ +template <typename T> +class JSUTreeIterator { +public: + JSUTreeIterator() : mTree(NULL) {} + JSUTreeIterator(JSUTree<T>* tree) : mTree(tree) {} + + JSUTreeIterator<T>& operator=(JSUTree<T>* tree) { + this->mTree = tree; + return *this; + } + + T* getObject() { return this->mTree->getObject(); } + + bool operator==(JSUTree<T>* other) { return this->mTree == other; } + + bool operator!=(JSUTree<T>* other) { return this->mTree != other; } + + JSUTreeIterator<T> operator++(int) { + JSUTreeIterator<T> prev = *this; + this->mTree = this->mTree->getNextChild(); + return prev; + } + + JSUTreeIterator<T>& operator++() { + this->mTree = this->mTree->getNextChild(); + return *this; + } + + T* operator*() { return this->getObject(); } + + T* operator->() { return this->getObject(); } + +private: + JSUTree<T>* mTree; +}; + +#endif /* JSULIST_H */ diff --git a/include/JSystem/JSupport/JSupport.h b/include/JSystem/JSupport/JSupport.h new file mode 100644 index 00000000..c4a47c61 --- /dev/null +++ b/include/JSystem/JSupport/JSupport.h @@ -0,0 +1,45 @@ +#ifndef JSUPPORT_H +#define JSUPPORT_H + +#include <dolphin.h> + +/** +* @ingroup jsystem-jsupport +* +*/ +template <typename T> +T* JSUConvertOffsetToPtr(const void* ptr, u32 offset) { + if (offset == 0) { + return NULL; + } else { + return (T*)((s32)ptr + (s32)offset); + } +} + +/** +* @ingroup jsystem-jsupport +* +*/ +template <typename T> +T* JSUConvertOffsetToPtr(const void* ptr, const void* offset) { + if (offset == NULL) { + return NULL; + } else { + return (T*)((s32)ptr + (s32)offset); + } +} + +inline u8 JSULoNibble(u8 param_0) { return param_0 & 0x0f; } +inline u8 JSUHiNibble(u8 param_0) {return param_0 >> 4; } + +inline u8 JSULoByte(u16 in) { + return in & 0xff; +} + +inline u8 JSUHiByte(u16 in) { + return in >> 8; +} + +inline u16 JSULoHalf(u32 param_0) {return param_0; } + +#endif diff --git a/include/JSystem/JUtility/JUTAssert.h b/include/JSystem/JUtility/JUTAssert.h new file mode 100644 index 00000000..5d469fb3 --- /dev/null +++ b/include/JSystem/JUtility/JUTAssert.h @@ -0,0 +1,64 @@ +#ifndef JUTASSERT_H +#define JUTASSERT_H + +#include "dolphin/os.h" + +#ifdef DEBUG +#define JUT_ASSERT(LINE, COND) \ + (COND) ? (void)0 : (JUTAssertion::showAssert(JUTAssertion::getSDevice(), __FILE__, LINE, #COND), OSPanic(__FILE__, LINE, "Halt")); + +#define JUT_ASSERT_MSG(LINE, COND, MSG) \ + (COND) ? (void)0 : (JUTAssertion::showAssert(JUTAssertion::getSDevice(), __FILE__, LINE, MSG), OSPanic(__FILE__, LINE, "Halt")); + +#define JUT_ASSERT_MSG_F(LINE, COND, MSG, ...) \ + (COND) ? (void)0 : (JUTAssertion::showAssert_f(JUTAssertion::getSDevice(), __FILE__, LINE, MSG, __VA_ARGS__), OSPanic(__FILE__, LINE, "Halt")); + +#define J3D_ASSERT(LINE, COND, MSG) JUT_ASSERT_MSG(LINE, (COND) != 0, MSG) + +#define JUT_PANIC(LINE, TEXT) \ + JUTAssertion::showAssert(JUTAssertion::getSDevice(), __FILE__, LINE, TEXT); \ + OSPanic(__FILE__, LINE, "Halt"); + +#define JUT_WARN_DEVICE(LINE, DEVICE, ...) \ + JUTAssertion::setWarningMessage_f(DEVICE, __FILE__, LINE, __VA_ARGS__); \ + +#define JUT_WARN(LINE, ...) \ + JUT_WARN_DEVICE(LINE, JUTAssertion::getSDevice(), __VA_ARGS__) + +#define JUT_LOG(LINE, ...) \ + JUTAssertion::setLogMessage_f(JUTAssertion::getSDevice(), __FILE__, LINE, __VA_ARGS__) + +#define JUT_CONFIRM(LINE, COND) \ + JUTAssertion::setConfirmMessage(JUTAssertion::getSDevice(), __FILE__, LINE, COND, #COND) + +#else +#define JUT_ASSERT(...) (void)0; +#define JUT_ASSERT_MSG(...) (void)0; +#define JUT_ASSERT_MSG_F(...) (void)0; +#define J3D_ASSERT(...) (void)0; +#define JUT_PANIC(...) +#define JUT_WARN(...) +#define JUT_WARN_DEVICE(...) +#define JUT_LOG(...) +#define JUT_CONFIRM(...) +#endif + +namespace JUTAssertion { + /* 802E495C */ void create(); + /* 802E4960 */ u32 flush_subroutine(); + /* 802E499C */ void flushMessage(); + /* 802E4A54 */ void flushMessage_dbPrint(); + /* 802E4C34 */ void setVisible(bool); + /* 802E4C3C */ void setMessageCount(int); + + u32 getSDevice(); + void showAssert(u32 device, const char * file, int line, const char * assertion); + void showAssert_f(u32 device, const char* file, int line, const char* msg, ...); + void setWarningMessage_f(u32 device, char * file, int line, const char * fmt, ...); + void setLogMessage_f(u32 device, char* file, int line, const char* fmt, ...); + void setConfirmMessage(u32 param_1, char* file, int line, bool param_4, const char* msg); +}; + +extern bool sAssertVisible; + +#endif /* JUTASSERT_H */ diff --git a/include/JSystem/JUtility/JUTTexture.h b/include/JSystem/JUtility/JUTTexture.h new file mode 100644 index 00000000..606cd581 --- /dev/null +++ b/include/JSystem/JUtility/JUTTexture.h @@ -0,0 +1,113 @@ +#ifndef JUTTEXTURE_H +#define JUTTEXTURE_H + +#include <dolphin/gx.h> + +class JUTPalette; + +/** +* @ingroup jsystem-jutility +* @brief Image data header. +* +* Acts as the header to image data. Usually texture data immediately follows it, +* so any pointer arithmetic to go past the end of this structure is so that a +* variable sized allocated buffer can be accessed. +* +*/ +struct ResTIMG { + /* 0x00 */ u8 format; + /* 0x01 */ u8 alphaEnabled; + /* 0x02 */ u16 width; + /* 0x04 */ u16 height; + /* 0x06 */ u8 wrapS; + /* 0x07 */ u8 wrapT; + /* 0x08 */ u8 indexTexture; + /* 0x09 */ u8 colorFormat; + /* 0x0A */ u16 numColors; + /* 0x0C */ u32 paletteOffset; + /* 0x10 */ u8 mipmapEnabled; + /* 0x11 */ u8 doEdgeLOD; + /* 0x12 */ u8 biasClamp; + /* 0x13 */ u8 maxAnisotropy; + /* 0x14 */ u8 minFilter; + /* 0x15 */ u8 magFilter; + /* 0x16 */ s8 minLOD; + /* 0x17 */ s8 maxLOD; + /* 0x18 */ u8 mipmapCount; + /* 0x19 */ u8 unknown; + /* 0x1A */ s16 LODBias; + /* 0x1C */ u32 imageOffset; +}; // Size: 0x20 + +/** +* @ingroup jsystem-jutility +* +*/ +class JUTTexture { +public: + JUTTexture() { + setCaptureFlag(false); + mEmbPalette = NULL; + mTexInfo = NULL; + } + + JUTTexture(const ResTIMG* p_timg, u8 param_1) { + mEmbPalette = NULL; + storeTIMG(p_timg, param_1); + setCaptureFlag(false); + } + + ~JUTTexture(); + void storeTIMG(ResTIMG const*, JUTPalette*, _GXTlut); + void storeTIMG(ResTIMG const*, u8); + void storeTIMG(ResTIMG const*, JUTPalette*); + void attachPalette(JUTPalette*); + void init(); + void initTexObj(_GXTlut); + void initTexObj(); + void load(_GXTexMapID); + + const ResTIMG* getTexInfo() const { return mTexInfo; } + s32 getFormat() const { return mTexInfo->format; } + s32 getTransparency() { return mTexInfo->alphaEnabled; } + s32 getWidth() const { return mTexInfo->width; } + s32 getHeight() const { return mTexInfo->height; } + void setCaptureFlag(bool flag) { mFlags &= 2 | flag; } + u8 getCaptureFlag() const { return mFlags & 1; } + u8 getEmbPaletteDelFlag() const { return mFlags & 2; } + void setEmbPaletteDelFlag(bool flag) { mFlags = (mFlags & 1) | (flag << 1);} + u8 getTlutName() const { return mTlutName; } + bool operator==(const JUTTexture& other) { + return mTexInfo == other.mTexInfo + && field_0x2c == other.field_0x2c + && mWrapS == other.mWrapS + && mWrapT == other.mWrapT + && mMinFilter == other.mMinFilter + && mMagFilter == other.mMagFilter + && mMinLOD == other.mMinLOD + && mMinLOD == other.mMinLOD + && mLODBias == other.mLODBias; + } + bool operator!=(const JUTTexture& other) { + return !operator==(other); + } + +private: + /* 0x00 */ GXTexObj mTexObj; + /* 0x20 */ const ResTIMG* mTexInfo; + /* 0x24 */ void* mTexData; + /* 0x28 */ JUTPalette* mEmbPalette; + /* 0x2C */ JUTPalette* field_0x2c; + /* 0x30 */ u8 mWrapS; + /* 0x31 */ u8 mWrapT; + /* 0x32 */ u8 mMinFilter; + /* 0x33 */ u8 mMagFilter; + /* 0x34 */ u16 mMinLOD; + /* 0x36 */ u16 mMaxLOD; + /* 0x38 */ s16 mLODBias; + /* 0x3A */ u8 mTlutName; + /* 0x3B */ u8 mFlags; + /* 0x3C */ void* field_0x3c; +}; + +#endif /* JUTTEXTURE_H */ diff --git a/include/JSystem/TPosition3.h b/include/JSystem/TPosition3.h new file mode 100644 index 00000000..807ce4fe --- /dev/null +++ b/include/JSystem/TPosition3.h @@ -0,0 +1,86 @@ +#ifndef TPOSITION3_H +#define TPOSITION3_H + +#include "dolphin/mtx.h" +#include "JSystem/JMath/JMath.h" +#include "JSystem/JGeometry.h" + +namespace JGeometry { + +template <typename T> +struct SMatrix34C { + T data[3][4]; +}; + +template <> +struct SMatrix34C<f32> { + f32 data[3][4]; + + void identity() { MTXIdentity(data); } + + typedef f32 ArrType[4]; + void set(const ArrType* src) { + JMath::gekko_ps_copy12(data, src); + } + + operator ArrType*() { return data; } + operator const ArrType*() const { return data; } +}; + +template <typename T> +struct SMatrix33C { + T data[3][3]; + + inline T& ref(int i, int j) { + return data[i][j]; + } + + inline T at(int i, int j) const { + return data[i][j]; + } + + inline void set(T param_1, T param_2, T param_3, T param_4, T param_5, + T param_6, T param_7, T param_8, T param_9) { + ref(0,0) = param_1; + ref(0,1) = param_2; + ref(0,2) = param_3; + ref(1,0) = param_4; + ref(1,1) = param_5; + ref(1,2) = param_6; + ref(2,0) = param_7; + ref(2,1) = param_8; + ref(2,2) = param_9; + } +}; + +template <typename T> +struct TMatrix34 : public T {}; + +template <typename T> +struct TRotation3 : public T {}; + +template<typename T> +struct TRotation3<SMatrix33C<T> > : public SMatrix33C<T> { + inline void getEulerXYZ(TVec3<T>* param_1) const { + if (at(2, 0) - TUtil<T>::one() >= -TUtil<T>::epsilon()) { + param_1->set(TUtil<T>::atan2(-at(0, 1), at(1, 1)), -TUtil<T>::halfPI(), 0.0); + } else { + if (at(2, 0) + TUtil<T>::one() <= TUtil<T>::epsilon()) { + param_1->set(TUtil<T>::atan2(at(0, 1), at(1, 1)), TUtil<T>::halfPI(), 0.0); + } else { + param_1->x = TUtil<T>::atan2(at(2, 1), at(2, 2)); + param_1->z = TUtil<T>::atan2(at(1, 0), at(0, 0)); + param_1->y = TUtil<T>::asin(-at(2, 0)); + } + } + } +}; + +template <typename T> +struct TPosition3 : public T {}; + +typedef TPosition3<TRotation3<TMatrix34<SMatrix34C<f32> > > > TPosition3f32; + +} // namespace JGeometry + +#endif |
