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 /src | |
| parent | 5df26c52fcc06e017f2cf525264d4f7563715e05 (diff) | |
Initial import of JParticle + JSUList from TP
Diffstat (limited to 'src')
| -rw-r--r-- | src/JSystem/JParticle/JPABaseShape.cpp | 1449 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAChildShape.cpp | 48 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPADynamicsBlock.cpp | 233 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAEmitter.cpp | 183 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAEmitterManager.cpp | 203 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAExTexShape.cpp | 35 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAExtraShape.cpp | 152 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAFieldBlock.cpp | 299 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAKeyBlock.cpp | 25 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAMath.cpp | 182 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAParticle.cpp | 331 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAResource.cpp | 1124 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAResourceLoader.cpp | 106 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPAResourceManager.cpp | 84 | ||||
| -rw-r--r-- | src/JSystem/JParticle/JPATexture.cpp | 15 | ||||
| -rw-r--r-- | src/JSystem/JSupport/JSUList.cpp | 162 |
16 files changed, 4631 insertions, 0 deletions
diff --git a/src/JSystem/JParticle/JPABaseShape.cpp b/src/JSystem/JParticle/JPABaseShape.cpp new file mode 100644 index 00000000..d869cd20 --- /dev/null +++ b/src/JSystem/JParticle/JPABaseShape.cpp @@ -0,0 +1,1449 @@ +// +// Generated By: dol2asm +// Translation Unit: JPABaseShape +// + +#include "JSystem/JParticle/JPABaseShape.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JParticle/JPAParticle.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "JSystem/JParticle/JPAResourceManager.h" +#include "JSystem/JMath/JMATrigonometric.h" +#include "dolphin/mtx.h" +#include "dolphin/gx.h" + +/* 80276A90-80276ACC 2713D0 003C+00 0/0 1/1 0/0 .text JPASetPointSize__FP18JPAEmitterWorkData */ +void JPASetPointSize(JPAEmitterWorkData* work) { + GXSetPointSize((u8)(25.0f * work->mGlobalPtclScl.x), GX_TO_ONE); +} + +/* 80276ACC-80276B08 27140C 003C+00 0/0 1/1 0/0 .text JPASetLineWidth__FP18JPAEmitterWorkData */ +void JPASetLineWidth(JPAEmitterWorkData* work) { + GXSetLineWidth((u8)(25.0f * work->mGlobalPtclScl.x), GX_TO_ONE); +} + +/* 80276B08-80276B4C 271448 0044+00 0/0 1/1 0/0 .text + * JPASetPointSize__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPASetPointSize(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + GXSetPointSize((u8)(ptcl->mParticleScaleX * (25.0f * work->mGlobalPtclScl.x)), GX_TO_ONE); +} + +/* 80276B4C-80276B90 27148C 0044+00 0/0 1/1 0/0 .text + * JPASetLineWidth__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPASetLineWidth(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + GXSetLineWidth((u8)(ptcl->mParticleScaleX * (25.0f * work->mGlobalPtclScl.x)), GX_TO_ONE); +} + +/* 80276B90-80276C2C 2714D0 009C+00 0/0 1/1 0/0 .text JPARegistPrm__FP18JPAEmitterWorkData */ +void JPARegistPrm(JPAEmitterWorkData* work) { + JPABaseEmitter* emtr = work->mpEmtr; + GXColor prm = emtr->mPrmClr; + prm.r = COLOR_MULTI(prm.r, emtr->mGlobalPrmClr.r); + prm.g = COLOR_MULTI(prm.g, emtr->mGlobalPrmClr.g); + prm.b = COLOR_MULTI(prm.b, emtr->mGlobalPrmClr.b); + prm.a = COLOR_MULTI(prm.a, emtr->mGlobalPrmClr.a); + GXSetTevColor(GX_TEVREG0, prm); +} + +/* 80276C2C-80276CB0 27156C 0084+00 0/0 1/1 0/0 .text JPARegistEnv__FP18JPAEmitterWorkData */ +void JPARegistEnv(JPAEmitterWorkData* work) { + JPABaseEmitter* emtr = work->mpEmtr; + GXColor env = emtr->mEnvClr; + env.r = COLOR_MULTI(env.r, emtr->mGlobalEnvClr.r); + env.g = COLOR_MULTI(env.g, emtr->mGlobalEnvClr.g); + env.b = COLOR_MULTI(env.b, emtr->mGlobalEnvClr.b); + GXSetTevColor(GX_TEVREG1, env); +} + +/* 80276CB0-80276DB0 2715F0 0100+00 0/0 1/1 0/0 .text JPARegistPrmEnv__FP18JPAEmitterWorkData */ +void JPARegistPrmEnv(JPAEmitterWorkData* work) { + JPABaseEmitter* emtr = work->mpEmtr; + GXColor prm = emtr->mPrmClr; + GXColor env = emtr->mEnvClr; + prm.r = COLOR_MULTI(prm.r, emtr->mGlobalPrmClr.r); + prm.g = COLOR_MULTI(prm.g, emtr->mGlobalPrmClr.g); + prm.b = COLOR_MULTI(prm.b, emtr->mGlobalPrmClr.b); + prm.a = COLOR_MULTI(prm.a, emtr->mGlobalPrmClr.a); + env.r = COLOR_MULTI(env.r, emtr->mGlobalEnvClr.r); + env.g = COLOR_MULTI(env.g, emtr->mGlobalEnvClr.g); + env.b = COLOR_MULTI(env.b, emtr->mGlobalEnvClr.b); + GXSetTevColor(GX_TEVREG0, prm); + GXSetTevColor(GX_TEVREG1, env); +} + +/* 80276DB0-80276E60 2716F0 00B0+00 0/0 1/1 0/0 .text + * JPARegistAlpha__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPARegistAlpha(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPABaseEmitter* emtr = work->mpEmtr; + GXColor prm = emtr->mPrmClr; + prm.r = COLOR_MULTI(prm.r, emtr->mGlobalPrmClr.r); + prm.g = COLOR_MULTI(prm.g, emtr->mGlobalPrmClr.g); + prm.b = COLOR_MULTI(prm.b, emtr->mGlobalPrmClr.b); + prm.a = COLOR_MULTI(prm.a, emtr->mGlobalPrmClr.a); + prm.a = COLOR_MULTI(prm.a, ptcl->mPrmColorAlphaAnm); + GXSetTevColor(GX_TEVREG0, prm); +} + +/* 80276E60-80276F10 2717A0 00B0+00 0/0 1/1 0/0 .text + * JPARegistPrmAlpha__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPARegistPrmAlpha(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPABaseEmitter* emtr = work->mpEmtr; + GXColor prm = ptcl->mPrmClr; + prm.r = COLOR_MULTI(prm.r, emtr->mGlobalPrmClr.r); + prm.g = COLOR_MULTI(prm.g, emtr->mGlobalPrmClr.g); + prm.b = COLOR_MULTI(prm.b, emtr->mGlobalPrmClr.b); + prm.a = COLOR_MULTI(prm.a, emtr->mGlobalPrmClr.a); + prm.a = COLOR_MULTI(prm.a, ptcl->mPrmColorAlphaAnm); + GXSetTevColor(GX_TEVREG0, prm); +} + +/* 80276F10-80277024 271850 0114+00 0/0 1/1 0/0 .text + * JPARegistPrmAlphaEnv__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPARegistPrmAlphaEnv(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPABaseEmitter* emtr = work->mpEmtr; + GXColor prm = ptcl->mPrmClr; + GXColor env = ptcl->mEnvClr; + prm.r = COLOR_MULTI(prm.r, emtr->mGlobalPrmClr.r); + prm.g = COLOR_MULTI(prm.g, emtr->mGlobalPrmClr.g); + prm.b = COLOR_MULTI(prm.b, emtr->mGlobalPrmClr.b); + prm.a = COLOR_MULTI(prm.a, emtr->mGlobalPrmClr.a); + prm.a = COLOR_MULTI(prm.a, ptcl->mPrmColorAlphaAnm); + env.r = COLOR_MULTI(env.r, emtr->mGlobalEnvClr.r); + env.g = COLOR_MULTI(env.g, emtr->mGlobalEnvClr.g); + env.b = COLOR_MULTI(env.b, emtr->mGlobalEnvClr.b); + GXSetTevColor(GX_TEVREG0, prm); + GXSetTevColor(GX_TEVREG1, env); +} + +/* 80277024-80277138 271964 0114+00 0/0 1/1 0/0 .text + * JPARegistAlphaEnv__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPARegistAlphaEnv(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPABaseEmitter* emtr = work->mpEmtr; + GXColor prm = emtr->mPrmClr; + GXColor env = ptcl->mEnvClr; + prm.r = COLOR_MULTI(prm.r, emtr->mGlobalPrmClr.r); + prm.g = COLOR_MULTI(prm.g, emtr->mGlobalPrmClr.g); + prm.b = COLOR_MULTI(prm.b, emtr->mGlobalPrmClr.b); + prm.a = COLOR_MULTI(prm.a, emtr->mGlobalPrmClr.a); + prm.a = COLOR_MULTI(prm.a, ptcl->mPrmColorAlphaAnm); + env.r = COLOR_MULTI(env.r, emtr->mGlobalEnvClr.r); + env.g = COLOR_MULTI(env.g, emtr->mGlobalEnvClr.g); + env.b = COLOR_MULTI(env.b, emtr->mGlobalEnvClr.b); + GXSetTevColor(GX_TEVREG0, prm); + GXSetTevColor(GX_TEVREG1, env); +} + +/* 80277138-802771BC 271A78 0084+00 0/0 1/1 0/0 .text + * JPARegistEnv__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPARegistEnv(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPABaseEmitter* emtr = work->mpEmtr; + GXColor env = ptcl->mEnvClr; + env.r = COLOR_MULTI(env.r, emtr->mGlobalEnvClr.r); + env.g = COLOR_MULTI(env.g, emtr->mGlobalEnvClr.g); + env.b = COLOR_MULTI(env.b, emtr->mGlobalEnvClr.b); + GXSetTevColor(GX_TEVREG1, env); +} + +/* 802771BC-802771E8 271AFC 002C+00 0/0 1/1 0/0 .text JPACalcClrIdxNormal__FP18JPAEmitterWorkData + */ +void JPACalcClrIdxNormal(JPAEmitterWorkData* work) { + JPABaseShape* bsp = work->mpRes->getBsp(); + s16 keyFrame; + if (work->mpEmtr->mTick < bsp->getClrAnmMaxFrm()) { + keyFrame = work->mpEmtr->mTick; + } else { + keyFrame = bsp->getClrAnmMaxFrm(); + } + work->mClrKeyFrame = keyFrame; +} + +/* 802771E8-80277210 271B28 0028+00 0/0 1/1 0/0 .text + * JPACalcClrIdxNormal__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcClrIdxNormal(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + s16 age = param_1->mAge; + s16 maxFrm = shape->getClrAnmMaxFrm(); + s16 keyFrame; + if (age < maxFrm) { + keyFrame = age; + } else { + keyFrame = maxFrm; + } + work->mClrKeyFrame = keyFrame; +} + +/* 80277210-80277240 271B50 0030+00 0/0 1/1 0/0 .text JPACalcClrIdxRepeat__FP18JPAEmitterWorkData + */ +void JPACalcClrIdxRepeat(JPAEmitterWorkData* work) { + JPABaseShape* shape = work->mpRes->getBsp(); + work->mClrKeyFrame = work->mpEmtr->mTick % (shape->getClrAnmMaxFrm() + 1); +} + +/* 80277240-8027727C 271B80 003C+00 0/0 1/1 0/0 .text + * JPACalcClrIdxRepeat__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcClrIdxRepeat(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + s32 tick = shape->getClrLoopOfst(param_1->mAnmRandom); + tick = param_1->mAge + tick; + work->mClrKeyFrame = tick % (shape->getClrAnmMaxFrm() + 1); +} + +/* 8027727C-802772BC 271BBC 0040+00 0/0 1/1 0/0 .text JPACalcClrIdxReverse__FP18JPAEmitterWorkData + */ +void JPACalcClrIdxReverse(JPAEmitterWorkData* work) { + JPABaseShape* shape = work->mpRes->getBsp(); + int maxFrm = shape->getClrAnmMaxFrm(); + u32 tick = work->mpEmtr->mTick; + u32 uVar1 = tick / maxFrm; + tick = tick % maxFrm; + uVar1 &= 1; + work->mClrKeyFrame = tick + (uVar1) * (maxFrm - tick * 2); +} + +/* 802772BC-80277308 271BFC 004C+00 0/0 1/1 0/0 .text + * JPACalcClrIdxReverse__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcClrIdxReverse(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + s32 tick = param_1->mAge + shape->getClrLoopOfst(param_1->mAnmRandom); + s32 maxFrm = shape->getClrAnmMaxFrm(); + s32 rem = tick % maxFrm; + work->mClrKeyFrame = rem + ((tick / maxFrm) & 1) * (maxFrm - rem * 2); +} + +/* 80277308-80277314 271C48 000C+00 0/0 1/1 0/0 .text JPACalcClrIdxMerge__FP18JPAEmitterWorkData + */ +void JPACalcClrIdxMerge(JPAEmitterWorkData* work) { + work->mClrKeyFrame = 0; +} + +/* 80277314-80277384 271C54 0070+00 0/0 1/1 0/0 .text + * JPACalcClrIdxMerge__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcClrIdxMerge(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + s32 maxFrm = shape->getClrAnmMaxFrm() + 1; + s32 tick = (s32)(param_1->mTime * maxFrm) + shape->getClrLoopOfst(param_1->mAnmRandom); + work->mClrKeyFrame = tick % maxFrm; +} + +/* 80277384-80277390 271CC4 000C+00 0/0 1/1 0/0 .text JPACalcClrIdxRandom__FP18JPAEmitterWorkData + */ +void JPACalcClrIdxRandom(JPAEmitterWorkData* work) { + work->mClrKeyFrame = 0; +} + +/* 80277390-802773C4 271CD0 0034+00 0/0 1/1 0/0 .text + * JPACalcClrIdxRandom__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcClrIdxRandom(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + s32 tick = shape->getClrLoopOfst(param_1->mAnmRandom); + s32 maxFrm = shape->getClrAnmMaxFrm() + 1; + work->mClrKeyFrame = tick % maxFrm; +} + +/* 802773C4-80277404 271D04 0040+00 0/0 1/1 0/0 .text JPACalcPrm__FP18JPAEmitterWorkData + */ +void JPACalcPrm(JPAEmitterWorkData* work) { + work->mpRes->getBsp()->getPrmClr(work->mClrKeyFrame, &work->mpEmtr->mPrmClr); +} + +/* 80277404-80277440 271D44 003C+00 0/0 1/1 0/0 .text + * JPACalcPrm__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcPrm(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + work->mpRes->getBsp()->getPrmClr(work->mClrKeyFrame, &ptcl->mPrmClr); +} + +/* 80277440-80277480 271D80 0040+00 0/0 1/1 0/0 .text JPACalcEnv__FP18JPAEmitterWorkData + */ +void JPACalcEnv(JPAEmitterWorkData* work) { + work->mpRes->getBsp()->getEnvClr(work->mClrKeyFrame, &work->mpEmtr->mEnvClr); +} + +/* 80277480-802774BC 271DC0 003C+00 0/0 1/1 0/0 .text + * JPACalcEnv__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcEnv(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + work->mpRes->getBsp()->getEnvClr(work->mClrKeyFrame, &ptcl->mEnvClr); +} + +/* 802774BC-80277504 271DFC 0048+00 0/0 1/1 0/0 .text + * JPACalcColorCopy__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcColorCopy(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPABaseEmitter* emtr = work->mpEmtr; + ptcl->mPrmClr = emtr->mPrmClr; + ptcl->mEnvClr = emtr->mEnvClr; +} + +/* 80277504-8027753C 271E44 0038+00 0/0 1/1 0/0 .text JPAGenTexCrdMtxIdt__FP18JPAEmitterWorkData + */ +void JPAGenTexCrdMtxIdt(JPAEmitterWorkData* param_0) { + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); +} + +/* 8027753C-80277574 271E7C 0038+00 0/0 1/1 0/0 .text JPAGenTexCrdMtxAnm__FP18JPAEmitterWorkData + */ +void JPAGenTexCrdMtxAnm(JPAEmitterWorkData* param_0) { + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0, GX_FALSE, GX_PTIDENTITY); +} + +/* 80277574-802775AC 271EB4 0038+00 0/0 1/1 0/0 .text JPAGenTexCrdMtxPrj__FP18JPAEmitterWorkData + */ +void JPAGenTexCrdMtxPrj(JPAEmitterWorkData* param_0) { + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX0, GX_FALSE, GX_PTIDENTITY); +} + +/* 802775AC-80277758 271EEC 01AC+00 0/0 1/1 0/0 .text + * JPAGenCalcTexCrdMtxAnm__FP18JPAEmitterWorkData */ +void JPAGenCalcTexCrdMtxAnm(JPAEmitterWorkData* work) { + JPABaseShape* shape = work->mpRes->getBsp(); + f32 dVar16 = work->mpEmtr->mTick; + f32 dVar15 = 0.5f * (1.0f + shape->getTilingS()); + f32 dVar14 = 0.5f * (1.0f + shape->getTilingT()); + f32 dVar11 = (dVar16 * shape->getIncTransX()) + shape->getInitTransX(); + f32 dVar10 = (dVar16 * shape->getIncTransY()) + shape->getInitTransY(); + f32 dVar13 = (dVar16 * shape->getIncScaleX()) + shape->getInitScaleX(); + f32 dVar12 = (dVar16 * shape->getIncScaleY()) + shape->getInitScaleY(); + s32 local_c0 = (dVar16 * shape->getIncRot()) + shape->getInitRot(); + f32 dVar8 = JMASSin(local_c0); + f32 dVar9 = JMASCos(local_c0); + Mtx local_108; + local_108[0][0] = dVar13 * dVar9; + local_108[0][1] = -dVar13 * dVar8; + local_108[0][2] = 0.0f; + local_108[0][3] = + (dVar15 + (dVar13 * ((dVar8 * (dVar14 + dVar10)) - (dVar9 * (dVar15 + dVar11))))); + local_108[1][0] = dVar12 * dVar8; + local_108[1][1] = dVar12 * dVar9; + local_108[1][2] = 0.0f; + local_108[1][3] = + (dVar14 + (-dVar12 * ((dVar8 * (dVar15 + dVar11)) + (dVar9 * (dVar14 + dVar10))))); + local_108[2][0] = 0.0f; + local_108[2][1] = 0.0f; + local_108[2][2] = 1.0f; + local_108[2][3] = 0.0f; + GXLoadTexMtxImm(local_108, 0x1e, GX_MTX2x4); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x1e, false, 0x7d); +} + +/* 80277758-802778EC 272098 0194+00 0/0 1/1 0/0 .text + * JPALoadCalcTexCrdMtxAnm__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPALoadCalcTexCrdMtxAnm(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + f32 dVar16 = param_1->mAge; + f32 dVar15 = 0.5f * (1.0f + shape->getTilingS()); + f32 dVar14 = 0.5f * (1.0f + shape->getTilingT()); + f32 dVar11 = (dVar16 * shape->getIncTransX()) + shape->getInitTransX(); + f32 dVar10 = (dVar16 * shape->getIncTransY()) + shape->getInitTransY(); + f32 dVar13 = (dVar16 * shape->getIncScaleX()) + shape->getInitScaleX(); + f32 dVar12 = (dVar16 * shape->getIncScaleY()) + shape->getInitScaleY(); + s32 local_c0 = (dVar16 * shape->getIncRot()) + shape->getInitRot(); + f32 dVar8 = JMASSin(local_c0); + f32 dVar9 = JMASCos(local_c0); + Mtx local_108; + local_108[0][0] = dVar13 * dVar9; + local_108[0][1] = -dVar13 * dVar8; + local_108[0][2] = 0.0f; + local_108[0][3] = + (dVar15 + (dVar13 * ((dVar8 * (dVar14 + dVar10)) - (dVar9 * (dVar15 + dVar11))))); + local_108[1][0] = dVar12 * dVar8; + local_108[1][1] = dVar12 * dVar9; + local_108[1][2] = 0.0f; + local_108[1][3] = + (dVar14 + (-dVar12 * ((dVar8 * (dVar15 + dVar11)) + (dVar9 * (dVar14 + dVar10))))); + local_108[2][0] = 0.0f; + local_108[2][1] = 0.0f; + local_108[2][2] = 1.0f; + local_108[2][3] = 0.0f; + GXLoadTexMtxImm(local_108, 0x1e, GX_MTX2x4); +} + +/* 802778EC-80277940 27222C 0054+00 0/0 1/1 0/0 .text JPALoadTex__FP18JPAEmitterWorkData + */ +void JPALoadTex(JPAEmitterWorkData* work) { + work->mpResMgr->load(work->mpRes->getTexIdx(work->mpRes->getBsp()->getTexIdx()), GX_TEXMAP0); +} + +/* 80277940-80277990 272280 0050+00 0/0 1/1 0/0 .text JPALoadTexAnm__FP18JPAEmitterWorkData */ +void JPALoadTexAnm(JPAEmitterWorkData* work) { + work->mpResMgr->load(work->mpRes->getTexIdx(work->mpEmtr->mTexAnmIdx), GX_TEXMAP0); +} + +/* 80277990-802779DC 2722D0 004C+00 0/0 1/1 0/0 .text + * JPALoadTexAnm__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPALoadTexAnm(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + work->mpResMgr->load(work->mpRes->getTexIdx(ptcl->mTexAnmIdx), GX_TEXMAP0); +} + +/* 802779DC-80277A18 27231C 003C+00 0/0 1/1 0/0 .text JPACalcTexIdxNormal__FP18JPAEmitterWorkData + */ +void JPACalcTexIdxNormal(JPAEmitterWorkData* work) { + JPABaseShape* shape = work->mpRes->getBsp(); + u8 tick = shape->getTexAnmKeyNum() - 1 < work->mpEmtr->mTick + ? shape->getTexAnmKeyNum() - 1 : work->mpEmtr->mTick; + work->mpEmtr->mTexAnmIdx = shape->getTexIdx(tick); +} + +/* 80277A18-80277A50 272358 0038+00 0/0 1/1 0/0 .text + * JPACalcTexIdxNormal__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcTexIdxNormal(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + u8 tick = shape->getTexAnmKeyNum() - 1 < param_1->mAge + ? shape->getTexAnmKeyNum() - 1 : param_1->mAge; + param_1->mTexAnmIdx = shape->getTexIdx(tick); +} + +/* 80277A50-80277A88 272390 0038+00 0/0 1/1 0/0 .text JPACalcTexIdxRepeat__FP18JPAEmitterWorkData + */ +void JPACalcTexIdxRepeat(JPAEmitterWorkData* work) { + JPABaseShape* shape = work->mpRes->getBsp(); + work->mpEmtr->mTexAnmIdx = shape->getTexIdx(work->mpEmtr->mTick % shape->getTexAnmKeyNum()); +} + +/* 80277A88-80277ACC 2723C8 0044+00 0/0 1/1 0/0 .text + * JPACalcTexIdxRepeat__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcTexIdxRepeat(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + param_1->mTexAnmIdx = shape->getTexIdx( + ((int)shape->getTexLoopOfst(param_1->mAnmRandom) + param_1->mAge) + % shape->getTexAnmKeyNum()); +} + +/* 80277ACC-80277B1C 27240C 0050+00 0/0 1/1 0/0 .text JPACalcTexIdxReverse__FP18JPAEmitterWorkData + */ +void JPACalcTexIdxReverse(JPAEmitterWorkData* work) { + JPABaseShape* shape = work->mpRes->getBsp(); + int tick = work->mpEmtr->mTick; + int keyNum = (int)shape->getTexAnmKeyNum() - 1; + int div = tick / keyNum; + int rem = tick % keyNum; + work->mpEmtr->mTexAnmIdx = shape->getTexIdx(rem + (div & 1) * (keyNum - rem * 2)); +} + +/* 80277B1C-80277B78 27245C 005C+00 0/0 1/1 0/0 .text + * JPACalcTexIdxReverse__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcTexIdxReverse(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + s32 tick = shape->getTexLoopOfst(param_1->mAnmRandom) + param_1->mAge; + int keyNum = (int)shape->getTexAnmKeyNum() - 1; + int div = tick / keyNum; + int rem = tick % keyNum; + param_1->mTexAnmIdx = shape->getTexIdx(rem + (div & 1) * (keyNum - rem * 2)); +} + +/* 80277B78-80277B94 2724B8 001C+00 0/0 1/1 0/0 .text JPACalcTexIdxMerge__FP18JPAEmitterWorkData + */ +void JPACalcTexIdxMerge(JPAEmitterWorkData* work) { + work->mpEmtr->mTexAnmIdx = work->mpRes->getBsp()->getTexIdx(); +} + +/* 80277B94-80277C0C 2724D4 0078+00 0/0 1/1 0/0 .text + * JPACalcTexIdxMerge__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcTexIdxMerge(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + s32 maxFrm = shape->getTexAnmKeyNum(); + s32 tick = (s32)(maxFrm * param_1->mTime) + shape->getTexLoopOfst(param_1->mAnmRandom); + param_1->mTexAnmIdx = shape->getTexIdx(tick % maxFrm); +} + +/* 80277C0C-80277C28 27254C 001C+00 0/0 1/1 0/0 .text JPACalcTexIdxRandom__FP18JPAEmitterWorkData + */ +void JPACalcTexIdxRandom(JPAEmitterWorkData* work) { + work->mpEmtr->mTexAnmIdx = work->mpRes->getBsp()->getTexIdx(); +} + +/* 80277C28-80277C64 272568 003C+00 0/0 1/1 0/0 .text + * JPACalcTexIdxRandom__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcTexIdxRandom(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + JPABaseShape* shape = work->mpRes->getBsp(); + param_1->mTexAnmIdx = shape->getTexIdx(((int)shape->getTexLoopOfst(param_1->mAnmRandom)) + % shape->getTexAnmKeyNum()); +} + +/* 80277C64-80277C8C 2725A4 0028+00 0/0 1/1 0/0 .text JPALoadPosMtxCam__FP18JPAEmitterWorkData */ +void JPALoadPosMtxCam(JPAEmitterWorkData* work) { + GXLoadPosMtxImm(work->mPosCamMtx, GX_PNMTX0); +} + +/* 80277C8C-80277C90 2725CC 0004+00 1/0 0/0 0/0 .text noLoadPrj__FPC18JPAEmitterWorkDataPA4_Cf */ +static void noLoadPrj(JPAEmitterWorkData const* work, const Mtx srt) { + /* empty function */ +} + +/* 80277C90-80277CC8 2725D0 0038+00 1/0 0/0 0/0 .text loadPrj__FPC18JPAEmitterWorkDataPA4_Cf */ +void loadPrj(JPAEmitterWorkData const* work, const Mtx srt) { + Mtx mtx; + MTXConcat(work->mPrjMtx, srt, mtx); + GXLoadTexMtxImm(mtx, GX_TEXMTX0, GX_MTX3x4); +} + +/* 80277CC8-80277E88 272608 01C0+00 1/0 0/0 0/0 .text loadPrjAnm__FPC18JPAEmitterWorkDataPA4_Cf */ +static void loadPrjAnm(JPAEmitterWorkData const* work, const Mtx srt) { + JPABaseShape* shape = work->mpRes->getBsp(); + f32 dVar16 = work->mpEmtr->getAge(); + f32 dVar15 = 0.5f * (1.0f + shape->getTilingS()); + f32 dVar14 = 0.5f * (1.0f + shape->getTilingT()); + f32 dVar11 = (dVar16 * shape->getIncTransX()) + shape->getInitTransX(); + f32 dVar10 = (dVar16 * shape->getIncTransY()) + shape->getInitTransY(); + f32 dVar13 = (dVar16 * shape->getIncScaleX()) + shape->getInitScaleX(); + f32 dVar12 = (dVar16 * shape->getIncScaleY()) + shape->getInitScaleY(); + s32 local_c0 = (dVar16 * shape->getIncRot()) + shape->getInitRot(); + f32 dVar8 = JMASSin(local_c0); + f32 dVar9 = JMASCos(local_c0); + Mtx local_108; + local_108[0][0] = dVar13 * dVar9; + local_108[0][1] = -dVar13 * dVar8; + local_108[0][2] = + (dVar15 + (dVar13 * ((dVar8 * (dVar14 + dVar10)) - (dVar9 * (dVar15 + dVar11))))); + local_108[0][3] = 0.0f; + local_108[1][0] = dVar12 * dVar8; + local_108[1][1] = dVar12 * dVar9; + local_108[1][2] = + (dVar14 + (-dVar12 * ((dVar8 * (dVar15 + dVar11)) + (dVar9 * (dVar14 + dVar10))))); + local_108[1][3] = 0.0f; + local_108[2][0] = 0.0f; + local_108[2][1] = 0.0f; + local_108[2][2] = 1.0f; + local_108[2][3] = 0.0f; + MTXConcat(local_108, work->mPrjMtx, local_108); + MTXConcat(local_108, srt, local_108); + GXLoadTexMtxImm(local_108, 0x1e, GX_MTX3x4); +} + +/* 803C42E0-803C4300 021400 0020+00 10/9 0/0 0/0 .data jpa_dl */ +static u8 jpa_dl[32] = { + 0x80, 0x00, 0x04, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* 803C4300-803C4320 021420 0020+00 1/0 0/0 0/0 .data jpa_dl_x */ +static u8 jpa_dl_x[32] = { + 0x80, 0x00, 0x08, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x48, 0x00, 0x49, 0x01, 0x4A, + 0x02, 0x4B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +typedef void (*projectionFunc)(JPAEmitterWorkData const*, const Mtx); + +/* 803C4320-803C432C -00001 000C+00 6/10 0/0 0/0 .data p_prj */ +static projectionFunc p_prj[3] = { + noLoadPrj, + loadPrj, + loadPrjAnm, +}; + +/* 80277E88-80277F70 2727C8 00E8+00 0/0 1/1 0/0 .text + * JPADrawBillboard__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + if (param_1->checkStatus(8) == 0) { + JGeometry::TVec3<f32> local_48; + MTXMultVec(work->mPosCamMtx, param_1->mPosition, local_48); + Mtx local_38; + local_38[0][0] = work->mGlobalPtclScl.x * param_1->mParticleScaleX; + local_38[0][3] = local_48.x; + local_38[1][1] = work->mGlobalPtclScl.y * param_1->mParticleScaleY; + local_38[1][3] = local_48.y; + local_38[2][2] = 1.0f; + local_38[2][3] = local_48.z; + local_38[2][1] = 0.0f; + local_38[2][0] = 0.0f; + local_38[1][2] = 0.0f; + local_38[1][0] = 0.0f; + local_38[0][2] = 0.0f; + local_38[0][1] = 0.0f; + GXLoadPosMtxImm(local_38, 0); + p_prj[work->mPrjType](work, local_38); + GXCallDisplayList(jpa_dl, sizeof(jpa_dl)); + } +} + +/* 80277F70-80278088 2728B0 0118+00 0/0 1/1 0/0 .text + * JPADrawRotBillboard__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawRotBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + if (param_1->checkStatus(8) == 0) { + JGeometry::TVec3<f32> local_48; + MTXMultVec(work->mPosCamMtx, param_1->mPosition, local_48); + f32 sinRot = JMASSin(param_1->mRotateAngle); + f32 cosRot = JMASCos(param_1->mRotateAngle); + f32 particleX = work->mGlobalPtclScl.x * param_1->mParticleScaleX; + f32 particleY = work->mGlobalPtclScl.y * param_1->mParticleScaleY; + + Mtx local_38; + local_38[0][0] = cosRot * particleX; + local_38[0][1] = -sinRot * particleY; + local_38[0][3] = local_48.x; + local_38[1][0] = sinRot * particleX; + local_38[1][1] = cosRot * particleY; + local_38[1][3] = local_48.y; + local_38[2][2] = 1.0f; + local_38[2][3] = local_48.z; + local_38[2][1] = 0.0f; + local_38[2][0] = 0.0f; + local_38[1][2] = 0.0f; + local_38[0][2] = 0.0f; + GXLoadPosMtxImm(local_38, 0); + p_prj[work->mPrjType](work, local_38); + GXCallDisplayList(jpa_dl, sizeof(jpa_dl)); + } +} + +/* 80278088-80278184 2729C8 00FC+00 0/0 1/1 0/0 .text + * JPADrawYBillboard__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawYBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + if (param_1->checkStatus(8) == 0) { + JGeometry::TVec3<f32> local_48; + MTXMultVec(work->mPosCamMtx, param_1->mPosition, local_48); + Mtx local_38; + f32 particleY = work->mGlobalPtclScl.y * param_1->mParticleScaleY; + local_38[0][0] = work->mGlobalPtclScl.x * param_1->mParticleScaleX; + local_38[0][3] = local_48.x; + local_38[1][1] = work->mYBBCamMtx[1][1] * particleY; + local_38[1][2] = work->mYBBCamMtx[1][2]; + local_38[1][3] = local_48.y; + local_38[2][1] = work->mYBBCamMtx[2][1] * particleY; + local_38[2][2] = work->mYBBCamMtx[2][2]; + local_38[2][3] = local_48.z; + local_38[2][0] = 0.0f; + local_38[1][0] = 0.0f; + local_38[0][2] = 0.0f; + local_38[0][1] = 0.0f; + GXLoadPosMtxImm(local_38, 0); + p_prj[work->mPrjType](work, local_38); + GXCallDisplayList(jpa_dl, sizeof(jpa_dl)); + } +} + +/* 80278184-802782B4 272AC4 0130+00 0/0 1/1 0/0 .text + * JPADrawRotYBillboard__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawRotYBillboard(JPAEmitterWorkData* work, JPABaseParticle* param_1) { + if (param_1->checkStatus(8) == 0) { + JGeometry::TVec3<f32> local_48; + MTXMultVec(work->mPosCamMtx, param_1->mPosition, local_48); + f32 sinRot = JMASSin(param_1->mRotateAngle); + f32 cosRot = JMASCos(param_1->mRotateAngle); + Mtx local_38; + f32 particleX = work->mGlobalPtclScl.x * param_1->mParticleScaleX; + f32 particleY = work->mGlobalPtclScl.y * param_1->mParticleScaleY; + f32 local_98 = (float)(sinRot * particleX); + f32 local_94 = (float)(cosRot * particleY); + f32 local_90 = work->mYBBCamMtx[1][1]; + f32 fVar1 = work->mYBBCamMtx[2][1]; + local_38[0][0] = (float)(cosRot * particleX); + local_38[0][1] = (float)(-sinRot * particleY); + local_38[0][2] = 0.0f; + local_38[0][3] = local_48.x; + local_38[1][0] = local_98 * local_90; + local_38[1][1] = local_94 * local_90; + local_38[1][2] = -fVar1; + local_38[1][3] = local_48.y; + local_38[2][0] = local_98 * fVar1; + local_38[2][1] = local_94 * fVar1; + local_38[2][2] = local_90; + local_38[2][3] = local_48.z; + GXLoadPosMtxImm(local_38, 0); + p_prj[work->mPrjType](work, local_38); + GXCallDisplayList(jpa_dl, sizeof(jpa_dl)); + } +} + +/* 802782B4-802782D0 272BF4 001C+00 1/0 0/0 0/0 .text + * dirTypeVel__FPC18JPAEmitterWorkDataPC15JPABaseParticlePQ29JGeometry8TVec3<f> */ +void dirTypeVel(JPAEmitterWorkData const* work, JPABaseParticle const* param_1, + JGeometry::TVec3<f32>* param_2) { + param_1->getVelVec(*param_2); +} + +/* 802782D0-802782EC 272C10 001C+00 1/0 0/0 0/0 .text + * dirTypePos__FPC18JPAEmitterWorkDataPC15JPABaseParticlePQ29JGeometry8TVec3<f> */ +void dirTypePos(JPAEmitterWorkData const* work, JPABaseParticle const* param_1, + JGeometry::TVec3<f32>* param_2) { + param_1->getLocalPosition(*param_2); +} + +/* 802782EC-80278320 272C2C 0034+00 1/0 0/0 0/0 .text + * dirTypePosInv__FPC18JPAEmitterWorkDataPC15JPABaseParticlePQ29JGeometry8TVec3<f> */ +void dirTypePosInv(JPAEmitterWorkData const* work, JPABaseParticle const* param_1, + JGeometry::TVec3<f32>* param_2) { + param_1->getLocalPosition(*param_2); + param_2->negate(); +} + +/* 80278320-8027833C 272C60 001C+00 1/0 0/0 0/0 .text + * dirTypeEmtrDir__FPC18JPAEmitterWorkDataPC15JPABaseParticlePQ29JGeometry8TVec3<f> */ +void dirTypeEmtrDir(JPAEmitterWorkData const* work, JPABaseParticle const* param_1, + JGeometry::TVec3<f32>* param_2) { + param_2->set(work->mGlobalEmtrDir); +} + +/* 8027833C-802783D4 272C7C 0098+00 1/0 0/0 0/0 .text + * dirTypePrevPtcl__FPC18JPAEmitterWorkDataPC15JPABaseParticlePQ29JGeometry8TVec3<f> */ +void dirTypePrevPtcl(JPAEmitterWorkData const* work, JPABaseParticle const* param_1, + JGeometry::TVec3<f32>* param_2) { + JGeometry::TVec3<f32> aTStack_24; + param_1->getGlobalPosition(aTStack_24); + JPANode<JPABaseParticle>* end = work->mpAlivePtcl->getEnd(); + JPANode<JPABaseParticle>* prev = work->mpCurNode->getPrev(); + + if (end != prev) { + JPABaseParticle* particle = work->mpCurNode->getPrev()->getObject(); + particle->getGlobalPosition(*param_2); + } else { + work->mpEmtr->calcEmitterGlobalPosition(param_2); + } + param_2->sub(aTStack_24); +} + +/* 802783D4-80278414 272D14 0040+00 1/0 0/0 0/0 .text rotTypeY__FffRA3_A4_f */ +static void rotTypeY(f32 param_0, f32 param_1, Mtx& param_2) { + param_2[0][0] = param_1; + param_2[0][1] = 0.0f; + param_2[0][2] = -param_0; + param_2[0][3] = 0.0f; + param_2[1][0] = 0.0f; + param_2[1][1] = 1.0f; + param_2[1][2] = 0.0f; + param_2[1][3] = 0.0f; + param_2[2][0] = param_0; + param_2[2][1] = 0.0f; + param_2[2][2] = param_1; + param_2[2][3] = 0.0f; +} + +/* 80278414-80278454 272D54 0040+00 1/0 0/0 0/0 .text rotTypeX__FffRA3_A4_f */ +static void rotTypeX(f32 param_0, f32 param_1, Mtx& param_2) { + param_2[0][0] = 1.0f; + param_2[0][1] = 0.0f; + param_2[0][2] = 0.0f; + param_2[0][3] = 0.0f; + param_2[1][0] = 0.0f; + param_2[1][1] = param_1; + param_2[1][2] = -param_0; + param_2[1][3] = 0.0f; + param_2[2][0] = 0.0f; + param_2[2][1] = param_0; + param_2[2][2] = param_1; + param_2[2][3] = 0.0f; +} + +/* 80278454-80278494 272D94 0040+00 1/0 0/0 0/0 .text rotTypeZ__FffRA3_A4_f */ +static void rotTypeZ(f32 param_0, f32 param_1, Mtx& param_2) { + param_2[0][0] = param_1; + param_2[0][1] = -param_0; + param_2[0][2] = 0.0f; + param_2[0][3] = 0.0f; + param_2[1][0] = param_0; + param_2[1][1] = param_1; + param_2[1][2] = 0.0f; + param_2[1][3] = 0.0f; + param_2[2][0] = 0.0f; + param_2[2][1] = 0.0f; + param_2[2][2] = 1.0f; + param_2[2][3] = 0.0f; +} + +/* 80278494-802784F0 272DD4 005C+00 1/0 0/0 0/0 .text rotTypeXYZ__FffRA3_A4_f */ +static void rotTypeXYZ(f32 param_0, f32 param_1, Mtx& param_2) { + f32 f3 = 0.33333298563957214f * (1.0f - param_1); + f32 fVar1; + f32 f4; + f4 = f3 + 0.5773500204086304f * param_0; + fVar1 = f3 - 0.5773500204086304f * param_0; + f3 += param_1; + param_2[0][0] = f3; + param_2[0][1] = fVar1; + param_2[0][2] = f4; + param_2[0][3] = 0.0f; + param_2[1][0] = f4; + param_2[1][1] = f3; + param_2[1][2] = fVar1; + param_2[1][3] = 0.0f; + param_2[2][0] = fVar1; + param_2[2][1] = f4; + param_2[2][2] = f3; + param_2[2][3] = 0.0f; +} + +/* 802784F0-8027853C 272E30 004C+00 1/0 0/0 0/0 .text basePlaneTypeXY__FPA4_fff */ +static void basePlaneTypeXY(MtxP param_0, f32 param_1, f32 param_2) { + param_0[0][0] *= param_1; + param_0[1][0] *= param_1; + param_0[2][0] *= param_1; + param_0[0][1] *= param_2; + param_0[1][1] *= param_2; + param_0[2][1] *= param_2; +} + +/* 8027853C-80278588 272E7C 004C+00 1/0 0/0 0/0 .text basePlaneTypeXZ__FPA4_fff */ +static void basePlaneTypeXZ(MtxP param_0, f32 param_1, f32 param_2) { + param_0[0][0] *= param_1; + param_0[1][0] *= param_1; + param_0[2][0] *= param_1; + param_0[0][2] *= param_2; + param_0[1][2] *= param_2; + param_0[2][2] *= param_2; +} + +/* 80278588-802785F8 272EC8 0070+00 1/0 0/0 0/0 .text basePlaneTypeX__FPA4_fff */ +static void basePlaneTypeX(MtxP param_0, f32 param_1, f32 param_2) { + param_0[0][0] *= param_1; + param_0[1][0] *= param_1; + param_0[2][0] *= param_1; + param_0[0][1] *= param_2; + param_0[1][1] *= param_2; + param_0[2][1] *= param_2; + param_0[0][2] *= param_1; + param_0[1][2] *= param_1; + param_0[2][2] *= param_1; +} + +/* 803C432C-803C4340 -00001 0014+00 2/5 0/0 0/0 .data p_direction */ +typedef void (*dirTypeFunc)(JPAEmitterWorkData const*, JPABaseParticle const*, + JGeometry::TVec3<f32>*); +static dirTypeFunc p_direction[5] = { + dirTypeVel, dirTypePos, dirTypePosInv, + dirTypeEmtrDir, dirTypePrevPtcl, +}; + +/* 803C4340-803C4354 -00001 0014+00 0/2 0/0 0/0 .data p_rot */ +typedef void (*rotTypeFunc)(f32, f32, Mtx&); +#pragma push +#pragma force_active on +static rotTypeFunc p_rot[5] = { + rotTypeY, rotTypeX, rotTypeZ, + rotTypeXYZ, rotTypeY, +}; +#pragma pop + +/* 803C4354-803C4360 -00001 000C+00 0/3 0/0 0/0 .data p_plane */ + +typedef void (*planeFunc)(MtxP, f32, f32); + +static planeFunc p_plane[3] = { + basePlaneTypeXY, + basePlaneTypeXZ, + basePlaneTypeX, +}; + +/* 804507A0-804507A8 -00001 0008+00 3/3 0/0 0/0 .sdata p_dl */ +static u8* p_dl[2] = { + jpa_dl, + jpa_dl_x, +}; + +/* 802785F8-80278994 272F38 039C+00 0/0 1/1 0/0 .text + * JPADrawDirection__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawDirection(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) { + if (param_1->checkStatus(8) == 0) { + JGeometry::TVec3<f32> local_6c; + JGeometry::TVec3<f32> local_78; + p_direction[param_0->mDirType](param_0, param_1, &local_6c); + if (!local_6c.isZero()) { + local_6c.normalize(); + local_78.cross(param_1->mBaseAxis, local_6c); + if (!local_78.isZero()) { + local_78.normalize(); + param_1->mBaseAxis.cross(local_6c, local_78); + param_1->mBaseAxis.normalize(); + Mtx local_60; + f32 fVar1 = param_0->mGlobalPtclScl.x * param_1->mParticleScaleX; + f32 fVar2 = param_0->mGlobalPtclScl.y * param_1->mParticleScaleY; + local_60[0][0] = param_1->mBaseAxis.x; + local_60[0][1] = local_6c.x; + local_60[0][2] = local_78.x; + local_60[0][3] = param_1->mPosition.x; + local_60[1][0] = param_1->mBaseAxis.y; + local_60[1][1] = local_6c.y; + local_60[1][2] = local_78.y; + local_60[1][3] = param_1->mPosition.y; + local_60[2][0] = param_1->mBaseAxis.z; + local_60[2][1] = local_6c.z; + local_60[2][2] = local_78.z; + local_60[2][3] = param_1->mPosition.z; + p_plane[param_0->mPlaneType](local_60, fVar1, fVar2); + MTXConcat(param_0->mPosCamMtx, local_60, local_60); + GXLoadPosMtxImm(local_60, 0); + p_prj[param_0->mPrjType](param_0, local_60); + GXCallDisplayList(p_dl[param_0->mDLType], sizeof(jpa_dl)); + } + } + } +} + +/* 80278994-80278DA8 2732D4 0414+00 0/0 1/1 0/0 .text + * JPADrawRotDirection__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawRotDirection(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) { + if (param_1->checkStatus(8) == 0) { + f32 sinRot = JMASSin(param_1->mRotateAngle); + f32 cosRot = JMASCos(param_1->mRotateAngle); + JGeometry::TVec3<f32> local_6c; + JGeometry::TVec3<f32> local_78; + p_direction[param_0->mDirType](param_0, param_1, &local_6c); + if (!local_6c.isZero()) { + local_6c.normalize(); + local_78.cross(param_1->mBaseAxis, local_6c); + if (!local_78.isZero()) { + local_78.normalize(); + param_1->mBaseAxis.cross(local_6c, local_78); + param_1->mBaseAxis.normalize(); + f32 particleX = param_0->mGlobalPtclScl.x * param_1->mParticleScaleX; + f32 particleY = param_0->mGlobalPtclScl.y * param_1->mParticleScaleY; + Mtx auStack_80; + Mtx local_60; + p_rot[param_0->mRotType](sinRot, cosRot, auStack_80); + p_plane[param_0->mPlaneType](auStack_80, particleX, particleY); + local_60[0][0] = param_1->mBaseAxis.x; + local_60[0][1] = local_6c.x; + local_60[0][2] = local_78.x; + local_60[0][3] = param_1->mPosition.x; + local_60[1][0] = param_1->mBaseAxis.y; + local_60[1][1] = local_6c.y; + local_60[1][2] = local_78.y; + local_60[1][3] = param_1->mPosition.y; + local_60[2][0] = param_1->mBaseAxis.z; + local_60[2][1] = local_6c.z; + local_60[2][2] = local_78.z; + local_60[2][3] = param_1->mPosition.z; + MTXConcat(local_60, auStack_80, auStack_80); + MTXConcat(param_0->mPosCamMtx, auStack_80, local_60); + GXLoadPosMtxImm(local_60, 0); + p_prj[param_0->mPrjType](param_0, local_60); + GXCallDisplayList(p_dl[param_0->mDLType], sizeof(jpa_dl)); + } + } + } +} + +/* 80278DA8-80278FC8 2736E8 0220+00 0/0 1/1 0/0 .text + * JPADrawDBillboard__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawDBillboard(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) { + if (param_1->checkStatus(8) == 0) { + JGeometry::TVec3<f32> local_70; + p_direction[param_0->mDirType](param_0, param_1, &local_70); + JGeometry::TVec3<f32> aTStack_7c; + aTStack_7c.set(param_0->mPosCamMtx[2][0], param_0->mPosCamMtx[2][1], + param_0->mPosCamMtx[2][2]); + local_70.cross(local_70, aTStack_7c); + if (!local_70.isZero()) { + local_70.normalize(); + MTXMultVecSR(param_0->mPosCamMtx, local_70, local_70); + JGeometry::TVec3<f32> local_88; + MTXMultVec(param_0->mPosCamMtx, param_1->mPosition, local_88); + f32 particleX = param_0->mGlobalPtclScl.x * param_1->mParticleScaleX; + f32 particleY = param_0->mGlobalPtclScl.y * param_1->mParticleScaleY; + Mtx local_60; + local_60[0][0] = local_70.x * particleX; + local_60[0][1] = -local_70.y * particleY; + local_60[0][3] = local_88.x; + local_60[1][0] = local_70.y * particleX; + local_60[1][1] = local_70.x * particleY; + local_60[1][3] = local_88.y; + local_60[2][2] = 1.0f; + local_60[2][3] = local_88.z; + local_60[2][1] = 0.0f; + local_60[2][0] = 0.0f; + local_60[1][2] = 0.0f; + local_60[0][2] = 0.0f; + GXLoadPosMtxImm(local_60, 0); + p_prj[param_0->mPrjType](param_0, local_60); + GXCallDisplayList(jpa_dl, sizeof(jpa_dl)); + } + } +} + +/* 80278FC8-80279110 273908 0148+00 0/0 1/1 0/0 .text + * JPADrawRotation__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawRotation(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) { + if (param_1->checkStatus(8) == 0) { + f32 sinRot = JMASSin(param_1->mRotateAngle); + f32 cosRot = JMASCos(param_1->mRotateAngle); + f32 particleX = param_0->mGlobalPtclScl.x * param_1->mParticleScaleX; + f32 particleY = param_0->mGlobalPtclScl.y * param_1->mParticleScaleY; + Mtx auStack_88; + p_rot[param_0->mRotType](sinRot, cosRot, auStack_88); + p_plane[param_0->mPlaneType](auStack_88, particleX, particleY); + auStack_88[0][3] = param_1->mPosition.x; + auStack_88[1][3] = param_1->mPosition.y; + auStack_88[2][3] = param_1->mPosition.z; + MTXConcat(param_0->mPosCamMtx, auStack_88, auStack_88); + GXLoadPosMtxImm(auStack_88, 0); + p_prj[param_0->mPrjType](param_0, auStack_88); + GXCallDisplayList(p_dl[param_0->mDLType], sizeof(jpa_dl)); + } +} + +/* 80279110-802791B0 273A50 00A0+00 0/0 1/1 0/0 .text + * JPADrawPoint__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawPoint(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + if (!!(ptcl->mStatus & JPAPtclStts_Invisible)) + return; + + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXBegin(GX_POINTS, GX_VTXFMT1, 1); + GXPosition3f32(ptcl->mPosition.x, ptcl->mPosition.y, ptcl->mPosition.z); + GXTexCoord2f32(0.0f, 0.0f); + GXEnd(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8); +} + +/* 802791B0-80279364 273AF0 01B4+00 0/0 1/1 0/0 .text + * JPADrawLine__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawLine(JPAEmitterWorkData* param_0, JPABaseParticle* param_1) { + if (param_1->checkStatus(8) == 0) { + JGeometry::TVec3<f32> local_1c; + JGeometry::setTVec3f(¶m_1->mPosition.x, &local_1c.x); + JGeometry::TVec3<f32> local_28; + param_1->getVelVec(local_28); + if (!local_28.isZero()) { + local_28.setLength(param_0->mGlobalPtclScl.y * (25.0f * param_1->mParticleScaleY)); + local_28.sub(local_1c, local_28); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXBegin(GX_LINES, GX_VTXFMT1, 2); + GXPosition3f32(local_1c.x, local_1c.y, local_1c.z); + GXTexCoord2f32(0.0f, 0.0f); + GXPosition3f32(local_28.x, local_28.y, local_28.z); + GXTexCoord2f32(0.0f, 1.0f); + GXEnd(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8); + } + } +} + +/* 80279364-8027936C 273CA4 0008+00 2/2 0/0 0/0 .text getNext__FP26JPANode<15JPABaseParticle> */ +JPANode<JPABaseParticle>* getNext(JPANode<JPABaseParticle>* param_0) { + return param_0->getNext(); +} + +/* 8027936C-80279374 273CAC 0008+00 2/2 0/0 0/0 .text getPrev__FP26JPANode<15JPABaseParticle> */ +JPANode<JPABaseParticle>* getPrev(JPANode<JPABaseParticle>* param_0) { + return param_0->getPrev(); +} + +typedef JPANode<JPABaseParticle>* (*getNodeFunc)(JPANode<JPABaseParticle>*); + +/* 80279374-8027996C 273CB4 05F8+00 0/0 1/1 0/0 .text JPADrawStripe__FP18JPAEmitterWorkData */ +void JPADrawStripe(JPAEmitterWorkData* param_0) { + JPABaseShape* shape = param_0->mpRes->getBsp(); + u32 ptcl_num = param_0->mpAlivePtcl->getNum(); + if (ptcl_num < 2) { + return; + } + + f32 coord = 0.0f; + f32 step = 1.0f / (ptcl_num - 1.0f); + f32 dVar14 = (1.0f + param_0->mPivot.x) * (25.0f * param_0->mGlobalPtclScl.x); + f32 dVar13 = (1.0f - param_0->mPivot.x) * (25.0f * param_0->mGlobalPtclScl.x); + Mtx local_c8; + f32 dVar11; + f32 dVar12; + JGeometry::TVec3<f32> local_ec; + JGeometry::TVec3<f32> local_e0[2]; + JGeometry::TVec3<f32> local_f8; + JGeometry::TVec3<f32> local_104; + getNodeFunc node_func; + JPANode<JPABaseParticle>* startNode; + if (shape->isDrawFwdAhead()) { + startNode = param_0->mpAlivePtcl->getLast(); + node_func = getPrev; + coord = 1.0f; + step = -step; + } else { + startNode = param_0->mpAlivePtcl->getFirst(); + node_func = getNext; + } + + GXLoadPosMtxImm(param_0->mPosCamMtx, 0); + p_prj[param_0->mPrjType](param_0, param_0->mPosCamMtx); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT1, ptcl_num << 1); + for (JPANode<JPABaseParticle>* node = startNode; node != param_0->mpAlivePtcl->getEnd(); + node = node_func(node), coord += step) { + param_0->mpCurNode = node; + JPABaseParticle* particle = node->getObject(); + local_ec.set(particle->mPosition); + dVar11 = JMASSin(particle->mRotateAngle); + dVar12 = JMASCos(particle->mRotateAngle); + local_e0[0].set(-particle->mParticleScaleX * dVar14, 0.0f, 0.0f); + local_e0[0].set(local_e0[0].x * dVar12, 0.0f, local_e0[0].x * dVar11); + local_e0[1].set(particle->mParticleScaleX * dVar13, 0.0f, 0.0f); + local_e0[1].set(local_e0[1].x * dVar12, 0.0f, local_e0[1].x * dVar11); + p_direction[param_0->mDirType](param_0, particle, &local_f8); + if (local_f8.isZero()) { + local_f8.set(0.0f, 1.0f, 0.0f); + } else { + local_f8.normalize(); + } + local_104.cross(particle->mBaseAxis, local_f8); + if (local_104.isZero()) { + local_104.set(1.0f, 0.0f, 0.0f); + } else { + local_104.normalize(); + } + particle->mBaseAxis.cross(local_f8, local_104); + particle->mBaseAxis.normalize(); + + local_c8[0][0] = local_104.x; + local_c8[0][1] = local_f8.x; + local_c8[0][2] = particle->mBaseAxis.x; + local_c8[0][3] = 0.0f; + local_c8[1][0] = local_104.y; + local_c8[1][1] = local_f8.y; + local_c8[1][2] = particle->mBaseAxis.y; + local_c8[1][3] = 0.0f; + local_c8[2][0] = local_104.z; + local_c8[2][1] = local_f8.z; + local_c8[2][2] = particle->mBaseAxis.z; + local_c8[2][3] = 0.0f; + MTXMultVecArraySR(local_c8, (Vec*)local_e0, (Vec*)local_e0, 2); + GXPosition3f32(local_e0[0].x + local_ec.x, local_e0[0].y + local_ec.y, + local_e0[0].z + local_ec.z); + GXTexCoord2f32(0.0f, coord); + GXPosition3f32(local_e0[1].x + local_ec.x, local_e0[1].y + local_ec.y, + local_e0[1].z + local_ec.z); + GXTexCoord2f32(1.0f, coord); + } + GXEnd(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8); +} + +/* 8027996C-8027A3D8 2742AC 0A6C+00 0/0 1/1 0/0 .text JPADrawStripeX__FP18JPAEmitterWorkData */ +void JPADrawStripeX(JPAEmitterWorkData* param_0) { + JPABaseShape* shape = param_0->mpRes->getBsp(); + u32 ptcl_num = param_0->mpAlivePtcl->getNum(); + if (ptcl_num < 2) { + return; + } + + f32 start_coord = 0.0f; + f32 coord = 0.0f; + f32 step = 1.0f / (ptcl_num - 1.0f); + f32 local_154 = (1.0f + param_0->mPivot.x) * (25.0f * param_0->mGlobalPtclScl.x); + f32 local_158 = (1.0f - param_0->mPivot.x) * (25.0f * param_0->mGlobalPtclScl.x); + f32 local_15c = (1.0f + param_0->mPivot.y) * (25.0f * param_0->mGlobalPtclScl.y); + f32 local_160 = (1.0f - param_0->mPivot.y) * (25.0f * param_0->mGlobalPtclScl.y); + Mtx local_90; + f32 dVar11; + f32 dVar12; + JGeometry::TVec3<f32> local_b4; + JGeometry::TVec3<f32> local_a8[2]; + JGeometry::TVec3<f32> local_c0; + JGeometry::TVec3<f32> local_cc; + JPANode<JPABaseParticle>* startNode; + getNodeFunc node_func; + if (shape->isDrawFwdAhead()) { + startNode = param_0->mpAlivePtcl->getLast(); + node_func = getPrev; + start_coord = coord = 1.0f; + step = -step; + } else { + startNode = param_0->mpAlivePtcl->getFirst(); + node_func = getNext; + } + + GXLoadPosMtxImm(param_0->mPosCamMtx, 0); + p_prj[param_0->mPrjType](param_0, param_0->mPosCamMtx); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT1, ptcl_num << 1); + for (JPANode<JPABaseParticle>* node = startNode; node != param_0->mpAlivePtcl->getEnd(); + node = node_func(node), coord += step) { + param_0->mpCurNode = node; + JPABaseParticle* particle = node->getObject(); + local_b4.set(particle->mPosition); + dVar11 = JMASSin(particle->mRotateAngle); + dVar12 = JMASCos(particle->mRotateAngle); + local_a8[0].set(-particle->mParticleScaleX * local_154, 0.0f, 0.0f); + local_a8[0].set(local_a8[0].x * dVar12, 0.0f, local_a8[0].x * dVar11); + local_a8[1].set(particle->mParticleScaleX * local_158, 0.0f, 0.0f); + local_a8[1].set(local_a8[1].x * dVar12, 0.0f, local_a8[1].x * dVar11); + p_direction[param_0->mDirType](param_0, particle, &local_c0); + if (local_c0.isZero()) { + local_c0.set(0.0f, 1.0f, 0.0f); + } else { + local_c0.normalize(); + } + local_cc.cross(particle->mBaseAxis, local_c0); + if (local_cc.isZero()) { + local_cc.set(1.0f, 0.0f, 0.0f); + } else { + local_cc.normalize(); + } + particle->mBaseAxis.cross(local_c0, local_cc); + particle->mBaseAxis.normalize(); + + local_90[0][0] = local_cc.x; + local_90[0][1] = local_c0.x; + local_90[0][2] = particle->mBaseAxis.x; + local_90[0][3] = 0.0f; + local_90[1][0] = local_cc.y; + local_90[1][1] = local_c0.y; + local_90[1][2] = particle->mBaseAxis.y; + local_90[1][3] = 0.0f; + local_90[2][0] = local_cc.z; + local_90[2][1] = local_c0.z; + local_90[2][2] = particle->mBaseAxis.z; + local_90[2][3] = 0.0f; + MTXMultVecArraySR(local_90, (Vec*)local_a8, (Vec*)local_a8, 2); + GXPosition3f32(local_a8[0].x + local_b4.x, local_a8[0].y + local_b4.y, + local_a8[0].z + local_b4.z); + GXTexCoord2f32(0.0f, coord); + GXPosition3f32(local_a8[1].x + local_b4.x, local_a8[1].y + local_b4.y, + local_a8[1].z + local_b4.z); + GXTexCoord2f32(1.0f, coord); + } + GXEnd(); + + coord = start_coord; + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT1, ptcl_num << 1); + for (JPANode<JPABaseParticle>* node = startNode; node != param_0->mpAlivePtcl->getEnd(); + node = node_func(node), coord += step) { + param_0->mpCurNode = node; + JPABaseParticle* particle = node->getObject(); + local_b4.set(particle->mPosition); + dVar11 = JMASCos(particle->mRotateAngle); + dVar12 = -JMASSin(particle->mRotateAngle); + local_a8[0].set(-particle->mParticleScaleY * local_15c, 0.0f, 0.0f); + local_a8[0].set(local_a8[0].x * dVar12, 0.0f, local_a8[0].x * dVar11); + local_a8[1].set(particle->mParticleScaleY * local_160, 0.0f, 0.0f); + local_a8[1].set(local_a8[1].x * dVar12, 0.0f, local_a8[1].x * dVar11); + p_direction[param_0->mDirType](param_0, particle, &local_c0); + if (local_c0.isZero()) { + local_c0.set(0.0f, 1.0f, 0.0f); + } else { + local_c0.normalize(); + } + local_cc.cross(particle->mBaseAxis, local_c0); + if (local_cc.isZero()) { + local_cc.set(1.0f, 0.0f, 0.0f); + } else { + local_cc.normalize(); + } + particle->mBaseAxis.cross(local_c0, local_cc); + particle->mBaseAxis.normalize(); + + local_90[0][0] = local_cc.x; + local_90[0][1] = local_c0.x; + local_90[0][2] = particle->mBaseAxis.x; + local_90[0][3] = 0.0f; + local_90[1][0] = local_cc.y; + local_90[1][1] = local_c0.y; + local_90[1][2] = particle->mBaseAxis.y; + local_90[1][3] = 0.0f; + local_90[2][0] = local_cc.z; + local_90[2][1] = local_c0.z; + local_90[2][2] = particle->mBaseAxis.z; + local_90[2][3] = 0.0f; + MTXMultVecArraySR(local_90, (Vec*)local_a8, (Vec*)local_a8, 2); + GXPosition3f32(local_a8[0].x + local_b4.x, local_a8[0].y + local_b4.y, + local_a8[0].z + local_b4.z); + GXTexCoord2f32(0.0f, coord); + GXPosition3f32(local_a8[1].x + local_b4.x, local_a8[1].y + local_b4.y, + local_a8[1].z + local_b4.z); + GXTexCoord2f32(1.0f, coord); + } + GXEnd(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8); +} + +/* 8027A3D8-8027A414 274D18 003C+00 0/0 1/1 0/0 .text + * JPADrawEmitterCallBackB__FP18JPAEmitterWorkData */ +void JPADrawEmitterCallBackB(JPAEmitterWorkData* work) { + if (work->mpEmtr->mpEmtrCallBack == NULL) + return; + + work->mpEmtr->mpEmtrCallBack->draw(work->mpEmtr); +} + +/* 8027A414-8027A454 274D54 0040+00 0/0 1/1 0/0 .text + * JPADrawParticleCallBack__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPADrawParticleCallBack(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + if (work->mpEmtr->mpPtclCallBack == NULL) + return; + + work->mpEmtr->mpPtclCallBack->draw(work->mpEmtr, ptcl); +} + +/* 8027A454-8027A6DC 274D94 0288+00 1/1 0/0 0/0 .text + * makeColorTable__FPP8_GXColorPC16JPAClrAnmKeyDataUcsP7JKRHeap */ +static void makeColorTable(GXColor** o_color_table, JPAClrAnmKeyData const* i_data, u8 param_2, + s16 i_size, JKRHeap* i_heap) { + GXColor* color_table = (GXColor*)JKRAllocFromHeap(i_heap, (i_size + 1) * 4, 4); + f32 r_step, g_step, b_step, a_step; + r_step = g_step = b_step = a_step = 0.0f; + f32 r = i_data[0].color.r; + f32 g = i_data[0].color.g; + f32 b = i_data[0].color.b; + f32 a = i_data[0].color.a; + int j = 0; + for (s16 i = 0; i < i_size + 1; i++) { + if (i == i_data[j].index) { + color_table[i] = i_data[j].color; + r = i_data[j].color.r; + g = i_data[j].color.g; + b = i_data[j].color.b; + a = i_data[j].color.a; + j++; + if (j < param_2) { + f32 base_step = 1.0f / (i_data[j].index - i_data[j - 1].index); + r_step = base_step * ((f32)i_data[j].color.r - r); + g_step = base_step * ((f32)i_data[j].color.g - g); + b_step = base_step * ((f32)i_data[j].color.b - b); + a_step = base_step * ((f32)i_data[j].color.a - a); + } else { + r_step = g_step = b_step = a_step = 0.0f; + } + } else { + r += r_step; + color_table[i].r = r; + g += g_step; + color_table[i].g = g; + b += b_step; + color_table[i].b = b; + a += a_step; + color_table[i].a = a; + } + } + *o_color_table = color_table; +} + +/* 8027A6DC-8027A7E8 27501C 010C+00 0/0 1/1 0/0 .text __ct__12JPABaseShapeFPCUcP7JKRHeap + */ +JPABaseShape::JPABaseShape(u8 const* pData, JKRHeap* pHeap) { + mpData = (const JPABaseShapeData*)pData; + + if (isTexCrdAnm()) { + mpTexCrdMtxAnmTbl = (const void*)(pData + sizeof(JPABaseShapeData)); + } else { + mpTexCrdMtxAnmTbl = NULL; + } + + if (isTexAnm()) { + u32 offs = sizeof(JPABaseShapeData); + if (isTexCrdAnm()) + offs = sizeof(JPABaseShapeData) + 0x28; + mpTexIdxAnimTbl = (const u8*)(pData + offs); + } else { + mpTexIdxAnimTbl = NULL; + } + + if (isPrmAnm()) { + makeColorTable(&mpPrmClrAnmTbl, (JPAClrAnmKeyData*)(pData + mpData->mClrPrmAnmOffset), + mpData->mClrPrmKeyNum, mpData->mClrAnmFrmMax, pHeap); + } else { + mpPrmClrAnmTbl = NULL; + } + + if (isEnvAnm()) { + makeColorTable(&mpEnvClrAnmTbl, (JPAClrAnmKeyData*)(pData + mpData->mClrEnvAnmOffset), + mpData->mClrEnvKeyNum, mpData->mClrAnmFrmMax, pHeap); + } else { + mpEnvClrAnmTbl = NULL; + } +} + +/* 803C4360-803C436C 021480 000C+00 0/1 0/0 0/0 .data st_bm__12JPABaseShape */ +GXBlendMode JPABaseShape::st_bm[3] = { + GX_BM_NONE, + GX_BM_BLEND, + GX_BM_LOGIC, +}; + +/* 803C436C-803C4394 02148C 0028+00 0/1 0/0 0/0 .data st_bf__12JPABaseShape */ +GXBlendFactor JPABaseShape::st_bf[10] = { + GX_BL_ZERO, GX_BL_ONE, GX_BL_SRCCLR, GX_BL_INVSRCCLR, + GX_BL_SRCCLR, GX_BL_INVSRCCLR, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, + GX_BL_DSTALPHA, GX_BL_INVDSTALPHA, +}; + +/* 803C4394-803C43D4 0214B4 0040+00 0/1 0/0 0/0 .data st_lo__12JPABaseShape */ +GXLogicOp JPABaseShape::st_lo[16] = { + GX_LO_CLEAR, GX_LO_SET, GX_LO_COPY, GX_LO_INVCOPY, GX_LO_NOOP, GX_LO_INV, + GX_LO_AND, GX_LO_NAND, GX_LO_OR, GX_LO_NOR, GX_LO_XOR, GX_LO_EQUIV, + GX_LO_REVAND, GX_LO_INVAND, GX_LO_REVOR, GX_LO_INVOR, +}; + +/* 803C43D4-803C43F4 0214F4 0020+00 0/1 0/0 0/0 .data st_c__12JPABaseShape */ +GXCompare JPABaseShape::st_c[8] = { + GX_NEVER, GX_LESS, GX_LEQUAL, GX_EQUAL, GX_NEQUAL, GX_GEQUAL, GX_GREATER, GX_ALWAYS, +}; + +/* 803C43F4-803C4404 021514 0010+00 0/1 0/0 0/0 .data st_ao__12JPABaseShape */ +GXAlphaOp JPABaseShape::st_ao[4] = { + GX_AOP_AND, + GX_AOP_OR, + GX_AOP_XOR, + GX_AOP_XNOR, +}; + +/* 803C4404-803C4464 021524 0060+00 0/1 0/0 0/0 .data st_ca__12JPABaseShape */ +GXTevColorArg JPABaseShape::st_ca[6][4] = { + { + GX_CC_ZERO, + GX_CC_TEXC, + GX_CC_ONE, + GX_CC_ZERO, + }, + { + GX_CC_ZERO, + GX_CC_C0, + GX_CC_TEXC, + GX_CC_ZERO, + }, + { + GX_CC_C0, + GX_CC_ONE, + GX_CC_TEXC, + GX_CC_ZERO, + }, + { + GX_CC_C1, + GX_CC_C0, + GX_CC_TEXC, + GX_CC_ZERO, + }, + { + GX_CC_ZERO, + GX_CC_TEXC, + GX_CC_C0, + GX_CC_C1, + }, + { + GX_CC_ZERO, + GX_CC_ZERO, + GX_CC_ZERO, + GX_CC_C0, + }, +}; + +/* 803C4464-803C4488 021584 0020+04 0/1 0/0 0/0 .data st_aa__12JPABaseShape */ +GXTevAlphaArg JPABaseShape::st_aa[2][4] = { + { + GX_CA_ZERO, + GX_CA_TEXA, + GX_CA_A0, + GX_CA_ZERO, + }, + { + GX_CA_ZERO, + GX_CA_ZERO, + GX_CA_ZERO, + GX_CA_A0, + }, +}; + +/* 8027A7E8-8027A918 275128 0130+00 0/0 1/1 0/0 .text setGX__12JPABaseShapeCFP18JPAEmitterWorkData + */ +void JPABaseShape::setGX(JPAEmitterWorkData* work) const { + const GXTevColorArg* colorArg = getTevColorArg(); + const GXTevAlphaArg* alphaArg = getTevAlphaArg(); + GXSetBlendMode(getBlendMode(), getBlendSrc(), getBlendDst(), getLogicOp()); + GXSetZMode(getZEnable(), getZCmp(), getZUpd()); + GXSetAlphaCompare(getAlphaCmp0(), getAlphaRef0(), getAlphaOp(), getAlphaCmp1(), getAlphaRef1()); + GXSetTevColorIn(GX_TEVSTAGE0, colorArg[0], colorArg[1], colorArg[2], colorArg[3]); + GXSetTevAlphaIn(GX_TEVSTAGE0, alphaArg[0], alphaArg[1], alphaArg[2], alphaArg[3]); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevDirect(GX_TEVSTAGE1); + GXSetZCompLoc(getZCompLoc()); +} diff --git a/src/JSystem/JParticle/JPAChildShape.cpp b/src/JSystem/JParticle/JPAChildShape.cpp new file mode 100644 index 00000000..cbc24cbb --- /dev/null +++ b/src/JSystem/JParticle/JPAChildShape.cpp @@ -0,0 +1,48 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAChildShape +// + +#include "JSystem/JParticle/JPAChildShape.h" +#include "JSystem/JParticle/JPAParticle.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "dolphin/gx.h" +#include "dolphin/os.h" + +/* 8027AEBC-8027AFDC 2757FC 0120+00 0/0 1/1 0/0 .text JPARegistChildPrmEnv__FP18JPAEmitterWorkData + */ +void JPARegistChildPrmEnv(JPAEmitterWorkData* work) { + JPAChildShape* csp = work->mpRes->getCsp(); + JPABaseEmitter* emtr = work->mpEmtr; + GXColor prm, env; + csp->getPrmClr(&prm); + csp->getEnvClr(&env); + prm.r = COLOR_MULTI(prm.r, emtr->mGlobalPrmClr.r); + prm.g = COLOR_MULTI(prm.g, emtr->mGlobalPrmClr.g); + prm.b = COLOR_MULTI(prm.b, emtr->mGlobalPrmClr.b); + prm.a = COLOR_MULTI(prm.a, emtr->mGlobalPrmClr.a); + env.r = COLOR_MULTI(env.r, emtr->mGlobalEnvClr.r); + env.g = COLOR_MULTI(env.g, emtr->mGlobalEnvClr.g); + env.b = COLOR_MULTI(env.b, emtr->mGlobalEnvClr.b); + GXSetTevColor(GX_TEVREG0, prm); + GXSetTevColor(GX_TEVREG1, env); +} + +/* 8027AFDC-8027B008 27591C 002C+00 0/0 1/1 0/0 .text + * JPACalcChildAlphaOut__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcChildAlphaOut(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + f32 anm = (1.0f - ptcl->mTime) * 255.0f; + OSf32tou8(&anm, &ptcl->mPrmColorAlphaAnm); +} + +/* 8027B008-8027B038 275948 0030+00 0/0 1/1 0/0 .text + * JPACalcChildScaleOut__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcChildScaleOut(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + ptcl->mParticleScaleX = ptcl->mScaleOut * (1.0f - ptcl->mTime); + ptcl->mParticleScaleY = ptcl->mAlphaWaveRandom * (1.0f - ptcl->mTime); +} + +/* 8027B038-8027B040 -00001 0008+00 0/0 0/0 0/0 .text __ct__13JPAChildShapeFPCUc */ +JPAChildShape::JPAChildShape(u8 const* pData) { + mpData = (JPAChildShapeData*)pData; +} diff --git a/src/JSystem/JParticle/JPADynamicsBlock.cpp b/src/JSystem/JParticle/JPADynamicsBlock.cpp new file mode 100644 index 00000000..672c8413 --- /dev/null +++ b/src/JSystem/JParticle/JPADynamicsBlock.cpp @@ -0,0 +1,233 @@ +// +// Generated By: dol2asm +// Translation Unit: JPADynamicsBlock +// + +#include "JSystem/JParticle/JPADynamicsBlock.h" +#include "JSystem/JMath/JMATrigonometric.h" +#include "JSystem/JParticle/JPAEmitter.h" + +/* 8027B144-8027B220 275A84 00DC+00 1/1 0/0 0/0 .text JPAVolumePoint__FP18JPAEmitterWorkData */ +void JPAVolumePoint(JPAEmitterWorkData* work) { + work->mVolumeCalcData.mVolumePos.zero(); + work->mVolumeCalcData.mVelOmni.set(work->mpEmtr->get_r_zh(), work->mpEmtr->get_r_zh(), + work->mpEmtr->get_r_zh()); + work->mVolumeCalcData.mVelAxis.set(work->mVolumeCalcData.mVelOmni.x, 0.0f, + work->mVolumeCalcData.mVelOmni.z); +} + +/* 8027B220-8027B33C 275B60 011C+00 1/1 0/0 0/0 .text JPAVolumeLine */ +void JPAVolumeLine(JPAEmitterWorkData* work) { + if (work->mpEmtr->checkFlag(JPADynFlag_FixedInterval)) { + work->mVolumeCalcData.mVolumePos.set( + 0.0f, 0.0f, + work->mVolumeSize * ((work->mVolumeEmitIdx / (work->mEmitCount - 1.0f) - 0.5f))); + work->mVolumeEmitIdx++; + } else { + work->mVolumeCalcData.mVolumePos.set(0.0f, 0.0f, + work->mVolumeSize * work->mpEmtr->get_r_zh()); + } + + work->mVolumeCalcData.mVelOmni.set(0.0f, 0.0f, + work->mVolumeCalcData.mVolumePos.z * work->mGlobalScl.z); + work->mVolumeCalcData.mVelAxis.set(0.0f, 0.0f, work->mVolumeCalcData.mVolumePos.z); +} + +/* 8027B33C-8027B4E8 275C7C 01AC+00 1/1 0/0 0/0 .text JPAVolumeCircle */ +// NONMATCHING regalloc. Could be issue with mul asm implementations +void JPAVolumeCircle(JPAEmitterWorkData* work) { + s16 theta; + f32 distance; + + if (work->mpEmtr->checkFlag(JPADynFlag_FixedInterval)) { + theta = (s16)((work->mVolumeEmitIdx << 16) / work->mEmitCount); + theta = theta * work->mVolumeSweep; + work->mVolumeEmitIdx++; + } else { + theta = work->mVolumeSweep * work->mpEmtr->get_r_ss(); + } + + distance = work->mpEmtr->get_r_f(); + if (work->mpEmtr->checkFlag(JPADynFlag_FixedDensity)) { + distance = 1.0f - (distance * distance); + } + + distance = work->mVolumeSize * (work->mVolumeMinRad + distance * (1.0f - work->mVolumeMinRad)); + work->mVolumeCalcData.mVolumePos.set(distance * JMASSin(theta), 0.0f, + distance * JMASCos(theta)); + work->mVolumeCalcData.mVelOmni.mul(work->mVolumeCalcData.mVolumePos, work->mGlobalScl); + work->mVolumeCalcData.mVelAxis.set(work->mVolumeCalcData.mVolumePos.x, 0.0f, + work->mVolumeCalcData.mVolumePos.z); +} + +/* 8027B4E8-8027B5F0 275E28 0108+00 1/1 0/0 0/0 .text JPAVolumeCube */ +void JPAVolumeCube(JPAEmitterWorkData* work) { + work->mVolumeCalcData.mVolumePos.set(work->mpEmtr->get_r_zh() * work->mVolumeSize, + work->mpEmtr->get_r_zh() * work->mVolumeSize, + work->mpEmtr->get_r_zh() * work->mVolumeSize); + work->mVolumeCalcData.mVelOmni.mul(work->mVolumeCalcData.mVolumePos, work->mGlobalScl); + work->mVolumeCalcData.mVelAxis.set(work->mVolumeCalcData.mVolumePos.x, 0.0f, work->mVolumeCalcData.mVolumePos.z); +} + +/* 8027B5F0-8027B87C 275F30 028C+00 1/1 0/0 0/0 .text JPAVolumeSphere__FP18JPAEmitterWorkData */ +static void JPAVolumeSphere(JPAEmitterWorkData* work) { + s16 phi, theta; + if (work->mpEmtr->checkFlag(JPADynFlag_FixedInterval)) { + phi = (u16)(work->mVolumeX * 0x8000 / (work->mDivNumber - 1) + 0x4000); + f32 tmp = (u16)(work->mVolumeAngleNum * 0x10000 / (work->mVolumeAngleMax - 1)); + theta = tmp * work->mVolumeSweep + 0x8000; + work->mVolumeAngleNum++; + if (work->mVolumeAngleNum == work->mVolumeAngleMax) { + work->mVolumeAngleNum = 0; + work->mVolumeX++; + if (work->mVolumeX * 2 < work->mDivNumber) { + work->mVolumeAngleMax = work->mVolumeAngleMax != 1 ? + work->mVolumeAngleMax + 4 : work->mVolumeAngleMax + 3; + } else { + work->mVolumeAngleMax = work->mVolumeAngleMax != 4 ? work->mVolumeAngleMax - 4 : 1; + } + } + } else { + phi = work->mpEmtr->get_r_ss() >> 1; + theta = work->mVolumeSweep * work->mpEmtr->get_r_ss(); + } + + f32 rnd = work->mpEmtr->get_r_f(); + if (work->mpEmtr->checkFlag(JPADynFlag_FixedDensity)) { + rnd = 1.0f - rnd * rnd * rnd; + } + f32 rad = work->mVolumeSize * (work->mVolumeMinRad + rnd * (1.0f - work->mVolumeMinRad)); + work->mVolumeCalcData.mVolumePos.set(rad * JMASCos(phi) * JMASSin(theta), -rad * JMASSin(phi), + rad * JMASCos(phi) * JMASCos(theta)); + work->mVolumeCalcData.mVelOmni.mul(work->mVolumeCalcData.mVolumePos, work->mGlobalScl); + work->mVolumeCalcData.mVelAxis.set(work->mVolumeCalcData.mVolumePos.x, 0.0f, + work->mVolumeCalcData.mVolumePos.z); +} + +/* 8027B87C-8027B9F8 2761BC 017C+00 1/1 0/0 0/0 .text JPAVolumeCylinder__FP18JPAEmitterWorkData */ +static void JPAVolumeCylinder(JPAEmitterWorkData* work) { + s16 theta = work->mVolumeSweep * work->mpEmtr->get_r_ss(); + f32 rnd = work->mpEmtr->get_r_f(); + if (work->mpEmtr->checkFlag(JPADynFlag_FixedDensity)) { + rnd = 1.0f - rnd * rnd; + } + f32 rad = work->mVolumeSize * (work->mVolumeMinRad + rnd * (1.0f - work->mVolumeMinRad)); + work->mVolumeCalcData.mVolumePos.set( + rad * JMASSin(theta), work->mVolumeSize * work->mpEmtr->get_r_zp(), rad * JMASCos(theta)); + work->mVolumeCalcData.mVelOmni.mul(work->mVolumeCalcData.mVolumePos, work->mGlobalScl); + work->mVolumeCalcData.mVelAxis.set(work->mVolumeCalcData.mVolumePos.x, 0.0f, + work->mVolumeCalcData.mVolumePos.z); +} + +/* 8027B9F8-8027BB18 276338 0120+00 1/1 0/0 0/0 .text JPAVolumeTorus__FP18JPAEmitterWorkData */ +static void JPAVolumeTorus(JPAEmitterWorkData* work) { + s16 theta = work->mVolumeSweep * work->mpEmtr->get_r_ss(); + s16 phi = work->mpEmtr->get_r_ss(); + f32 rad = work->mVolumeSize * work->mVolumeMinRad; + work->mVolumeCalcData.mVelAxis.set(rad * JMASSin(theta) * JMASCos(phi), rad * JMASSin(phi), + rad * JMASCos(theta) * JMASCos(phi)); + work->mVolumeCalcData.mVolumePos.set( + work->mVolumeCalcData.mVelAxis.x + work->mVolumeSize * JMASSin(theta), + work->mVolumeCalcData.mVelAxis.y, + work->mVolumeCalcData.mVelAxis.z + work->mVolumeSize * JMASCos(theta)); + work->mVolumeCalcData.mVelOmni.mul(work->mVolumeCalcData.mVolumePos, work->mGlobalScl); +} + +/* 8027BB18-8027BB4C 276458 0034+00 0/0 1/1 0/0 .text __ct__16JPADynamicsBlockFPCUc */ +JPADynamicsBlock::JPADynamicsBlock(u8 const* data) { + mpData = (const JPADynamicsBlockData*)data; + init(); +} + +enum { + VOL_Cube = 0x00, + VOL_Sphere = 0x01, + VOL_Cylinder = 0x02, + VOL_Torus = 0x03, + VOL_Point = 0x04, + VOL_Circle = 0x05, + VOL_Line = 0x06, +}; + +/* 8027BB4C-8027BBE8 27648C 009C+00 2/1 0/0 0/0 .text init__16JPADynamicsBlockFv */ +void JPADynamicsBlock::init() { + switch (getVolumeType()) { + case VOL_Cube: + mpCalcVolumeFunc = &JPAVolumeCube; + break; + case VOL_Sphere: + mpCalcVolumeFunc = &JPAVolumeSphere; + break; + case VOL_Cylinder: + mpCalcVolumeFunc = &JPAVolumeCylinder; + break; + case VOL_Torus: + mpCalcVolumeFunc = &JPAVolumeTorus; + break; + case VOL_Point: + mpCalcVolumeFunc = &JPAVolumePoint; + break; + case VOL_Circle: + mpCalcVolumeFunc = &JPAVolumeCircle; + break; + case VOL_Line: + mpCalcVolumeFunc = &JPAVolumeLine; + break; + } +} + +/* 8027BBE8-8027BDEC 276528 0204+00 0/0 1/1 0/0 .text + * create__16JPADynamicsBlockFP18JPAEmitterWorkData */ +void JPADynamicsBlock::create(JPAEmitterWorkData* work) { + if (work->mpEmtr->checkStatus(JPAEmtrStts_RateStepEmit)) { + s32 emitCount; + s32 createCount; + + // Probably an inlined function. + if (work->mpEmtr->checkFlag(JPADynFlag_FixedInterval)) { + s32 count; + if (getVolumeType() == VOL_Sphere) { + count = 4 * getDivNumber() * getDivNumber() + 2; + } else { + count = getDivNumber(); + } + emitCount = count; + + work->mVolumeEmitIdx = 0; + } else { + f32 newPtclCount = + work->mpEmtr->mRate * (getRateRndm() * work->mpEmtr->get_r_zp() + 1.0f); + f32 newEmitCount = work->mpEmtr->mEmitCount + newPtclCount; + work->mpEmtr->mEmitCount = newEmitCount; + emitCount = (s32)newEmitCount; + work->mpEmtr->mEmitCount -= emitCount; + + if (work->mpEmtr->checkStatus(JPAEmtrStts_FirstEmit) && 0.0f < newPtclCount && + newPtclCount < 1.0f) + emitCount = 1; + } + + work->mEmitCount = emitCount; + if (work->mpEmtr->checkStatus(JPAEmtrStts_StopEmit)) { + emitCount = 0; + } + + // Probably an inlined function. + createCount = emitCount; + while (createCount > 0) { + JPABaseParticle* ptcl = work->mpEmtr->createParticle(); + if (ptcl == NULL) + break; + createCount--; + } + } + + if (++work->mpEmtr->mRateStepTimer >= (work->mpEmtr->mRateStep + 1)) { + work->mpEmtr->mRateStepTimer -= (work->mpEmtr->mRateStep + 1); + work->mpEmtr->setStatus(JPAEmtrStts_RateStepEmit); + } else { + work->mpEmtr->clearStatus(JPAEmtrStts_RateStepEmit); + } + + work->mpEmtr->clearStatus(JPAEmtrStts_FirstEmit); +} diff --git a/src/JSystem/JParticle/JPAEmitter.cpp b/src/JSystem/JParticle/JPAEmitter.cpp new file mode 100644 index 00000000..517421c8 --- /dev/null +++ b/src/JSystem/JParticle/JPAEmitter.cpp @@ -0,0 +1,183 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAEmitter +// + +#include "JSystem/JParticle/JPAEmitter.h" +#include "JSystem/JParticle/JPAEmitterManager.h" +#include "JSystem/JParticle/JPAParticle.h" +#include "JSystem/JParticle/JPAResourceManager.h" +#include "JSystem/JParticle/JPABaseShape.h" +#include "dolphin/types.h" + +// +// Types: +// + +// +// Forward References: +// + +// +// External References: +// + +// +// Declarations: +// + +/* 8027E6A4-8027E6EC 278FE4 0048+00 0/0 14/14 16/16 .text __dt__18JPAEmitterCallBackFv */ +JPAEmitterCallBack::~JPAEmitterCallBack() { +} + +/* 8027E6EC-8027EA40 27902C 0354+00 0/0 1/1 0/0 .text + * init__14JPABaseEmitterFP17JPAEmitterManagerP11JPAResource */ +void JPABaseEmitter::init(JPAEmitterManager* param_0, JPAResource* param_1) { + mpEmtrMgr = param_0; + mpRes = param_1; + mpRes->getDyn()->getEmitterScl(&mLocalScl); + mpRes->getDyn()->getEmitterTrs(&mLocalTrs); + mpRes->getDyn()->getEmitterDir(&mLocalDir); + mLocalDir.normalize(); + mpRes->getDyn()->getEmitterRot(&mLocalRot); + mMaxFrame = mpRes->getDyn()->getMaxFrame(); + mLifeTime = mpRes->getDyn()->getLifetime(); + mVolumeSize = mpRes->getDyn()->getVolumeSize(); + mRate = mpRes->getDyn()->getRate(); + mRateStep = mpRes->getDyn()->getRateStep(); + mVolumeSweep = mpRes->getDyn()->getVolumeSweep(); + mVolumeMinRad = mpRes->getDyn()->getVolumeMinRad(); + mAwayFromCenterSpeed = mpRes->getDyn()->getInitVelOmni(); + mAwayFromAxisSpeed = mpRes->getDyn()->getInitVelAxis(); + mDirSpeed = mpRes->getDyn()->getInitVelDir(); + mSpread = mpRes->getDyn()->getInitVelDirSp(); + mRndmDirSpeed = mpRes->getDyn()->getInitVelRndm(); + mAirResist = mpRes->getDyn()->getAirRes(); + mRndm.set_seed(mpEmtrMgr->pWd->mRndm.get_rndm_u()); + MTXIdentity(mGlobalRot); + mGlobalScl.set(1.0f, 1.0f, 1.0f); + mGlobalTrs.zero(); + mGlobalPScl.set(1.0f, 1.0f); + mGlobalEnvClr.a = 0xff; + mGlobalEnvClr.b = 0xff; + mGlobalEnvClr.g = 0xff; + mGlobalEnvClr.r = 0xff; + mGlobalPrmClr.a = 0xff; + mGlobalPrmClr.b = 0xff; + mGlobalPrmClr.g = 0xff; + mGlobalPrmClr.r = 0xff; + param_1->getBsp()->getPrmClr(&mPrmClr); + param_1->getBsp()->getEnvClr(&mEnvClr); + mpUserWork = NULL; + mScaleOut = 1.0f; + mEmitCount = 0.0f; + initStatus(0x30); + mDrawTimes = 1; + mTick = 0; + mWaitTime = 0; + mRateStepTimer = 0; + mTexAnmIdx = 0; +} + +/* 8027EA40-8027EB60 279380 0120+00 0/0 3/3 0/0 .text createParticle__14JPABaseEmitterFv + */ +JPABaseParticle* JPABaseEmitter::createParticle() { + if (mpPtclPool->getNum() != 0) { + JPANode<JPABaseParticle>* node = mpPtclPool->pop_front(); + mAlivePtclBase.push_front(node); + mpRes->getDyn()->calc(mpEmtrMgr->pWd); + node->mData.init_p(mpEmtrMgr->pWd); + return &node->mData; + } + + return NULL; +} + +/* 8027EB60-8027EC60 2794A0 0100+00 0/0 1/1 0/0 .text + * createChild__14JPABaseEmitterFP15JPABaseParticle */ +JPABaseParticle* JPABaseEmitter::createChild(JPABaseParticle* parent) { + if (mpPtclPool->getNum() != 0) { + JPANode<JPABaseParticle>* node = mpPtclPool->pop_front(); + mAlivePtclChld.push_front(node); + node->mData.init_c(mpEmtrMgr->pWd, parent); + return &node->mData; + } + + return NULL; +} + +/* 8027EC60-8027EDD4 2795A0 0174+00 0/0 2/2 21/21 .text deleteAllParticle__14JPABaseEmitterFv */ +void JPABaseEmitter::deleteAllParticle() { + while (mAlivePtclBase.getNum()) + mpPtclPool->push_front(mAlivePtclBase.pop_back()); + while (mAlivePtclChld.getNum()) + mpPtclPool->push_front(mAlivePtclChld.pop_back()); +} + +/* 8027EDD4-8027EE14 279714 0040+00 0/0 1/1 0/0 .text processTillStartFrame__14JPABaseEmitterFv */ +bool JPABaseEmitter::processTillStartFrame() { + JPADynamicsBlock* dyn = mpRes->getDyn(); + s16 startFrame = dyn->getStartFrame(); + + if (mWaitTime >= startFrame) + return true; + + if (!(mStatus & 2)) + mWaitTime++; + + return false; +} + +/* 8027EE14-8027EEB0 279754 009C+00 0/0 1/1 0/0 .text processTermination__14JPABaseEmitterFv */ +bool JPABaseEmitter::processTermination() { + if (checkStatus(0x100)) { + return true; + } + + if (mMaxFrame == 0) { + return false; + } + if (mMaxFrame < 0) { + setStatus(8); + return getParticleNumber() == 0; + } + if (mTick >= mMaxFrame) { + setStatus(8); + if (checkStatus(0x40)) { + return 0; + } + return getParticleNumber() == 0; + } + return false; +} + +/* 8027EEB0-8027EF30 2797F0 0080+00 0/0 1/1 0/0 .text + * calcEmitterGlobalPosition__14JPABaseEmitterCFPQ29JGeometry8TVec3<f> */ +void JPABaseEmitter::calcEmitterGlobalPosition(JGeometry::TVec3<f32>* dst) const { + Mtx mtx; + MTXScale(mtx, mGlobalScl.x, mGlobalScl.y, mGlobalScl.z); + MTXConcat(mGlobalRot, mtx, mtx); + mtx[0][3] = mGlobalTrs.x; + mtx[1][3] = mGlobalTrs.y; + mtx[2][3] = mGlobalTrs.z; + MTXMultVec(mtx, mLocalTrs, *dst); +} + +/* 8027EF30-8027EF40 279870 0010+00 0/0 1/1 0/0 .text getCurrentCreateNumber__14JPABaseEmitterCFv + */ +u32 JPABaseEmitter::getCurrentCreateNumber() const { + return mpEmtrMgr->pWd->mEmitCount; +} + +/* 8027EF40-8027EF50 279880 0010+00 0/0 3/3 0/0 .text getDrawCount__14JPABaseEmitterCFv + */ +u8 JPABaseEmitter::getDrawCount() const { + return mpEmtrMgr->pWd->mDrawCount; +} + +/* 8027EF50-8027EFA4 279890 0054+00 0/0 1/1 0/0 .text + * loadTexture__14JPABaseEmitterFUc11_GXTexMapID */ +bool JPABaseEmitter::loadTexture(u8 idx, GXTexMapID texMapID) { + mpEmtrMgr->pWd->mpResMgr->load(mpRes->getTexIdx(idx), texMapID); + return true; +} diff --git a/src/JSystem/JParticle/JPAEmitterManager.cpp b/src/JSystem/JParticle/JPAEmitterManager.cpp new file mode 100644 index 00000000..649f4226 --- /dev/null +++ b/src/JSystem/JParticle/JPAEmitterManager.cpp @@ -0,0 +1,203 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAEmitterManager +// + +#include "JSystem/JParticle/JPAEmitterManager.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "JSystem/JParticle/JPAParticle.h" +#include "JSystem/JParticle/JPAResourceManager.h" +#include "JSystem/JUtility/JUTAssert.h" +#include "dolphin/gx.h" + +/* 8027DCA0-8027DEBC 2785E0 021C+00 0/0 1/1 0/0 .text __ct__17JPAEmitterManagerFUlUlP7JKRHeapUcUc + */ +JPAEmitterManager::JPAEmitterManager(u32 i_ptclNum, u32 i_emtrNum, JKRHeap* pHeap, u8 i_gidMax, + u8 i_ridMax) { + emtrNum = i_emtrNum; + ptclNum = i_ptclNum; + gidMax = i_gidMax; + ridMax = i_ridMax; + + JUT_ASSERT(40, emtrNum && ptclNum && gidMax && ridMax); + + JPABaseEmitter* p_emtr_link = new (pHeap, 0) JPABaseEmitter[emtrNum]; + JUT_ASSERT(44, p_emtr_link); + for (u32 i = 0; i < emtrNum; i++) + mFreeEmtrList.prepend(&p_emtr_link[i].mLink); + + JPANode<JPABaseParticle>* p_ptcl_node = new (pHeap, 0) JPANode<JPABaseParticle>[ptclNum]; + JUT_ASSERT(51, p_ptcl_node); + for (u32 i = 0; i < ptclNum; i++) + mPtclPool.push_back(&p_ptcl_node[i]); + + pEmtrUseList = new (pHeap, 0) JSUList<JPABaseEmitter>[gidMax]; + JUT_ASSERT(58, pEmtrUseList); + pResMgrAry = new (pHeap, 0) JPAResourceManager*[ridMax]; + JUT_ASSERT(62, pResMgrAry) + for (int i = 0; i < ridMax; i++) { + pResMgrAry[i] = NULL; + } + + pWd = new (pHeap, 0) JPAEmitterWorkData(); + JUT_ASSERT(67, pWd); +} + +/* 8027DEBC-8027DFA0 2787FC 00E4+00 0/0 3/3 0/0 .text + * createSimpleEmitterID__17JPAEmitterManagerFRCQ29JGeometry8TVec3<f>UsUcUcP18JPAEmitterCallBackP19JPAParticleCallBack + */ +JPABaseEmitter* JPAEmitterManager::createSimpleEmitterID(JGeometry::TVec3<f32> const& pos, + u16 resID, u8 group_id, u8 res_mgr_id, + JPAEmitterCallBack* emtrCB, + JPAParticleCallBack* ptclCB) { + JUT_ASSERT(88, group_id < gidMax); + JUT_ASSERT(89, res_mgr_id < ridMax); + JUT_ASSERT(90, pResMgrAry[res_mgr_id] != 0); + JPAResource* pRes = pResMgrAry[res_mgr_id]->getResource(resID); + + if (pRes == NULL) { + JUT_WARN_DEVICE(94, 3, "JPA : User Index %d is NOT exist\n", resID); + } else if (mFreeEmtrList.getNumLinks() == 0) { + JUT_WARN_DEVICE(97, 3, "JPA : Can NOT create emitter more\n"); + } else { + JSULink<JPABaseEmitter>* pLink = mFreeEmtrList.getFirst(); + mFreeEmtrList.remove(pLink); + pEmtrUseList[group_id].append(pLink); + JPABaseEmitter* emtr = pLink->getObject(); + emtr->init(this, pRes); + emtr->mpPtclPool = &mPtclPool; + emtr->mpEmtrCallBack = emtrCB; + emtr->mpPtclCallBack = ptclCB; + emtr->mGroupID = group_id; + emtr->mResMgrID = res_mgr_id; + emtr->mGlobalTrs.set(pos); + return emtr; + } + + return NULL; +} + +/* 8027DFA0-8027E028 2788E0 0088+00 0/0 3/3 0/0 .text calc__17JPAEmitterManagerFUc */ +void JPAEmitterManager::calc(u8 group_id) { + JUT_ASSERT(154, group_id < gidMax); + JSULink<JPABaseEmitter>* pNext = NULL; + for (JSULink<JPABaseEmitter>* pLink = pEmtrUseList[group_id].getFirst(); + pLink != pEmtrUseList[group_id].getEnd(); pLink = pNext) { + pNext = pLink->getNext(); + + JPABaseEmitter* emtr = pLink->getObject(); + + if (emtr->mpRes->calc(pWd, emtr) && !emtr->checkStatus(0x200)) + forceDeleteEmitter(emtr); + } +} + +/* 8027E028-8027E220 278968 01F8+00 0/0 1/1 0/0 .text draw__17JPAEmitterManagerFPC11JPADrawInfoUc + */ +void JPAEmitterManager::draw(JPADrawInfo const* drawInfo, u8 group_id) { + JUT_ASSERT(192, group_id < gidMax); + drawInfo->getCamMtx(pWd->mPosCamMtx); + drawInfo->getPrjMtx(pWd->mPrjMtx); + calcYBBCam(); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXEnableTexOffsets(GX_TEXCOORD0, GX_TRUE, GX_TRUE); + GXEnableTexOffsets(GX_TEXCOORD1, GX_TRUE, GX_TRUE); + GXEnableTexOffsets(GX_TEXCOORD2, GX_TRUE, GX_TRUE); + GXSetCullMode(GX_CULL_NONE); + GXSetCoPlanar(GX_FALSE); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S8, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S8, 0); + GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GXSetCurrentMtx(GX_PNMTX0); + GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, + GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, + GX_AF_NONE); + GXSetNumChans(0); + + for (JSULink<JPABaseEmitter>* pLink = pEmtrUseList[group_id].getFirst(); + pLink != pEmtrUseList[group_id].getEnd(); pLink = pLink->getNext()) { + JPABaseEmitter* emtr = pLink->getObject(); + if (!emtr->checkStatus(0x04)) { + pWd->mpResMgr = pResMgrAry[emtr->mResMgrID]; + emtr->mpRes->draw(pWd, emtr); + } + } +} + +/* 8027E220-8027E278 278B60 0058+00 0/0 1/1 0/0 .text forceDeleteAllEmitter__17JPAEmitterManagerFv + */ +void JPAEmitterManager::forceDeleteAllEmitter() { + for (u8 i = 0; i < gidMax; i++) + forceDeleteGroupEmitter(i); +} + +/* 8027E278-8027E2D8 278BB8 0060+00 1/1 0/0 0/0 .text + * forceDeleteGroupEmitter__17JPAEmitterManagerFUc */ +void JPAEmitterManager::forceDeleteGroupEmitter(u8 group_id) { + JUT_ASSERT(288, group_id < gidMax); + while (pEmtrUseList[group_id].getNumLinks()) + forceDeleteEmitter(pEmtrUseList[group_id].getLast()->getObject()); +} + +/* 8027E2D8-8027E344 278C18 006C+00 3/3 1/1 0/0 .text + * forceDeleteEmitter__17JPAEmitterManagerFP14JPABaseEmitter */ +void JPAEmitterManager::forceDeleteEmitter(JPABaseEmitter* emtr) { + emtr->deleteAllParticle(); + emtr->setStatus(0x300); + pEmtrUseList[emtr->getGroupID()].remove(&emtr->mLink); + mFreeEmtrList.prepend(&emtr->mLink); +} + +/* 8027E344-8027E354 278C84 0010+00 0/0 2/2 0/0 .text + * entryResourceManager__17JPAEmitterManagerFP18JPAResourceManagerUc */ +void JPAEmitterManager::entryResourceManager(JPAResourceManager* resMgr, u8 resMgrID) { + JUT_ASSERT_MSG_F(325, resMgrID < ridMax && (pResMgrAry[resMgrID]) == 0, + "res_id %d res_id_max %d array[%d] = %x", resMgrID, ridMax, resMgrID, + pResMgrAry[resMgrID]); + pResMgrAry[resMgrID] = resMgr; +} + +/* 8027E354-8027E3F4 278C94 00A0+00 0/0 1/1 0/0 .text clearResourceManager__17JPAEmitterManagerFUc + */ +void JPAEmitterManager::clearResourceManager(u8 res_mgr_id) { + JUT_ASSERT(339, res_mgr_id < ridMax); + for (u8 i = 0; i < gidMax; i++) { + JSULink<JPABaseEmitter>* pNext = NULL; + for (JSULink<JPABaseEmitter>* pLink = pEmtrUseList[i].getFirst(); + pLink != pEmtrUseList[i].getEnd(); pLink = pNext) { + pNext = pLink->getNext(); + + if (res_mgr_id == pLink->getObject()->getResourceManagerID()) + forceDeleteEmitter(pLink->getObject()); + } + } + + pResMgrAry[res_mgr_id] = NULL; +} + +/* 8027E3F4-8027E51C 278D34 0128+00 1/1 0/0 0/0 .text calcYBBCam__17JPAEmitterManagerFv + */ +void JPAEmitterManager::calcYBBCam() { + JGeometry::TVec3<float> v(0.0f, pWd->mPosCamMtx[1][1], pWd->mPosCamMtx[2][1]); + JUT_ASSERT(367, !v.isZero()); + v.normalize(); + pWd->mYBBCamMtx[0][0] = 1.0f; + pWd->mYBBCamMtx[0][1] = 0.0f; + pWd->mYBBCamMtx[0][2] = 0.0f; + pWd->mYBBCamMtx[0][3] = pWd->mPosCamMtx[0][3]; + pWd->mYBBCamMtx[1][0] = 0.0f; + pWd->mYBBCamMtx[1][1] = v.y; + pWd->mYBBCamMtx[1][2] = -v.z; + pWd->mYBBCamMtx[1][3] = pWd->mPosCamMtx[1][3]; + pWd->mYBBCamMtx[2][0] = 0.0f; + pWd->mYBBCamMtx[2][1] = v.z; + pWd->mYBBCamMtx[2][2] = v.y; + pWd->mYBBCamMtx[2][3] = pWd->mPosCamMtx[2][3]; +} diff --git a/src/JSystem/JParticle/JPAExTexShape.cpp b/src/JSystem/JParticle/JPAExTexShape.cpp new file mode 100644 index 00000000..4763459a --- /dev/null +++ b/src/JSystem/JParticle/JPAExTexShape.cpp @@ -0,0 +1,35 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAExTexShape +// + +#include "JSystem/JParticle/JPAExTexShape.h" +#include "JSystem/JParticle/JPAResourceManager.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "dolphin/gx.h" + +/* 8027B040-8027B13C 275980 00FC+00 0/0 1/1 0/0 .text JPALoadExTex__FP18JPAEmitterWorkData */ +void JPALoadExTex(JPAEmitterWorkData* work) { + JPAExTexShape* ets = work->mpRes->getEts(); + + GXTexCoordID secTexCoordID = GX_TEXCOORD1; + if (ets->isUseIndirect()) { + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, + GX_PTIDENTITY); + u8 texIdx = ets->getIndTexIdx(); + work->mpResMgr->load(work->mpRes->getTexIdx(texIdx), GX_TEXMAP2); + secTexCoordID = GX_TEXCOORD2; + } + + if (ets->isUseSecTex()) { + GXSetTexCoordGen2(secTexCoordID, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, + GX_PTIDENTITY); + u8 texIdx = ets->getSecTexIdx(); + work->mpResMgr->load(work->mpRes->getTexIdx(texIdx), GX_TEXMAP3); + } +} + +/* 8027B13C-8027B144 -00001 0008+00 0/0 0/0 0/0 .text __ct__13JPAExTexShapeFPCUc */ +JPAExTexShape::JPAExTexShape(u8 const* data) { + mpData = (const JPAExTexShapeData*)data; +}
\ No newline at end of file diff --git a/src/JSystem/JParticle/JPAExtraShape.cpp b/src/JSystem/JParticle/JPAExtraShape.cpp new file mode 100644 index 00000000..2c269a31 --- /dev/null +++ b/src/JSystem/JParticle/JPAExtraShape.cpp @@ -0,0 +1,152 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAExtraShape +// + +#include "JSystem/JParticle/JPAExtraShape.h" +#include "JSystem/JMath/JMATrigonometric.h" +#include "JSystem/JParticle/JPAParticle.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "dolphin/os.h" + +/* 8027A918-8027A990 275258 0078+00 0/0 1/1 0/0 .text + * JPACalcScaleX__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcScaleX(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPAExtraShape* esp = work->mpRes->getEsp(); + if (work->mScaleAnm < esp->getScaleInTiming()) { + ptcl->mParticleScaleX = + ptcl->mScaleOut * (esp->getScaleIncRateX() * work->mScaleAnm + esp->getScaleInValueX()); + } else if (work->mScaleAnm > esp->getScaleOutTiming()) { + ptcl->mParticleScaleX = + ptcl->mScaleOut * + (esp->getScaleDecRateX() * (work->mScaleAnm - esp->getScaleOutTiming()) + 1.0f); + } else { + ptcl->mParticleScaleX = ptcl->mScaleOut; + } +} + +/* 8027A990-8027AA08 2752D0 0078+00 0/0 1/1 0/0 .text + * JPACalcScaleY__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcScaleY(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPAExtraShape* esp = work->mpRes->getEsp(); + if (work->mScaleAnm < esp->getScaleInTiming()) { + ptcl->mParticleScaleY = + ptcl->mScaleOut * (esp->getScaleIncRateY() * work->mScaleAnm + esp->getScaleInValueY()); + } else if (work->mScaleAnm > esp->getScaleOutTiming()) { + ptcl->mParticleScaleY = + ptcl->mScaleOut * + (esp->getScaleDecRateY() * (work->mScaleAnm - esp->getScaleOutTiming()) + 1.0f); + } else { + ptcl->mParticleScaleY = ptcl->mScaleOut; + } +} + +/* 8027AA08-8027AA14 275348 000C+00 0/0 1/1 0/0 .text + * JPACalcScaleCopy__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcScaleCopy(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPAExtraShape* esp = work->mpRes->getEsp(); + ptcl->mParticleScaleY = ptcl->mParticleScaleX; +} + +/* 8027AA14-8027AA20 275354 000C+00 0/0 1/1 0/0 .text + * JPACalcScaleAnmNormal__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcScaleAnmNormal(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + work->mScaleAnm = ptcl->mTime; +} + +/* 8027AA20-8027AA84 275360 0064+00 0/0 1/1 0/0 .text + * JPACalcScaleAnmRepeatX__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcScaleAnmRepeatX(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPAExtraShape* esp = work->mpRes->getEsp(); + work->mScaleAnm = (ptcl->mAge % esp->getScaleAnmCycleX()) / (f32)esp->getScaleAnmCycleX(); +} + +/* 8027AA84-8027AAE8 2753C4 0064+00 0/0 1/1 0/0 .text + * JPACalcScaleAnmRepeatY__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcScaleAnmRepeatY(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPAExtraShape* esp = work->mpRes->getEsp(); + work->mScaleAnm = (ptcl->mAge % esp->getScaleAnmCycleY()) / (f32)esp->getScaleAnmCycleY(); +} + +/* 8027AAE8-8027AB7C 275428 0094+00 0/0 1/1 0/0 .text + * JPACalcScaleAnmReverseX__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcScaleAnmReverseX(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPAExtraShape* esp = work->mpRes->getEsp(); + s32 cycle = ptcl->mAge / esp->getScaleAnmCycleX(); + f32 base = (ptcl->mAge % esp->getScaleAnmCycleX()) / (f32)esp->getScaleAnmCycleX(); + work->mScaleAnm = base + ((cycle & 1) * (1.0f - base * 2.0f)); +} + +/* 8027AB7C-8027AC10 2754BC 0094+00 0/0 1/1 0/0 .text + * JPACalcScaleAnmReverseY__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcScaleAnmReverseY(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPAExtraShape* esp = work->mpRes->getEsp(); + s32 cycle = ptcl->mAge / esp->getScaleAnmCycleY(); + f32 base = (ptcl->mAge % esp->getScaleAnmCycleY()) / (f32)esp->getScaleAnmCycleY(); + work->mScaleAnm = base + ((cycle & 1) * (1.0f - base * 2.0f)); +} + +/* 8027AC10-8027AC98 275550 0088+00 0/0 1/1 0/0 .text + * JPACalcAlphaAnm__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcAlphaAnm(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPAExtraShape* esp = work->mpRes->getEsp(); + f32 alpha; + if (ptcl->mTime < esp->getAlphaInTiming()) { + alpha = 255.0f * (esp->getAlphaInValue() + esp->getAlphaIncRate() * ptcl->mTime); + } else if (ptcl->mTime > esp->getAlphaOutTiming()) { + alpha = 255.0f * ((ptcl->mTime - esp->getAlphaOutTiming()) * esp->getAlphaDecRate() + + esp->getAlphaBaseValue()); + } else { + alpha = 255.0f * esp->getAlphaBaseValue(); + } + OSf32tou8(&alpha, &ptcl->mPrmColorAlphaAnm); +} + +/* 8027AC98-8027AD88 2755D8 00F0+00 0/0 1/1 0/0 .text + * JPACalcAlphaFlickAnm__FP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPACalcAlphaFlickAnm(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + JPAExtraShape* esp = work->mpRes->getEsp(); + f32 alpha; + if (ptcl->mTime < esp->getAlphaInTiming()) { + alpha = (esp->getAlphaInValue() + esp->getAlphaIncRate() * ptcl->mTime); + } else if (ptcl->mTime > esp->getAlphaOutTiming()) { + alpha = ((ptcl->mTime - esp->getAlphaOutTiming()) * esp->getAlphaDecRate() + + esp->getAlphaBaseValue()); + } else { + alpha = esp->getAlphaBaseValue(); + } + s32 theta = ptcl->mAlphaWaveRandom * ptcl->mAge * 16384.0f * (1.0f - esp->getAlphaFreq()); + f32 wave = JMASSin(theta); + alpha *= (1.0f + esp->getAlphaAmp() * (wave - 1.0f) * 0.5f) * 255.0f; + OSf32tou8(&alpha, &ptcl->mPrmColorAlphaAnm); +} + +/* 8027AD88-8027ADBC 2756C8 0034+00 0/0 1/1 0/0 .text __ct__13JPAExtraShapeFPCUc */ +JPAExtraShape::JPAExtraShape(u8 const* data) { + mpData = (const JPAExtraShapeData*)data; + init(); +} + +/* 8027ADBC-8027AEBC 2756FC 0100+00 1/1 0/0 0/0 .text init__13JPAExtraShapeFv */ +void JPAExtraShape::init() { + mAlphaIncRate = (getAlphaInTiming() != 0.0f) ? + (getAlphaBaseValue() - getAlphaInValue()) / getAlphaInTiming() : + 1.0f; + mAlphaDecRate = (getAlphaOutTiming() != 1.0f) ? + (getAlphaOutValue() - getAlphaBaseValue()) / (1.0f - getAlphaOutTiming()) : + 1.0f; + + if (getScaleInTiming() != 0.0f) { + mScaleIncRateX = (1.0f - getScaleInValueX()) / getScaleInTiming(); + mScaleIncRateY = (1.0f - getScaleInValueY()) / getScaleInTiming(); + } else { + mScaleIncRateX = mScaleIncRateY = 1.0f; + } + + if (getScaleOutTiming() != 1.0f) { + mScaleDecRateX = (getScaleOutValueX() - 1.0f) / (1.0f - getScaleOutTiming()); + mScaleDecRateY = (getScaleOutValueY() - 1.0f) / (1.0f - getScaleOutTiming()); + } else { + mScaleDecRateX = mScaleDecRateY = 1.0f; + } +} diff --git a/src/JSystem/JParticle/JPAFieldBlock.cpp b/src/JSystem/JParticle/JPAFieldBlock.cpp new file mode 100644 index 00000000..c9a4c038 --- /dev/null +++ b/src/JSystem/JParticle/JPAFieldBlock.cpp @@ -0,0 +1,299 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAFieldBlock +// + +#include "JSystem/JParticle/JPAFieldBlock.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "JSystem/JParticle/JPAParticle.h" + +/* 8027BDEC-8027BF18 27672C 012C+00 8/8 0/0 0/0 .text + * calcAffect__12JPAFieldBaseFP13JPAFieldBlockP15JPABaseParticle */ +void JPAFieldBase::calcAffect(JPAFieldBlock* block, JPABaseParticle* ptcl) { + JGeometry::TVec3<f32> vec = mAccel; + if (!ptcl->checkStatus(4) && block->checkStatus(0x78)) { + vec.scale(calcFadeAffect(block, ptcl->mTime)); + } + + switch (block->getAddType()) { + case 0: + ptcl->mVelType0.add(vec); + break; + case 1: + ptcl->mVelType1.add(vec); + break; + case 2: + ptcl->mVelType2.add(vec); + break; + } +} + +/* 8027BF18-8027BFB4 276858 009C+00 2/2 0/0 0/0 .text + * calcFadeAffect__12JPAFieldBaseCFP13JPAFieldBlockf */ +f32 JPAFieldBase::calcFadeAffect(JPAFieldBlock* block, f32 time) const { + f32 fade = 1.0f; + if ((block->checkStatus(8) && time < block->getEnTime()) + || (block->checkStatus(0x10) && time >= block->getDisTime())) + { + fade = 0.0f; + } else if (block->checkStatus(0x40) && time >= block->getFadeOutTime()) { + fade = (block->getDisTime() - time) * block->getFadeOutRate(); + } else if (block->checkStatus(0x20) && time < block->getFadeInTime()) { + fade = (time - block->getEnTime()) * block->getFadeInRate(); + } + return fade; +} + +/* 8027BFB4-8027C054 2768F4 00A0+00 1/0 0/0 0/0 .text + * prepare__15JPAFieldGravityFP18JPAEmitterWorkDataP13JPAFieldBlock */ +void JPAFieldGravity::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) { + if (block->checkStatus(2)) { + mAccel.scale(block->getMag(), block->getDir()); + } else { + MTXMultVecSR(work->mRotationMtx, &block->getDir(), &mAccel); + mAccel.scale(block->getMag()); + } +} + +/* 8027C054-8027C07C 276994 0028+00 1/0 0/0 0/0 .text + * calc__15JPAFieldGravityFP18JPAEmitterWorkDataP13JPAFieldBlockP15JPABaseParticle */ +void JPAFieldGravity::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) { + calcAffect(block, ptcl); +} + +/* 8027C07C-8027C1B8 2769BC 013C+00 1/0 0/0 0/0 .text + * prepare__11JPAFieldAirFP18JPAEmitterWorkDataP13JPAFieldBlock */ +void JPAFieldAir::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) { + JGeometry::TVec3<f32> vec; + vec.normalize(block->getDir()); + if (block->checkStatus(2)) { + mAccel.scale(block->getMag(), vec); + } else { + MTXMultVecSR(work->mRotationMtx, vec, mAccel); + mAccel.scale(block->getMag()); + } +} + +/* 8027C1B8-8027C24C 276AF8 0094+00 1/0 0/0 0/0 .text + * calc__11JPAFieldAirFP18JPAEmitterWorkDataP13JPAFieldBlockP15JPABaseParticle */ +void JPAFieldAir::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) { + calcAffect(block, ptcl); + if (block->checkStatus(4)) { + f32 len = ptcl->mVelType1.length(); + if (len > block->getMagRndm()) { + ptcl->mVelType1.scale(block->getMagRndm() / len); + } + } +} + +/* 8027C24C-8027C29C 276B8C 0050+00 1/0 0/0 0/0 .text + * prepare__14JPAFieldMagnetFP18JPAEmitterWorkDataP13JPAFieldBlock */ +void JPAFieldMagnet::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) { + mDir.sub(block->getPos(), work->mEmitterPos); + MTXMultVecSR(work->mRotationMtx, &mDir, &mDir); +} + +/* 8027C29C-8027C36C 276BDC 00D0+00 1/0 0/0 0/0 .text + * calc__14JPAFieldMagnetFP18JPAEmitterWorkDataP13JPAFieldBlockP15JPABaseParticle */ +void JPAFieldMagnet::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) { + mAccel.sub(mDir, ptcl->mLocalPosition); + mAccel.setLength(block->getMag()); + calcAffect(block, ptcl); +} + +/* 8027C36C-8027C3E0 276CAC 0074+00 1/0 0/0 0/0 .text + * prepare__14JPAFieldNewtonFP18JPAEmitterWorkDataP13JPAFieldBlock */ +void JPAFieldNewton::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) { + mDir.sub(block->getPos(), work->mEmitterPos); + MTXMultVecSR(work->mRotationMtx, &mDir, &mDir); + mCutoff = block->getVal1() * block->getVal1(); +} + +/* 8027C3E0-8027C56C 276D20 018C+00 1/0 0/0 0/0 .text + * calc__14JPAFieldNewtonFP18JPAEmitterWorkDataP13JPAFieldBlockP15JPABaseParticle */ +void JPAFieldNewton::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) { + mAccel.sub(mDir, ptcl->mLocalPosition); + f32 len_sq = mAccel.squared(); + if (len_sq > mCutoff) { + mAccel.setLength(mCutoff * (block->getMag() * 10.0f) / len_sq); + } else { + mAccel.setLength(block->getMag() * 10.0f); + } + calcAffect(block, ptcl); +} + +/* 8027C56C-8027C674 276EAC 0108+00 1/0 0/0 0/0 .text + * prepare__14JPAFieldVortexFP18JPAEmitterWorkDataP13JPAFieldBlock */ +void JPAFieldVortex::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) { + MTXMultVecSR(work->mGlobalRot, &block->getDir(), &field_0x10); + field_0x10.normalize(); + field_0x1c = block->getPos().z * block->getPos().z; + field_0x20 = 1.0f / field_0x1c; +} + +/* 8027C674-8027C814 276FB4 01A0+00 1/0 0/0 0/0 .text + * calc__14JPAFieldVortexFP18JPAEmitterWorkDataP13JPAFieldBlockP15JPABaseParticle */ +void JPAFieldVortex::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) { + JGeometry::TVec3<f32> vec; + vec.scale(field_0x10.dot(ptcl->mLocalPosition), field_0x10); + vec.sub(ptcl->mLocalPosition, vec); + f32 mag = vec.squared(); + if (mag > field_0x1c) { + mag = block->getMagRndm(); + } else { + mag *= field_0x20; + mag = (1.0f - mag) * block->getMag() + mag * block->getMagRndm(); + } + vec.normalize(); + mAccel.cross(vec, field_0x10); + mAccel.scale(mag); + calcAffect(block, ptcl); +} + +/* 8027C814-8027CA94 277154 0280+00 1/0 0/0 0/0 .text + * prepare__18JPAFieldConvectionFP18JPAEmitterWorkDataP13JPAFieldBlock */ +void JPAFieldConvection::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) { + JGeometry::TVec3<f32> vec1, vec2; + vec2.cross(block->getPos(), block->getDir()); + vec1.cross(block->getDir(), vec2); + MTXMultVecSR(work->mGlobalRot, &vec1, &field_0x10); + MTXMultVecSR(work->mGlobalRot, &block->getDir(), field_0x1c); + MTXMultVecSR(work->mGlobalRot, &vec2, &field_0x28); + field_0x10.normalize(); + field_0x1c.normalize(); + field_0x28.normalize(); +} + +/* 8027CA94-8027CCCC 2773D4 0238+00 1/0 0/0 0/0 .text + * calc__18JPAFieldConvectionFP18JPAEmitterWorkDataP13JPAFieldBlockP15JPABaseParticle */ +void JPAFieldConvection::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, + JPABaseParticle* ptcl) { + JGeometry::TVec3<f32> vec1, vec2, vec3; + vec1.scale(field_0x10.dot(ptcl->mLocalPosition), field_0x10); + vec3.scale(field_0x28.dot(ptcl->mLocalPosition), field_0x28); + vec1.add(vec3); + vec1.setLength(vec1, block->getVal1()); + vec2.sub(ptcl->mLocalPosition, vec1); + vec3.cross(field_0x1c, vec1); + mAccel.cross(vec3, vec2); + mAccel.setLength(block->getMag()); + calcAffect(block, ptcl); +} + +/* 8027CCCC-8027CDE4 27760C 0118+00 1/0 0/0 0/0 .text + * calc__14JPAFieldRandomFP18JPAEmitterWorkDataP13JPAFieldBlockP15JPABaseParticle */ +void JPAFieldRandom::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) { + if (ptcl->mAge == 0 || (block->getCycle() != 0 && ptcl->mAge % block->getCycle() == 0)) { + JPABaseEmitter* emtr = work->mpEmtr; + mAccel.set(emtr->get_r_zh(), emtr->get_r_zh(), emtr->get_r_zh()); + mAccel.scale(block->getMag()); + calcAffect(block, ptcl); + } +} + +/* 8027CDE4-8027CE64 277724 0080+00 1/0 0/0 0/0 .text + * calc__12JPAFieldDragFP18JPAEmitterWorkDataP13JPAFieldBlockP15JPABaseParticle */ +void JPAFieldDrag::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) { + if (!ptcl->checkStatus(4)) { + f32 fade = calcFadeAffect(block, ptcl->mTime); + ptcl->mDrag *= 1.0f - fade * (1.0f - block->getMag()); + } else { + ptcl->mDrag *= block->getMag(); + } +} + +/* 8027CE64-8027CFA8 2777A4 0144+00 1/0 0/0 0/0 .text + * prepare__12JPAFieldSpinFP18JPAEmitterWorkDataP13JPAFieldBlock */ +void JPAFieldSpin::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) { + JGeometry::TVec3<f32> axis; + MTXMultVecSR(work->mGlobalRot, &block->getDir(), &axis); + axis.normalize(); + Mtx mtx; + MTXRotAxisRad(mtx, &axis, block->getMag()); + field_0x10.set(mtx[0][0], mtx[1][0], mtx[2][0]); + field_0x1c.set(mtx[0][1], mtx[1][1], mtx[2][1]); + field_0x28.set(mtx[0][2], mtx[1][2], mtx[2][2]); +} + +/* 8027CFA8-8027D088 2778E8 00E0+00 1/0 0/0 0/0 .text + * calc__12JPAFieldSpinFP18JPAEmitterWorkDataP13JPAFieldBlockP15JPABaseParticle */ +void JPAFieldSpin::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) { + Mtx mtx; + mtx[0][0] = field_0x10.x; + mtx[1][0] = field_0x10.y; + mtx[2][0] = field_0x10.z; + mtx[0][1] = field_0x1c.x; + mtx[1][1] = field_0x1c.y; + mtx[2][1] = field_0x1c.z; + mtx[0][2] = field_0x28.x; + mtx[1][2] = field_0x28.y; + mtx[2][2] = field_0x28.z; + mtx[0][3] = mtx[1][3] = mtx[2][3] = 0.0f; + Vec vec; + MTXMultVecSR(mtx, &ptcl->mLocalPosition, &vec); + mAccel.set(vec.x - ptcl->mLocalPosition.x, vec.y - ptcl->mLocalPosition.y, + vec.z - ptcl->mLocalPosition.z); + calcAffect(block, ptcl); +} + +/* 8027D088-8027D0C0 2779C8 0038+00 0/0 1/1 0/0 .text __ct__13JPAFieldBlockFPCUcP7JKRHeap + */ +JPAFieldBlock::JPAFieldBlock(u8 const* data, JKRHeap* heap) + : mpData((const JPAFieldBlockData*)data) { + init(heap); +} + +/* 8027D0C0-8027D3AC 277A00 02EC+00 2/1 0/0 0/0 .text init__13JPAFieldBlockFP7JKRHeap */ +void JPAFieldBlock::init(JKRHeap* heap) { + mFadeInRate = getFadeInTime() - getEnTime(); + if (mFadeInRate == 0.0f) { + mFadeInRate = 1.0f; + } else { + mFadeInRate = 1.0f / mFadeInRate; + } + + mFadeOutRate = getDisTime() - getFadeOutTime(); + if (mFadeOutRate == 0.0f) { + mFadeOutRate = 1.0f; + } else { + mFadeOutRate = 1.0f / mFadeOutRate; + } + + getPosOrig(&mPos); + getDirOrig(&mDir); + mMag = getMagOrig(); + + switch (getType()) { + case FIELD_GRAVITY: + mpField = new (heap, 0) JPAFieldGravity(); + break; + case FIELD_AIR: + mpField = new (heap, 0) JPAFieldAir(); + break; + case FIELD_MAGNET: + mpField = new (heap, 0) JPAFieldMagnet(); + break; + case FIELD_NEWTON: + mpField = new (heap, 0) JPAFieldNewton(); + break; + case FIELD_VORTEX: + mpField = new (heap, 0) JPAFieldVortex(); + break; + case FIELD_RANDOM: + mpField = new (heap, 0) JPAFieldRandom(); + break; + case FIELD_DRAG: + mpField = new (heap, 0) JPAFieldDrag(); + break; + case FIELD_CONVECTION: + mpField = new (heap, 0) JPAFieldConvection(); + break; + case FIELD_SPIN: + mpField = new (heap, 0) JPAFieldSpin(); + break; + default: + mpField = NULL; + break; + } +} diff --git a/src/JSystem/JParticle/JPAKeyBlock.cpp b/src/JSystem/JParticle/JPAKeyBlock.cpp new file mode 100644 index 00000000..fdb1e8e6 --- /dev/null +++ b/src/JSystem/JParticle/JPAKeyBlock.cpp @@ -0,0 +1,25 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAKeyBlock +// + +#include "JSystem/JParticle/JPAKeyBlock.h" +#include "JSystem/JParticle/JPAMath.h" + +/* 8027D730-8027D740 278070 0010+00 0/0 1/1 0/0 .text __ct__11JPAKeyBlockFPCUc */ +JPAKeyBlock::JPAKeyBlock(const u8* data) + : mDataStart(data) + , field_0x4(reinterpret_cast<const float*>(&data[0xC])) +{ +} + +/* 8027D740-8027D7D4 278080 0094+00 0/0 1/1 0/0 .text calc__11JPAKeyBlockFf */ +f32 JPAKeyBlock::calc(float p1) { + if (mDataStart[0xB] != '\0') { + int v1 = (int)field_0x4[(mDataStart[9] - 1) * 4] + 1; + // p1 -= (v1 * ((int)p1 / v1)); + int v2 = ((int)p1 / v1); + p1 = p1 - (v2 * v1); + } + return JPACalcKeyAnmValue(p1, mDataStart[9], field_0x4); +} diff --git a/src/JSystem/JParticle/JPAMath.cpp b/src/JSystem/JParticle/JPAMath.cpp new file mode 100644 index 00000000..c8686038 --- /dev/null +++ b/src/JSystem/JParticle/JPAMath.cpp @@ -0,0 +1,182 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAMath +// + +#include "JSystem/JParticle/JPAMath.h" +#include "JSystem/JMath/JMATrigonometric.h" +#include "JSystem/J2DGraph/J2DAnimation.h" + +// +// Types: +// + +// +// Forward References: +// + +extern "C" void func_80280588(); +extern "C" void JPAGetYZRotateMtx__FssPA4_f(); +extern "C" void JPAGetXYZRotateMtx__FsssPA4_f(); +extern "C" void func_802807E0(); +extern "C" void func_80280808(); +extern "C" void JPACalcKeyAnmValue__FfUsPCf(); + +// +// External References: +// + +extern "C" void _savegpr_28(); +extern "C" void _restgpr_28(); +extern "C" u8 sincosTable___5JMath[65536]; + +// +// Declarations: +// + +/* ############################################################################################## */ +// Probably some local function needed to change float literal order +static f32 floatDummyFunc() { + return 1.0f; +} + +/* 80280588-802806C0 27AEC8 0138+00 0/0 1/1 0/0 .text JPAGetDirMtx__FRCQ29JGeometry8TVec3<f>PA4_f + */ +void JPAGetDirMtx(JGeometry::TVec3<f32> const& param_0, f32 (*param_1)[4]) { + JGeometry::TVec3<float> local_78(param_0.y, -param_0.x, 0.0f); + f32 len = local_78.length(); + + if (len <= JGeometry::TUtil<f32>::epsilon()) { + local_78.zero(); + } else { + local_78.scale(1.0f / len); + } + f32 xsquared = local_78.x * local_78.x; + f32 ysquared = local_78.y * local_78.y; + f32 xlen = local_78.x * len; + f32 ylen = local_78.y * len; + f32 fVar5 = (1.0f - param_0.z) * (local_78.x * local_78.y); + param_1[0][0] = xsquared + param_0.z * (1.0f - xsquared); + param_1[0][1] = fVar5; + param_1[0][2] = -ylen; + param_1[0][3] = 0.0f; + param_1[1][0] = fVar5; + param_1[1][1] = ysquared + param_0.z * (1.0f - ysquared); + param_1[1][2] = xlen; + param_1[1][3] = 0.0f; + param_1[2][0] = ylen; + param_1[2][1] = -xlen; + param_1[2][2] = param_0.z; + param_1[2][3] = 0.0f; +} + +/* 802806C0-80280734 27B000 0074+00 0/0 1/1 0/0 .text JPAGetYZRotateMtx__FssPA4_f */ +void JPAGetYZRotateMtx(s16 angleY, s16 angleZ, f32 (*param_2)[4]) { + f32 cosy = JMASCos(angleY); + f32 cosz = JMASCos(angleZ); + f32 siny = JMASSin(angleY); + f32 sinz = JMASSin(angleZ); + param_2[0][0] = (cosy * cosz); + param_2[0][1] = -sinz; + param_2[0][2] = (siny * cosz); + param_2[1][0] = (cosy * sinz); + param_2[1][1] = cosz; + param_2[1][2] = (siny * sinz); + param_2[2][0] = -siny; + param_2[2][2] = cosy; + param_2[2][3] = 0.0f; + param_2[2][1] = 0.0f; + param_2[1][3] = 0.0f; + param_2[0][3] = 0.0f; +} + +/* 80280734-802807E0 27B074 00AC+00 0/0 6/6 11/11 .text JPAGetXYZRotateMtx__FsssPA4_f */ +void JPAGetXYZRotateMtx(s16 x, s16 y, s16 z, Mtx mtx) { + f32 cosx = JMASCos(x); + f32 cosy = JMASCos(y); + f32 cosz = JMASCos(z); + f32 sinx = JMASSin(x); + f32 siny = JMASSin(y); + f32 sinz = JMASSin(z); + mtx[0][0] = cosy * cosz; + mtx[1][0] = cosy * sinz; + mtx[2][0] = -siny; + mtx[2][1] = sinx * cosy; + mtx[2][2] = cosx * cosy; + f32 cosxsinz = cosx * sinz; + f32 sinxcosz = sinx * cosz; + mtx[0][1] = sinxcosz * siny - cosxsinz; + mtx[1][2] = cosxsinz * siny - sinxcosz; + f32 sinxsinz = sinx * sinz; + f32 cosxcosz = cosx * cosz; + mtx[0][2] = sinxsinz + cosxcosz * siny; + mtx[1][1] = cosxcosz + sinxsinz * siny; + mtx[2][3] = 0.0f; + mtx[1][3] = 0.0f; + mtx[0][3] = 0.0f; +} + +/* 802807E0-80280808 27B120 0028+00 0/0 11/11 71/71 .text + * JPASetRMtxTVecfromMtx__FPA4_CfPA4_fPQ29JGeometry8TVec3<f> */ +void JPASetRMtxTVecfromMtx(f32 const (*param_0)[4], f32 (*param_1)[4], + JGeometry::TVec3<f32>* param_2) { + JGeometry::TVec3<f32> dummy; + JPASetRMtxSTVecfromMtx(param_0, param_1, &dummy, param_2); +} + +/* 80280808-80280984 27B148 017C+00 1/1 1/1 53/53 .text + * JPASetRMtxSTVecfromMtx__FPA4_CfPA4_fPQ29JGeometry8TVec3<f>PQ29JGeometry8TVec3<f> */ +void JPASetRMtxSTVecfromMtx(f32 const (*param_0)[4], f32 (*param_1)[4], + JGeometry::TVec3<f32>* param_2, JGeometry::TVec3<f32>* param_3) { + JGeometry::TVec3<float> aTStack_54; + aTStack_54.set(param_0[0][0], param_0[1][0], param_0[2][0]); + param_2->x = aTStack_54.length(); + aTStack_54.set(param_0[0][1], param_0[1][1], param_0[2][1]); + param_2->y = aTStack_54.length(); + aTStack_54.set(param_0[0][2], param_0[1][2], param_0[2][2]); + param_2->z = aTStack_54.length(); + MTXIdentity(param_1); + if (param_2->x != 0.0f) { + f32 fVar5 = 1.0f / param_2->x; + param_1[0][0] = param_0[0][0] * fVar5; + param_1[1][0] = param_0[1][0] * fVar5; + param_1[2][0] = param_0[2][0] * fVar5; + } + if (param_2->y != 0.0f) { + f32 fVar5 = 1.0f / param_2->y; + param_1[0][1] = param_0[0][1] * fVar5; + param_1[1][1] = param_0[1][1] * fVar5; + param_1[2][1] = param_0[2][1] * fVar5; + } + if (param_2->z != 0.0f) { + f32 fVar5 = 1.0f / param_2->z; + param_1[0][2] = param_0[0][2] * fVar5; + param_1[1][2] = param_0[1][2] * fVar5; + param_1[2][2] = param_0[2][2] * fVar5; + } + param_3->set(param_0[0][3], param_0[1][3], param_0[2][3]); +} + +/* 80280984-80280A48 27B2C4 00C4+00 0/0 2/1 0/0 .text JPACalcKeyAnmValue__FfUsPCf */ +f32 JPACalcKeyAnmValue(f32 param_0, u16 param_1, f32 const* param_2) { + if (param_0 < param_2[0]) { + return param_2[1]; + } + int ind = param_1 - 1; + if (param_2[ind * 4] <= param_0) { + return param_2[ind * 4 + 1]; + } + int x = param_1; + while (x > 1) { + u32 uVar3 = x / 2; + if (param_0 >= param_2[uVar3 * 4]) { + param_2 += uVar3 * 4; + x -= uVar3; + } else { + x = uVar3; + } + } + return JMAHermiteInterpolation(param_0, param_2[0], param_2[1], + param_2[3], param_2[4], + param_2[5], param_2[6]); +} diff --git a/src/JSystem/JParticle/JPAParticle.cpp b/src/JSystem/JParticle/JPAParticle.cpp new file mode 100644 index 00000000..c06c62b9 --- /dev/null +++ b/src/JSystem/JParticle/JPAParticle.cpp @@ -0,0 +1,331 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAParticle +// + +#include "JSystem/JParticle/JPAParticle.h" +#include "JSystem/JParticle/JPABaseShape.h" +#include "JSystem/JParticle/JPAChildShape.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "JSystem/JParticle/JPAEmitterManager.h" +#include "JSystem/JParticle/JPAExtraShape.h" + +/* 8027EFA4-8027EFEC 2798E4 0048+00 0/0 11/11 1/1 .text __dt__19JPAParticleCallBackFv */ +JPAParticleCallBack::~JPAParticleCallBack() { + /* empty function */ +} + +/* 8027EFEC-8027F8C8 27992C 08DC+00 0/0 1/1 0/0 .text + * init_p__15JPABaseParticleFP18JPAEmitterWorkData */ +void JPABaseParticle::init_p(JPAEmitterWorkData* work) { + JPABaseEmitter* emtr = work->mpEmtr; + JPAExtraShape* esp = work->mpRes->getEsp(); + JPABaseShape* bsp = work->mpRes->getBsp(); + JPADynamicsBlock* dyn = work->mpRes->getDyn(); + + mAge = -1; + mLifeTime = (1.0f - dyn->getLifetimeRndm() * emtr->get_r_f()) * emtr->mLifeTime; + mTime = 0.0f; + + initStatus(0); + MTXMultVecSR(work->mGlobalSR, &work->mVolumeCalcData.mVolumePos, &mLocalPosition); + if (emtr->checkFlag(8)) { + setStatus(0x20); + } + + mOffsetPosition.set(work->mGlobalPos); + mPosition.set(mOffsetPosition.x + mLocalPosition.x * work->mPublicScale.x, + mOffsetPosition.y + mLocalPosition.y * work->mPublicScale.y, + mOffsetPosition.z + mLocalPosition.z * work->mPublicScale.z); + + JGeometry::TVec3<f32> velOmni; + if (emtr->mAwayFromCenterSpeed) { + velOmni.setLength(work->mVolumeCalcData.mVelOmni, emtr->mAwayFromCenterSpeed); + } else { + velOmni.zero(); + } + + JGeometry::TVec3<f32> velAxis; + if (emtr->mAwayFromAxisSpeed) { + velAxis.setLength(work->mVolumeCalcData.mVelAxis, emtr->mAwayFromAxisSpeed); + } else { + velAxis.zero(); + } + + JGeometry::TVec3<f32> velDir; + if (emtr->mDirSpeed) { + Mtx mtx; + JPAGetYZRotateMtx(emtr->get_r_zp() * 0x8000 * emtr->mSpread, emtr->get_r_ss(), mtx); + MTXConcat(work->mDirectionMtx, mtx, mtx); + velDir.set(emtr->mDirSpeed * mtx[0][2], + emtr->mDirSpeed * mtx[1][2], + emtr->mDirSpeed * mtx[2][2]); + } else { + velDir.zero(); + } + + JGeometry::TVec3<f32> velRndm; + if (emtr->mRndmDirSpeed) { + velRndm.set(emtr->mRndmDirSpeed * emtr->get_r_zh(), + emtr->mRndmDirSpeed * emtr->get_r_zh(), + emtr->mRndmDirSpeed * emtr->get_r_zh()); + } else { + velRndm.zero(); + } + + f32 ratio = emtr->get_r_zp() * dyn->getInitVelRatio() + 1.0f; + mVelType1.set(ratio * (velOmni.x + velAxis.x + velDir.x + velRndm.x), + ratio * (velOmni.y + velAxis.y + velDir.y + velRndm.y), + ratio * (velOmni.z + velAxis.z + velDir.z + velRndm.z)); + + if (emtr->checkFlag(4)) { + mVelType1.mul(emtr->mLocalScl); + } + MTXMultVecSR(work->mGlobalRot, &mVelType1, &mVelType1); + + mVelType0.zero(); + + mMoment = 1.0f - dyn->getMomentRndm() * emtr->get_r_f(); + mDrag = 1.0f; + field_0x78 = 0; + + mBaseAxis.set(work->mGlobalRot[0][1], work->mGlobalRot[1][1], work->mGlobalRot[2][1]); + + mPrmClr = emtr->mPrmClr; + mEnvClr = emtr->mEnvClr; + + mAnmRandom = emtr->get_r_f() * bsp->getLoopOfstValue(); + + if (esp != NULL && esp->isEnableScaleAnm()) { + mParticleScaleX = mParticleScaleY = mScaleOut = emtr->mScaleOut * (emtr->get_r_zp() * esp->getScaleRndm() + 1.0f); + } else { + mParticleScaleX = mParticleScaleY = mScaleOut = emtr->mScaleOut; + } + + mPrmColorAlphaAnm = 0xff; + + if (esp != NULL && esp->isEnableAlphaFlick()) { + mAlphaWaveRandom = emtr->get_r_zp() * esp->getAlphaFreqRndm() + 1.0f; + } else { + mAlphaWaveRandom = 1.0f; + } + + if (esp != NULL) { + if (esp->isEnableRotateAnm()) { + mRotateAngle = esp->getRotateInitAngle() + esp->getRotateRndmAngle() * emtr->get_r_zh(); + mRotateSpeed = esp->getRotateInitSpeed() * + (esp->getRotateRndmSpeed() * emtr->get_r_zp() + 1.0f); + mRotateSpeed = emtr->get_r_zp() < esp->getRotateDirection() ? + mRotateSpeed : (s16)-mRotateSpeed; + } else { + mRotateAngle = 0; + mRotateSpeed = 0; + } + } else { + mRotateAngle = 0; + mRotateSpeed = 0; + } +} + +/* 8027F8C8-8027FFD0 27A208 0708+00 0/0 1/1 0/0 .text + * init_c__15JPABaseParticleFP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPABaseParticle::init_c(JPAEmitterWorkData* work, JPABaseParticle* parent) { + JPABaseEmitter* emtr = work->mpEmtr; + JPAChildShape* csp = work->mpRes->getCsp(); + + mAge = -1; + mLifeTime = csp->getLife(); + mTime = 0.0f; + initStatus(4); + mLocalPosition.set(parent->mLocalPosition); + + f32 pos_rndm = csp->getPosRndm(); + if (pos_rndm != 0.0f) { + JGeometry::TVec3<f32> rnd(emtr->get_r_zh(), emtr->get_r_zh(), emtr->get_r_zh()); + rnd.setLength(pos_rndm * emtr->get_r_f()); + mLocalPosition.add(rnd); + } + + if (emtr->checkFlag(0x10)) { + setStatus(0x20); + } + + mOffsetPosition.set(parent->mOffsetPosition); + + f32 base_speed = csp->getBaseVel() * (csp->getBaseVelRndm() * emtr->get_r_zp() + 1.0f); + JGeometry::TVec3<f32> base_vel(emtr->get_r_zp(), emtr->get_r_zp(), emtr->get_r_zp()); + base_vel.setLength(base_speed); + mVelType1.scaleAdd(csp->getVelInhRate(), parent->mVelType1, base_vel); + mVelType0.scale(csp->getVelInhRate(), parent->mVelType2); + + mMoment = parent->mMoment; + if (csp->isFieldAffected()) { + mDrag = parent->mDrag; + } else { + setStatus(0x40); + mDrag = 1.0f; + } + field_0x78 = parent->field_0x78; + + mVelType2.set(mVelType0); + f32 ratio = mMoment * mDrag; + mVelocity.set(ratio * (mVelType1.x + mVelType2.x), + ratio * (mVelType1.y + mVelType2.y), + ratio * (mVelType1.z + mVelType2.z)); + + mBaseAxis.set(parent->mBaseAxis); + + if (csp->isScaleInherited()) { + mParticleScaleX = mScaleOut = parent->mParticleScaleX * csp->getScaleInhRate(); + mParticleScaleY = mAlphaWaveRandom = parent->mParticleScaleY * csp->getScaleInhRate(); + } else { + mParticleScaleX = mScaleOut = mParticleScaleY = mAlphaWaveRandom = 1.0f; + } + + if (csp->isColorInherited()) { + mPrmClr.r = parent->mPrmClr.r * csp->getColorInhRate(); + mPrmClr.g = parent->mPrmClr.g * csp->getColorInhRate(); + mPrmClr.b = parent->mPrmClr.b * csp->getColorInhRate(); + mEnvClr.r = parent->mEnvClr.r * csp->getColorInhRate(); + mEnvClr.g = parent->mEnvClr.g * csp->getColorInhRate(); + mEnvClr.b = parent->mEnvClr.b * csp->getColorInhRate(); + } else { + csp->getPrmClr(&mPrmClr); + csp->getEnvClr(&mEnvClr); + } + + mPrmColorAlphaAnm = 0xff; + if (csp->isAlphaInherited()) { + mPrmClr.a = COLOR_MULTI(parent->mPrmClr.a, parent->mPrmColorAlphaAnm) + * csp->getAlphaInhRate(); + } else { + mPrmClr.a = csp->getPrmAlpha(); + } + + mRotateAngle = parent->mRotateAngle; + if (csp->isRotateOn()) { + mRotateSpeed = csp->getRotInitSpeed(); + } else { + mRotateSpeed = 0; + } + + mTexAnmIdx = 0; +} + +/* 8027FFD0-80280260 27A910 0290+00 0/0 1/1 0/0 .text + * calc_p__15JPABaseParticleFP18JPAEmitterWorkData */ +bool JPABaseParticle::calc_p(JPAEmitterWorkData* work) { + if (++mAge >= mLifeTime) { + return true; + } + mTime = (f32)mAge / (f32)mLifeTime; + + if (checkStatus(0x20)) { + mOffsetPosition.set(work->mGlobalPos); + } + + mVelType2.zero(); + if (!checkStatus(0x40)) { + work->mpRes->calcField(work, this); + } + mVelType2.add(mVelType0); + mVelType1.scale(work->mpEmtr->mAirResist); + f32 ratio = mMoment * mDrag; + mVelocity.set(ratio * (mVelType1.x + mVelType2.x), + ratio * (mVelType1.y + mVelType2.y), + ratio * (mVelType1.z + mVelType2.z)); + + if (work->mpEmtr->mpPtclCallBack != NULL) { + work->mpEmtr->mpPtclCallBack->execute(work->mpEmtr, this); + } + + if (checkStatus(2)) { + return true; + } + + work->mpRes->calc_p(work, this); + mRotateAngle += mRotateSpeed; + + if (work->mpRes->getCsp() != NULL && canCreateChild(work)) { + for (int i = work->mpRes->getCsp()->getRate(); i > 0; i--) { + work->mpEmtr->createChild(this); + } + } + + mLocalPosition.add(mVelocity); + mPosition.set(mOffsetPosition.x + mLocalPosition.x * work->mPublicScale.x, + mOffsetPosition.y + mLocalPosition.y * work->mPublicScale.y, + mOffsetPosition.z + mLocalPosition.z * work->mPublicScale.z); + + return false; +} + +/* 80280260-802804C8 27ABA0 0268+00 0/0 1/1 0/0 .text + * calc_c__15JPABaseParticleFP18JPAEmitterWorkData */ +bool JPABaseParticle::calc_c(JPAEmitterWorkData* work) { + if (++mAge >= mLifeTime) { + return true; + } + mTime = (f32)mAge / (f32)mLifeTime; + + if (mAge != 0) { + if (checkStatus(0x20)) { + mOffsetPosition.set(work->mGlobalPos); + } + + mVelType1.y -= work->mpRes->getCsp()->getGravity(); + mVelType2.zero(); + if (!checkStatus(0x40)) { + work->mpRes->calcField(work, this); + } + mVelType2.add(mVelType0); + mVelType1.scale(work->mpEmtr->mAirResist); + f32 ratio = mMoment * mDrag; + mVelocity.set(ratio * (mVelType1.x + mVelType2.x), + ratio * (mVelType1.y + mVelType2.y), + ratio * (mVelType1.z + mVelType2.z)); + } + + if (work->mpEmtr->mpPtclCallBack != NULL) { + work->mpEmtr->mpPtclCallBack->execute(work->mpEmtr, this); + } + + if (checkStatus(2)) { + return true; + } + + work->mpRes->calc_c(work, this); + mRotateAngle += mRotateSpeed; + mLocalPosition.add(mVelocity); + mPosition.set(mOffsetPosition.x + mLocalPosition.x * work->mPublicScale.x, + mOffsetPosition.y + mLocalPosition.y * work->mPublicScale.y, + mOffsetPosition.z + mLocalPosition.z * work->mPublicScale.z); + + return false; +} + +/* 802804C8-80280548 27AE08 0080+00 1/1 0/0 0/0 .text + * canCreateChild__15JPABaseParticleFP18JPAEmitterWorkData */ +bool JPABaseParticle::canCreateChild(JPAEmitterWorkData* work) { + JPAChildShape* csp = work->mpRes->getCsp(); + bool ret = false; + int time = mAge - (int)((mLifeTime - 1) * csp->getTiming()); + if (time >= 0 && time % (csp->getStep() + 1) == 0) { + ret = true; + } + return ret; +} + +/* 80280548-80280568 27AE88 0020+00 0/0 3/3 0/0 .text + * getWidth__15JPABaseParticleCFPC14JPABaseEmitter */ +f32 JPABaseParticle::getWidth(JPABaseEmitter const* emtr) const { + f32 scale = 2.0f * mParticleScaleX; + return scale * emtr->mpEmtrMgr->pWd->mGlobalPtclScl.x; +} + +/* 80280568-80280588 27AEA8 0020+00 0/0 3/3 0/0 .text + * getHeight__15JPABaseParticleCFPC14JPABaseEmitter */ +f32 JPABaseParticle::getHeight(JPABaseEmitter const* emtr) const { + f32 scale = 2.0f * mParticleScaleY; + return scale * emtr->mpEmtrMgr->pWd->mGlobalPtclScl.y; +} diff --git a/src/JSystem/JParticle/JPAResource.cpp b/src/JSystem/JParticle/JPAResource.cpp new file mode 100644 index 00000000..01bba7d2 --- /dev/null +++ b/src/JSystem/JParticle/JPAResource.cpp @@ -0,0 +1,1124 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAResource +// + +#include "JSystem/JParticle/JPAResource.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JParticle/JPABaseShape.h" +#include "JSystem/JParticle/JPAChildShape.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "JSystem/JParticle/JPAExTexShape.h" +#include "JSystem/JParticle/JPAExtraShape.h" +#include "JSystem/JParticle/JPAFieldBlock.h" +#include "JSystem/JParticle/JPAKeyBlock.h" +#include "JSystem/JParticle/JPAParticle.h" +#include "JSystem/JParticle/JPAResourceManager.h" +#include "dolphin/gx.h" +#include "global.h" + +/* 80274010-80274080 26E950 0070+00 0/0 1/1 0/0 .text __ct__11JPAResourceFv */ +JPAResource::JPAResource() { + mpDrawEmitterChildFuncList = NULL; + mpDrawEmitterFuncList = NULL; + mpCalcEmitterFuncList = NULL; + mpDrawParticleChildFuncList = NULL; + mpCalcParticleChildFuncList = NULL; + mpDrawParticleFuncList = NULL; + mpCalcParticleFuncList = NULL; + mpBaseShape = NULL; + mpExtraShape = NULL; + mpChildShape = NULL; + mpExTexShape = NULL; + mpDynamicsBlock = NULL; + mpFieldBlocks = NULL; + mpKeyBlocks = NULL; + mpTDB1 = NULL; + mpDrawParticleChildFuncListNum = 0; + mpCalcParticleChildFuncListNum = 0; + mpDrawParticleFuncListNum = 0; + mpCalcParticleFuncListNum = 0; + mpDrawEmitterChildFuncListNum = 0; + mpDrawEmitterFuncListNum = 0; + mpCalcEmitterFuncListNum = 0; + mTDB1Num = 0; + mKeyBlockNum = 0; + mFieldBlockNum = 0; + mUsrIdx = 0; +} + +/* 803C40C0-803C4220 0211E0 0144+1C 2/2 0/0 0/0 .data jpa_pos */ +static u8 jpa_pos[324] ALIGN_DECL(32) = { + 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x32, 0xCE, 0x00, 0x00, 0xCE, 0x00, 0xE7, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x19, 0xCE, 0x00, 0xE7, 0xCE, 0x00, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, + 0x00, 0xCE, 0xCE, 0x00, 0x00, 0x19, 0x00, 0x32, 0x19, 0x00, 0x32, 0xE7, 0x00, 0x00, 0xE7, 0x00, + 0xE7, 0x19, 0x00, 0x19, 0x19, 0x00, 0x19, 0xE7, 0x00, 0xE7, 0xE7, 0x00, 0xCE, 0x19, 0x00, 0x00, + 0x19, 0x00, 0x00, 0xE7, 0x00, 0xCE, 0xE7, 0x00, 0x00, 0x32, 0x00, 0x32, 0x32, 0x00, 0x32, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE7, 0x32, 0x00, 0x19, 0x32, 0x00, 0x19, 0x00, 0x00, 0xE7, 0x00, 0x00, + 0xCE, 0x32, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, + 0x00, 0x00, 0x32, 0x00, 0x32, 0x00, 0x00, 0x32, 0xE7, 0x00, 0x00, 0x19, 0x00, 0x00, 0x19, 0x00, + 0x32, 0xE7, 0x00, 0x32, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xCE, 0x00, 0x32, + 0x00, 0x00, 0xE7, 0x32, 0x00, 0xE7, 0x32, 0x00, 0x19, 0x00, 0x00, 0x19, 0xE7, 0x00, 0xE7, 0x19, + 0x00, 0xE7, 0x19, 0x00, 0x19, 0xE7, 0x00, 0x19, 0xCE, 0x00, 0xE7, 0x00, 0x00, 0xE7, 0x00, 0x00, + 0x19, 0xCE, 0x00, 0x19, 0x00, 0x00, 0xCE, 0x32, 0x00, 0xCE, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE7, 0x00, 0xCE, 0x19, 0x00, 0xCE, 0x19, 0x00, 0x00, 0xE7, 0x00, 0x00, 0xCE, 0x00, 0xCE, 0x00, + 0x00, 0xCE, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0xCE, + 0x32, 0x00, 0xCE, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x19, 0x00, 0xCE, 0x19, 0x00, 0xCE, 0xE7, + 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x00, 0x00, 0xCE, 0xCE, 0x00, 0x19, 0x00, 0x00, + 0x19, 0x32, 0x00, 0xE7, 0x32, 0x00, 0xE7, 0x00, 0x00, 0x19, 0xE7, 0x00, 0x19, 0x19, 0x00, 0xE7, + 0x19, 0x00, 0xE7, 0xE7, 0x00, 0x19, 0xCE, 0x00, 0x19, 0x00, 0x00, 0xE7, 0x00, 0x00, 0xE7, 0xCE, + 0x00, 0x32, 0x00, 0x00, 0x32, 0x32, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x32, 0xE7, 0x00, + 0x32, 0x19, 0x00, 0x00, 0x19, 0x00, 0x00, 0xE7, 0x00, 0x32, 0xCE, 0x00, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xCE, +}; + +/* 803C4220-803C4240 021340 0020+00 2/2 0/0 0/0 .data jpa_crd */ +static u8 jpa_crd[32] ALIGN_DECL(32) = { + 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02, +}; + +/* 80274080-802755E8 26E9C0 1568+00 2/0 1/1 0/0 .text init__11JPAResourceFP7JKRHeap */ +void JPAResource::init(JKRHeap* heap) { + BOOL is_glbl_clr_anm = mpBaseShape->isGlblClrAnm(); + BOOL is_glbl_tex_anm = mpBaseShape->isGlblTexAnm(); + BOOL is_prm_anm = mpBaseShape->isPrmAnm(); + BOOL is_env_anm = mpBaseShape->isEnvAnm(); + BOOL is_tex_anm = mpBaseShape->isTexAnm(); + BOOL is_tex_crd_anm = mpBaseShape->isTexCrdAnm(); + BOOL is_prj_tex = mpBaseShape->isPrjTex(); + BOOL is_enable_scale_anm = mpExtraShape != NULL && mpExtraShape->isEnableScaleAnm(); + BOOL is_enable_alpha_anm = mpExtraShape != NULL && mpExtraShape->isEnableAlphaAnm(); + BOOL is_enable_alpha_flick = mpExtraShape != NULL && mpExtraShape->isEnableAlphaAnm() + && mpExtraShape->isEnableAlphaFlick(); + BOOL is_enable_rotate_anm = mpExtraShape != NULL && mpExtraShape->isEnableRotateAnm(); + BOOL is_rotate_on = is_enable_rotate_anm + || (mpChildShape != NULL && mpChildShape->isRotateOn()); + BOOL base_type_5_6 = mpBaseShape->getType() == 5 || mpBaseShape->getType() == 6; + BOOL base_type_0 = mpBaseShape->getType() == 0; + BOOL base_type_0_1 = mpBaseShape->getType() == 0 || mpBaseShape->getType() == 1; + BOOL child_type_5_6 = mpChildShape != NULL + && (mpChildShape->getType() == 5 || mpChildShape->getType() == 6); + BOOL child_type_0 = mpChildShape != NULL && mpChildShape->getType() == 0; + BOOL child_type_0_1 = mpChildShape != NULL + && (mpChildShape->getType() == 0 || mpChildShape->getType() == 1); + BOOL is_draw_parent = !mpBaseShape->isNoDrawParent(); + BOOL is_draw_child = !mpBaseShape->isNoDrawChild(); + + if (is_glbl_tex_anm && is_tex_anm) { + mpCalcEmitterFuncListNum++; + } + + if (is_glbl_clr_anm) { + if (is_prm_anm) { + mpCalcEmitterFuncListNum++; + } + if (is_env_anm) { + mpCalcEmitterFuncListNum++; + } + if (is_prm_anm || is_env_anm) { + mpCalcEmitterFuncListNum++; + } + } + + if (mpCalcEmitterFuncListNum != 0) { + mpCalcEmitterFuncList = + (EmitterFunc*)JKRAllocFromHeap(heap, mpCalcEmitterFuncListNum * 4, 4); + } + + int func_no = 0; + + if (is_glbl_tex_anm && is_tex_anm) { + switch (mpBaseShape->getTexAnmType()) { + case 0: + mpCalcEmitterFuncList[func_no] = &JPACalcTexIdxNormal; + break; + case 1: + mpCalcEmitterFuncList[func_no] = &JPACalcTexIdxRepeat; + break; + case 2: + mpCalcEmitterFuncList[func_no] = &JPACalcTexIdxReverse; + break; + case 3: + mpCalcEmitterFuncList[func_no] = &JPACalcTexIdxMerge; + break; + case 4: + mpCalcEmitterFuncList[func_no] = &JPACalcTexIdxRandom; + break; + } + func_no++; + } + + if (is_glbl_clr_anm) { + if (is_prm_anm) { + mpCalcEmitterFuncList[func_no] = &JPACalcPrm; + func_no++; + } + if (is_env_anm) { + mpCalcEmitterFuncList[func_no] = &JPACalcEnv; + func_no++; + } + if (is_prm_anm || is_env_anm) { + switch (mpBaseShape->getClrAnmType()) { + case 0: + mpCalcEmitterFuncList[func_no] = &JPACalcClrIdxNormal; + break; + case 1: + mpCalcEmitterFuncList[func_no] = &JPACalcClrIdxRepeat; + break; + case 2: + mpCalcEmitterFuncList[func_no] = &JPACalcClrIdxReverse; + break; + case 3: + mpCalcEmitterFuncList[func_no] = &JPACalcClrIdxMerge; + break; + case 4: + mpCalcEmitterFuncList[func_no] = &JPACalcClrIdxRandom; + break; + } + } + } + + if (!is_glbl_tex_anm && is_tex_anm) { + mpCalcParticleFuncListNum++; + } + + if (!base_type_5_6 && (is_enable_alpha_anm || is_enable_alpha_flick)) { + mpCalcParticleFuncListNum++; + } + + if (!is_glbl_clr_anm) { + if (is_prm_anm) { + mpCalcParticleFuncListNum++; + } + if (is_env_anm) { + mpCalcParticleFuncListNum++; + } + if (is_prm_anm || is_env_anm) { + mpCalcParticleFuncListNum++; + } + } else { + mpCalcParticleFuncListNum++; + } + + if (is_enable_scale_anm) { + if (mpBaseShape->getType() != 0) { + if (mpExtraShape->isScaleXYDiff()) { + if (mpExtraShape->getScaleAnmTypeX() == 0 && mpExtraShape->getScaleAnmTypeY() == 0) { + mpCalcParticleFuncListNum++; + } else { + mpCalcParticleFuncListNum++; + mpCalcParticleFuncListNum++; + } + } else { + mpCalcParticleFuncListNum++; + } + } + mpCalcParticleFuncListNum++; + mpCalcParticleFuncListNum++; + } + + if (mpCalcParticleFuncListNum != 0) { + mpCalcParticleFuncList = + (ParticleFunc*)JKRAllocFromHeap(heap, mpCalcParticleFuncListNum * 4, 4); + } + + func_no = 0; + + if (!is_glbl_tex_anm && is_tex_anm) { + switch (mpBaseShape->getTexAnmType()) { + case 0: + mpCalcParticleFuncList[func_no] = &JPACalcTexIdxNormal; + break; + case 1: + mpCalcParticleFuncList[func_no] = &JPACalcTexIdxRepeat; + break; + case 2: + mpCalcParticleFuncList[func_no] = &JPACalcTexIdxReverse; + break; + case 3: + mpCalcParticleFuncList[func_no] = &JPACalcTexIdxMerge; + break; + case 4: + mpCalcParticleFuncList[func_no] = &JPACalcTexIdxRandom; + break; + } + func_no++; + } + + if (!base_type_5_6 && (is_enable_alpha_anm || is_enable_alpha_flick)) { + if (is_enable_alpha_flick) { + mpCalcParticleFuncList[func_no] = &JPACalcAlphaFlickAnm; + func_no++; + } else { + mpCalcParticleFuncList[func_no] = &JPACalcAlphaAnm; + func_no++; + } + } + + if (!is_glbl_clr_anm) { + if (is_prm_anm) { + mpCalcParticleFuncList[func_no] = &JPACalcPrm; + func_no++; + } + if (is_env_anm) { + mpCalcParticleFuncList[func_no] = &JPACalcEnv; + func_no++; + } + if (is_prm_anm || is_env_anm) { + switch (mpBaseShape->getClrAnmType()) { + case 0: + mpCalcParticleFuncList[func_no] = &JPACalcClrIdxNormal; + break; + case 1: + mpCalcParticleFuncList[func_no] = &JPACalcClrIdxRepeat; + break; + case 2: + mpCalcParticleFuncList[func_no] = &JPACalcClrIdxReverse; + break; + case 3: + mpCalcParticleFuncList[func_no] = &JPACalcClrIdxMerge; + break; + case 4: + mpCalcParticleFuncList[func_no] = &JPACalcClrIdxRandom; + break; + } + func_no++; + } + } else { + mpCalcParticleFuncList[func_no] = &JPACalcColorCopy; + func_no++; + } + + if (is_enable_scale_anm) { + if (mpBaseShape->getType() != 0) { + if (mpExtraShape->isScaleXYDiff()) { + mpCalcParticleFuncList[func_no] = &JPACalcScaleY; + func_no++; + if (mpExtraShape->getScaleAnmTypeY() != 0 || mpExtraShape->getScaleAnmTypeX() != 0) { + switch (mpExtraShape->getScaleAnmTypeY()) { + case 0: + mpCalcParticleFuncList[func_no] = &JPACalcScaleAnmNormal; + break; + case 1: + mpCalcParticleFuncList[func_no] = &JPACalcScaleAnmRepeatY; + break; + case 2: + mpCalcParticleFuncList[func_no] = &JPACalcScaleAnmReverseY; + break; + } + func_no++; + } + } else { + mpCalcParticleFuncList[func_no] = &JPACalcScaleCopy; + func_no++; + } + } + mpCalcParticleFuncList[func_no] = &JPACalcScaleX; + func_no++; + switch (mpExtraShape->getScaleAnmTypeX()) { + case 0: + mpCalcParticleFuncList[func_no] = &JPACalcScaleAnmNormal; + break; + case 1: + mpCalcParticleFuncList[func_no] = &JPACalcScaleAnmRepeatX; + break; + case 2: + mpCalcParticleFuncList[func_no] = &JPACalcScaleAnmReverseX; + break; + } + } + + if (mpChildShape != NULL && mpChildShape->isScaleOutOn()) { + mpCalcParticleChildFuncListNum++; + } + + if (mpChildShape != NULL && mpChildShape->isAlphaOutOn()) { + mpCalcParticleChildFuncListNum++; + } + + if (mpCalcParticleChildFuncListNum != 0) { + mpCalcParticleChildFuncList = + (ParticleFunc*)JKRAllocFromHeap(heap, mpCalcParticleChildFuncListNum * 4, 4); + } + + func_no = 0; + + if (mpChildShape != NULL && mpChildShape->isScaleOutOn()) { + mpCalcParticleChildFuncList[func_no] = &JPACalcChildScaleOut; + func_no++; + } + + if (mpChildShape != NULL && mpChildShape->isAlphaOutOn()) { + mpCalcParticleChildFuncList[func_no] = &JPACalcChildAlphaOut; + } + + if (is_draw_parent && base_type_5_6) { + mpDrawEmitterFuncListNum++; + } + + mpDrawEmitterFuncListNum++; + + if (mpExTexShape != NULL) { + mpDrawEmitterFuncListNum++; + } + + if (is_glbl_tex_anm || !is_tex_anm) { + mpDrawEmitterFuncListNum++; + } + + mpDrawEmitterFuncListNum++; + + if (base_type_0_1) { + mpDrawEmitterFuncListNum++; + } + + if (base_type_0_1 && !is_enable_scale_anm) { + mpDrawEmitterFuncListNum++; + } + + if (is_glbl_clr_anm || (!is_prm_anm && !is_enable_alpha_anm) || !is_env_anm) { + mpDrawEmitterFuncListNum++; + } + + if (mpDrawEmitterFuncListNum != 0) { + mpDrawEmitterFuncList = + (EmitterFunc*)JKRAllocFromHeap(heap, mpDrawEmitterFuncListNum * 4, 4); + } + + func_no = 0; + + if (is_draw_parent && base_type_5_6) { + if (mpBaseShape->getType() == 5) { + mpDrawEmitterFuncList[func_no] = &JPADrawStripe; + func_no++; + } else { + mpDrawEmitterFuncList[func_no] = &JPADrawStripeX; + func_no++; + } + } + + mpDrawEmitterFuncList[func_no] = &JPADrawEmitterCallBackB; + func_no++; + + if (mpExTexShape != NULL) { + mpDrawEmitterFuncList[func_no] = &JPALoadExTex; + func_no++; + } + + if (!is_tex_anm) { + mpDrawEmitterFuncList[func_no] = &JPALoadTex; + func_no++; + } else if (is_glbl_tex_anm) { + mpDrawEmitterFuncList[func_no] = &JPALoadTexAnm; + func_no++; + } + + if (base_type_0_1) { + mpDrawEmitterFuncList[func_no] = &JPAGenTexCrdMtxIdt; + func_no++; + } else if (is_prj_tex) { + mpDrawEmitterFuncList[func_no] = &JPAGenTexCrdMtxPrj; + func_no++; + } else if (is_tex_crd_anm) { + if (base_type_5_6) { + mpDrawEmitterFuncList[func_no] = &JPAGenCalcTexCrdMtxAnm; + func_no++; + } else { + mpDrawEmitterFuncList[func_no] = &JPAGenTexCrdMtxAnm; + func_no++; + } + } else { + mpDrawEmitterFuncList[func_no] = &JPAGenTexCrdMtxIdt; + func_no++; + } + + if (base_type_0_1) { + mpDrawEmitterFuncList[func_no] = &JPALoadPosMtxCam; + func_no++; + } + + if (base_type_0_1 && !is_enable_scale_anm) { + if (base_type_0) { + mpDrawEmitterFuncList[func_no] = &JPASetPointSize; + func_no++; + } else { + mpDrawEmitterFuncList[func_no] = &JPASetLineWidth; + func_no++; + } + } + + if (is_glbl_clr_anm) { + if (base_type_5_6 || !is_enable_alpha_anm) { + mpDrawEmitterFuncList[func_no] = &JPARegistPrmEnv; + } else if (is_enable_alpha_anm) { + mpDrawEmitterFuncList[func_no] = &JPARegistEnv; + } + } else if (!is_prm_anm && !is_enable_alpha_anm) { + if (!is_env_anm) { + mpDrawEmitterFuncList[func_no] = &JPARegistPrmEnv; + } else { + mpDrawEmitterFuncList[func_no] = &JPARegistPrm; + } + } else if (!is_env_anm) { + mpDrawEmitterFuncList[func_no] = &JPARegistEnv; + } + + if (is_draw_child && child_type_5_6) { + mpDrawEmitterChildFuncListNum++; + } + + mpDrawEmitterChildFuncListNum++; + + if (child_type_0_1) { + mpDrawEmitterChildFuncListNum++; + } + + if (mpChildShape != NULL && !mpChildShape->isAlphaOutOn() && !mpChildShape->isAlphaInherited() + && !mpChildShape->isColorInherited()) { + mpDrawEmitterChildFuncListNum++; + } + + if (mpDrawEmitterChildFuncListNum != 0) { + mpDrawEmitterChildFuncList = + (EmitterFunc*)JKRAllocFromHeap(heap, mpDrawEmitterChildFuncListNum * 4, 4); + } + + func_no = 0; + + if (is_draw_child && child_type_5_6) { + if (mpChildShape->getType() == 5) { + mpDrawEmitterChildFuncList[func_no] = &JPADrawStripe; + func_no++; + } else { + mpDrawEmitterChildFuncList[func_no] = &JPADrawStripeX; + func_no++; + } + } + + mpDrawEmitterChildFuncList[func_no] = &JPADrawEmitterCallBackB; + func_no++; + + if (child_type_0_1) { + mpDrawEmitterChildFuncList[func_no] = &JPALoadPosMtxCam; + func_no++; + } + + if (mpChildShape != NULL && !mpChildShape->isAlphaOutOn() && !mpChildShape->isAlphaInherited() + && !mpChildShape->isColorInherited()) { + mpDrawEmitterChildFuncList[func_no] = &JPARegistChildPrmEnv; + } + + if (is_draw_parent && !base_type_5_6) { + mpDrawParticleFuncListNum++; + } + + mpDrawParticleFuncListNum++; + + if (!is_glbl_tex_anm && is_tex_anm) { + mpDrawParticleFuncListNum++; + } + + if ((base_type_0_1 && is_enable_scale_anm) || (is_tex_crd_anm && !is_prj_tex)) { + mpDrawParticleFuncListNum++; + } + + if ((!is_glbl_clr_anm && (is_prm_anm || is_env_anm || is_enable_alpha_anm)) + || (is_glbl_clr_anm && is_enable_alpha_anm && !base_type_5_6)) { + mpDrawParticleFuncListNum++; + } + + if (mpDrawParticleFuncListNum != 0) { + mpDrawParticleFuncList = + (ParticleFunc*)JKRAllocFromHeap(heap, mpDrawParticleFuncListNum * 4, 4); + } + + func_no = 0; + + if (is_draw_parent && !base_type_5_6) { + switch (mpBaseShape->getType()) { + case 2: + if (is_enable_rotate_anm) { + mpDrawParticleFuncList[func_no] = &JPADrawRotBillboard; + } else { + mpDrawParticleFuncList[func_no] = &JPADrawBillboard; + } + break; + case 10: + if (is_enable_rotate_anm) { + mpDrawParticleFuncList[func_no] = &JPADrawRotYBillboard; + } else { + mpDrawParticleFuncList[func_no] = &JPADrawYBillboard; + } + break; + case 3: + case 4: + if (is_enable_rotate_anm) { + mpDrawParticleFuncList[func_no] = &JPADrawRotDirection; + } else { + mpDrawParticleFuncList[func_no] = &JPADrawDirection; + } + break; + case 9: + mpDrawParticleFuncList[func_no] = &JPADrawDBillboard; + break; + case 7: + case 8: + mpDrawParticleFuncList[func_no] = &JPADrawRotation; + break; + case 0: + mpDrawParticleFuncList[func_no] = &JPADrawPoint; + break; + case 1: + mpDrawParticleFuncList[func_no] = &JPADrawLine; + break; + } + func_no++; + } + + mpDrawParticleFuncList[func_no] = &JPADrawParticleCallBack; + func_no++; + + if (!is_glbl_tex_anm && is_tex_anm) { + mpDrawParticleFuncList[func_no] = &JPALoadTexAnm; + func_no++; + } + + if (base_type_0_1 && is_enable_scale_anm) { + if (base_type_0) { + mpDrawParticleFuncList[func_no] = &JPASetPointSize; + func_no++; + } else { + mpDrawParticleFuncList[func_no] = &JPASetLineWidth; + func_no++; + } + } else if (is_tex_crd_anm && !is_prj_tex) { + mpDrawParticleFuncList[func_no] = &JPALoadCalcTexCrdMtxAnm; + func_no++; + } + + if (!is_glbl_clr_anm) { + if (is_prm_anm) { + if (is_env_anm) { + mpDrawParticleFuncList[func_no] = &JPARegistPrmAlphaEnv; + } else { + mpDrawParticleFuncList[func_no] = &JPARegistPrmAlpha; + } + } else if (is_enable_alpha_anm) { + if (is_env_anm) { + mpDrawParticleFuncList[func_no] = &JPARegistAlphaEnv; + } else { + mpDrawParticleFuncList[func_no] = &JPARegistAlpha; + } + } else if (is_env_anm) { + mpDrawParticleFuncList[func_no] = &JPARegistEnv; + } + } else if (is_enable_alpha_anm && !base_type_5_6) { + mpDrawParticleFuncList[func_no] = &JPARegistAlpha; + } + + if (is_draw_child && mpChildShape != NULL && !child_type_5_6) { + mpDrawParticleChildFuncListNum++; + } + + mpDrawParticleChildFuncListNum++; + + if (child_type_0_1) { + mpDrawParticleChildFuncListNum++; + } + + if (mpChildShape != NULL && (mpChildShape->isAlphaOutOn() || mpChildShape->isAlphaInherited() + || mpChildShape->isColorInherited())) { + mpDrawParticleChildFuncListNum++; + } + + if (mpDrawParticleChildFuncListNum != 0) { + mpDrawParticleChildFuncList = + (ParticleFunc*)JKRAllocFromHeap(heap, mpDrawParticleChildFuncListNum * 4, 4); + } + + func_no = 0; + + if (is_draw_child && mpChildShape != NULL && !child_type_5_6) { + switch (mpChildShape->getType()) { + case 2: + if (is_rotate_on) { + mpDrawParticleChildFuncList[func_no] = &JPADrawRotBillboard; + } else { + mpDrawParticleChildFuncList[func_no] = &JPADrawBillboard; + } + break; + case 10: + if (is_rotate_on) { + mpDrawParticleChildFuncList[func_no] = &JPADrawRotYBillboard; + } else { + mpDrawParticleChildFuncList[func_no] = &JPADrawYBillboard; + } + break; + case 3: + case 4: + if (is_rotate_on) { + mpDrawParticleChildFuncList[func_no] = &JPADrawRotDirection; + } else { + mpDrawParticleChildFuncList[func_no] = &JPADrawDirection; + } + break; + case 9: + mpDrawParticleChildFuncList[func_no] = &JPADrawDBillboard; + break; + case 7: + case 8: + mpDrawParticleChildFuncList[func_no] = &JPADrawRotation; + break; + case 0: + mpDrawParticleChildFuncList[func_no] = &JPADrawPoint; + break; + case 1: + mpDrawParticleChildFuncList[func_no] = &JPADrawLine; + break; + } + func_no++; + } + + mpDrawParticleChildFuncList[func_no] = &JPADrawParticleCallBack; + func_no++; + + if (child_type_0_1) { + if (child_type_0) { + mpDrawParticleChildFuncList[func_no] = &JPASetPointSize; + func_no++; + } else { + mpDrawParticleChildFuncList[func_no] = &JPASetLineWidth; + func_no++; + } + } + + if (mpChildShape != NULL && (mpChildShape->isAlphaOutOn() || mpChildShape->isAlphaInherited() + || mpChildShape->isColorInherited())) { + mpDrawParticleChildFuncList[func_no] = &JPARegistPrmAlphaEnv; + } +} + +/* 802755E8-80275A94 26FF28 04AC+00 0/0 1/1 0/0 .text + * calc__11JPAResourceFP18JPAEmitterWorkDataP14JPABaseEmitter */ +bool JPAResource::calc(JPAEmitterWorkData* work, JPABaseEmitter* emtr) { + work->mpEmtr = emtr; + work->mpRes = this; + work->mEmitCount = 0; + + if (!emtr->processTillStartFrame()) { + return false; + } + + if (emtr->processTermination()) { + return true; + } + + if (emtr->checkStatus(2)) { + if (emtr->mpEmtrCallBack != NULL) { + emtr->mpEmtrCallBack->execute(emtr); + if (emtr->checkStatus(0x100)) { + return true; + } + emtr->mpEmtrCallBack->executeAfter(emtr); + if (emtr->checkStatus(0x100)) { + return true; + } + } + + } else { + calcKey(work); + + for (int i = mFieldBlockNum - 1; i >= 0; i--) { + mpFieldBlocks[i]->initOpParam(); + } + + if (emtr->mpEmtrCallBack != NULL) { + emtr->mpEmtrCallBack->execute(emtr); + if (emtr->checkStatus(0x100)) { + return true; + } + } + + calcWorkData_c(work); + + for (int i = mpCalcEmitterFuncListNum - 1; i >= 0; i--) { + (*mpCalcEmitterFuncList[i])(work); + } + + for (int i = mFieldBlockNum - 1; i >= 0; i--) { + mpFieldBlocks[i]->prepare(work); + } + + if (!emtr->checkStatus(8)) { + mpDynamicsBlock->create(work); + } + + if (emtr->mpEmtrCallBack != NULL) { + emtr->mpEmtrCallBack->executeAfter(emtr); + if (emtr->checkStatus(0x100)) { + return true; + } + } + + JPANode<JPABaseParticle>* node = emtr->mAlivePtclBase.getFirst(); + JPANode<JPABaseParticle>* next; + while (node != emtr->mAlivePtclBase.getEnd()) { + next = node->getNext(); + if (node->getObject()->calc_p(work)) { + emtr->mpPtclPool->push_front(emtr->mAlivePtclBase.erase(node)); + } + node = next; + } + + node = emtr->mAlivePtclChld.getFirst(); + while (node != emtr->mAlivePtclChld.getEnd()) { + next = node->getNext(); + if (node->getObject()->calc_c(work)) { + emtr->mpPtclPool->push_front(emtr->mAlivePtclChld.erase(node)); + } + node = next; + } + + emtr->mTick++; + } + + return false; +} + +/* 80275A94-80275B74 2703D4 00E0+00 0/0 1/1 0/0 .text + * draw__11JPAResourceFP18JPAEmitterWorkDataP14JPABaseEmitter */ +void JPAResource::draw(JPAEmitterWorkData* work, JPABaseEmitter* emtr) { + work->mpEmtr = emtr; + work->mpRes = this; + work->mDrawCount = 0; + calcWorkData_d(work); + mpBaseShape->setGX(work); + for (s32 i = 1; i <= emtr->getDrawTimes(); i++) { + work->mDrawCount++; + if (mpBaseShape->isDrawPrntAhead() && mpChildShape != NULL) + drawC(work); + drawP(work); + if (!mpBaseShape->isDrawPrntAhead() && mpChildShape != NULL) + drawC(work); + } +} + +/* 80275B74-80275EB0 2704B4 033C+00 1/1 0/0 0/0 .text drawP__11JPAResourceFP18JPAEmitterWorkData + */ +void JPAResource::drawP(JPAEmitterWorkData* work) { + work->mpEmtr->clearStatus(0x80); + + work->mGlobalPtclScl.x = work->mpEmtr->mGlobalPScl.x * mpBaseShape->getBaseSizeX(); + work->mGlobalPtclScl.y = work->mpEmtr->mGlobalPScl.y * mpBaseShape->getBaseSizeY(); + + if (mpBaseShape->getType() == 0) { + work->mGlobalPtclScl.x *= 1.02f; + } else if (mpBaseShape->getType() == 1) { + work->mGlobalPtclScl.x *= 1.02f; + work->mGlobalPtclScl.y *= 0.4f; + } + + if (mpExtraShape != NULL && mpExtraShape->isEnableScaleAnm()) { + work->mPivot.x = mpExtraShape->getScaleCenterX() - 1.0f; + work->mPivot.y = mpExtraShape->getScaleCenterY() - 1.0f; + } else { + work->mPivot.x = work->mPivot.y = 0.0f; + } + + work->mDirType = mpBaseShape->getDirType(); + work->mRotType = mpBaseShape->getRotType(); + work->mDLType = mpBaseShape->getType() == 4 || mpBaseShape->getType() == 8; + work->mPlaneType = work->mDLType ? 2 : mpBaseShape->getBasePlaneType(); + work->mPrjType = mpBaseShape->isPrjTex() ? (mpBaseShape->isTexCrdAnm() ? 2 : 1) : 0; + + work->mpAlivePtcl = &work->mpEmtr->mAlivePtclBase; + setPTev(); + + for (int i = mpDrawEmitterFuncListNum - 1; i >= 0; i--) { + (*mpDrawEmitterFuncList[i])(work); + } + + if (mpBaseShape->isDrawFwdAhead()) { + JPANode<JPABaseParticle>* node = work->mpEmtr->mAlivePtclBase.getLast(); + for (; node != work->mpEmtr->mAlivePtclBase.getEnd(); node = node->getPrev()) { + work->mpCurNode = node; + if (mpDrawParticleFuncList != NULL) { + for (int i = mpDrawParticleFuncListNum - 1; i >= 0; i--) { + (*mpDrawParticleFuncList[i])(work, node->getObject()); + } + } + } + } else { + JPANode<JPABaseParticle>* node = work->mpEmtr->mAlivePtclBase.getFirst(); + for (; node != work->mpEmtr->mAlivePtclBase.getEnd(); node = node->getNext()) { + work->mpCurNode = node; + if (mpDrawParticleFuncList != NULL) { + for (int i = mpDrawParticleFuncListNum - 1; i >= 0; i--) { + (*mpDrawParticleFuncList[i])(work, node->getObject()); + } + } + } + } + + GXSetMisc(GX_MT_XF_FLUSH, 0); + + if (work->mpEmtr->mpEmtrCallBack != NULL) { + work->mpEmtr->mpEmtrCallBack->drawAfter(work->mpEmtr); + } +} + +/* 80275EB0-802761A8 2707F0 02F8+00 1/1 0/0 0/0 .text drawC__11JPAResourceFP18JPAEmitterWorkData + */ +void JPAResource::drawC(JPAEmitterWorkData* work) { + work->mpEmtr->setStatus(0x80); + + if (mpChildShape->isScaleInherited()) { + work->mGlobalPtclScl.x = work->mpEmtr->mGlobalPScl.x * mpBaseShape->getBaseSizeX(); + work->mGlobalPtclScl.y = work->mpEmtr->mGlobalPScl.y * mpBaseShape->getBaseSizeY(); + } else { + work->mGlobalPtclScl.x = work->mpEmtr->mGlobalPScl.x * mpChildShape->getScaleX(); + work->mGlobalPtclScl.y = work->mpEmtr->mGlobalPScl.y * mpChildShape->getScaleY(); + } + + if (mpChildShape->getType() == 0) { + work->mGlobalPtclScl.x *= 1.02f; + } else if (mpChildShape->getType() == 1) { + work->mGlobalPtclScl.x *= 1.02f; + work->mGlobalPtclScl.y *= 0.4f; + } + + work->mPivot.x = work->mPivot.y = 0.0f; + + work->mDirType = mpChildShape->getDirType(); + work->mRotType = mpChildShape->getRotType(); + work->mDLType = mpChildShape->getType() == 4 || mpChildShape->getType() == 8; + work->mPlaneType = work->mDLType ? 2 : mpChildShape->getBasePlaneType(); + work->mPrjType = 0; + + work->mpAlivePtcl = &work->mpEmtr->mAlivePtclChld; + setCTev(work); + + for (int i = mpDrawEmitterChildFuncListNum - 1; i >= 0; i--) { + (*mpDrawEmitterChildFuncList[i])(work); + } + + if (mpBaseShape->isDrawFwdAhead()) { + JPANode<JPABaseParticle>* node = work->mpEmtr->mAlivePtclChld.getLast(); + for (; node != work->mpEmtr->mAlivePtclChld.getEnd(); node = node->getPrev()) { + work->mpCurNode = node; + if (mpDrawParticleChildFuncList != NULL) { + for (int i = mpDrawParticleChildFuncListNum - 1; i >= 0; i--) { + (*mpDrawParticleChildFuncList[i])(work, node->getObject()); + } + } + } + } else { + JPANode<JPABaseParticle>* node = work->mpEmtr->mAlivePtclChld.getFirst(); + for (; node != work->mpEmtr->mAlivePtclChld.getEnd(); node = node->getNext()) { + work->mpCurNode = node; + if (mpDrawParticleChildFuncList != NULL) { + for (int i = mpDrawParticleChildFuncListNum - 1; i >= 0; i--) { + (*mpDrawParticleChildFuncList[i])(work, node->getObject()); + } + } + } + } + + GXSetMisc(GX_MT_XF_FLUSH, 0); + + if (work->mpEmtr->mpEmtrCallBack != NULL) { + work->mpEmtr->mpEmtrCallBack->drawAfter(work->mpEmtr); + } +} + +/* 802761A8-8027642C 270AE8 0284+00 1/1 0/0 0/0 .text setPTev__11JPAResourceFv */ +void JPAResource::setPTev() { + GXTexCoordID tex_coord = GX_TEXCOORD1; + u8 tev_stages = 1; + u8 tex_gens = 1; + u8 ind_stages = 0; + + int base_plane_type = (mpBaseShape->getType() == 3 || mpBaseShape->getType() == 7) ? + mpBaseShape->getBasePlaneType() : 0; + int center_offset; + if (mpExtraShape != NULL) { + center_offset = + (mpExtraShape->getScaleCenterX() + 3 * mpExtraShape->getScaleCenterY()) * 0xC; + } else { + center_offset = 0x30; + } + int pos_offset = center_offset + base_plane_type * 0x6C; + int crd_offset = (mpBaseShape->getTilingS() + 2 * mpBaseShape->getTilingT()) * 8; + GXSetArray(GX_VA_POS, jpa_pos + pos_offset, 3); + GXSetArray(GX_VA_TEX0, jpa_crd + crd_offset, 2); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + + if (mpExTexShape != NULL) { + if (mpExTexShape->isUseIndirect()) { + GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD1, GX_TEXMAP2); + GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1); + GXSetIndTexMtx(GX_ITM_0, (f32(*)[3])mpExTexShape->getIndTexMtx(), mpExTexShape->getExpScale()); + GXSetTevIndirect(GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_STU, GX_ITM_0, + GX_ITW_OFF, GX_ITW_OFF, 0, 0, GX_ITBA_OFF); + ind_stages++; + tex_gens++; + tex_coord = GX_TEXCOORD2; + } + if (mpExTexShape->isUseSecTex()) { + GXSetTevOrder(GX_TEVSTAGE1, tex_coord, GX_TEXMAP3, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, + GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, + GX_TEVPREV); + tev_stages++; + tex_gens++; + } + } + + GXSetNumTevStages(tev_stages); + GXSetNumIndStages(ind_stages); + if (mpBaseShape->isClipOn()) { + GXSetMisc(GX_MT_XF_FLUSH, 8); + GXSetClipMode(GX_CLIP_ENABLE); + } else { + GXSetClipMode(GX_CLIP_DISABLE); + } + GXSetNumTexGens(tex_gens); +} + +/* 8027642C-8027658C 270D6C 0160+00 1/1 0/0 0/0 .text setCTev__11JPAResourceFP18JPAEmitterWorkData + */ +void JPAResource::setCTev(JPAEmitterWorkData* work) { + int base_plane_type = (mpChildShape->getType() == 3 || mpChildShape->getType() == 7) ? + mpChildShape->getBasePlaneType() : 0; + int pos_offset = 0x30 + base_plane_type * 0x6C; + GXSetArray(GX_VA_POS, jpa_pos + pos_offset, 3); + GXSetArray(GX_VA_TEX0, jpa_crd, 2); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3C); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetNumTevStages(1); + GXSetNumIndStages(0); + if (mpChildShape->isClipOn()) { + GXSetMisc(GX_MT_XF_FLUSH, 8); + GXSetClipMode(GX_CLIP_ENABLE); + } else { + GXSetClipMode(GX_CLIP_DISABLE); + } + GXSetNumTexGens(1); + work->mpResMgr->load(work->mpRes->getTexIdx(mpChildShape->getTexIdx()), GX_TEXMAP1); +} + +/* 8027658C-80276608 270ECC 007C+00 0/0 1/1 0/0 .text + * calc_p__11JPAResourceFP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPAResource::calc_p(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + if (mpCalcParticleFuncList != NULL) { + for (int i = mpCalcParticleFuncListNum - 1; i >= 0; i--) { + (*mpCalcParticleFuncList[i])(work, ptcl); + } + } +} + +/* 80276608-80276684 270F48 007C+00 0/0 1/1 0/0 .text + * calc_c__11JPAResourceFP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPAResource::calc_c(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + if (mpCalcParticleChildFuncList != NULL) { + for (int i = mpCalcParticleChildFuncListNum - 1; i >= 0; i--) { + (*mpCalcParticleChildFuncList[i])(work, ptcl); + } + } +} + +/* 80276684-80276700 270FC4 007C+00 0/0 2/2 0/0 .text + * calcField__11JPAResourceFP18JPAEmitterWorkDataP15JPABaseParticle */ +void JPAResource::calcField(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { + for (int i = mFieldBlockNum - 1; i >= 0; i--) { + mpFieldBlocks[i]->calc(work, ptcl); + } +} + +/* 80276700-80276840 271040 0140+00 2/1 0/0 0/0 .text calcKey__11JPAResourceFP18JPAEmitterWorkData + */ +void JPAResource::calcKey(JPAEmitterWorkData* work) { + for (int i = mKeyBlockNum - 1; i >= 0; i--) { + f32 val = mpKeyBlocks[i]->calc(work->mpEmtr->mTick); + switch (mpKeyBlocks[i]->getID()) { + case 0: + work->mpEmtr->mRate = val; + break; + case 1: + work->mpEmtr->mVolumeSize = val; + break; + case 3: + work->mpEmtr->mVolumeMinRad = val; + break; + case 4: + work->mpEmtr->mLifeTime = val; + break; + case 6: + work->mpEmtr->mAwayFromCenterSpeed = val; + break; + case 7: + work->mpEmtr->mAwayFromAxisSpeed = val; + break; + case 8: + work->mpEmtr->mDirSpeed = val; + break; + case 9: + work->mpEmtr->mSpread = val; + break; + case 10: + work->mpEmtr->mScaleOut = val; + break; + } + } +} + +/* 80276840-80276A0C 271180 01CC+00 1/1 0/0 0/0 .text + * calcWorkData_c__11JPAResourceFP18JPAEmitterWorkData */ +void JPAResource::calcWorkData_c(JPAEmitterWorkData* work) { + work->mVolumeSize = work->mpEmtr->mVolumeSize; + work->mVolumeMinRad = work->mpEmtr->mVolumeMinRad; + work->mVolumeSweep = work->mpEmtr->mVolumeSweep; + work->mVolumeX = 0; + work->mVolumeAngleNum = 0; + work->mVolumeAngleMax = 1; + work->mDivNumber = mpDynamicsBlock->getDivNumber() * 2 + 1; + Mtx local_scl_mtx, local_rot_mtx, global_mtx; + MTXScale(local_scl_mtx, work->mpEmtr->mLocalScl.x, work->mpEmtr->mLocalScl.y, + work->mpEmtr->mLocalScl.z); + JPAGetXYZRotateMtx(work->mpEmtr->mLocalRot.x * 182, work->mpEmtr->mLocalRot.y * 182, + work->mpEmtr->mLocalRot.z * 182, local_rot_mtx); + MTXScale(global_mtx, work->mpEmtr->mGlobalScl.x, work->mpEmtr->mGlobalScl.y, + work->mpEmtr->mGlobalScl.z); + MTXConcat(work->mpEmtr->mGlobalRot, global_mtx, global_mtx); + global_mtx[0][3] = work->mpEmtr->mGlobalTrs.x; + global_mtx[1][3] = work->mpEmtr->mGlobalTrs.y; + global_mtx[2][3] = work->mpEmtr->mGlobalTrs.z; + MTXCopy(work->mpEmtr->mGlobalRot, work->mRotationMtx); + MTXConcat(work->mRotationMtx, local_rot_mtx, work->mGlobalRot); + MTXConcat(work->mGlobalRot, local_scl_mtx, work->mGlobalSR); + work->mEmitterPos.set(work->mpEmtr->mLocalTrs); + work->mGlobalScl.mul(work->mpEmtr->mGlobalScl, work->mpEmtr->mLocalScl); + JPAGetDirMtx(work->mpEmtr->mLocalDir, work->mDirectionMtx); + work->mPublicScale.set(work->mpEmtr->mGlobalScl); + MTXMultVec(global_mtx, &work->mpEmtr->mLocalTrs, &work->mGlobalPos); +} + +/* 80276A0C-80276A8C 27134C 0080+00 1/1 0/0 0/0 .text + * calcWorkData_d__11JPAResourceFP18JPAEmitterWorkData */ +void JPAResource::calcWorkData_d(JPAEmitterWorkData* work) { + Mtx mtx; + JPAGetXYZRotateMtx(work->mpEmtr->mLocalRot.x * 0xB6, work->mpEmtr->mLocalRot.y * 0xB6, + work->mpEmtr->mLocalRot.z * 0xB6, mtx); + MTXConcat(work->mpEmtr->mGlobalRot, mtx, work->mGlobalRot); + MTXMultVecSR(work->mGlobalRot, &work->mpEmtr->mLocalDir, &work->mGlobalEmtrDir); +} + +#pragma push +#pragma force_active on +static u8 jpa_resource_padding[28] = {0}; +#pragma pop diff --git a/src/JSystem/JParticle/JPAResourceLoader.cpp b/src/JSystem/JParticle/JPAResourceLoader.cpp new file mode 100644 index 00000000..580e913a --- /dev/null +++ b/src/JSystem/JParticle/JPAResourceLoader.cpp @@ -0,0 +1,106 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAResourceLoader +// + +#include "JSystem/JParticle/JPAResourceLoader.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JParticle/JPABaseShape.h" +#include "JSystem/JParticle/JPAChildShape.h" +#include "JSystem/JParticle/JPADynamicsBlock.h" +#include "JSystem/JParticle/JPAExTexShape.h" +#include "JSystem/JParticle/JPAExtraShape.h" +#include "JSystem/JParticle/JPAFieldBlock.h" +#include "JSystem/JParticle/JPAKeyBlock.h" +#include "JSystem/JParticle/JPAResource.h" +#include "JSystem/JParticle/JPAResourceManager.h" + +/* 8027D8A0-8027D8E0 2781E0 0040+00 0/0 1/1 0/0 .text + * __ct__17JPAResourceLoaderFPCUcP18JPAResourceManager */ +JPAResourceLoader::JPAResourceLoader(u8 const* data, JPAResourceManager* mgr) { + if (*(u32*)(data + 4) == '2-10') { + load_jpc(data, mgr); + } +} + +struct JPAResourceHeader { + /* 0x0 */ u16 mUsrIdx; + /* 0x2 */ u16 mBlockNum; + /* 0x4 */ u8 mFieldBlockNum; + /* 0x5 */ u8 mKeyBlockNum; + /* 0x6 */ u8 mTDB1Num; +}; + +/* 8027D8E0-8027DCA0 278220 03C0+00 1/1 0/0 0/0 .text + * load_jpc__17JPAResourceLoaderFPCUcP18JPAResourceManager */ +void JPAResourceLoader::load_jpc(u8 const* data, JPAResourceManager* mgr) { + JKRHeap* heap = mgr->mpHeap; + mgr->mResMax = *(u16*)(data + 8); + mgr->mTexMax = *(u16*)(data + 0xA); + mgr->mpResArr = new (heap, 0) JPAResource*[mgr->mResMax]; + mgr->mpTexArr = new (heap, 0) JPATexture*[mgr->mTexMax]; + + u32 offset = 0x10; + for (int i = 0; i < *(u16*)(data + 8); i++) { + JPAResourceHeader* header = (JPAResourceHeader*)(data + offset); + JPAResource* res = new (heap, 0) JPAResource(); + res->mFieldBlockNum = header->mFieldBlockNum; + res->mpFieldBlocks = res->mFieldBlockNum != 0 ? + new (heap, 0) JPAFieldBlock*[res->mFieldBlockNum] : NULL; + res->mKeyBlockNum = header->mKeyBlockNum; + res->mpKeyBlocks = res->mKeyBlockNum != 0 ? + new (heap, 0) JPAKeyBlock*[res->mKeyBlockNum] : NULL; + res->mTDB1Num = header->mTDB1Num; + res->mpTDB1 = NULL; + res->mUsrIdx = header->mUsrIdx; + + offset += 8; + u32 field_idx = 0; + u32 key_idx = 0; + + for (int j = 0; j < header->mBlockNum; j++) { + u32 magic = *(u32*)(data + offset); + u32 size = *(u32*)(data + offset + 4); + switch (magic) { + case 'FLD1': + res->mpFieldBlocks[field_idx] = new (heap, 0) JPAFieldBlock(data + offset, heap); + field_idx++; + break; + case 'KFA1': + res->mpKeyBlocks[key_idx] = new (heap, 0) JPAKeyBlock(data + offset); + key_idx++; + break; + case 'BEM1': + res->mpDynamicsBlock = new (heap, 0) JPADynamicsBlock(data + offset); + break; + case 'BSP1': + res->mpBaseShape = new (heap, 0) JPABaseShape(data + offset, heap); + break; + case 'ESP1': + res->mpExtraShape = new (heap, 0) JPAExtraShape(data + offset); + break; + case 'SSP1': + res->mpChildShape = new (heap, 0) JPAChildShape(data + offset); + break; + case 'ETX1': + res->mpExTexShape = new (heap, 0) JPAExTexShape(data + offset); + break; + case 'TDB1': + res->mpTDB1 = (const u16*)(data + offset + 8); + break; + } + offset += size; + } + + res->init(heap); + mgr->registRes(res); + } + + offset = *(u32*)(data + 0xC); + for (int i = 0; i < *(u16*)(data + 0xA); i++) { + u32 size = *(u32*)(data + offset + 4); + JPATexture* tex = new (heap, 0) JPATexture(data + offset); + mgr->registTex(tex); + offset += size; + } +} diff --git a/src/JSystem/JParticle/JPAResourceManager.cpp b/src/JSystem/JParticle/JPAResourceManager.cpp new file mode 100644 index 00000000..e06be753 --- /dev/null +++ b/src/JSystem/JParticle/JPAResourceManager.cpp @@ -0,0 +1,84 @@ +// +// Generated By: dol2asm +// Translation Unit: JPAResourceManager +// + +#include "JSystem/JParticle/JPAResourceManager.h" +#include "JSystem/JParticle/JPADynamicsBlock.h" +#include "JSystem/JParticle/JPAResource.h" +#include "string.h" + +struct JPAResourceLoader { + /* 8027D8A0 */ JPAResourceLoader(u8 const*, JPAResourceManager*); +}; + +/* 80273E10-80273E68 26E750 0058+00 0/0 2/2 0/0 .text __ct__18JPAResourceManagerFPCvP7JKRHeap */ +JPAResourceManager::JPAResourceManager(void const* pData, JKRHeap* pHeap) { + mpResArr = NULL; + mpTexArr = NULL; + mResMax = 0; + mResNum = 0; + mTexMax = 0; + mTexNum = 0; + mpHeap = pHeap; + JPAResourceLoader loader((u8 const*)pData, this); +} + +/* 80273E68-80273EA8 26E7A8 0040+00 1/1 1/1 0/0 .text getResource__18JPAResourceManagerCFUs */ +JPAResource* JPAResourceManager::getResource(u16 usrIdx) const { + for (u16 i = 0; i < mResNum; i++) + if (mpResArr[i]->getUsrIdx() == usrIdx) + return mpResArr[i]; + return NULL; +} + +/* 80273EA8-80273EEC 26E7E8 0044+00 0/0 2/2 0/0 .text + * checkUserIndexDuplication__18JPAResourceManagerCFUs */ +bool JPAResourceManager::checkUserIndexDuplication(u16 usrIdx) const { + for (s32 i = 0; i < mResNum; i++) + if (mpResArr[i]->getUsrIdx() == usrIdx) + return true; + return false; +} + +/* 80273EEC-80273F8C 26E82C 00A0+00 0/0 2/2 0/0 .text + * swapTexture__18JPAResourceManagerFPC7ResTIMGPCc */ +const ResTIMG* JPAResourceManager::swapTexture(ResTIMG const* img, char const* swapName) { + const ResTIMG* ret = NULL; + + for (s32 i = 0; i < mTexNum; i++) { + if (strcmp(swapName, mpTexArr[i]->getName()) == 0) { + JUTTexture* tex = mpTexArr[i]->getJUTTexture(); + ret = tex->getTexInfo(); + tex->storeTIMG(img, (u8)0); + break; + } + } + + return ret; +} + +/* 80273F8C-80273FAC 26E8CC 0020+00 0/0 1/1 0/0 .text + * registRes__18JPAResourceManagerFP11JPAResource */ +void JPAResourceManager::registRes(JPAResource* res) { + mpResArr[mResNum] = res; + mResNum++; +} + +/* 80273FAC-80273FCC 26E8EC 0020+00 0/0 1/1 0/0 .text + * registTex__18JPAResourceManagerFP10JPATexture */ +void JPAResourceManager::registTex(JPATexture* tex) { + mpTexArr[mTexNum] = tex; + mTexNum++; +} + +/* 80273FCC-80274010 26E90C 0044+00 0/0 6/6 0/0 .text getResUserWork__18JPAResourceManagerCFUs */ +u32 JPAResourceManager::getResUserWork(u16 usrIdx) const { + u32 ret = 0; + + JPAResource* res = getResource(usrIdx); + if (res != NULL) + ret = res->getDyn()->getResUserWork(); + + return ret; +}
\ No newline at end of file diff --git a/src/JSystem/JParticle/JPATexture.cpp b/src/JSystem/JParticle/JPATexture.cpp new file mode 100644 index 00000000..17aac802 --- /dev/null +++ b/src/JSystem/JParticle/JPATexture.cpp @@ -0,0 +1,15 @@ +// +// Generated By: dol2asm +// Translation Unit: JPATexture +// + +#include "JSystem/JParticle/JPATexture.h" + +/* 8027D7D4-8027D83C 278114 0068+00 0/0 1/1 0/0 .text __ct__10JPATextureFPCUc */ +JPATexture::JPATexture(u8 const* pData) { + mpData = (const JPATextureData*)pData; + mTexture.storeTIMG(&mpData->mResTIMG, (u8)0); +} + +/* 8027D83C-8027D8A0 27817C 0064+00 1/0 0/0 0/0 .text __dt__10JPATextureFv */ +JPATexture::~JPATexture() {}
\ No newline at end of file diff --git a/src/JSystem/JSupport/JSUList.cpp b/src/JSystem/JSupport/JSUList.cpp new file mode 100644 index 00000000..eb906508 --- /dev/null +++ b/src/JSystem/JSupport/JSUList.cpp @@ -0,0 +1,162 @@ +// +// Generated By: dol2asm +// Translation Unit: JSUList +// + +#include "JSystem/JSupport/JSUList.h" + +JSUPtrLink::JSUPtrLink(void* object) { + mList = NULL; + mObject = object; + mPrev = NULL; + mNext = NULL; +} + +JSUPtrLink::~JSUPtrLink() { + if (mList != NULL) { + mList->remove(this); + } +} + +JSUPtrList::JSUPtrList(bool init) { + if (init) { + initiate(); + } +} + +JSUPtrList::~JSUPtrList() { + JSUPtrLink* node = mHead; + s32 removed = 0; + while (mLength > removed) { + node->mList = NULL; + node = node->getNext(); + removed += 1; + } +} + +void JSUPtrList::initiate() { + mHead = NULL; + mTail = NULL; + mLength = 0; +} + +void JSUPtrList::setFirst(JSUPtrLink* first) { + first->mList = this; + first->mPrev = NULL; + first->mNext = NULL; + mTail = first; + mHead = first; + mLength = 1; +} + +bool JSUPtrList::append(JSUPtrLink* ptr) { + JSUPtrList* list = ptr->mList; + bool result = (NULL == list); + if (!result) { + result = list->remove(ptr); + } + + if (result) { + if (mLength == 0) { + setFirst(ptr); + } else { + ptr->mList = this; + ptr->mPrev = mTail; + ptr->mNext = NULL; + mTail->mNext = ptr; + mTail = ptr; + mLength++; + } + } + + return result; +} + +bool JSUPtrList::prepend(JSUPtrLink* ptr) { + JSUPtrList* list = ptr->mList; + bool result = (NULL == list); + if (!result) { + result = list->remove(ptr); + } + + if (result) { + if (mLength == 0) { + setFirst(ptr); + } else { + ptr->mList = this; + ptr->mPrev = NULL; + ptr->mNext = mHead; + mHead->mPrev = ptr; + mHead = ptr; + mLength++; + } + } + + return result; +} + +bool JSUPtrList::insert(JSUPtrLink* before, JSUPtrLink* ptr) { + if (before == mHead) { + return prepend(ptr); + } else if (before == NULL) { + return append(ptr); + } + + if (before->mList != this) { + return false; + } + + bool result = (NULL == ptr->mList); + if (!result) { + result = ptr->mList->remove(ptr); + } + + if (result) { + JSUPtrLink* prev = before->mPrev; + ptr->mList = this; + ptr->mPrev = prev; + ptr->mNext = before; + prev->mNext = ptr; + before->mPrev = ptr; + mLength++; + } + + return result; +} + +bool JSUPtrList::remove(JSUPtrLink* ptr) { + bool is_parent = (ptr->mList == this); + if (is_parent) { + if (mLength == 1) { + mHead = NULL; + mTail = NULL; + } else if (ptr == mHead) { + ptr->mNext->mPrev = NULL; + mHead = ptr->mNext; + } else if (ptr == mTail) { + ptr->mPrev->mNext = NULL; + mTail = ptr->mPrev; + } else { + ptr->mPrev->mNext = ptr->mNext; + ptr->mNext->mPrev = ptr->mPrev; + } + + ptr->mList = NULL; + mLength--; + } + + return is_parent; +} + +JSUPtrLink* JSUPtrList::getNthLink(u32 index) const { + if (index >= mLength) { + return NULL; + } + + JSUPtrLink* node = mHead; + for (u32 i = 0; i < index; i++) { + node = node->getNext(); + } + + return node; +}
\ No newline at end of file |
