diff --git a/include/JSystem/JGeometry.h b/include/JSystem/JGeometry.h index ecbdcbc4c5..f72694fb44 100644 --- a/include/JSystem/JGeometry.h +++ b/include/JSystem/JGeometry.h @@ -389,6 +389,37 @@ struct TBox2 : public TBox > { // clang-format on +// Row-major storage: at()/ref() are transposed relative to SMatrix33C, so +// setting a direction writes three contiguous floats. +template +struct SMatrix33R { + T mMtx[3][3]; +}; + +template <> +struct SMatrix33R { + SMatrix33R() {} + + f32 at(u32 i, u32 j) const { return mMtx[j][i]; } + f32& ref(u32 i, u32 j) { return mMtx[j][i]; } + + f32 mMtx[3][3]; +}; + +template +struct TMatrix33 : public T { + TMatrix33() {} + + void mult(const TVec3& src, TVec3& dst) const { + dst.set(this->at(0, 0) * src.x + this->at(0, 1) * src.y + this->at(0, 2) * src.z, + this->at(1, 0) * src.x + this->at(1, 1) * src.y + this->at(1, 2) * src.z, + this->at(2, 0) * src.x + this->at(2, 1) * src.y + this->at(2, 2) * src.z); + } + + void mult(TVec3& v) const { mult(v, v); } +}; + + } // namespace JGeometry #endif diff --git a/include/JSystem/TPosition3.h b/include/JSystem/TPosition3.h index 2e77b4ebbe..ad23b00405 100644 --- a/include/JSystem/TPosition3.h +++ b/include/JSystem/TPosition3.h @@ -2,6 +2,7 @@ #define TPOSITION3_H #include "dolphin/mtx/mtx.h" +#include "JSystem/JGeometry.h" #include "JSystem/JMath/JMath.h" namespace JGeometry { @@ -28,7 +29,19 @@ template struct TMatrix34 : public T {}; template -struct TRotation3 : public T {}; +struct TRotation3 : public T { + void setXYZDir(const TVec3& x, const TVec3& y, const TVec3& z) { + this->ref(0, 0) = x.x; + this->ref(1, 0) = x.y; + this->ref(2, 0) = x.z; + this->ref(0, 1) = y.x; + this->ref(1, 1) = y.y; + this->ref(2, 1) = y.z; + this->ref(0, 2) = z.x; + this->ref(1, 2) = z.y; + this->ref(2, 2) = z.z; + } +}; template struct TPosition3 : public T {}; diff --git a/src/JSystem/JParticle/JPADrawVisitor.cpp b/src/JSystem/JParticle/JPADrawVisitor.cpp index 43f85bb007..d7f80096f2 100644 --- a/src/JSystem/JParticle/JPADrawVisitor.cpp +++ b/src/JSystem/JParticle/JPADrawVisitor.cpp @@ -33,24 +33,24 @@ void JPADrawExecLoadExTex::exec(const JPADrawContext* pDC) { u16 texIdx; GXTexCoordID coord = GX_TEXCOORD1; switch (pDC->petx->getIndTexMode()) { - case 1: - GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); - GXEnableTexOffsets(GX_TEXCOORD1, GX_TRUE, GX_TRUE); - texIdx = pDC->pTexIdx[pDC->petx->getIndTextureID()]; - pDC->mpTextureResource->pTexResArray[texIdx]->load(GX_TEXMAP5); - coord = GX_TEXCOORD2; - break; - case 2: - GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); - GXSetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); - GXEnableTexOffsets(GX_TEXCOORD1, GX_TRUE, GX_TRUE); - GXEnableTexOffsets(GX_TEXCOORD2, GX_TRUE, GX_TRUE); - texIdx = pDC->pTexIdx[pDC->petx->getIndTextureID()]; - pDC->mpTextureResource->pTexResArray[texIdx]->load(GX_TEXMAP5); - texIdx = pDC->pTexIdx[pDC->petx->getSubTextureID()]; - pDC->mpTextureResource->pTexResArray[texIdx]->load(GX_TEXMAP6); - coord = GX_TEXCOORD3; - break; + case 1: + GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); + GXEnableTexOffsets(GX_TEXCOORD1, GX_TRUE, GX_TRUE); + texIdx = pDC->pTexIdx[pDC->petx->getIndTextureID()]; + pDC->mpTextureResource->pTexResArray[texIdx]->load(GX_TEXMAP5); + coord = GX_TEXCOORD2; + break; + case 2: + GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); + GXSetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); + GXEnableTexOffsets(GX_TEXCOORD1, GX_TRUE, GX_TRUE); + GXEnableTexOffsets(GX_TEXCOORD2, GX_TRUE, GX_TRUE); + texIdx = pDC->pTexIdx[pDC->petx->getIndTextureID()]; + pDC->mpTextureResource->pTexResArray[texIdx]->load(GX_TEXMAP5); + texIdx = pDC->pTexIdx[pDC->petx->getSubTextureID()]; + pDC->mpTextureResource->pTexResArray[texIdx]->load(GX_TEXMAP6); + coord = GX_TEXCOORD3; + break; } if (pDC->petx->isEnableSecondTex()) { @@ -187,7 +187,7 @@ void JPADrawExecRegisterPrmColorAnm::exec(const JPADrawContext* pDC, JPABasePart prm.r = JPA_U8_THRE(prm.r, JPADrawContext::pcb->mPrmColor.r); prm.g = JPA_U8_THRE(prm.g, JPADrawContext::pcb->mPrmColor.g); prm.b = JPA_U8_THRE(prm.b, JPADrawContext::pcb->mPrmColor.b); - u8 a = JPA_U8_THRE(prm.a, JPADrawContext::pcb->mPrmColor.a); + u8 a = JPA_U8_THRE(prm.a, JPADrawContext::pcb->mPrmColor.a); prm.a = params->mAlphaOut * a; GXSetTevColor(GX_TEVREG0, prm); } @@ -199,7 +199,7 @@ void JPADrawExecRegisterPrmAlphaAnm::exec(const JPADrawContext* pDC, JPABasePart prm.r = JPA_U8_THRE(prm.r, JPADrawContext::pcb->mPrmColor.r); prm.g = JPA_U8_THRE(prm.g, JPADrawContext::pcb->mPrmColor.g); prm.b = JPA_U8_THRE(prm.b, JPADrawContext::pcb->mPrmColor.b); - u8 a = JPA_U8_THRE(prm.a, JPADrawContext::pcb->mPrmColor.a); + u8 a = JPA_U8_THRE(prm.a, JPADrawContext::pcb->mPrmColor.a); prm.a = params->mAlphaOut * a; GXSetTevColor(GX_TEVREG0, prm); } @@ -222,7 +222,7 @@ void JPADrawExecRegisterPrmCEnv::exec(const JPADrawContext* pDC, JPABaseParticle prm.r = JPA_U8_THRE(prm.r, JPADrawContext::pcb->mPrmColor.r); prm.g = JPA_U8_THRE(prm.g, JPADrawContext::pcb->mPrmColor.g); prm.b = JPA_U8_THRE(prm.b, JPADrawContext::pcb->mPrmColor.b); - u8 a = JPA_U8_THRE(prm.a, JPADrawContext::pcb->mPrmColor.a); + u8 a = JPA_U8_THRE(prm.a, JPADrawContext::pcb->mPrmColor.a); prm.a = params->mAlphaOut * a; env.r = JPA_U8_THRE(env.r, JPADrawContext::pcb->mEnvColor.r); env.g = JPA_U8_THRE(env.g, JPADrawContext::pcb->mEnvColor.g); @@ -239,7 +239,7 @@ void JPADrawExecRegisterPrmAEnv::exec(const JPADrawContext* pDC, JPABaseParticle prm.r = JPA_U8_THRE(prm.r, JPADrawContext::pcb->mPrmColor.r); prm.g = JPA_U8_THRE(prm.g, JPADrawContext::pcb->mPrmColor.g); prm.b = JPA_U8_THRE(prm.b, JPADrawContext::pcb->mPrmColor.b); - u8 a = JPA_U8_THRE(prm.a, JPADrawContext::pcb->mPrmColor.a); + u8 a = JPA_U8_THRE(prm.a, JPADrawContext::pcb->mPrmColor.a); prm.a = params->mAlphaOut * a; env.r = JPA_U8_THRE(env.r, JPADrawContext::pcb->mEnvColor.r); env.g = JPA_U8_THRE(env.g, JPADrawContext::pcb->mEnvColor.g); @@ -352,12 +352,76 @@ void JPADrawExecRotBillBoard::exec(const JPADrawContext* pDC, JPABaseParticle* p /* 80260F2C-8026110C .text exec__21JPADrawExecYBillBoardFPC14JPADrawContextP15JPABaseParticle */ void JPADrawExecYBillBoard::exec(const JPADrawContext* pDC, JPABaseParticle* ptcl) { - /* Nonmatching */ + if (ptcl->isInvisibleParticle()) + return; + + JPADrawParams* params = ptcl->getDrawParamPPtr(); + f32 scaleX = params->mScaleX; + f32 scaleY = params->mScaleY; + + f32 x0 = scaleX * (JPADrawContext::pcb->mGlobalScaleX - JPADrawContext::pcb->mPivotX); + f32 y0 = scaleY * (JPADrawContext::pcb->mGlobalScaleY - JPADrawContext::pcb->mPivotY); + scaleX *= (JPADrawContext::pcb->mGlobalScaleX + JPADrawContext::pcb->mPivotX); + scaleY *= (JPADrawContext::pcb->mGlobalScaleY + JPADrawContext::pcb->mPivotY); + + JGeometry::TVec3 pt[4]; + pt[0].set(-scaleX, +scaleY, 0.0f); + pt[1].set(+x0, +scaleY, 0.0f); + pt[2].set(+x0, -y0, 0.0f); + pt[3].set(-scaleX, -y0, 0.0f); + MTXMultVecArray(JPADrawContext::pcb->mDrawYBBMtx, pt, pt, ARRAY_SIZE(pt)); + + JGeometry::TVec3 pos; + ptcl->getGlobalPosition(pos); + MTXMultVecSR(JPADrawContext::pcb->mDrawMtxPtr, pos, &pos); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(pt[0].x + pos.x, pt[0].y + pos.y, pt[0].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[0].x, JPADrawContext::pcb->mTexCoordPt[0].y); + GXPosition3f32(pt[1].x + pos.x, pt[1].y + pos.y, pt[1].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[1].x, JPADrawContext::pcb->mTexCoordPt[1].y); + GXPosition3f32(pt[2].x + pos.x, pt[2].y + pos.y, pt[2].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[2].x, JPADrawContext::pcb->mTexCoordPt[2].y); + GXPosition3f32(pt[3].x + pos.x, pt[3].y + pos.y, pt[3].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[3].x, JPADrawContext::pcb->mTexCoordPt[3].y); + GXEnd(); } /* 8026110C-8026134C .text exec__24JPADrawExecRotYBillBoardFPC14JPADrawContextP15JPABaseParticle */ void JPADrawExecRotYBillBoard::exec(const JPADrawContext* pDC, JPABaseParticle* ptcl) { - /* Nonmatching */ + if (ptcl->isInvisibleParticle()) + return; + + JPADrawParams* params = ptcl->getDrawParamPPtr(); + f32 sin = JMASSin(params->mRotateAngle); + f32 cos = JMASCos(params->mRotateAngle); + + f32 x0 = -params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX + JPADrawContext::pcb->mPivotX); + f32 y0 = +params->mScaleY * (JPADrawContext::pcb->mGlobalScaleY + JPADrawContext::pcb->mPivotY); + f32 x1 = +params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX - JPADrawContext::pcb->mPivotX); + f32 y1 = -params->mScaleY * (JPADrawContext::pcb->mGlobalScaleY - JPADrawContext::pcb->mPivotY); + + JGeometry::TVec3 pt[4]; + pt[0].set(x0 * cos - y0 * sin, y0 * cos + x0 * sin, 0.0f); + pt[1].set(x1 * cos - y0 * sin, y0 * cos + x1 * sin, 0.0f); + pt[2].set(x1 * cos - y1 * sin, y1 * cos + x1 * sin, 0.0f); + pt[3].set(x0 * cos - y1 * sin, y1 * cos + x0 * sin, 0.0f); + MTXMultVecArray(JPADrawContext::pcb->mDrawYBBMtx, pt, pt, ARRAY_SIZE(pt)); + + JGeometry::TVec3 pos; + ptcl->getGlobalPosition(pos); + MTXMultVecSR(JPADrawContext::pcb->mDrawMtxPtr, pos, &pos); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(pt[0].x + pos.x, pt[0].y + pos.y, pt[0].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[0].x, JPADrawContext::pcb->mTexCoordPt[0].y); + GXPosition3f32(pt[1].x + pos.x, pt[1].y + pos.y, pt[1].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[1].x, JPADrawContext::pcb->mTexCoordPt[1].y); + GXPosition3f32(pt[2].x + pos.x, pt[2].y + pos.y, pt[2].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[2].x, JPADrawContext::pcb->mTexCoordPt[2].y); + GXPosition3f32(pt[3].x + pos.x, pt[3].y + pos.y, pt[3].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[3].x, JPADrawContext::pcb->mTexCoordPt[3].y); + GXEnd(); } /* 8026134C-80261368 .text dirTypeVel__FP15JPABaseParticleP14JPABaseEmitterRQ29JGeometry8TVec3 */ @@ -510,27 +574,352 @@ void basePlaneTypeXZ(f32 x0, f32 x1, f32 y0, f32 y1, JGeometry::TVec3* out) /* 8026168C-80261AD0 .text exec__22JPADrawExecDirectionalFPC14JPADrawContextP15JPABaseParticle */ void JPADrawExecDirectional::exec(const JPADrawContext* pDC, JPABaseParticle* ptcl) { - /* Nonmatching */ + if (ptcl->isInvisibleParticle()) + return; + + JPADrawParams* params = ptcl->getDrawParamPPtr(); + + JGeometry::TVec3 pt[4]; + JPADrawContext::pcb->mBasePlaneTypeFunc( + -params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX + JPADrawContext::pcb->mPivotX), + +params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX - JPADrawContext::pcb->mPivotX), + +params->mScaleY * (JPADrawContext::pcb->mGlobalScaleY + JPADrawContext::pcb->mPivotY), + -params->mScaleY * (JPADrawContext::pcb->mGlobalScaleY - JPADrawContext::pcb->mPivotY), + pt + ); + + JGeometry::TVec3 dir; + JPADrawContext::pcb->mDirTypeFunc(ptcl, pDC->pbe, dir); + if (dir.isZero()) + return; + dir.normalize(); + + JGeometry::TVec3 side; + side.cross(params->mAxis, dir); + if (side.isZero()) + return; + side.normalize(); + + params->mAxis.cross(dir, side); + params->mAxis.normalize(); + + Mtx mtx; + mtx[0][0] = params->mAxis.x; + mtx[0][1] = dir.x; + mtx[0][2] = side.x; + mtx[0][3] = 0.0f; + mtx[1][0] = params->mAxis.y; + mtx[1][1] = dir.y; + mtx[1][2] = side.y; + mtx[1][3] = 0.0f; + mtx[2][0] = params->mAxis.z; + mtx[2][1] = dir.z; + mtx[2][2] = side.z; + mtx[2][3] = 0.0f; + MTXMultVecArray(mtx, pt, pt, ARRAY_SIZE(pt)); + + JGeometry::TVec3 pos; + ptcl->getGlobalPosition(pos); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(pt[0].x + pos.x, pt[0].y + pos.y, pt[0].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[0].x, JPADrawContext::pcb->mTexCoordPt[0].y); + GXPosition3f32(pt[1].x + pos.x, pt[1].y + pos.y, pt[1].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[1].x, JPADrawContext::pcb->mTexCoordPt[1].y); + GXPosition3f32(pt[2].x + pos.x, pt[2].y + pos.y, pt[2].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[2].x, JPADrawContext::pcb->mTexCoordPt[2].y); + GXPosition3f32(pt[3].x + pos.x, pt[3].y + pos.y, pt[3].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[3].x, JPADrawContext::pcb->mTexCoordPt[3].y); + GXEnd(); } /* 80261AD0-80261F60 .text exec__25JPADrawExecRotDirectionalFPC14JPADrawContextP15JPABaseParticle */ void JPADrawExecRotDirectional::exec(const JPADrawContext* pDC, JPABaseParticle* ptcl) { - /* Nonmatching */ + if (ptcl->isInvisibleParticle()) + return; + + JPADrawParams* params = ptcl->getDrawParamPPtr(); + f32 sin = JMASSin(params->mRotateAngle); + f32 cos = JMASCos(params->mRotateAngle); + + Mtx rotMtx; + JGeometry::TVec3 pt[4]; + JPADrawContext::pcb->mBasePlaneTypeFunc( + -params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX + JPADrawContext::pcb->mPivotX), + +params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX - JPADrawContext::pcb->mPivotX), + +params->mScaleY * (JPADrawContext::pcb->mGlobalScaleY + JPADrawContext::pcb->mPivotY), + -params->mScaleY * (JPADrawContext::pcb->mGlobalScaleY - JPADrawContext::pcb->mPivotY), + pt + ); + JPADrawContext::pcb->mRotTypeFunc(sin, cos, rotMtx); + + JGeometry::TVec3 dir; + JPADrawContext::pcb->mDirTypeFunc(ptcl, pDC->pbe, dir); + if (dir.isZero()) + return; + dir.normalize(); + + JGeometry::TVec3 side; + side.cross(params->mAxis, dir); + if (side.isZero()) + return; + side.normalize(); + + params->mAxis.cross(dir, side); + params->mAxis.normalize(); + + Mtx mtx; + mtx[0][0] = params->mAxis.x; + mtx[0][1] = dir.x; + mtx[0][2] = side.x; + mtx[0][3] = 0.0f; + mtx[1][0] = params->mAxis.y; + mtx[1][1] = dir.y; + mtx[1][2] = side.y; + mtx[1][3] = 0.0f; + mtx[2][0] = params->mAxis.z; + mtx[2][1] = dir.z; + mtx[2][2] = side.z; + mtx[2][3] = 0.0f; + + Mtx concat; + MTXConcat(mtx, rotMtx, concat); + MTXMultVecArray(concat, pt, pt, ARRAY_SIZE(pt)); + + JGeometry::TVec3 pos; + ptcl->getGlobalPosition(pos); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(pt[0].x + pos.x, pt[0].y + pos.y, pt[0].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[0].x, JPADrawContext::pcb->mTexCoordPt[0].y); + GXPosition3f32(pt[1].x + pos.x, pt[1].y + pos.y, pt[1].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[1].x, JPADrawContext::pcb->mTexCoordPt[1].y); + GXPosition3f32(pt[2].x + pos.x, pt[2].y + pos.y, pt[2].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[2].x, JPADrawContext::pcb->mTexCoordPt[2].y); + GXPosition3f32(pt[3].x + pos.x, pt[3].y + pos.y, pt[3].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[3].x, JPADrawContext::pcb->mTexCoordPt[3].y); + GXEnd(); } /* 80261F60-802624D4 .text exec__27JPADrawExecDirectionalCrossFPC14JPADrawContextP15JPABaseParticle */ void JPADrawExecDirectionalCross::exec(const JPADrawContext* pDC, JPABaseParticle* ptcl) { - /* Nonmatching */ + if (ptcl->isInvisibleParticle()) + return; + + JPADrawParams* params = ptcl->getDrawParamPPtr(); + + f32 x0 = -params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX + JPADrawContext::pcb->mPivotX); + f32 y0 = +params->mScaleY * (JPADrawContext::pcb->mGlobalScaleY + JPADrawContext::pcb->mPivotY); + f32 x1 = +params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX - JPADrawContext::pcb->mPivotX); + f32 y1 = -params->mScaleY * (JPADrawContext::pcb->mGlobalScaleY - JPADrawContext::pcb->mPivotY); + + JGeometry::TVec3 pt[8]; + pt[0].set(x0, y0, 0.0f); + pt[1].set(x1, y0, 0.0f); + pt[2].set(x1, y1, 0.0f); + pt[3].set(x0, y1, 0.0f); + f32 z0 = 0.5f * (x1 - x0); + f32 x2 = 0.5f * (x1 + x0); + pt[4].set(x2, y0, z0); + f32 z1 = 0.5f * (x0 - x1); + pt[5].set(x2, y0, z1); + pt[6].set(x2, y1, z1); + pt[7].set(x2, y1, z0); + + JGeometry::TVec3 dir; + JPADrawContext::pcb->mDirTypeFunc(ptcl, pDC->pbe, dir); + if (dir.isZero()) + return; + dir.normalize(); + + JGeometry::TVec3 side; + side.cross(params->mAxis, dir); + if (side.isZero()) + return; + side.normalize(); + + params->mAxis.cross(dir, side); + params->mAxis.normalize(); + + Mtx mtx; + mtx[0][0] = params->mAxis.x; + mtx[0][1] = dir.x; + mtx[0][2] = side.x; + mtx[0][3] = 0.0f; + mtx[1][0] = params->mAxis.y; + mtx[1][1] = dir.y; + mtx[1][2] = side.y; + mtx[1][3] = 0.0f; + mtx[2][0] = params->mAxis.z; + mtx[2][1] = dir.z; + mtx[2][2] = side.z; + mtx[2][3] = 0.0f; + MTXMultVecArray(mtx, pt, pt, ARRAY_SIZE(pt)); + + JGeometry::TVec3 pos; + ptcl->getGlobalPosition(pos); + + GXBegin(GX_QUADS, GX_VTXFMT0, 8); + GXPosition3f32(pt[0].x + pos.x, pt[0].y + pos.y, pt[0].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[0].x, JPADrawContext::pcb->mTexCoordPt[0].y); + GXPosition3f32(pt[1].x + pos.x, pt[1].y + pos.y, pt[1].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[1].x, JPADrawContext::pcb->mTexCoordPt[1].y); + GXPosition3f32(pt[2].x + pos.x, pt[2].y + pos.y, pt[2].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[2].x, JPADrawContext::pcb->mTexCoordPt[2].y); + GXPosition3f32(pt[3].x + pos.x, pt[3].y + pos.y, pt[3].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[3].x, JPADrawContext::pcb->mTexCoordPt[3].y); + GXPosition3f32(pt[4].x + pos.x, pt[4].y + pos.y, pt[4].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[0].x, JPADrawContext::pcb->mTexCoordPt[0].y); + GXPosition3f32(pt[5].x + pos.x, pt[5].y + pos.y, pt[5].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[1].x, JPADrawContext::pcb->mTexCoordPt[1].y); + GXPosition3f32(pt[6].x + pos.x, pt[6].y + pos.y, pt[6].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[2].x, JPADrawContext::pcb->mTexCoordPt[2].y); + GXPosition3f32(pt[7].x + pos.x, pt[7].y + pos.y, pt[7].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[3].x, JPADrawContext::pcb->mTexCoordPt[3].y); + GXEnd(); } /* 802624D4-80262A98 .text exec__30JPADrawExecRotDirectionalCrossFPC14JPADrawContextP15JPABaseParticle */ void JPADrawExecRotDirectionalCross::exec(const JPADrawContext* pDC, JPABaseParticle* ptcl) { - /* Nonmatching */ + if (ptcl->isInvisibleParticle()) + return; + + JPADrawParams* params = ptcl->getDrawParamPPtr(); + f32 sin = JMASSin(params->mRotateAngle); + f32 cos = JMASCos(params->mRotateAngle); + + f32 x0 = -params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX + JPADrawContext::pcb->mPivotX); + f32 y0 = +params->mScaleY * (JPADrawContext::pcb->mGlobalScaleY + JPADrawContext::pcb->mPivotY); + f32 x1 = +params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX - JPADrawContext::pcb->mPivotX); + f32 y1 = -params->mScaleY * (JPADrawContext::pcb->mGlobalScaleY - JPADrawContext::pcb->mPivotY); + + Mtx rotMtx; + JGeometry::TVec3 pt[8]; + pt[0].set(x0, y0, 0.0f); + pt[1].set(x1, y0, 0.0f); + pt[2].set(x1, y1, 0.0f); + pt[3].set(x0, y1, 0.0f); + f32 z0 = 0.5f * (x1 - x0); + f32 x2 = 0.5f * (x1 + x0); + pt[4].set(x2, y0, z0); + f32 z1 = 0.5f * (x0 - x1); + pt[5].set(x2, y0, z1); + pt[6].set(x2, y1, z1); + pt[7].set(x2, y1, z0); + + JPADrawContext::pcb->mRotTypeFunc(sin, cos, rotMtx); + + JGeometry::TVec3 dir; + JPADrawContext::pcb->mDirTypeFunc(ptcl, pDC->pbe, dir); + if (dir.isZero()) + return; + dir.normalize(); + + JGeometry::TVec3 side; + side.cross(params->mAxis, dir); + if (side.isZero()) + return; + side.normalize(); + + params->mAxis.cross(dir, side); + params->mAxis.normalize(); + + Mtx mtx; + mtx[0][0] = params->mAxis.x; + mtx[0][1] = dir.x; + mtx[0][2] = side.x; + mtx[0][3] = 0.0f; + mtx[1][0] = params->mAxis.y; + mtx[1][1] = dir.y; + mtx[1][2] = side.y; + mtx[1][3] = 0.0f; + mtx[2][0] = params->mAxis.z; + mtx[2][1] = dir.z; + mtx[2][2] = side.z; + mtx[2][3] = 0.0f; + + Mtx concat; + MTXConcat(mtx, rotMtx, concat); + MTXMultVecArray(concat, pt, pt, ARRAY_SIZE(pt)); + + JGeometry::TVec3 pos; + ptcl->getGlobalPosition(pos); + + GXBegin(GX_QUADS, GX_VTXFMT0, 8); + GXPosition3f32(pt[0].x + pos.x, pt[0].y + pos.y, pt[0].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[0].x, JPADrawContext::pcb->mTexCoordPt[0].y); + GXPosition3f32(pt[1].x + pos.x, pt[1].y + pos.y, pt[1].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[1].x, JPADrawContext::pcb->mTexCoordPt[1].y); + GXPosition3f32(pt[2].x + pos.x, pt[2].y + pos.y, pt[2].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[2].x, JPADrawContext::pcb->mTexCoordPt[2].y); + GXPosition3f32(pt[3].x + pos.x, pt[3].y + pos.y, pt[3].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[3].x, JPADrawContext::pcb->mTexCoordPt[3].y); + GXPosition3f32(pt[4].x + pos.x, pt[4].y + pos.y, pt[4].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[0].x, JPADrawContext::pcb->mTexCoordPt[0].y); + GXPosition3f32(pt[5].x + pos.x, pt[5].y + pos.y, pt[5].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[1].x, JPADrawContext::pcb->mTexCoordPt[1].y); + GXPosition3f32(pt[6].x + pos.x, pt[6].y + pos.y, pt[6].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[2].x, JPADrawContext::pcb->mTexCoordPt[2].y); + GXPosition3f32(pt[7].x + pos.x, pt[7].y + pos.y, pt[7].z + pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[3].x, JPADrawContext::pcb->mTexCoordPt[3].y); + GXEnd(); } /* 80262A98-80262DC0 .text exec__23JPADrawExecDirBillBoardFPC14JPADrawContextP15JPABaseParticle */ void JPADrawExecDirBillBoard::exec(const JPADrawContext* pDC, JPABaseParticle* ptcl) { - /* Nonmatching */ + if (ptcl->isInvisibleParticle()) + return; + + JGeometry::TVec3 dir; + JPADrawContext::pcb->mDirTypeFunc(ptcl, pDC->pbe, dir); + JGeometry::TVec3 zdir(*(Vec*)JPADrawContext::pcb->mDrawMtxPtr[2]); + dir.cross(dir, zdir); + if (dir.isZero()) + return; + dir.normalize(); + MTXMultVecSR(JPADrawContext::pcb->mDrawMtxPtr, dir, &dir); + + JPADrawParams* params = ptcl->getDrawParamPPtr(); + f32 dirY = dir.y; + f32 scaleX = params->mScaleX; + f32 scaleY = params->mScaleY; + + f32 x1 = scaleX * (JPADrawContext::pcb->mGlobalScaleX - JPADrawContext::pcb->mPivotX); + f32 y1 = scaleY * (JPADrawContext::pcb->mGlobalScaleY - JPADrawContext::pcb->mPivotY); + scaleX *= (JPADrawContext::pcb->mGlobalScaleX + JPADrawContext::pcb->mPivotX); + scaleY *= (JPADrawContext::pcb->mGlobalScaleY + JPADrawContext::pcb->mPivotY); + + f32 x0 = -scaleX; + y1 = -y1; + f32 dirX = dir.x; + + JGeometry::TVec2 p0; + JGeometry::TVec2 p1; + JGeometry::TVec2 p2; + JGeometry::TVec2 p3; + p0.set(x0, scaleY); + p1.set(x1, scaleY); + p2.set(x1, y1); + p3.set(x0, y1); + p0.set(dirX * p0.x - dirY * p0.y, dirX * p0.y + dirY * p0.x); + p1.set(dirX * p1.x - dirY * p1.y, dirX * p1.y + dirY * p1.x); + p2.set(dirX * p2.x - dirY * p2.y, dirX * p2.y + dirY * p2.x); + p3.set(dirX * p3.x - dirY * p3.y, dirX * p3.y + dirY * p3.x); + + JGeometry::TVec3 pos; + ptcl->getGlobalPosition(pos); + MTXMultVec(JPADrawContext::pcb->mDrawMtxPtr, pos, &pos); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(p0.x + pos.x, p0.y + pos.y, pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[0].x, JPADrawContext::pcb->mTexCoordPt[0].y); + GXPosition3f32(p1.x + pos.x, p1.y + pos.y, pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[1].x, JPADrawContext::pcb->mTexCoordPt[1].y); + GXPosition3f32(p2.x + pos.x, p2.y + pos.y, pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[2].x, JPADrawContext::pcb->mTexCoordPt[2].y); + GXPosition3f32(p3.x + pos.x, p3.y + pos.y, pos.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[3].x, JPADrawContext::pcb->mTexCoordPt[3].y); + GXEnd(); } /* 80262DC0-80262FBC .text exec__19JPADrawExecRotationFPC14JPADrawContextP15JPABaseParticle */ @@ -590,13 +979,10 @@ void JPADrawExecRotationCross::exec(const JPADrawContext* pDC, JPABaseParticle* pt[2].set(x1, y1, 0.0f); pt[3].set(x0, y1, 0.0f); - f32 x2 = (x1 + x0) * 0.5f; - f32 z0 = (x1 - x0) * 0.5f; - f32 z1 = (x0 - x1) * 0.5f; - pt[4].set(x2, y0, z0); - pt[5].set(x2, y0, z1); - pt[6].set(x2, y1, z1); - pt[7].set(x2, y1, z0); + pt[4].set((pt[1].x + pt[0].x) * 0.5f, y0, (pt[1].x - pt[0].x) * 0.5f); + pt[5].set((pt[1].x + pt[0].x) * 0.5f, y0, (pt[0].x - pt[1].x) * 0.5f); + pt[6].set((pt[1].x + pt[0].x) * 0.5f, y1, (pt[0].x - pt[1].x) * 0.5f); + pt[7].set((pt[1].x + pt[0].x) * 0.5f, y1, (pt[1].x - pt[0].x) * 0.5f); Mtx rotMtx; JPADrawContext::pcb->mRotTypeFunc(sin, cos, rotMtx); @@ -678,12 +1064,206 @@ JSULink* stripeGetPrev(JSULink* link) { /* 80263518-80263A68 .text exec__17JPADrawExecStripeFPC14JPADrawContext */ void JPADrawExecStripe::exec(const JPADrawContext* pDC) { - /* Nonmatching */ + u32 numLinks = pDC->mpActiveParticles->getNumLinks(); + if (numLinks < 2) + return; + + typedef JSULink* (*NextFunc)(JSULink*); + + JSULink* start; + NextFunc getNext; + f32 texT = 0.0f; + f32 texStep = 1.0f / (numLinks - 1); + if (!pDC->pbsp->getListOrder()) { + start = pDC->mpActiveParticles->getFirst(); + getNext = stripeGetNext; + } else { + start = pDC->mpActiveParticles->getLast(); + getNext = stripeGetPrev; + texT = 1.0f; + texStep = -texStep; + } + + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, numLinks * 2); + for (JSULink* link = start; link != NULL; link = getNext(link), texT += texStep) { + JPABaseParticle* ptcl = link->getObject(); + JGeometry::TVec3 pos; + ptcl->getGlobalPosition(pos); + + JPADrawParams* params = ptcl->getDrawParamPPtr(); + f32 sin = JMASSin(params->mRotateAngle); + f32 cos = JMASCos(params->mRotateAngle); + + f32 sx0; + f32 sx1; + f32 cx0; + f32 cx1; + f32 x0 = -params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX + JPADrawContext::pcb->mPivotX); + sx0 = x0 * sin; + cx0 = x0 * cos; + f32 x1 = +params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX - JPADrawContext::pcb->mPivotX); + sx1 = x1 * sin; + cx1 = x1 * cos; + + JGeometry::TVec3 dir; + JPADrawContext::pcb->mDirTypeFunc(ptcl, pDC->pbe, dir); + if (dir.isZero()) + dir.set(0.0f, 1.0f, 0.0f); + else + dir.normalize(); + + JGeometry::TVec3 side; + side.cross(params->mAxis, dir); + if (side.isZero()) + side.set(1.0f, 0.0f, 0.0f); + else + side.normalize(); + + params->mAxis.cross(dir, side); + params->mAxis.normalize(); + + JGeometry::TRotation3 > > mtx; + mtx.setXYZDir(side, dir, params->mAxis); + + f32* hack = &mtx.mMtx[0][0]; + + JGeometry::TVec3 v1(cx0, 0.0f, sx0); + JGeometry::TVec3 v2(cx1, 0.0f, sx1); + mtx.mult(v1); + mtx.mult(v2); + + GXPosition3f32(v1.x + pos.x, v1.y + pos.y, v1.z + pos.z); + GXTexCoord2f32(0.0f, texT); + GXPosition3f32(v2.x + pos.x, v2.y + pos.y, v2.z + pos.z); + GXTexCoord2f32(1.0f, texT); + } + GXEnd(); } /* 80263A68-802643B0 .text exec__22JPADrawExecStripeCrossFPC14JPADrawContext */ void JPADrawExecStripeCross::exec(const JPADrawContext* pDC) { - /* Nonmatching */ + u32 numLinks = pDC->mpActiveParticles->getNumLinks(); + if (numLinks < 2) + return; + + typedef JSULink* (*NextFunc)(JSULink*); + + JSULink* start; + NextFunc getNext; + f32 texT0; + f32 texT; + f32 texStep = 1.0f / (numLinks - 1); + if (!pDC->pbsp->getListOrder()) { + start = pDC->mpActiveParticles->getFirst(); + getNext = stripeGetNext; + texT = texT0 = 0.0f; + } else { + start = pDC->mpActiveParticles->getLast(); + getNext = stripeGetPrev; + texT = texT0 = 1.0f; + texStep = -texStep; + } + + // `dir` is shared between both loops: loop 1 passes its address to the + // indirect mDirTypeFunc call, which pins it to the stack for the whole + // function, so loop 2's accesses go through memory as well. + JGeometry::TVec3 dir; + JGeometry::TRotation3 > > mtx; + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, numLinks * 2); + for (JSULink* link = start; link != NULL; link = getNext(link), texT += texStep) { + JPABaseParticle* ptcl = link->getObject(); + JGeometry::TVec3 pos; + ptcl->getGlobalPosition(pos); + + JPADrawParams* params = ptcl->getDrawParamPPtr(); + f32 sin = JMASSin(params->mRotateAngle); + f32 cos = JMASCos(params->mRotateAngle); + + f32 x0 = -params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX + JPADrawContext::pcb->mPivotX); + JGeometry::TVec3 v1(x0 * cos, 0.0f, x0 * sin); + f32 x1 = +params->mScaleX * (JPADrawContext::pcb->mGlobalScaleX - JPADrawContext::pcb->mPivotX); + JGeometry::TVec3 v2(x1 * cos, 0.0f, x1 * sin); + + JPADrawContext::pcb->mDirTypeFunc(ptcl, pDC->pbe, dir); + if (dir.isZero()) + dir.set(0.0f, 1.0f, 0.0f); + else + dir.normalize(); + + JGeometry::TVec3 side; + side.cross(params->mAxis, dir); + if (side.isZero()) + side.set(1.0f, 0.0f, 0.0f); + else + side.normalize(); + + params->mAxis.cross(dir, side); + params->mAxis.normalize(); + + mtx.setXYZDir(side, dir, params->mAxis); + + f32* hack = &mtx.mMtx[0][0]; + + mtx.mult(v1); + mtx.mult(v2); + + GXPosition3f32(v1.x + pos.x, v1.y + pos.y, v1.z + pos.z); + GXTexCoord2f32(0.0f, texT); + GXPosition3f32(v2.x + pos.x, v2.y + pos.y, v2.z + pos.z); + GXTexCoord2f32(1.0f, texT); + } + GXEnd(); + + texT = texT0; + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, numLinks * 2); + for (JSULink* link = start; link != NULL; link = getNext(link), texT += texStep) { + JPABaseParticle* ptcl = link->getObject(); + JGeometry::TVec3 pos; + ptcl->getGlobalPosition(pos); + + JPADrawParams* params = ptcl->getDrawParamPPtr(); + f32 cos = JMASCos(params->mRotateAngle); + f32 sin = -JMASSin(params->mRotateAngle); + + f32 scaleY = params->mScaleY; + f32 x0 = scaleY * (JPADrawContext::pcb->mGlobalScaleY + JPADrawContext::pcb->mPivotY); + // This stripe is the perpendicular one, so the width direction is + // (-sin, 0, cos) instead of the first loop's (cos, 0, sin). + JGeometry::TVec3 v1(x0 * sin, 0.0f, x0 * cos); + scaleY = -scaleY; + f32 x1 = scaleY * (JPADrawContext::pcb->mGlobalScaleY - JPADrawContext::pcb->mPivotY); + JGeometry::TVec3 v2(x1 * sin, 0.0f, x1 * cos); + + ptcl->getVelVec(dir); + + if (dir.isZero()) + dir.set(0.0f, 1.0f, 0.0f); + else + dir.normalize(); + + JGeometry::TVec3 side; + side.cross(params->mAxis, dir); + if (side.isZero()) + side.set(1.0f, 0.0f, 0.0f); + else + side.normalize(); + + params->mAxis.cross(dir, side); + params->mAxis.normalize(); + + mtx.setXYZDir(side, dir, params->mAxis); + + f32* hack2 = &mtx.mMtx[0][0]; + + mtx.mult(v1); + mtx.mult(v2); + + GXPosition3f32(v1.x + pos.x, v1.y + pos.y, v1.z + pos.z); + GXTexCoord2f32(0.0f, texT); + GXPosition3f32(v2.x + pos.x, v2.y + pos.y, v2.z + pos.z); + GXTexCoord2f32(1.0f, texT); + } + GXEnd(); } /* 802643B0-802644B4 .text exec__33JPADrawExecRegisterColorEmitterPEFPC14JPADrawContext */ @@ -828,7 +1408,8 @@ void JPADrawCalcScaleX::calc(const JPADrawContext* pDC, JPABaseParticle* ptcl) { if (JPADrawContext::pcb->mScaleAnmTiming < pDC->pesp->getScaleInTiming()) { params->mScaleX = params->mScaleOut * ((pDC->pesp->getIncreaseRateX() * JPADrawContext::pcb->mScaleAnmTiming) + pDC->pesp->getScaleInValueX()); } else if (JPADrawContext::pcb->mScaleAnmTiming > pDC->pesp->getScaleOutTiming()) { - params->mScaleX = params->mScaleOut * ((pDC->pesp->getDecreaseRateX() * (JPADrawContext::pcb->mScaleAnmTiming - pDC->pesp->getScaleOutTiming())) + 1.0f); + params->mScaleX = + params->mScaleOut * ((pDC->pesp->getDecreaseRateX() * (JPADrawContext::pcb->mScaleAnmTiming - pDC->pesp->getScaleOutTiming())) + 1.0f); } else { params->mScaleX = params->mScaleOut; } @@ -840,7 +1421,8 @@ void JPADrawCalcScaleY::calc(const JPADrawContext* pDC, JPABaseParticle* ptcl) { if (JPADrawContext::pcb->mScaleAnmTiming < pDC->pesp->getScaleInTiming()) { params->mScaleY = params->mScaleOut * ((pDC->pesp->getIncreaseRateY() * JPADrawContext::pcb->mScaleAnmTiming) + pDC->pesp->getScaleInValueY()); } else if (JPADrawContext::pcb->mScaleAnmTiming > pDC->pesp->getScaleOutTiming()) { - params->mScaleY = params->mScaleOut * ((pDC->pesp->getDecreaseRateY() * (JPADrawContext::pcb->mScaleAnmTiming - pDC->pesp->getScaleOutTiming())) + 1.0f); + params->mScaleY = + params->mScaleOut * ((pDC->pesp->getDecreaseRateY() * (JPADrawContext::pcb->mScaleAnmTiming - pDC->pesp->getScaleOutTiming())) + 1.0f); } else { params->mScaleY = params->mScaleOut; } @@ -854,7 +1436,8 @@ void JPADrawCalcScaleXBySpeed::calc(const JPADrawContext* pDC, JPABaseParticle* if (JPADrawContext::pcb->mScaleAnmTiming < pDC->pesp->getScaleInTiming()) { params->mScaleX = params->mScaleOut * ((pDC->pesp->getIncreaseRateX() * JPADrawContext::pcb->mScaleAnmTiming) + pDC->pesp->getScaleInValueX()); } else if (JPADrawContext::pcb->mScaleAnmTiming > pDC->pesp->getScaleOutTiming()) { - params->mScaleX = params->mScaleOut * ((pDC->pesp->getDecreaseRateX() * (JPADrawContext::pcb->mScaleAnmTiming - pDC->pesp->getScaleOutTiming())) + 1.0f); + params->mScaleX = + params->mScaleOut * ((pDC->pesp->getDecreaseRateX() * (JPADrawContext::pcb->mScaleAnmTiming - pDC->pesp->getScaleOutTiming())) + 1.0f); } else { params->mScaleX = params->mScaleOut; } @@ -869,7 +1452,8 @@ void JPADrawCalcScaleYBySpeed::calc(const JPADrawContext* pDC, JPABaseParticle* if (JPADrawContext::pcb->mScaleAnmTiming < pDC->pesp->getScaleInTiming()) { params->mScaleY = params->mScaleOut * ((pDC->pesp->getIncreaseRateY() * JPADrawContext::pcb->mScaleAnmTiming) + pDC->pesp->getScaleInValueY()); } else if (JPADrawContext::pcb->mScaleAnmTiming > pDC->pesp->getScaleOutTiming()) { - params->mScaleY = params->mScaleOut * ((pDC->pesp->getDecreaseRateY() * (JPADrawContext::pcb->mScaleAnmTiming - pDC->pesp->getScaleOutTiming())) + 1.0f); + params->mScaleY = + params->mScaleOut * ((pDC->pesp->getDecreaseRateY() * (JPADrawContext::pcb->mScaleAnmTiming - pDC->pesp->getScaleOutTiming())) + 1.0f); } else { params->mScaleY = params->mScaleOut; } @@ -998,12 +1582,14 @@ void JPADrawCalcAlphaFlickNrmSin::calc(const JPADrawContext* pDC, JPABaseParticl /* 80265D54-80265EC4 .text calc__27JPADrawCalcAlphaFlickAddSinFPC14JPADrawContextP15JPABaseParticle */ void JPADrawCalcAlphaFlickAddSin::calc(const JPADrawContext* pDC, JPABaseParticle* ptcl) { - /* Nonmatching - operand swap */ JPADrawParams* params = ptcl->getDrawParamPPtr(); f32 theta = (ptcl->getAge() * 0x4000) * params->mAlphaWaveRandom; - f32 sin2 = JMASSin(theta * (1.0f - pDC->pesp->getAlphaWaveParam2())); - f32 sin1 = JMASSin(theta * (1.0f - pDC->pesp->getAlphaWaveParam1())); - params->mAlphaOut *= (params->mAlphaWaveRandom * ((((sin1 + sin2) - 2.0f) * 0.5f) * pDC->pesp->getAlphaWaveParam3()) + 2.0f) * 0.5f; + params->mAlphaOut *= + (params->mAlphaWaveRandom * + ((((JMASSin(theta * (1.0f - pDC->pesp->getAlphaWaveParam1())) + JMASSin(theta * (1.0f - pDC->pesp->getAlphaWaveParam2()))) - 2.0f) * 0.5f) * + pDC->pesp->getAlphaWaveParam3()) + + 2.0f) * + 0.5f; if (params->mAlphaOut < 0.0f) params->mAlphaOut = 0.0f; } @@ -1031,7 +1617,8 @@ void JPADrawCalcTextureAnmIndexNormal::calc(const JPADrawContext* pDC, JPABasePa void JPADrawCalcTextureAnmIndexRepeat::calc(const JPADrawContext* pDC, JPABaseParticle* ptcl) { JPADrawParams* params = ptcl->getDrawParamPPtr(); s32 tick = ptcl->getAge(); - params->mTexIdx = pDC->pTexIdx[pDC->pbsp->getTextureIndex(((params->mLoopOffset & pDC->pbsp->getTexLoopOffset()) + tick) % pDC->pbsp->getTextureAnmKeyNum())]; + params->mTexIdx = + pDC->pTexIdx[pDC->pbsp->getTextureIndex(((params->mLoopOffset & pDC->pbsp->getTexLoopOffset()) + tick) % pDC->pbsp->getTextureAnmKeyNum())]; } /* 802661B4-80266284 .text calc__33JPADrawCalcTextureAnmIndexReverseFPC14JPADrawContextP15JPABaseParticle */