diff --git a/include/Kyoto/Basics/CCast.hpp b/include/Kyoto/Basics/CCast.hpp index 9215d06e..e602f2d2 100644 --- a/include/Kyoto/Basics/CCast.hpp +++ b/include/Kyoto/Basics/CCast.hpp @@ -25,6 +25,16 @@ inline f32 ToReal32(register const u8& in) { } return r; } + +inline s16 FtoS(register f32 in) { + s16 a; + register s16* ptr = &a; + + asm { + psq_st in, 0(ptr), 1, OS_FASTCAST_S16 + } + return *ptr; +} #else inline u8 ToUint8(f32 in) { return static_cast(in); @@ -32,6 +42,9 @@ inline u8 ToUint8(f32 in) { inline f32 ToReal32(u8 in) { return static_cast(in); } +inline s16 FtoS(f32 in) { + return static_cast(in); +} #endif } // namespace CCast diff --git a/include/Kyoto/Graphics/CColor.hpp b/include/Kyoto/Graphics/CColor.hpp index a1434e86..66a87441 100644 --- a/include/Kyoto/Graphics/CColor.hpp +++ b/include/Kyoto/Graphics/CColor.hpp @@ -5,6 +5,8 @@ #include "Kyoto/Basics/CCast.hpp" +#include + #ifdef __MWERKS__ #pragma cpp_extensions on #endif @@ -39,6 +41,7 @@ public: u8 GetBlueu8() const { return mB; } u8 GetAlphau8() const { return mA; } u16 ToRGB5A3() const; + GXColor ToGX(u32); static const CColor& Black(); static const CColor& White(); @@ -72,4 +75,8 @@ private: static const CColor sOrangeColor; }; +#ifdef __MWERKS__ +#pragma cpp_extensions off +#endif + #endif // __CCOLOR_HPP__ diff --git a/include/Kyoto/Graphics/CCubeMaterial.hpp b/include/Kyoto/Graphics/CCubeMaterial.hpp index 496b1fa3..7e4eb820 100644 --- a/include/Kyoto/Graphics/CCubeMaterial.hpp +++ b/include/Kyoto/Graphics/CCubeMaterial.hpp @@ -11,7 +11,7 @@ extern CVector3f sPlayerPosition; class CCubeMaterial { public: private: - void SetupBlendMode(u32 blendFactors, const CModelFlags& flags, bool alphaTest); + static void SetupBlendMode(u32 blendFactors, const CModelFlags& flags, bool alphaTest); static CVector3f sViewingFrom; }; diff --git a/include/Kyoto/Graphics/CGX.hpp b/include/Kyoto/Graphics/CGX.hpp index a92e1ba0..1671e978 100644 --- a/include/Kyoto/Graphics/CGX.hpp +++ b/include/Kyoto/Graphics/CGX.hpp @@ -5,7 +5,8 @@ #include -#include "dolphin/gx.h" +#include +#include class CGX { public: @@ -124,6 +125,10 @@ public: static void ResetGXStates(); static void ResetGXStatesFull(); // name? + static inline void LoadTexMtxImm(const f32 mtx[][4], unsigned long id, GXTexMtxType type) { + GXLoadTexMtxImm(const_cast(mtx), id, type); + } + static GXColor GetChanAmbColor(EChannelId channel); static void GetFog(GXFogType* fogType, f32* fogStartZ, f32* fogEndZ, f32* fogNearZ, f32* fogFarZ, GXColor* fogColor); diff --git a/include/Kyoto/Graphics/CGraphics.hpp b/include/Kyoto/Graphics/CGraphics.hpp index 90bf4f65..6cc909f0 100644 --- a/include/Kyoto/Graphics/CGraphics.hpp +++ b/include/Kyoto/Graphics/CGraphics.hpp @@ -52,9 +52,13 @@ public: static void StreamEnd(); static const CTransform4f& GetViewMatrix() { return mViewMatrix; } + static const CTransform4f& GetModelMatrix() { return mModelMatrix; } + + static float GetSecondsMod900(); private: static CTransform4f mViewMatrix; + static CTransform4f mModelMatrix; }; #endif diff --git a/include/Kyoto/Graphics/CModelFlags.hpp b/include/Kyoto/Graphics/CModelFlags.hpp index 556466b8..1c137a5f 100644 --- a/include/Kyoto/Graphics/CModelFlags.hpp +++ b/include/Kyoto/Graphics/CModelFlags.hpp @@ -63,7 +63,7 @@ public: static CModelFlags ColorModulate(const CColor& color); private: - u8 x0_blendMode; + s8 x0_blendMode; u8 x1_matSetIdx; u16 x2_flags; CColor x4_color; diff --git a/include/Kyoto/Math/CMath.hpp b/include/Kyoto/Math/CMath.hpp new file mode 100644 index 00000000..b159f67b --- /dev/null +++ b/include/Kyoto/Math/CMath.hpp @@ -0,0 +1,16 @@ +#ifndef _CMATH_HPP +#define _CMATH_HPP + +#include "types.h" + +class CMath { +public: + static f32 FastCosR(f32 v); + static f32 FastSinR(f32 v); + static inline f32 FastFmod(f32 x, f32 y) { + s32 v = static_cast(x * (1.f / y)); + return x - v * y; + } +}; + +#endif \ No newline at end of file diff --git a/include/Kyoto/Math/CTransform4f.hpp b/include/Kyoto/Math/CTransform4f.hpp index 91c609f7..61a040fe 100644 --- a/include/Kyoto/Math/CTransform4f.hpp +++ b/include/Kyoto/Math/CTransform4f.hpp @@ -5,6 +5,8 @@ #include "Kyoto/Math/CVector3f.hpp" +typedef const f32 (*ConstMtxPtr)[4]; + class CInputStream; class CMatrix3f; @@ -13,6 +15,8 @@ public: CTransform4f() { // TODO } + CTransform4f(const CVector3f& m0, const CVector3f& m1, const CVector3f& m2, const CVector3f& pos) + : m0(m0), posX(pos.GetX()), m1(m1), posY(pos.GetY()), m2(m2), posZ(pos.GetZ()) {} CTransform4f(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32); CTransform4f(const CInputStream& in); CTransform4f(const CMatrix3f& rotation, const CVector3f& translation); @@ -23,36 +27,37 @@ public: CVector3f GetRight() const { return CVector3f(m0.GetX(), m1.GetX(), m2.GetX()); } CVector3f GetForward() const { return CVector3f(m0.GetY(), m1.GetY(), m2.GetY()); } CVector3f GetUp() const { return CVector3f(m0.GetZ(), m1.GetZ(), m2.GetZ()); } + ConstMtxPtr GetCStyleMatrix() const { return reinterpret_cast(this); } CMatrix3f BuildMatrix3f() const; - // Get00__12CTransform4fCFv - // Get01__12CTransform4fCFv - // Get02__12CTransform4fCFv - // Get03__12CTransform4fCFv - // Get10__12CTransform4fCFv - // Get11__12CTransform4fCFv - // Get12__12CTransform4fCFv - // Get13__12CTransform4fCFv - // Get20__12CTransform4fCFv - // Get21__12CTransform4fCFv - // Get22__12CTransform4fCFv - // Get23__12CTransform4fCFv + f32 Get00() const { return m0.GetX(); } + f32 Get01() const { return m0.GetY(); } + f32 Get02() const { return m0.GetZ(); } + f32 Get03() const { return posX; } + f32 Get10() const { return m1.GetX(); } + f32 Get11() const { return m1.GetY(); } + f32 Get12() const { return m1.GetZ(); } + f32 Get13() const { return posY; } + f32 Get20() const { return m2.GetX(); } + f32 Get21() const { return m2.GetY(); } + f32 Get22() const { return m2.GetZ(); } + f32 Get23() const { return posZ; } // GetColumn__12CTransform4fCF5EDimX // GetColumn__12CTransform4fCF5EDimY // GetColumn__12CTransform4fCF5EDimZ // GetColumn__12CTransform4fCFi // GetCStyleMatrix__12CTransform4fCFv // GetInverse__12CTransform4fCFv - // GetQuickInverse__12CTransform4fCFv + CTransform4f GetQuickInverse() const; // GetRotation__12CTransform4fCFv - // GetRow__12CTransform4fCF5EDimX - // GetRow__12CTransform4fCF5EDimY - // GetRow__12CTransform4fCF5EDimZ + inline const CVector3f& GetRow(EDimX dim) const { return m0; } + inline const CVector3f& GetRow(EDimY dim) const { return m1; } + inline const CVector3f& GetRow(EDimZ dim) const { return m2; } // GetRow__12CTransform4fCFi // GetUp__12CTransform4fCFv // LookAt__12CTransform4fFRC9CVector3fRC9CVector3fRC9CVector3f // MakeRotationsBasedOnY__12CTransform4fFRC13CUnitVector3f - // MultiplyIgnoreTranslation__12CTransform4fCFRC12CTransform4f + CTransform4f MultiplyIgnoreTranslation(const CTransform4f& other) const; // Orthonormalize__12CTransform4fFv // Rotate__12CTransform4fCFRC9CVector3f // RotateLocalX__12CTransform4fFRC9CRelAngle @@ -85,8 +90,8 @@ public: void AddTranslationZ(f32 z) { posZ += z; } CTransform4f& operator*=(const CTransform4f& other); - CTransform4f& operator*(const CTransform4f& vec); - CTransform4f& operator*(const CVector3f& vec); + CTransform4f operator*(const CTransform4f& vec) const; + CTransform4f operator*(const CVector3f& vec) const; static CTransform4f FromColumns(const CVector3f&, const CVector3f&, const CVector3f&, const CVector3f&); static const CTransform4f& Identity() { return sIdentity; } diff --git a/include/Kyoto/Math/CVector3f.hpp b/include/Kyoto/Math/CVector3f.hpp index 62390834..c7871bf3 100644 --- a/include/Kyoto/Math/CVector3f.hpp +++ b/include/Kyoto/Math/CVector3f.hpp @@ -8,6 +8,10 @@ class CInputStream; class COutputStream; +enum EDimX { kDX }; +enum EDimY { kDY }; +enum EDimZ { kDZ }; + class CVector3f { public: CVector3f() : mX(0.f), mY(0.f), mZ(0.f) {} @@ -37,8 +41,15 @@ public: // IsEqu__9CVector3fCFRC9CVector3ff // Lerp__9CVector3fFRC9CVector3fRC9CVector3ff + f32& operator[](EDimX dim) { return mX; } + f32& operator[](EDimY dim) { return mY; } + f32& operator[](EDimZ dim) { return mZ; } + f32 operator[](EDimX) const { return mX; } + f32 operator[](EDimY) const { return mY; } + f32 operator[](EDimZ) const { return mZ; } + f32& operator[](s32 i) { return *(&mX + i); } - f32 operator[](s32 i) const { return *(&mX + i); } + // f32 operator[](s32 i) const { return *(&mX + i); } bool IsNonZero() const { return mX != 0.f || mY != 0.f || mZ != 0.f; } void DropZ() { mZ = 0.f; } diff --git a/include/Kyoto/Streams/CInputStream.hpp b/include/Kyoto/Streams/CInputStream.hpp index 140dc023..65b693ec 100644 --- a/include/Kyoto/Streams/CInputStream.hpp +++ b/include/Kyoto/Streams/CInputStream.hpp @@ -54,7 +54,7 @@ inline u32 cinput_stream_helper(const TType< u32 >& type, CInputStream& in) { return in.ReadLong(); } template <> -inline unsigned long cinput_stream_helper(const TType< unsigned long >& type, CInputStream& in) { +inline unsigned int cinput_stream_helper(const TType< unsigned int >& type, CInputStream& in) { return in.ReadLong(); } template <> diff --git a/include/dolphin/mtx.h b/include/dolphin/mtx.h new file mode 100644 index 00000000..4475ce77 --- /dev/null +++ b/include/dolphin/mtx.h @@ -0,0 +1,9 @@ +#ifndef DOLPHIN_MTX_H +#define DOLPHIN_MTX_H + +#include + +typedef f32 Mtx[3][4]; +typedef f32 (*MtxPtr)[4]; + +#endif \ No newline at end of file diff --git a/include/dolphin/os/OSFastCast.h b/include/dolphin/os/OSFastCast.h index effad6c8..48a83383 100644 --- a/include/dolphin/os/OSFastCast.h +++ b/include/dolphin/os/OSFastCast.h @@ -6,8 +6,10 @@ extern "C" { #endif #define OS_FASTCAST_U8 2 - +#define OS_FASTCAST_S16 5 + #ifdef __cplusplus } #endif + #endif diff --git a/include/types.h b/include/types.h index b848a610..46042027 100644 --- a/include/types.h +++ b/include/types.h @@ -12,6 +12,8 @@ extern "C" { // Pointer to unknown, to be determined at a later date. typedef void* unkptr; +#define SBig(x) x + #ifdef __cplusplus } #endif diff --git a/libc/string.h b/libc/string.h index 7633b1f1..58966199 100644 --- a/libc/string.h +++ b/libc/string.h @@ -7,8 +7,11 @@ extern "C" { #endif -void* memcpy(void* dest, const void* src, size_t num); -void* memset(void* dest, int ch, size_t count); +#pragma section code_type ".init" +void* memcpy(void* dst, const void* src, size_t n); +void* memset(void* dst, int val, size_t n); +void __fill_mem(void* dst, int val, unsigned long n); +#pragma section code_type size_t strlen(const char* s); char* strcpy(char* dest, const char* src); diff --git a/src/Kyoto/Graphics/CCubeMaterial.cpp b/src/Kyoto/Graphics/CCubeMaterial.cpp index cbdcd501..fb94c32e 100644 --- a/src/Kyoto/Graphics/CCubeMaterial.cpp +++ b/src/Kyoto/Graphics/CCubeMaterial.cpp @@ -1,5 +1,51 @@ #include "Kyoto/Graphics/CCubeMaterial.hpp" +#include "Kyoto/Graphics/CGX.hpp" +#include "Kyoto/Graphics/CGraphics.hpp" +#include "Kyoto/Math/CMath.hpp" + +#include + +inline void CGX::SetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) { + u32 flags = MaskAndShiftLeft(comp0, 7, 0) | MaskAndShiftLeft(ref0, 0xFF, 3) | MaskAndShiftLeft(op, 7, 11) | + MaskAndShiftLeft(comp1, 7, 14) | MaskAndShiftLeft(ref1, 0xFF, 17); + if (sGXState.x248_alphaCompare != flags) { + sGXState.x248_alphaCompare = flags; + GXSetAlphaCompare(comp0, ref0, op, comp1, ref1); + GXSetZCompLoc(comp0 == GX_ALWAYS); + } +} +inline void CGX::SetBlendMode(GXBlendMode mode, GXBlendFactor srcFac, GXBlendFactor dstFac, GXLogicOp op) { + u32 flags = MaskAndShiftLeft(mode, 3, 0) | MaskAndShiftLeft(srcFac, 7, 2) | MaskAndShiftLeft(dstFac, 7, 5) | MaskAndShiftLeft(op, 0xF, 8); + if (flags != sGXState.x56_blendMode) { + update_fog(flags); + sGXState.x56_blendMode = flags; + GXSetBlendMode(mode, srcFac, dstFac, op); + } +} +inline void CGX::SetTevOrder(GXTevStageID stageId, GXTexCoordID texCoord, GXTexMapID texMap, GXChannelID color) { + STevState& state = sGXState.x68_tevStates[stageId]; + u32 flags = MaskAndShiftLeft(texCoord, 0xFF, 0) | MaskAndShiftLeft(texMap, 0xFF, 8) | MaskAndShiftLeft(color, 0xFF, 16); + if (state.x14_tevOrderFlags != flags) { + state.x14_tevOrderFlags = flags; + GXSetTevOrder(stageId, texCoord, texMap, color); + } +} +inline void CGX::SetTevKColorSel(GXTevStageID stageId, GXTevKColorSel sel) { + STevState& state = sGXState.x68_tevStates[stageId]; + if (sel != state.x18_kColorSel) { + state.x18_kColorSel = sel; + GXSetTevKColorSel(stageId, sel); + } +} +inline void CGX::SetTevKAlphaSel(GXTevStageID stageId, GXTevKAlphaSel sel) { + STevState& state = sGXState.x68_tevStates[stageId]; + if (sel != state.x19_kAlphaSel) { + state.x19_kAlphaSel = sel; + GXSetTevKAlphaSel(stageId, sel); + } +} + #include "Kyoto/Math/CTransform4f.hpp" CVector3f sPlayerPosition; @@ -7,5 +53,173 @@ CVector3f CCubeMaterial::sViewingFrom; static CTransform4f sTextureProjectionTransform = CTransform4f::Identity(); void CCubeMaterial::SetupBlendMode(u32 blendFactors, const CModelFlags& flags, bool alphaTest) { + GXBlendFactor newSrcFactor = static_cast< GXBlendFactor >(blendFactors & 0xFFFF); + GXBlendFactor newDstFactor = static_cast< GXBlendFactor >(blendFactors >> 0x10); + CModelFlags::ETrans blendMode = flags.GetTrans(); + if (alphaTest) { + CGX::SetAlphaCompare(GX_GEQUAL, 64, GX_AOP_OR, GX_NEVER, 0); + newSrcFactor = GX_BL_ONE; + newDstFactor = GX_BL_ZERO; + } else { + CGX::SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + } + // TODO: how to check + if (blendMode > 4 && newSrcFactor == GX_BL_ONE) { + newSrcFactor = GX_BL_SRCALPHA; + if (newDstFactor == GX_BL_ZERO) { + newDstFactor = blendMode > 6 ? GX_BL_ONE : GX_BL_INVSRCALPHA; + } + } + CGX::SetBlendMode(GX_BM_BLEND, newSrcFactor, newDstFactor, GX_LO_CLEAR); +} +void HandleTev(s32 tevCur, const u32* materialDataCur, const u32* texMapTexCoordFlags, bool shadowMapsEnabled) { + const GXTevStageID stage = static_cast< GXTevStageID >(tevCur); + const u32 colorArgs = shadowMapsEnabled ? 0x7a04f : SBig(materialDataCur[0]); + const u32 alphaArgs = SBig(materialDataCur[1]); + const u32 colorOps = SBig(materialDataCur[2]); + const u32 alphaOps = SBig(materialDataCur[3]); + + CGX::SetStandardDirectTev_Compressed(stage, colorArgs, alphaArgs, colorOps, alphaOps); + + u32 tmtcFlags = SBig(*texMapTexCoordFlags); + u32 matFlags = SBig(materialDataCur[4]); + CGX::SetTevOrder(stage, static_cast< GXTexCoordID >(tmtcFlags & 0xFF), static_cast< GXTexMapID >(tmtcFlags >> 8 & 0xFF), + static_cast< GXChannelID >(matFlags & 0xFF)); + CGX::SetTevKColorSel(stage, static_cast< GXTevKColorSel >(matFlags >> 0x8 & 0xFF)); + CGX::SetTevKAlphaSel(stage, static_cast< GXTevKAlphaSel >(matFlags >> 0x10 & 0xFF)); +} + +u32 HandleAnimatedUV(const u32* uvAnim, GXTexMtx texMtx, GXPTTexMtx ptTexMtx) { + static const Mtx postMtx = { + {0.5f, 0.0f, 0.0f, 0.5f}, + {0.0f, 0.0f, 0.5f, 0.5f}, + {0.0f, 0.0f, 0.0f, 1.0f}, + }; + static Mtx translateMtx = { + {0.5f, 0.0f, 0.0f, 0.5f}, + {0.0f, 0.0f, 0.5f, 0.5f}, + {0.0f, 0.0f, 0.0f, 1.0f}, + }; + u32 type = SBig(*uvAnim); + const f32* params = reinterpret_cast< const f32* >(uvAnim + 1); + switch (type) { + case 0: { + CTransform4f xf = CGraphics::GetViewMatrix().GetQuickInverse().MultiplyIgnoreTranslation(CGraphics::GetModelMatrix()); + xf.SetTranslation(CVector3f::Zero()); + CGX::LoadTexMtxImm(xf.GetCStyleMatrix(), texMtx, GX_MTX3x4); + CGX::LoadTexMtxImm(postMtx, ptTexMtx, GX_MTX3x4); + return 1; + } + case 1: { + CTransform4f xf = CGraphics::GetViewMatrix().GetQuickInverse() * CGraphics::GetModelMatrix(); + CGX::LoadTexMtxImm(xf.GetCStyleMatrix(), texMtx, GX_MTX3x4); + CGX::LoadTexMtxImm(postMtx, ptTexMtx, GX_MTX3x4); + return 1; + } + case 2: { + const f32 f1 = SBig(params[0]); + const f32 f2 = SBig(params[1]); + const f32 f3 = SBig(params[2]); + const f32 f4 = SBig(params[3]); + const f32 seconds = CGraphics::GetSecondsMod900(); + translateMtx[0][3] = f1 + seconds * f3; + translateMtx[1][3] = f2 + seconds * f4; + CGX::LoadTexMtxImm(translateMtx, texMtx, GX_MTX3x4); + return 5; + } + case 3: { + const f32 f1 = SBig(params[0]); + const f32 f2 = SBig(params[1]); + const f32 seconds = CGraphics::GetSecondsMod900(); + const f32 angle = f1 + seconds * f2; + const f32 asin = CMath::FastSinR(angle); + const f32 acos = CMath::FastCosR(angle); + Mtx mtx = { + {acos, -asin, 0.f, (1.f - (acos - asin)) * 0.5f}, + {asin, acos, 0.f, (1.f - (asin + acos)) * 0.5f}, + {0.f, 0.f, 1.f, 0.f}, + }; + CGX::LoadTexMtxImm(mtx, texMtx, GX_MTX3x4); + return 3; + } + case 4: + case 5: { + const f32 f1 = SBig(params[0]); + const f32 f2 = SBig(params[1]); + const f32 f3 = SBig(params[2]); + const f32 f4 = SBig(params[3]); + const f32 value = (f4 + CGraphics::GetSecondsMod900()) * f1 * f3; + const f32 fmod = CMath::FastFmod(value, 1.f); + const f32 fs = CCast::FtoS(fmod * f2); + const f32 v2 = fs * f3; + if (type == 4) { + translateMtx[0][3] = v2; + translateMtx[1][3] = 0.f; + } else { + translateMtx[0][3] = 0.f; + translateMtx[1][3] = v2; + } + CGX::LoadTexMtxImm(translateMtx, texMtx, GX_MTX3x4); + return 5; + } + case 6: { + static const Mtx sTexMtx = { + {0.f, 0.f, 0.f, 0.f}, + {0.f, 0.f, 0.f, 0.f}, + {0.f, 0.f, 0.f, 0.f}, + }; + static const Mtx sPtMtx = { + {0.5f, 0.f, 0.f, 0.f}, + {0.f, 0.f, 0.5f, 0.f}, + {0.f, 0.f, 0.f, 1.f}, + }; + const CTransform4f& mm = CGraphics::GetModelMatrix(); + Mtx tmpTexMtx; + Mtx tmpPtMtx; + __memcpy(&tmpTexMtx, &sTexMtx, sizeof(Mtx)); + const CVector3f& dx = mm.GetRow(kDX); + tmpTexMtx[0][0] = mm.Get00(); + tmpTexMtx[0][1] = mm.Get01(); + tmpTexMtx[0][2] = mm.Get02(); + tmpTexMtx[1][0] = mm.Get10(); + tmpTexMtx[1][1] = mm.Get11(); + tmpTexMtx[1][2] = mm.Get12(); + tmpTexMtx[2][0] = mm.Get20(); + tmpTexMtx[2][1] = mm.Get21(); + tmpTexMtx[2][2] = mm.Get22(); + __memcpy(&tmpPtMtx, &sPtMtx, sizeof(Mtx)); + tmpPtMtx[0][3] = mm.Get03() * 0.05f; + tmpPtMtx[1][3] = mm.Get13() * 0.05f; + CGX::LoadTexMtxImm(tmpTexMtx, texMtx, GX_MTX3x4); + CGX::LoadTexMtxImm(tmpPtMtx, ptTexMtx, GX_MTX3x4); + return 1; + } + case 7: { + static const Mtx sPtMtx = { + {0.f, 0.f, 0.f, 0.f}, + {0.f, 0.f, 0.f, 0.f}, + {0.f, 0.f, 0.f, 1.f}, + }; + const CTransform4f& vm = CGraphics::GetViewMatrix(); + CTransform4f xf = CGraphics::GetViewMatrix().GetQuickInverse().MultiplyIgnoreTranslation(CGraphics::GetModelMatrix()); + f32 v = SBig(params[0]) / 2.f; + f32 v03 = 0.025f * (vm.Get03() + vm.Get13()) * SBig(params[1]); + f32 v13 = 0.05f * vm.Get23() * SBig(params[1]); + f32 v03f = CMath::FastFmod(v03, 1.f); + f32 v13f = CMath::FastFmod(v13, 1.f); + xf.SetTranslation(CVector3f::Zero()); + Mtx tmpPtMtx; + __memcpy(&tmpPtMtx, &sPtMtx, sizeof(Mtx)); + tmpPtMtx[0][0] = v; + tmpPtMtx[0][3] = v03f; + tmpPtMtx[1][2] = v; + tmpPtMtx[1][3] = v13f; + CGX::LoadTexMtxImm(xf.GetCStyleMatrix(), texMtx, GX_MTX3x4); + CGX::LoadTexMtxImm(tmpPtMtx, ptTexMtx, GX_MTX3x4); + return 3; + } + default: + return 0; + } } \ No newline at end of file