diff --git a/include/JSystem/JParticle/JPAEmitter.h b/include/JSystem/JParticle/JPAEmitter.h index 77b25b495..e40be37c5 100644 --- a/include/JSystem/JParticle/JPAEmitter.h +++ b/include/JSystem/JParticle/JPAEmitter.h @@ -130,9 +130,25 @@ public: /* 0x148 */ u32 mDivNumber; }; +struct JPAFrameManager { +public: + JPAFrameManager() : mFrame(0.0f) {} + + f32 getFrame() const { return mFrame; } + void setFrame(f32 frame) { mFrame = frame; } + void incFrame() { + mFrame++; + if (mFrame < 0.0f) + mFrame = 0.0f; + } + +private: + /* 0x00 */ f32 mFrame; +}; + class JPABaseEmitter { public: - JPABaseEmitter() : mLink(this), mRandomSeed(0), mTick(0.0f), mTime(0.0f) {} + JPABaseEmitter() : mLink(this), mRandomSeed(0) {} ~JPABaseEmitter() {} typedef void (JPABaseEmitter::*VolumeFunc)(); @@ -351,8 +367,8 @@ public: /* 0x08C */ s32 mUseKeyFlag; /* 0x090 */ JSULink mLink; /* 0x0A0 */ JPADraw mDraw; - /* 0x164 */ f32 mTick; - /* 0x168 */ f32 mTime; + /* 0x164 */ JPAFrameManager mTick; + /* 0x168 */ JPAFrameManager mTime; /* 0x16C */ JPAFieldManager mFieldManager; /* 0x17C */ JSUList mActiveParticles; /* 0x188 */ JSUList mChildParticles; diff --git a/src/JSystem/JParticle/JPADrawVisitor.cpp b/src/JSystem/JParticle/JPADrawVisitor.cpp index 6ae4eac24..ffde85f2c 100644 --- a/src/JSystem/JParticle/JPADrawVisitor.cpp +++ b/src/JSystem/JParticle/JPADrawVisitor.cpp @@ -78,7 +78,7 @@ void JPADrawExecGenPrjTexMtx::exec(const JPADrawContext* pDC) { f32 fovy = JPABaseEmitter::getFovy(); C_MTXLightPerspective(projMtx, fovy, aspect, 0.5f, -0.5f, 0.5f, 0.5f); - f32 tick = pDC->pbe->mTick; + f32 tick = pDC->pbe->mTick.getFrame(); f32 transX = tick * pDC->pbsp->getTexScrollTransX() + pDC->pbsp->getTexStaticTransX(); f32 transY = tick * pDC->pbsp->getTexScrollTransY() + pDC->pbsp->getTexStaticTransY(); f32 scaleX = tick * pDC->pbsp->getTexScrollScaleX() + pDC->pbsp->getTexStaticScaleX(); @@ -124,7 +124,7 @@ void JPADrawExecGenIdtMtx::exec(const JPADrawContext* pDC) { /* 8025FFB0-802602F0 .text exec__20JPADrawExecSetTexMtxFPC14JPADrawContext */ void JPADrawExecSetTexMtx::exec(const JPADrawContext* pDC) { - s32 tick = pDC->pbe->mTick; + s32 tick = pDC->pbe->mTick.getFrame(); f32 tilingX = 0.5f * pDC->pbsp->getTilingX(); f32 tilingY = 0.5f * pDC->pbsp->getTilingY(); f32 transX = tick * pDC->pbsp->getTexScrollTransX() + pDC->pbsp->getTexStaticTransX(); @@ -657,14 +657,14 @@ void JPADrawCalcColorEnv::calc(const JPADrawContext* pDC) { /* 802647E0-8026486C .text calc__30JPADrawCalcColorAnmFrameNormalFPC14JPADrawContext */ void JPADrawCalcColorAnmFrameNormal::calc(const JPADrawContext* pDC) { - s32 tick = pDC->pbe->mTick; + s32 tick = pDC->pbe->mTick.getFrame(); s32 frame = (tick < pDC->pbsp->getColorRegAnmMaxFrm()) ? tick : pDC->pbsp->getColorRegAnmMaxFrm(); JPADrawContext::pcb->mColorAnmFrame = frame; } /* 8026486C-802648E0 .text calc__30JPADrawCalcColorAnmFrameRepeatFPC14JPADrawContext */ void JPADrawCalcColorAnmFrameRepeat::calc(const JPADrawContext* pDC) { - f32 tick = pDC->pbe->mTick; + f32 tick = pDC->pbe->mTick.getFrame(); s32 frame = ((u32)tick) % (pDC->pbsp->getColorRegAnmMaxFrm() + 1); JPADrawContext::pcb->mColorAnmFrame = frame; } @@ -672,7 +672,7 @@ void JPADrawCalcColorAnmFrameRepeat::calc(const JPADrawContext* pDC) { /* 802648E0-8026495C .text calc__31JPADrawCalcColorAnmFrameReverseFPC14JPADrawContext */ void JPADrawCalcColorAnmFrameReverse::calc(const JPADrawContext* pDC) { /* Nonmatching */ - s32 tick = pDC->pbe->mTick; + s32 tick = pDC->pbe->mTick.getFrame(); s32 frame = tick / pDC->pbsp->getColorRegAnmMaxFrm(); JPADrawContext::pcb->mColorAnmFrame = frame; } @@ -689,7 +689,7 @@ void JPADrawCalcColorAnmFrameRandom::calc(const JPADrawContext* pDC) { /* 8026497C-80264A34 .text calc__32JPADrawCalcTextureAnmIndexNormalFPC14JPADrawContext */ void JPADrawCalcTextureAnmIndexNormal::calc(const JPADrawContext* pDC) { - s32 tick = pDC->pbe->mTick; + s32 tick = pDC->pbe->mTick.getFrame(); s32 idx = ((pDC->pbsp->getTextureAnmKeyNum() - 1) < tick) ? pDC->pbsp->getTextureAnmKeyNum() - 1 : tick; pDC->mpDraw->mTexIdx = pDC->pTexIdx[pDC->pbsp->getTextureIndex(idx)]; } @@ -697,7 +697,7 @@ void JPADrawCalcTextureAnmIndexNormal::calc(const JPADrawContext* pDC) { /* 80264A34-80264AD0 .text calc__32JPADrawCalcTextureAnmIndexRepeatFPC14JPADrawContext */ void JPADrawCalcTextureAnmIndexRepeat::calc(const JPADrawContext* pDC) { /* Nonmatching */ - f32 tick = pDC->pbe->mTick; + f32 tick = pDC->pbe->mTick.getFrame(); s32 maxFrame = pDC->pbsp->getTextureAnmKeyNum(); s32 idx = pDC->pbsp->getTextureIndex((s32)tick % maxFrame); pDC->mpDraw->mTexIdx = pDC->pTexIdx[idx]; diff --git a/src/JSystem/JParticle/JPAEmitter.cpp b/src/JSystem/JParticle/JPAEmitter.cpp index a52934a54..a1ca2903c 100644 --- a/src/JSystem/JParticle/JPAEmitter.cpp +++ b/src/JSystem/JParticle/JPAEmitter.cpp @@ -142,8 +142,8 @@ void JPABaseEmitter::create(JPADataBlockLinkInfo* info) { mGlobalPrmColor.r = mGlobalPrmColor.g = mGlobalPrmColor.b = mGlobalPrmColor.a = 0xFF; mEmitCount = 0.0f; mRateStepTimer = 0.0f; - mTick = 0.0f; - mTime = 0.0f; + mTick.setFrame(0.0f); + mTime.setFrame(0.0f); mUserData = 0; mRandomSeed.setSeed(emtrInfo.mRandom.get()); mFieldManager.initField(info, &emtrInfo); @@ -162,7 +162,6 @@ void JPABaseEmitter::create(JPADataBlockLinkInfo* info) { /* 8025D0B0-8025D294 .text calcEmitterInfo__14JPABaseEmitterFv */ void JPABaseEmitter::calcEmitterInfo() { - /* Nonmatching */ emtrInfo.mpCurEmitter = this; emtrInfo.mVolumeEmitXCount = 0; emtrInfo.mVolumeEmitAngleCount = 0; @@ -205,9 +204,7 @@ void JPABaseEmitter::calc() { calcAfterCB(); calcParticle(); calcChild(); - mTick += 1.0f; - if (mTick < 0.0f) - mTick = 0.0f; + mTick.incFrame(); } else { calcBeforeCB(); calcAfterCB(); @@ -216,7 +213,6 @@ void JPABaseEmitter::calc() { /* 8025D3C0-8025D5D4 .text calcCreatePtcls__14JPABaseEmitterFv */ void JPABaseEmitter::calcCreatePtcls() { - /* Nonmatching */ if (checkStatus(JPAEmtrStts_RateStepEmit)) { s32 emitCount = 0; if (checkEmDataFlag(0x02)) { // Fixed interval @@ -226,12 +222,13 @@ void JPABaseEmitter::calcCreatePtcls() { emtrInfo.mVolumeEmitIdx = 0; } else { f32 incr = mRate * (1.0f + mRateRndm * getRandomRF()); - mEmitCount += incr; + f32 newCounter = mEmitCount + incr; + mEmitCount = newCounter; - if (mEmitCount >= 1) { + if (newCounter >= 1) { emitCount = mEmitCount; mEmitCount -= emitCount; - } else if (mEmitCount > 0 && checkStatus(JPAEmtrStts_FirstEmit)) { + } else if (incr > 0 && checkStatus(JPAEmtrStts_FirstEmit)) { emitCount = 1; } } @@ -248,7 +245,7 @@ void JPABaseEmitter::calcCreatePtcls() { } } - if (mRateStepTimer++ >= mRateStep + 1) { + if (++mRateStepTimer >= mRateStep + 1) { mRateStepTimer -= mRateStep + 1; setStatus(JPAEmtrStts_RateStepEmit); } else { @@ -339,7 +336,7 @@ void JPABaseEmitter::calcChild() { void JPABaseEmitter::calcKey() { for (s32 i = 0; i < getEmitterDataBlockInfoPtr()->getKeyNum(); i++) { JPAKeyBlock* key = getEmitterDataBlockInfoPtr()->getKey()[i]; - f32 tick = mTick; + f32 tick = mTick.getFrame(); const f32* dataPtr = key->getKeyDataPtr(); u32 dataNum = key->getNumber(); if (key->isLoopEnable()) { @@ -402,13 +399,11 @@ JPABaseParticle * JPABaseEmitter::getPtclFromVacList() { /* 8025DBB4-8025DC2C .text doStartFrameProcess__14JPABaseEmitterFv */ bool JPABaseEmitter::doStartFrameProcess() { /* Nonmatching */ - if (mTime >= mStartFrame) + if (mTime.getFrame() >= mStartFrame) return true; if (!checkStatus(JPAEmtrStts_StopCalc)) { - mTime++; - if (mTime < 0.0f) - mTime = 0.0f; + mTime.incFrame(); } return false; @@ -421,7 +416,7 @@ bool JPABaseEmitter::doTerminationProcess() { } else if (mMaxFrame < 0) { mFlags |= JPAEmtrStts_EnableDeleteEmitter; return getParticleNumber() == 0; - } else if (mTick >= mMaxFrame) { + } else if (mTick.getFrame() >= mMaxFrame) { mFlags |= JPAEmtrStts_EnableDeleteEmitter; if (mFlags & JPAEmtrStts_Immortal) return false; diff --git a/src/JSystem/JParticle/JPAParticle.cpp b/src/JSystem/JParticle/JPAParticle.cpp index a7e78394e..56ac95832 100644 --- a/src/JSystem/JParticle/JPAParticle.cpp +++ b/src/JSystem/JParticle/JPAParticle.cpp @@ -39,7 +39,7 @@ void JPABaseParticle::initParticle() { velDir.zero(); if (emtr->mInitialVelDir != 0.0f) { Mtx mtx; - JPAGetYZRotateMtx(emtr->mSpread * emtr->getRandomRF() * 0x7FFF, emtr->getRandomF(), mtx); + JPAGetYZRotateMtx(emtr->mSpread * emtr->getRandomSS(), emtr->getRandomSS(), mtx); MTXConcat(emtrInfo.mEmitterDirMtx, mtx, mtx); velDir.set(mtx[0][2], mtx[1][2], mtx[2][2]); velDir.scale(emtr->mInitialVelDir); @@ -97,7 +97,7 @@ void JPABaseParticle::initChild(JPABaseParticle* parent) { JPABaseEmitter * emtr = emtrInfo.mpCurEmitter; JPASweepShape * sweep = emtr->mpDataLinkInfo->getSweepShape(); - mStatus = 5; + mStatus = 0x04 | 0x01; if (!sweep->isEnableField()) { mStatus |= 0x40; @@ -113,13 +113,11 @@ void JPABaseParticle::initChild(JPABaseParticle* parent) { rndmVel.setLength(baseVel); f32 baseVelInf = sweep->getVelInfRate(); - mBaseVel.set( - rndmVel.x + baseVelInf * parent->mBaseVel.x, - rndmVel.y + baseVelInf * parent->mBaseVel.y, - rndmVel.z + baseVelInf * parent->mBaseVel.z - ); + mBaseVel.x = rndmVel.x + parent->mBaseVel.x * baseVelInf; + mBaseVel.y = rndmVel.y + parent->mBaseVel.y * baseVelInf; + mBaseVel.z = rndmVel.z + parent->mBaseVel.z * baseVelInf; - mFieldAccel.scale(sweep->getVelInfRate(), parent->mFieldAccel); + mFieldAccel.scale(sweep->getVelInfRate(), parent->mFieldVel); mAccel.set(0.0f, -sweep->getGravity(), 0.0f); mAirResist = parent->mAirResist; mMoment = parent->mMoment; @@ -128,9 +126,12 @@ void JPABaseParticle::initChild(JPABaseParticle* parent) { mCurNormTime = 0.0f; mFieldVel.set(mFieldAccel); + f32 velScale = mMoment * mDrag; JGeometry::TVec3 vel; - vel.add(mBaseVel, mFieldVel); - mVelocity.scale(mMoment * mDrag, vel); + vel.x = (mBaseVel.x + mFieldVel.x) * velScale; + vel.y = (mBaseVel.y + mFieldVel.y) * velScale; + vel.z = (mBaseVel.z + mFieldVel.z) * velScale; + mVelocity = vel; if (emtr->checkEmDataFlag(0x10)) mStatus |= 0x20; @@ -170,21 +171,14 @@ void JPABaseParticle::incFrame() { /* 8025EB90-8025ECE8 .text calcVelocity__15JPABaseParticleFv */ void JPABaseParticle::calcVelocity() { mFieldVel.zero(); - if (mStatus & 0x20) + if (checkStatus(0x20)) mGlobalPosition.set(JPABaseEmitter::emtrInfo.mEmitterGlobalCenter); - mBaseVel.x += mAccel.x; - mBaseVel.y += mAccel.y; - mBaseVel.z += mAccel.z; - if (!(mStatus & 0x40)) + mBaseVel.add(mAccel); + if (!checkStatus(0x40)) JPABaseEmitter::emtrInfo.mpCurEmitter->mFieldManager.calc(this); - mFieldVel.x += mFieldAccel.x; - mFieldVel.y += mFieldAccel.y; - mFieldVel.z += mFieldAccel.z; + mFieldVel.add(mFieldAccel); - f32 airResist = mAirResist; - mBaseVel.x *= airResist; - mBaseVel.y *= airResist; - mBaseVel.z *= airResist; + mBaseVel.scale(mAirResist); f32 velScale = mMoment * mDrag; JGeometry::TVec3 vel; @@ -197,9 +191,7 @@ void JPABaseParticle::calcVelocity() { /* 8025ECE8-8025ED6C .text calcPosition__15JPABaseParticleFv */ void JPABaseParticle::calcPosition() { - mLocalPosition.x += mVelocity.x; - mLocalPosition.y += mVelocity.y; - mLocalPosition.z += mVelocity.z; + mLocalPosition.add(mVelocity); mPosition.set( mLocalPosition.x * JPABaseEmitter::emtrInfo.mPublicScale.x + mGlobalPosition.x,