diff --git a/include/JSystem/JGeometry.h b/include/JSystem/JGeometry.h index 000f09ea8..c17cb3ff4 100644 --- a/include/JSystem/JGeometry.h +++ b/include/JSystem/JGeometry.h @@ -153,9 +153,24 @@ struct TVec3 { return C_VECSquareMag((Vec*)&x); } + f32 normalize_broken() { + f32 sq = squared(); + if (sq <= 3.814697e-06f) { + return 0.0f; + } + f32 norm; + if (sq <= 0.0f) { + norm = sq; + } else { + norm = fsqrt_step(sq); + } + scale(norm); + return norm; + } + f32 normalize() { f32 sq = squared(); - if (sq <= FLT_EPSILON * 32.0f) { + if (sq <= 3.814697e-06f) { return 0.0f; } f32 norm; @@ -170,7 +185,7 @@ struct TVec3 { f32 normalize(const TVec3& other) { f32 sq = other.squared(); - if (sq <= FLT_EPSILON * 32.0f) { + if (sq <= 3.814697e-06f) { zero(); return 0.0f; } @@ -189,18 +204,9 @@ struct TVec3 { } void scale(register f32 sc) { - register f32 z; - register f32 x_y; - register f32* dst = &x; - register f32 zres; - asm { - psq_l x_y, 0(dst), 0, 0 - psq_l z, 8(dst), 1, 0 - ps_muls0 x_y, x_y, sc - psq_st x_y, 0(dst), 0, 0 - ps_muls0 zres, z, sc - psq_st zres, 8(dst), 1, 0 - }; + x *= sc; + y *= sc; + z *= sc; } void scale(register f32 sc, const TVec3& other) { @@ -247,7 +253,7 @@ struct TVec3 { } bool isZero() const { - return squared() <= 32.0f * FLT_EPSILON; + return squared() <= 32.0f * 3.814697e-06f; } void cross(const TVec3& a, const TVec3& b) { @@ -256,7 +262,7 @@ struct TVec3 { void setLength(f32 len) { f32 sq = squared(); - if (sq <= FLT_EPSILON * 32.0f) { + if (sq <= 3.814697e-06f * 32.0f) { return; } f32 norm; diff --git a/include/JSystem/JParticle/JPADynamicsBlock.h b/include/JSystem/JParticle/JPADynamicsBlock.h index fc7f383fd..1f60dc6bd 100644 --- a/include/JSystem/JParticle/JPADynamicsBlock.h +++ b/include/JSystem/JParticle/JPADynamicsBlock.h @@ -58,7 +58,7 @@ public: virtual f32 getRate() = 0; virtual f32 getRateRndm() = 0; virtual u32 getRateStep() = 0; - virtual u32 getMaxFrame() = 0; + virtual s16 getMaxFrame() = 0; virtual u32 getStartFrame() = 0; virtual u32 getLifeTime() = 0; virtual f32 getLifeTimeRndm() = 0; @@ -88,7 +88,7 @@ public: virtual f32 getRate() { return mpData->mRate; } virtual f32 getRateRndm() { return mpData->mRateRndm; } virtual u32 getRateStep() { return mpData->mRateStep; } - virtual u32 getMaxFrame() { return mpData->mMaxFrame; } + virtual s16 getMaxFrame() { return mpData->mMaxFrame; } virtual u32 getStartFrame() { return mpData->mStartFrame; } virtual u32 getLifeTime() { return mpData->mLifeTime; } virtual f32 getLifeTimeRndm() { return mpData->mLifeTimeRndm; } diff --git a/include/JSystem/JParticle/JPAEmitter.h b/include/JSystem/JParticle/JPAEmitter.h index a1ee1b72d..245c85c69 100644 --- a/include/JSystem/JParticle/JPAEmitter.h +++ b/include/JSystem/JParticle/JPAEmitter.h @@ -243,8 +243,8 @@ public: /* 0x000 */ VolumeFunc mVolumeFunc; /* 0x00C */ JGeometry::TVec3 mEmitterScale; - /* 0x018 */ cXyz mEmitterTranslation; - /* 0x024 */ csXyz mEmitterRot; + /* 0x018 */ JGeometry::TVec3 mEmitterTranslation; + /* 0x024 */ JGeometry::TVec3 mEmitterRot; /* 0x02A */ u8 mVolumeType; /* 0x02B */ u8 mRateStep; /* 0x02C */ JGeometry::TVec3 mEmitterDir; diff --git a/include/JSystem/JParticle/JPAField.h b/include/JSystem/JParticle/JPAField.h index 20580b972..115be0dce 100644 --- a/include/JSystem/JParticle/JPAField.h +++ b/include/JSystem/JParticle/JPAField.h @@ -9,6 +9,7 @@ class JPAEmitterInfo; class JPAFieldData; class JPABaseParticle; class JPABaseField; +class JPAFieldBlock; class JPAFieldManager { public: @@ -30,6 +31,8 @@ public: virtual ~JPAFieldData(); JSULink* getLinkBufferPtr() { return &mLink; } + static JPAEmitterInfo * pEmtrInfo; + public: /* 0x04 */ JPABaseField * mpBaseField; /* 0x08 */ JSULink mLink; @@ -39,7 +42,7 @@ public: /* 0x34 */ u32 field_0x34; /* 0x38 */ u32 field_0x38; /* 0x3C */ JGeometry::TVec3 mAirDir; - /* 0x48 */ u32 field_0x48; + /* 0x48 */ f32 mMaxDistSq; /* 0x4C */ f32 mFadeOutRate; /* 0x50 */ f32 mFadeInRate; /* 0x54 */ JGeometry::TVec3 mPos; @@ -61,4 +64,99 @@ public: /* 0x99 */ u8 mCycle; }; +class JPABaseField { +public: + virtual ~JPABaseField() {} + virtual void init(JPAFieldData*, JPABaseParticle*) {} + virtual void preCalc(JPAFieldData*); + virtual void calc(JPAFieldData*, JPABaseParticle*) {} + virtual bool isItinRange(JPAFieldData*, f32); + + void loadFieldData(JPAFieldData*, JPAFieldBlock*); + f32 calcFadeAffect(JPAFieldData*, f32); + void calcVel(JPAFieldData*, JPABaseParticle*); +}; + +class JPAGravityField : public JPABaseField { +public: + virtual ~JPAGravityField() {} + virtual void preCalc(JPAFieldData*); + virtual void calc(JPAFieldData*, JPABaseParticle*); +}; + +class JPAAirField : public JPABaseField { +public: + virtual ~JPAAirField() {} + virtual void preCalc(JPAFieldData*); + virtual void calc(JPAFieldData*, JPABaseParticle*); +}; + +class JPAMagnetField : public JPABaseField { +public: + virtual ~JPAMagnetField() {} + virtual void preCalc(JPAFieldData*); + virtual void calc(JPAFieldData*, JPABaseParticle*); +}; + +class JPANewtonField : public JPABaseField { +public: + virtual ~JPANewtonField() {} + virtual void preCalc(JPAFieldData*); + virtual void calc(JPAFieldData*, JPABaseParticle*); +}; + +class JPAVortexField : public JPABaseField { +public: + virtual ~JPAVortexField() {} + virtual void preCalc(JPAFieldData*); + virtual void calc(JPAFieldData*, JPABaseParticle*); + virtual bool isItinRange(JPAFieldData*, f32) { return true; } +}; + +class JPAConvectionField : public JPABaseField { +public: + virtual ~JPAConvectionField() {} + virtual void preCalc(JPAFieldData*); + virtual void calc(JPAFieldData*, JPABaseParticle*); + virtual bool isItinRange(JPAFieldData*, f32) { return true; } +}; + +class JPARandomField : public JPABaseField { +public: + virtual ~JPARandomField() {} + virtual void calc(JPAFieldData*, JPABaseParticle*); +}; + +class JPADragField : public JPABaseField { +public: + virtual ~JPADragField() {} + virtual void init(JPAFieldData*, JPABaseParticle*); + virtual void preCalc(JPAFieldData*); + virtual void calc(JPAFieldData*, JPABaseParticle*); +}; + +class JPASpinField : public JPABaseField { +public: + virtual ~JPASpinField() {} + virtual void preCalc(JPAFieldData*); + virtual void calc(JPAFieldData*, JPABaseParticle*); + virtual bool isItinRange(JPAFieldData*, f32) { return true; } +}; + +class JPAFieldContainer { +public: + ~JPAFieldContainer() {} + +public: + /* 0x00 */ JPAGravityField mGravity; + /* 0x04 */ JPAAirField mAir; + /* 0x08 */ JPAMagnetField mMagnet; + /* 0x0C */ JPANewtonField mNewton; + /* 0x10 */ JPAVortexField mVortex; + /* 0x14 */ JPAConvectionField mConvection; + /* 0x18 */ JPARandomField mRandom; + /* 0x1C */ JPADragField mDrag; + /* 0x20 */ JPASpinField mSpin; +}; + #endif /* JPAFIELD_H */ diff --git a/include/JSystem/JParticle/JPAFieldBlock.h b/include/JSystem/JParticle/JPAFieldBlock.h index 850ae6f70..54e17c251 100644 --- a/include/JSystem/JParticle/JPAFieldBlock.h +++ b/include/JSystem/JParticle/JPAFieldBlock.h @@ -23,7 +23,7 @@ struct JPAFieldBlockData { class JPAFieldBlock { public: virtual ~JPAFieldBlock() {} - virtual u32 getType() = 0; + virtual u8 getType() = 0; virtual u32 getID() = 0; virtual u32 getVelType() = 0; virtual u32 getCycle() = 0; @@ -47,7 +47,7 @@ public: JPAFieldBlockArc(const u8*); virtual ~JPAFieldBlockArc() {} - virtual u32 getType() { return (mpData->mFlag >> 0) & 0x0F; } + virtual u8 getType() { return (mpData->mFlag >> 0) & 0x0F; } virtual u32 getVelType() { return (mpData->mFlag >> 8) & 0x03; } virtual u32 getSttFlag() { return (mpData->mFlag >> 16) & 0xFFFF; } virtual u32 getCycle() { return mpData->mCycle; } diff --git a/include/dolphin/mtx/vec.h b/include/dolphin/mtx/vec.h index 06b4ff1e7..8870fc0fe 100644 --- a/include/dolphin/mtx/vec.h +++ b/include/dolphin/mtx/vec.h @@ -34,21 +34,9 @@ void C_VECHalfAngle(const Vec* a, const Vec* b, Vec* half); void C_VECReflect(const Vec* src, const Vec* normal, Vec* dst); inline void C_VECAdd(register const Vec* a, register const Vec* b, register Vec* ab) { - register f32 axy; - register f32 bxy; - register f32 az; - register f32 sumz; - register f32 bz; - asm { - psq_l axy, 0(a), 0, 0 - psq_l bxy, 0(b), 0, 0 - ps_add axy, axy, bxy - psq_st axy, 0(ab), 0, 0 - psq_l az, 8(a), 1, 0 - psq_l bz, 8(b), 1, 0 - ps_add sumz, az, bz - psq_st sumz, 8(ab), 1, 0 - } + ab->x = a->x + b->x; + ab->y = a->y + b->y; + ab->z = a->z + b->z; } inline void C_VECSubtract(register const Vec* a, register const Vec* b, register Vec* ab) { @@ -70,19 +58,7 @@ inline void C_VECSubtract(register const Vec* a, register const Vec* b, register } inline f32 C_VECSquareMag(const Vec* v) { - register f32 x_y; - register f32 z; - register f32 res; - register const f32* src = &v->x; - asm { - psq_l x_y, 0(src), 0, 0 - ps_mul x_y, x_y, x_y - lfs z, 8(src) - ps_madd res, z, z, x_y - ps_sum0 res, res, x_y, x_y - } - ; - return res; + return v->x * v->x + v->y * v->y + v->z * v->z; } /* When compiling in debug mode, use C implementations */ diff --git a/src/JSystem/JParticle/JPABaseShape.cpp b/src/JSystem/JParticle/JPABaseShape.cpp index ee9774019..922e9deba 100644 --- a/src/JSystem/JParticle/JPABaseShape.cpp +++ b/src/JSystem/JParticle/JPABaseShape.cpp @@ -90,40 +90,31 @@ static void dummy() { } /* 80257248-80257508 .text __ct__15JPABaseShapeArcFPCUcP7JKRHeap */ -JPABaseShapeArc::JPABaseShapeArc(const u8* pData, JKRHeap* pHeap) { +JPABaseShapeArc::JPABaseShapeArc(const u8* data, JKRHeap* pHeap) { /* Nonmatching */ - pBsd = (const JPABaseShapeData*) pData; - mColLoopOffset = -((u16)(pBsd->mFlags >> 11) & 1); - mTexLoopOffset = -((u16)(pBsd->mFlags >> 13) & 1); + pBsd = reinterpret_cast(data+0x0C); + mColLoopOffset = -((pBsd->mFlags >> 11) & 0x01); + mTexLoopOffset = -((pBsd->mFlags >> 13) & 0x01); - bool bFlag2 = false; - if (!(pBsd->mFlags & 0x1000)) { - if (getType() == JPAType_Stripe || getType() == JPAType_StripeCross) - bFlag2 = true; - } + bool isEnableGlobalColAnm = (!(pBsd->mFlags & 0x1000) && (getType() == JPAType_Stripe || getType() == JPAType_StripeCross)) ? true : false; + bool isEnableGlobalTexAnm = (!(pBsd->mFlags & 0x4000) && (getType() == JPAType_Stripe || getType() == JPAType_StripeCross)) ? true : false; + mGlobalAnmFlags = isEnableGlobalColAnm << 1 | isEnableGlobalTexAnm << 0; - bool bFlag1 = false; - if (!(pBsd->mFlags & 0x4000)) { - if (getType() == JPAType_Stripe || getType() == JPAType_StripeCross) - bFlag1 = true; - } - - mGlobalAnmFlags = bFlag2 << 1 | bFlag1 << 0; if (isEnableTextureAnm() && getTextureAnmKeyNum() != 0) - mpTexAnmIdxArr = (const u8*)(pData + 0x60); + mpTexAnmIdxArr = (const u8*)(data + 0x60); else mpTexAnmIdxArr = NULL; if (isEnablePrmAnm()) { JUT_ASSERT(0x11f, pBsd->prmAnmKeyNum != 0); - mpPrmColorArr = makeColorTable((JPAColorRegAnmKey*)(pData + pBsd->mPrmAnimDataOffs), pBsd->prmAnmKeyNum, pBsd->mColorRegAnmMaxFrm, pHeap); + mpPrmColorArr = makeColorTable((JPAColorRegAnmKey*)(data + pBsd->mPrmAnimDataOffs), pBsd->prmAnmKeyNum, pBsd->mColorRegAnmMaxFrm, pHeap); } else { mpPrmColorArr = NULL; } if (isEnableEnvAnm()) { JUT_ASSERT(0x127, pBsd->envAnmKeyNum != 0); - mpEnvColorArr = makeColorTable((JPAColorRegAnmKey*)(pData + pBsd->mEnvAnimDataOffs), pBsd->envAnmKeyNum, pBsd->mColorRegAnmMaxFrm, pHeap); + mpEnvColorArr = makeColorTable((JPAColorRegAnmKey*)(data + pBsd->mEnvAnimDataOffs), pBsd->envAnmKeyNum, pBsd->mColorRegAnmMaxFrm, pHeap); } else { mpEnvColorArr = NULL; } diff --git a/src/JSystem/JParticle/JPAEmitter.cpp b/src/JSystem/JParticle/JPAEmitter.cpp index 0275be60e..73c18ebb4 100644 --- a/src/JSystem/JParticle/JPAEmitter.cpp +++ b/src/JSystem/JParticle/JPAEmitter.cpp @@ -4,8 +4,10 @@ // #include "JSystem/JParticle/JPAEmitter.h" +#include "JSystem/JParticle/JPADynamicsBlock.h" #include "JSystem/JParticle/JPAExtraShape.h" #include "JSystem/JParticle/JPASweepShape.h" +#include "JSystem/JParticle/JPAKeyBlock.h" #include "dolphin/mtx/mtx.h" #include "dolphin/mtx/mtxvec.h" @@ -58,8 +60,71 @@ void JPABaseEmitter::calcVolumeTorus() { } /* 8025CB54-8025D0B0 .text create__14JPABaseEmitterFP20JPADataBlockLinkInfo */ -void JPABaseEmitter::create(JPADataBlockLinkInfo*) { - /* Nonmatching */ +void JPABaseEmitter::create(JPADataBlockLinkInfo* info) { + mpDataLinkInfo = info; + + JPADynamicsBlock * dyn = getEmitterDataBlockInfoPtr()->getDynamics(); + dyn->getEmitterScl(mEmitterScale); + dyn->getEmitterTrs(mEmitterTranslation); + dyn->getEmitterRot(mEmitterRot); + mVolumeType = dyn->getVolumeType(); + mRateStep = dyn->getRateStep(); + mDivNumber = dyn->getDivNumber(); + mRate = dyn->getRate(); + mRateRndm = dyn->getRateRndm(); + mMaxFrame = dyn->getMaxFrame(); + mStartFrame = dyn->getStartFrame(); + mVolumeSize = dyn->getVolumeSize(); + mVolumeSweep = dyn->getVolumeSweep(); + mVolumeMinRad = dyn->getVolumeMinRad(); + mLifeTime = dyn->getLifeTime(); + mLifeTimeRndm = dyn->getLifeTimeRndm(); + mMoment = dyn->getMoment(); + mMomentRndm = dyn->getMomentRndm(); + mInitialVelRatio = dyn->getInitVelRatio(); + mAccelRndm = dyn->getAccelRndm(); + mAirResist = dyn->getAirResist(); + mAirResistRndm = dyn->getAirResistRndm(); + mInitialVelOmni = dyn->getInitVelOmni(); + mInitialVelAxis = dyn->getInitVelAxis(); + mInitialVelRndm = dyn->getInitVelRndm(); + mInitialVelDir = dyn->getInitVelDir(); + mAccel = dyn->getAccel(); + dyn->getEmitterDir(mEmitterDir); + // This appears to be an attempt at a normalize, but it scales by the length instead (???) + mEmitterDir.normalize_broken(); + mSpread = dyn->getSpread(); + mDataFlag = dyn->getDataFlag(); + mUseKeyFlag = dyn->getUseKeyFlag(); + mFlags = JPAEmtrStts_FirstEmit | JPAEmtrStts_RateStepEmit; + MTXIdentity(mGlobalRotation); + mGlobalDynamicsScale.x = 1.0f; + mGlobalDynamicsScale.y = 1.0f; + mGlobalDynamicsScale.z = 1.0f; + mGlobalTranslation.zero(); + mGlobalParticleScale.x = 1.0f; + mGlobalParticleScale.y = 1.0f; + mGlobalParticleScale.z = 1.0f; + mGlobalEnvColor.r = mGlobalEnvColor.g = mGlobalEnvColor.b = mGlobalEnvColor.a = 0xFF; + mGlobalPrmColor.r = mGlobalPrmColor.g = mGlobalPrmColor.b = mGlobalPrmColor.a = 0xFF; + mEmitCount = 0.0f; + mRateStepTimer = 0.0f; + mTick = 0.0f; + mTime = 0.0f; + mUserData = 0; + mRandomSeed.setSeed(emtrInfo.mRandom.get()); + mFieldManager.initField(info, &emtrInfo); + + switch (mVolumeType) { + case 0: mVolumeFunc = &JPABaseEmitter::calcVolumeCube; break; + case 1: mVolumeFunc = &JPABaseEmitter::calcVolumeSphere; break; + case 2: mVolumeFunc = &JPABaseEmitter::calcVolumeCylinder; break; + case 3: mVolumeFunc = &JPABaseEmitter::calcVolumeTorus; break; + case 4: mVolumeFunc = &JPABaseEmitter::calcVolumePoint; break; + case 5: mVolumeFunc = &JPABaseEmitter::calcVolumeCircle; break; + case 6: mVolumeFunc = &JPABaseEmitter::calcVolumeLine; break; + default: mVolumeFunc = NULL; break; + } } /* 8025D0B0-8025D294 .text calcEmitterInfo__14JPABaseEmitterFv */ @@ -94,7 +159,7 @@ void JPABaseEmitter::calcEmitterInfo() { emtrInfo.mPublicScale.x = mGlobalDynamicsScale.x * 1.0f; emtrInfo.mPublicScale.y = mGlobalDynamicsScale.y * 1.0f; emtrInfo.mPublicScale.z = mGlobalDynamicsScale.z * 1.0f; - MTXMultVec(mtx, &mEmitterTranslation, emtrInfo.mEmitterGlobalCenter); + MTXMultVec(mtx, mEmitterTranslation, emtrInfo.mEmitterGlobalCenter); } /* 8025D294-8025D3C0 .text calc__14JPABaseEmitterFv */ @@ -210,6 +275,31 @@ void JPABaseEmitter::calcChild() { /* 8025D8CC-8025DA90 .text calcKey__14JPABaseEmitterFv */ void JPABaseEmitter::calcKey() { /* Nonmatching */ + for (u32 i = 0; i < getEmitterDataBlockInfoPtr()->getKeyNum(); i++) { + JPAKeyBlock* key = getEmitterDataBlockInfoPtr()->getKey()[i]; + f32 tick = mTick; + const f32* dataPtr = key->getKeyDataPtr(); + u32 dataNum = key->getNumber(); + if (key->isLoopEnable()) { + s32 tickMax = (s32)(dataPtr[(dataNum - 1) * 4]) + 1; + tick -= (s32)tick % (s32)tickMax; + } + f32 value = JPAGetKeyFrameValue(tick, dataNum, dataPtr); + + switch (key->getID()) { + case 0: mRate = value; break; + case 1: mVolumeSize = value; break; + case 2: mVolumeSweep = value; break; + case 3: mVolumeMinRad = value; break; + case 4: mLifeTime = value; break; + case 5: mMoment = value; break; + case 6: mInitialVelOmni = value; break; + case 7: mInitialVelAxis = value; break; + case 8: mInitialVelDir = value; break; + case 9: mSpread = value; break; + case 10: mDraw.mScaleOut = value; break; + } + } } /* 8025DA90-8025DAD8 .text deleteParticle__14JPABaseEmitterFP15JPABaseParticleP26JSUList<15JPABaseParticle> */ @@ -286,7 +376,7 @@ void JPABaseEmitter::calcEmitterGlobalPosition(JGeometry::TVec3& dst) { mtx[0][3] = mGlobalTranslation.x; mtx[1][3] = mGlobalTranslation.y; mtx[2][3] = mGlobalTranslation.z; - MTXMultVec(mtx, &mEmitterTranslation, dst); + MTXMultVec(mtx, mEmitterTranslation, dst); } /* 8025DD5C-8025DDE8 .text calcgReRDirection__14JPABaseEmitterFv */ diff --git a/src/JSystem/JParticle/JPAEmitterLoader.cpp b/src/JSystem/JParticle/JPAEmitterLoader.cpp index 154b60879..5f59a8813 100644 --- a/src/JSystem/JParticle/JPAEmitterLoader.cpp +++ b/src/JSystem/JParticle/JPAEmitterLoader.cpp @@ -20,6 +20,8 @@ class JPAEmitterArchiveLoader_v10 { public: void load(); + JPAEmitterResource* getEmitterResource() { return mpEmtrRes; } + JPATextureResource* getTextureResource() { return mpTexRes; } public: /* 0x00 */ JKRHeap* pHeap; @@ -41,8 +43,8 @@ void JPAEmitterArchiveLoaderDataBase::load(const u8* data, JKRHeap* heap, JPAEmi loader.mpEmtrRes = NULL; loader.mpTexRes = NULL; loader.load(); - *dstEmtrRes = loader.mpEmtrRes; - *dstTexRes = loader.mpTexRes; + *dstEmtrRes = loader.getEmitterResource(); + *dstTexRes = loader.getTextureResource(); } else { JUT_WARN(201, "%s", "This is WRONG Version File\n"); } @@ -65,7 +67,9 @@ void JPAEmitterArchiveLoader_v10::load() { mpTexRes = new(pHeap, 0) JPATextureResource(header->texResNum, pHeap); u32 offs = 0x20; - for (u32 i = 0; i < header->emtrResNum; i++) { + for (s32 i = 0; i < header->emtrResNum; i++) { + const u8* data = &pData[offs]; + JPAEmitterData* pEmtrRes = new(pHeap, 0) JPAEmitterData(); JUT_ASSERT(234, pEmtrRes); @@ -77,21 +81,22 @@ void JPAEmitterArchiveLoader_v10::load() { JUT_ASSERT(243, pEmtrRes->pLinkInfoArray); pEmtrRes->pLinkInfoArray[0] = pLinkInfo; - pLinkInfo->keyNum = pData[offs + 0x14]; + pLinkInfo->keyNum = data[0x14]; pLinkInfo->keyBlocks = (JPAKeyBlock**) (pLinkInfo->keyNum != 0 ? new(pHeap, 0) JPAKeyBlockArc*[pLinkInfo->keyNum] : NULL); JUT_ASSERT(250, pLinkInfo->keyBlocks || pLinkInfo->keyNum == 0); - pLinkInfo->fldNum = pData[offs + 0x15]; + pLinkInfo->fldNum = data[0x15]; pLinkInfo->fldBlocks = (JPAFieldBlock**) (pLinkInfo->fldNum != 0 ? new(pHeap, 0) JPAFieldBlockArc*[pLinkInfo->fldNum] : NULL); JUT_ASSERT(256, pLinkInfo->fldBlocks || pLinkInfo->fldNum == 0); - pLinkInfo->mTextureNum = pData[offs + 0x16]; + pLinkInfo->mTextureNum = data[0x16]; pLinkInfo->texDataBase = NULL; u32 fld_cntr = 0; u32 key_cntr = 0; + u32 j = 0; u32 blockOffs = offs + 0x20; - for (u32 j = 0; j < *((u32*)(pData + offs + 0x0C)); j++) { + for (; j < *((u32*)(data + 0x0C)); j++) { const u8* block = (const u8*)(pData + blockOffs); u32 size = ((u32*)block)[1]; switch (((u32*)block)[0]) { @@ -133,15 +138,15 @@ void JPAEmitterArchiveLoader_v10::load() { blockOffs += size; } - mpEmtrRes->registration(pEmtrRes, *(u16*)(pData + 0x18)); + getEmitterResource()->registration(pEmtrRes, *(u16*)(data + 0x18)); offs = blockOffs; } - for (u32 i = 0; i < header->texResNum; i++) { + for (s32 i = 0; i < header->texResNum; i++) { u32 size = *(u32*)(pData + offs + 0x04); - JPATextureArc * pTex = new(pHeap, 0) JPATextureArc(pData + offs); + JPATextureArc* pTex = new(pHeap, 0) JPATextureArc(pData + offs); JUT_ASSERT(319, pTex); - mpTexRes->registration(pTex); + getTextureResource()->registration(pTex); offs += size; } } diff --git a/src/JSystem/JParticle/JPAField.cpp b/src/JSystem/JParticle/JPAField.cpp index 39e68d2df..47fb46230 100644 --- a/src/JSystem/JParticle/JPAField.cpp +++ b/src/JSystem/JParticle/JPAField.cpp @@ -4,30 +4,81 @@ // #include "JSystem/JParticle/JPAField.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "JSystem/JParticle/JPAParticle.h" +#include "JSystem/JParticle/JPAFieldBlock.h" +#include "JSystem/JUtility/JUTAssert.h" + +JPAFieldContainer fc; +JPAEmitterInfo * JPAFieldData::pEmtrInfo; /* 80259EE8-8025A0D8 .text loadFieldData__12JPABaseFieldFP12JPAFieldDataP13JPAFieldBlock */ -void JPABaseField::loadFieldData(JPAFieldData*, JPAFieldBlock*) { - /* Nonmatching */ +void JPABaseField::loadFieldData(JPAFieldData* data, JPAFieldBlock* block) { + data->mType = block->getType(); + data->mID = block->getID(); + data->mVelType = block->getVelType(); + data->mCycle = block->getCycle(); + data->mSttFlag = block->getSttFlag(); + data->mMag = block->getMag(); + data->mMagRndm = block->getMagRndm(); + data->mMaxDist = block->getMaxDist(); + block->getPos(data->mPos); + block->getDir(data->mDir); + data->mVal1 = block->getVal1(); + data->mVal2 = block->getVal2(); + data->mVal3 = block->getVal3(); + data->mFadeIn = block->getFadeIn(); + data->mFadeOut = block->getFadeOut(); + data->mEnTime = block->getEnTime(); + data->mDisTime = block->getDisTime(); + if (!(data->mSttFlag & 0x10)) + data->mDisTime = 1.0f; + data->mVel.zero(); } /* 8025A0D8-8025A21C .text calcVel__12JPABaseFieldFP12JPAFieldDataP15JPABaseParticle */ -void JPABaseField::calcVel(JPAFieldData*, JPABaseParticle*) { - /* Nonmatching */ +void JPABaseField::calcVel(JPAFieldData* data, JPABaseParticle* ptcl) { + /* Nonmatching - copy of vel shouldn't be using PS */ + JGeometry::TVec3 vel = data->mVel; + + if (!(ptcl->mStatus & 0x04)) { + f32 fadeAffect = calcFadeAffect(data, ptcl->mCurNormTime); + vel.scale(fadeAffect); + } + + switch (data->mVelType) { + case 0: ptcl->mFieldAccel.add(vel); break; + case 1: ptcl->mBaseVel += vel; break; + case 2: ptcl->mFieldVel += vel; break; + } } /* 8025A21C-8025A2B0 .text calcFadeAffect__12JPABaseFieldFP12JPAFieldDataf */ -void JPABaseField::calcFadeAffect(JPAFieldData*, float) { +f32 JPABaseField::calcFadeAffect(JPAFieldData* data, f32 t) { /* Nonmatching */ } /* 8025A2B0-8025A330 .text preCalc__12JPABaseFieldFP12JPAFieldData */ -void JPABaseField::preCalc(JPAFieldData*) { - /* Nonmatching */ +void JPABaseField::preCalc(JPAFieldData* data) { + data->mMaxDistSq = data->mMaxDist * data->mMaxDist; + + data->mFadeOutRate = data->mDisTime - data->mFadeOut; + if (data->mFadeOutRate == 0.0f) { + data->mFadeOutRate = 1.0f; + } else { + data->mFadeOutRate = 1.0f / data->mFadeOutRate; + } + data->mFadeInRate = data->mFadeIn - data->mEnTime; + if (data->mFadeInRate == 0.0f) { + data->mFadeInRate = 1.0f; + } else { + data->mFadeInRate = 1.0f / data->mFadeInRate; + } } /* 8025A330-8025A344 .text isItinRange__12JPABaseFieldFP12JPAFieldDataf */ -void JPABaseField::isItinRange(JPAFieldData*, float) { - /* Nonmatching */ +bool JPABaseField::isItinRange(JPAFieldData* data, f32 v) { + return v < data->mMaxDistSq; } /* 8025A344-8025A3E4 .text preCalc__15JPAGravityFieldFP12JPAFieldData */ @@ -116,111 +167,76 @@ void JPASpinField::calc(JPAFieldData*, JPABaseParticle*) { } /* 8025B7F8-8025B960 .text initField__15JPAFieldManagerFP20JPADataBlockLinkInfoP14JPAEmitterInfo */ -void JPAFieldManager::initField(JPADataBlockLinkInfo*, JPAEmitterInfo*) { +void JPAFieldManager::initField(JPADataBlockLinkInfo* dataInfo, JPAEmitterInfo* emtrInfo) { /* Nonmatching */ + u8 fieldNum = dataInfo->getFieldNum(); + JPAFieldBlock** fieldBlock = dataInfo->getField(); + for (u8 i = 0; i < fieldNum; i++) { + if (mVacList->getNumLinks() != 0) { + JPAFieldData* field = mVacList->getFirst()->getObject(); + mVacList->remove(field->getLinkBufferPtr()); + mList.append(field->getLinkBufferPtr()); + + switch (fieldBlock[i]->getType()) { + case 0: field->mpBaseField = &fc.mGravity; break; + case 1: field->mpBaseField = &fc.mAir; break; + case 2: field->mpBaseField = &fc.mMagnet; break; + case 3: field->mpBaseField = &fc.mNewton; break; + case 4: field->mpBaseField = &fc.mVortex; break; + case 5: field->mpBaseField = &fc.mConvection; break; + case 6: field->mpBaseField = &fc.mRandom; break; + case 7: field->mpBaseField = &fc.mDrag; break; + case 8: field->mpBaseField = &fc.mSpin; break; + default: break; + } + + JPAFieldData::pEmtrInfo = emtrInfo; + field->mpBaseField->loadFieldData(field, fieldBlock[i]); + } else { + JUT_WARN(0x25c, "%s", "JPariticle::Entry Over!!! (Field Number)"); + } + } } /* 8025B960-8025B9C0 .text init__15JPAFieldManagerFP15JPABaseParticle */ -void JPAFieldManager::init(JPABaseParticle*) { - /* Nonmatching */ +void JPAFieldManager::init(JPABaseParticle* ptcl) { + for (JSULink* link = mList.getFirst(); link != NULL; link = link->getNext()) { + JPAFieldData* data = link->getObject(); + data->mpBaseField->init(data, ptcl); + } } /* 8025B9C0-8025BA10 .text preCalc__15JPAFieldManagerFv */ void JPAFieldManager::preCalc() { - /* Nonmatching */ + for (JSULink* link = mList.getFirst(); link != NULL; link = link->getNext()) { + JPAFieldData* data = link->getObject(); + data->mpBaseField->preCalc(data); + } } /* 8025BA10-8025BAD8 .text calc__15JPAFieldManagerFP15JPABaseParticle */ -void JPAFieldManager::calc(JPABaseParticle*) { +void JPAFieldManager::calc(JPABaseParticle* ptcl) { /* Nonmatching */ + for (JSULink* link = mList.getFirst(); link != NULL; link = link->getNext()) { + JPAFieldData* data = link->getObject(); + data->mpBaseField->calc(data, ptcl); + // more to do here + } } /* 8025BAD8-8025BB20 .text deleteField__15JPAFieldManagerFP12JPAFieldData */ -void JPAFieldManager::deleteField(JPAFieldData*) { - /* Nonmatching */ +void JPAFieldManager::deleteField(JPAFieldData* data) { + mList.remove(data->getLinkBufferPtr()); + mVacList->prepend(data->getLinkBufferPtr()); } /* 8025BB20-8025BB74 .text deleteAllField__15JPAFieldManagerFv */ void JPAFieldManager::deleteAllField() { /* Nonmatching */ -} - -/* 8025BB74-8025BB78 .text init__12JPABaseFieldFP12JPAFieldDataP15JPABaseParticle */ -void JPABaseField::init(JPAFieldData*, JPABaseParticle*) { - /* Nonmatching */ -} - -/* 8025BB78-8025BB7C .text calc__12JPABaseFieldFP12JPAFieldDataP15JPABaseParticle */ -void JPABaseField::calc(JPAFieldData*, JPABaseParticle*) { - /* Nonmatching */ -} - -/* 8025BB7C-8025BBD8 .text __dt__12JPASpinFieldFv */ -JPASpinField::~JPASpinField() { - /* Nonmatching */ -} - -/* 8025BBD8-8025BBE0 .text isItinRange__12JPASpinFieldFP12JPAFieldDataf */ -void JPASpinField::isItinRange(JPAFieldData*, float) { - /* Nonmatching */ -} - -/* 8025BBE0-8025BC3C .text __dt__12JPADragFieldFv */ -JPADragField::~JPADragField() { - /* Nonmatching */ -} - -/* 8025BC3C-8025BC98 .text __dt__14JPARandomFieldFv */ -JPARandomField::~JPARandomField() { - /* Nonmatching */ -} - -/* 8025BC98-8025BCF4 .text __dt__18JPAConvectionFieldFv */ -JPAConvectionField::~JPAConvectionField() { - /* Nonmatching */ -} - -/* 8025BCF4-8025BCFC .text isItinRange__18JPAConvectionFieldFP12JPAFieldDataf */ -void JPAConvectionField::isItinRange(JPAFieldData*, float) { - /* Nonmatching */ -} - -/* 8025BCFC-8025BD58 .text __dt__14JPAVortexFieldFv */ -JPAVortexField::~JPAVortexField() { - /* Nonmatching */ -} - -/* 8025BD58-8025BD60 .text isItinRange__14JPAVortexFieldFP12JPAFieldDataf */ -void JPAVortexField::isItinRange(JPAFieldData*, float) { - /* Nonmatching */ -} - -/* 8025BD60-8025BDBC .text __dt__14JPANewtonFieldFv */ -JPANewtonField::~JPANewtonField() { - /* Nonmatching */ -} - -/* 8025BDBC-8025BE18 .text __dt__14JPAMagnetFieldFv */ -JPAMagnetField::~JPAMagnetField() { - /* Nonmatching */ -} - -/* 8025BE18-8025BE74 .text __dt__11JPAAirFieldFv */ -JPAAirField::~JPAAirField() { - /* Nonmatching */ -} - -/* 8025BE74-8025BED0 .text __dt__15JPAGravityFieldFv */ -JPAGravityField::~JPAGravityField() { - /* Nonmatching */ -} - -/* 8025BED0-8025BF18 .text __dt__12JPABaseFieldFv */ -JPABaseField::~JPABaseField() { - /* Nonmatching */ -} - -/* 8025BFC4-8025C128 .text __dt__17JPAFieldContainerFv */ -JPAFieldContainer::~JPAFieldContainer() { - /* Nonmatching */ + for (JSULink* link = mList.getFirst(); link != NULL;) { + JSULink* next = link->getNext(); + JPAFieldData* data = link->getObject(); + deleteField(data); + link = next; + } }