diff --git a/include/JSystem/J2D/J2DAnm.h b/include/JSystem/J2D/J2DAnm.h index 04e7c9baa..66a900434 100644 --- a/include/JSystem/J2D/J2DAnm.h +++ b/include/JSystem/J2D/J2DAnm.h @@ -544,8 +544,8 @@ struct J2DAnmTransformKey : public J2DAnmTransform { J2DAnmTransformKey() : J2DAnmTransform(nullptr, nullptr, nullptr) { - _24 = 0; - mInfoTable = nullptr; + mRotationScale = 0; + mInfoTable = nullptr; } virtual ~J2DAnmTransformKey() { } // _08 (weak) @@ -559,7 +559,7 @@ struct J2DAnmTransformKey : public J2DAnmTransform { // _00-_1C = J2DAnmTransform u8 _1C[6]; // _1C, unknown u16 _22; // _22 - int _24; // _24 + int mRotationScale; // _24 J3DAnmTransformKeyTable* mInfoTable; // _28 }; diff --git a/include/JSystem/JParticle/JPABlock.h b/include/JSystem/JParticle/JPABlock.h index a93407782..b73e03f70 100644 --- a/include/JSystem/JParticle/JPABlock.h +++ b/include/JSystem/JParticle/JPABlock.h @@ -165,7 +165,7 @@ struct JPAKeyBlock { void init_jpa(const u8*, JKRHeap*); const JPAKeyBlockData* mDataStart; // _00 - const f32* _04; // _04 + const f32* mKeyFrameData; // _04 }; #endif diff --git a/include/JSystem/JParticle/JPAEmitter.h b/include/JSystem/JParticle/JPAEmitter.h index 2ac8294ba..aae934ae5 100644 --- a/include/JSystem/JParticle/JPAEmitter.h +++ b/include/JSystem/JParticle/JPAEmitter.h @@ -301,7 +301,7 @@ struct JPABaseEmitter { } void setVolumeSize(u16 size) { mVolumeSize = size; } void setLifeTime(s16 lifetime) { mLifeTime = lifetime; } - u32 getAge() const { return mTick; } + u32 getAge() const { return mCurrentFrame; } f32 getRandF32() { return mRandom.getRandF32(); } f32 getRandZP() { return mRandom.getRandZP(); } @@ -345,7 +345,7 @@ struct JPABaseEmitter { u32 mFlags; // _F4 f32 mEmitCount; // _F8 f32 mScaleOut; // _FC - u32 mTick; // _100 + u32 mCurrentFrame; // _100 s16 mWaitTime; // _104 s16 mRateStepTimer; // _106 GXColor mPrmClr; // _108 @@ -410,7 +410,7 @@ struct JPAEmitterWorkData { int mRotType; // _204 int mPlaneType; // _208 int mDLType; // _20C - int mPrjType; // _210 + int mProjectionType; // _210 s16 mClrKeyFrame; // _214 u8 mDrawCount; // _216 }; diff --git a/src/JSystem/J2D/J2DAnimation.cpp b/src/JSystem/J2D/J2DAnimation.cpp index b80e67f9c..127fe7466 100644 --- a/src/JSystem/J2D/J2DAnimation.cpp +++ b/src/JSystem/J2D/J2DAnimation.cpp @@ -14,13 +14,14 @@ f32 J2DGetKeyFrameInterpolation(f32, J3DAnmKeyTableBase*, T*); * @note Address: 0x8005AF0C * @note Size: 0x56C */ -void J2DAnmTransformFull::getTransform(u16 p1, J3DTransformInfo* transformInfo) const +void J2DAnmTransformFull::getTransform(u16 transformIndex, J3DTransformInfo* transformInfo) const { - u16 idx = (p1 * 3); + u16 idx = (transformIndex * 3); J3DAnmTransformFullTable* xPart = &mTable[idx]; J3DAnmTransformFullTable* yPart = &mTable[idx + 1]; J3DAnmTransformFullTable* zPart = &mTable[idx + 2]; - u16 xMaxFrame = xPart->mScaleMaxFrame; + + u16 xMaxFrame = xPart->mScaleMaxFrame; if (getFrame() < 0) { transformInfo->mScale.x = mScaleVals[xPart->mScaleOffset]; } else if (getFrame() >= xMaxFrame) { @@ -28,6 +29,7 @@ void J2DAnmTransformFull::getTransform(u16 p1, J3DTransformInfo* transformInfo) } else { transformInfo->mScale.x = mScaleVals[(xPart->mScaleOffset + (int)getFrame())]; } + u16 yMaxFrame = yPart->mScaleMaxFrame; if (getFrame() < 0) { transformInfo->mScale.y = mScaleVals[yPart->mScaleOffset]; @@ -36,6 +38,7 @@ void J2DAnmTransformFull::getTransform(u16 p1, J3DTransformInfo* transformInfo) } else { transformInfo->mScale.y = mScaleVals[(yPart->mScaleOffset + (int)getFrame())]; } + u16 zMaxFrame = zPart->mScaleMaxFrame; if (getFrame() < 0) { transformInfo->mScale.z = mScaleVals[zPart->mScaleOffset]; @@ -44,6 +47,7 @@ void J2DAnmTransformFull::getTransform(u16 p1, J3DTransformInfo* transformInfo) } else { transformInfo->mScale.z = mScaleVals[(zPart->mScaleOffset + (int)getFrame())]; } + xMaxFrame = xPart->mRotationMaxFrame; if (getFrame() < 0) { transformInfo->mRotation.x = mRotationVals[xPart->mRotationOffset]; @@ -52,6 +56,7 @@ void J2DAnmTransformFull::getTransform(u16 p1, J3DTransformInfo* transformInfo) } else { transformInfo->mRotation.x = mRotationVals[(xPart->mRotationOffset + (int)getFrame())]; } + yMaxFrame = yPart->mRotationMaxFrame; if (getFrame() < 0) { transformInfo->mRotation.y = mRotationVals[yPart->mRotationOffset]; @@ -60,6 +65,7 @@ void J2DAnmTransformFull::getTransform(u16 p1, J3DTransformInfo* transformInfo) } else { transformInfo->mRotation.y = mRotationVals[(yPart->mRotationOffset + (int)getFrame())]; } + zMaxFrame = zPart->mRotationMaxFrame; if (getFrame() < 0) { transformInfo->mRotation.z = mRotationVals[zPart->mRotationOffset]; @@ -68,6 +74,7 @@ void J2DAnmTransformFull::getTransform(u16 p1, J3DTransformInfo* transformInfo) } else { transformInfo->mRotation.z = mRotationVals[(zPart->mRotationOffset + (int)getFrame())]; } + xMaxFrame = xPart->mTranslationMaxFrame; if (getFrame() < 0) { transformInfo->mTranslation.x = mTranslationVals[xPart->mTranslationOffset]; @@ -76,6 +83,7 @@ void J2DAnmTransformFull::getTransform(u16 p1, J3DTransformInfo* transformInfo) } else { transformInfo->mTranslation.x = mTranslationVals[(xPart->mTranslationOffset + (int)getFrame())]; } + yMaxFrame = yPart->mTranslationMaxFrame; if (getFrame() < 0) { transformInfo->mTranslation.y = mTranslationVals[yPart->mTranslationOffset]; @@ -84,6 +92,7 @@ void J2DAnmTransformFull::getTransform(u16 p1, J3DTransformInfo* transformInfo) } else { transformInfo->mTranslation.y = mTranslationVals[(yPart->mTranslationOffset + (int)getFrame())]; } + zMaxFrame = zPart->mTranslationMaxFrame; if (getFrame() < 0) { transformInfo->mTranslation.z = mTranslationVals[zPart->mTranslationOffset]; @@ -98,9 +107,9 @@ void J2DAnmTransformFull::getTransform(u16 p1, J3DTransformInfo* transformInfo) * @note Address: 0x8005B478 * @note Size: 0x420 */ -void J2DAnmTransformKey::calcTransform(f32 p1, u16 p2, J3DTransformInfo* transformInfo) const +void J2DAnmTransformKey::calcTransform(f32 frame, u16 transformIndex, J3DTransformInfo* transformInfo) const { - u16 idx = p2 * 3; + u16 idx = transformIndex * 3; J3DAnmTransformKeyTable* xInf = &mInfoTable[idx]; J3DAnmTransformKeyTable* yInf = &mInfoTable[idx + 1]; J3DAnmTransformKeyTable* zInf = &mInfoTable[idx + 2]; @@ -113,7 +122,7 @@ void J2DAnmTransformKey::calcTransform(f32 p1, u16 p2, J3DTransformInfo* transfo transformInfo->mScale.x = mScaleVals[xInf->mScaleInfo.mOffset]; break; default: - transformInfo->mScale.x = J2DGetKeyFrameInterpolation(p1, &xInf->mScaleInfo, &mScaleVals[xInf->mScaleInfo.mOffset]); + transformInfo->mScale.x = J2DGetKeyFrameInterpolation(frame, &xInf->mScaleInfo, &mScaleVals[xInf->mScaleInfo.mOffset]); } switch (yInf->mScaleInfo.mMaxFrame) { @@ -124,7 +133,7 @@ void J2DAnmTransformKey::calcTransform(f32 p1, u16 p2, J3DTransformInfo* transfo transformInfo->mScale.y = mScaleVals[yInf->mScaleInfo.mOffset]; break; default: - transformInfo->mScale.y = J2DGetKeyFrameInterpolation(p1, &yInf->mScaleInfo, &mScaleVals[yInf->mScaleInfo.mOffset]); + transformInfo->mScale.y = J2DGetKeyFrameInterpolation(frame, &yInf->mScaleInfo, &mScaleVals[yInf->mScaleInfo.mOffset]); } switch (zInf->mScaleInfo.mMaxFrame) { @@ -135,7 +144,7 @@ void J2DAnmTransformKey::calcTransform(f32 p1, u16 p2, J3DTransformInfo* transfo transformInfo->mScale.z = mScaleVals[zInf->mScaleInfo.mOffset]; break; default: - transformInfo->mScale.z = J2DGetKeyFrameInterpolation(p1, &zInf->mScaleInfo, &mScaleVals[zInf->mScaleInfo.mOffset]); + transformInfo->mScale.z = J2DGetKeyFrameInterpolation(frame, &zInf->mScaleInfo, &mScaleVals[zInf->mScaleInfo.mOffset]); } switch (xInf->mRotationInfo.mMaxFrame) { @@ -143,12 +152,12 @@ void J2DAnmTransformKey::calcTransform(f32 p1, u16 p2, J3DTransformInfo* transfo transformInfo->mRotation.x = 0; break; case 1: - transformInfo->mRotation.x = mRotationVals[xInf->mRotationInfo.mOffset] << _24; + transformInfo->mRotation.x = mRotationVals[xInf->mRotationInfo.mOffset] << mRotationScale; break; default: transformInfo->mRotation.x - = static_cast(J2DGetKeyFrameInterpolation(p1, &xInf->mRotationInfo, &mRotationVals[xInf->mRotationInfo.mOffset])) - << _24; + = static_cast(J2DGetKeyFrameInterpolation(frame, &xInf->mRotationInfo, &mRotationVals[xInf->mRotationInfo.mOffset])) + << mRotationScale; } switch (yInf->mRotationInfo.mMaxFrame) { @@ -156,12 +165,12 @@ void J2DAnmTransformKey::calcTransform(f32 p1, u16 p2, J3DTransformInfo* transfo transformInfo->mRotation.y = 0; break; case 1: - transformInfo->mRotation.y = mRotationVals[yInf->mRotationInfo.mOffset] << _24; + transformInfo->mRotation.y = mRotationVals[yInf->mRotationInfo.mOffset] << mRotationScale; break; default: transformInfo->mRotation.y - = static_cast(J2DGetKeyFrameInterpolation(p1, &yInf->mRotationInfo, &mRotationVals[yInf->mRotationInfo.mOffset])) - << _24; + = static_cast(J2DGetKeyFrameInterpolation(frame, &yInf->mRotationInfo, &mRotationVals[yInf->mRotationInfo.mOffset])) + << mRotationScale; } switch (zInf->mRotationInfo.mMaxFrame) { @@ -169,12 +178,12 @@ void J2DAnmTransformKey::calcTransform(f32 p1, u16 p2, J3DTransformInfo* transfo transformInfo->mRotation.z = 0; break; case 1: - transformInfo->mRotation.z = mRotationVals[zInf->mRotationInfo.mOffset] << _24; + transformInfo->mRotation.z = mRotationVals[zInf->mRotationInfo.mOffset] << mRotationScale; break; default: transformInfo->mRotation.z - = static_cast(J2DGetKeyFrameInterpolation(p1, &zInf->mRotationInfo, &mRotationVals[zInf->mRotationInfo.mOffset])) - << _24; + = static_cast(J2DGetKeyFrameInterpolation(frame, &zInf->mRotationInfo, &mRotationVals[zInf->mRotationInfo.mOffset])) + << mRotationScale; } switch (xInf->mTranslationInfo.mMaxFrame) { @@ -186,7 +195,7 @@ void J2DAnmTransformKey::calcTransform(f32 p1, u16 p2, J3DTransformInfo* transfo break; default: transformInfo->mTranslation.x - = J2DGetKeyFrameInterpolation(p1, &xInf->mTranslationInfo, &mTranslationVals[xInf->mTranslationInfo.mOffset]); + = J2DGetKeyFrameInterpolation(frame, &xInf->mTranslationInfo, &mTranslationVals[xInf->mTranslationInfo.mOffset]); } switch (yInf->mTranslationInfo.mMaxFrame) { @@ -198,7 +207,7 @@ void J2DAnmTransformKey::calcTransform(f32 p1, u16 p2, J3DTransformInfo* transfo break; default: transformInfo->mTranslation.y - = J2DGetKeyFrameInterpolation(p1, &yInf->mTranslationInfo, &mTranslationVals[yInf->mTranslationInfo.mOffset]); + = J2DGetKeyFrameInterpolation(frame, &yInf->mTranslationInfo, &mTranslationVals[yInf->mTranslationInfo.mOffset]); } switch (zInf->mTranslationInfo.mMaxFrame) { @@ -210,7 +219,7 @@ void J2DAnmTransformKey::calcTransform(f32 p1, u16 p2, J3DTransformInfo* transfo break; default: transformInfo->mTranslation.z - = J2DGetKeyFrameInterpolation(p1, &zInf->mTranslationInfo, &mTranslationVals[zInf->mTranslationInfo.mOffset]); + = J2DGetKeyFrameInterpolation(frame, &zInf->mTranslationInfo, &mTranslationVals[zInf->mTranslationInfo.mOffset]); } } @@ -303,6 +312,7 @@ void J2DAnmColorKey::getColor(u16 idx, GXColor* color) const OSf32tou8(&val, &color->r); } } + switch (info->mColorInfo[1].mMaxFrame) { case 0: color->g = 0; @@ -320,6 +330,7 @@ void J2DAnmColorKey::getColor(u16 idx, GXColor* color) const OSf32tou8(&val, &color->g); } } + switch (info->mColorInfo[2].mMaxFrame) { case 0: color->b = 0; @@ -337,6 +348,7 @@ void J2DAnmColorKey::getColor(u16 idx, GXColor* color) const OSf32tou8(&val, &color->b); } } + switch (info->mColorInfo[3].mMaxFrame) { case 0: color->a = 0; @@ -425,6 +437,7 @@ void J2DAnmVtxColorKey::getColor(u8 tableIdx, u16 idx, GXColor* color) const color->r = 255; } } + switch (info->mColorInfo[1].mMaxFrame) { case 0: color->g = 0; @@ -442,6 +455,7 @@ void J2DAnmVtxColorKey::getColor(u8 tableIdx, u16 idx, GXColor* color) const color->g = 255; } } + switch (info->mColorInfo[2].mMaxFrame) { case 0: color->b = 0; @@ -459,6 +473,7 @@ void J2DAnmVtxColorKey::getColor(u8 tableIdx, u16 idx, GXColor* color) const color->b = 255; } } + switch (info->mColorInfo[3].mMaxFrame) { case 0: color->a = 0; @@ -488,6 +503,7 @@ void J2DAnmTextureSRTKey::calcTransform(f32 frame, u16 inputIdx, J3DTextureSRTIn J3DAnmTransformKeyTable* xInf = &mInfoTable[idx]; J3DAnmTransformKeyTable* yInf = &mInfoTable[idx + 1]; J3DAnmTransformKeyTable* zInf = &mInfoTable[idx + 2]; + switch (xInf->mScaleInfo.mMaxFrame) { case 0: texInfo->mScaleX = 1; @@ -498,6 +514,7 @@ void J2DAnmTextureSRTKey::calcTransform(f32 frame, u16 inputIdx, J3DTextureSRTIn default: texInfo->mScaleX = J2DGetKeyFrameInterpolation(frame, &xInf->mScaleInfo, &mScaleVals[xInf->mScaleInfo.mOffset]); } + switch (yInf->mScaleInfo.mMaxFrame) { case 0: texInfo->mScaleY = 1; @@ -508,6 +525,7 @@ void J2DAnmTextureSRTKey::calcTransform(f32 frame, u16 inputIdx, J3DTextureSRTIn default: texInfo->mScaleY = J2DGetKeyFrameInterpolation(frame, &yInf->mScaleInfo, &mScaleVals[yInf->mScaleInfo.mOffset]); } + switch (zInf->mRotationInfo.mMaxFrame) { case 0: texInfo->mRotation = 0; @@ -520,6 +538,7 @@ void J2DAnmTextureSRTKey::calcTransform(f32 frame, u16 inputIdx, J3DTextureSRTIn = static_cast(J2DGetKeyFrameInterpolation(frame, &zInf->mRotationInfo, &mRotationVals[zInf->mRotationInfo.mOffset])) << _10; } + switch (xInf->mTranslationInfo.mMaxFrame) { case 0: texInfo->mTranslationX = 0; @@ -531,6 +550,7 @@ void J2DAnmTextureSRTKey::calcTransform(f32 frame, u16 inputIdx, J3DTextureSRTIn texInfo->mTranslationX = J2DGetKeyFrameInterpolation(frame, &xInf->mTranslationInfo, &mTranslationVals[xInf->mTranslationInfo.mOffset]); } + switch (yInf->mTranslationInfo.mMaxFrame) { case 0: texInfo->mTranslationY = 0; @@ -580,32 +600,37 @@ void J2DAnmTextureSRTKey::searchUpdateMaterialID(J2DScreen* screen) void J2DAnmTexPattern::searchUpdateMaterialID(J2DScreen* screen) { if (screen && screen->mNameTab && screen->mTexRes) { - for (u16 entry = 0; entry < this->getUpdateMaterialNum(); entry++) { - s32 idx = screen->mNameTab->getIndex(mNameTab.getName(entry)); - if (idx != -1) { - mUpdateMaterialID[entry] = idx; + for (u16 entryIndex = 0; entryIndex < this->getUpdateMaterialNum(); entryIndex++) { + s32 nameIndex = screen->mNameTab->getIndex(mNameTab.getName(entryIndex)); + if (nameIndex != -1) { + mUpdateMaterialID[entryIndex] = nameIndex; } else { - mUpdateMaterialID[entry] = 0xFFFF; + mUpdateMaterialID[entryIndex] = 0xFFFF; } } delete[] mImgPtrArray; mImgPtrArray = new J2DAnmTexPatternTIMGPointer[screen->mTexRes->mCount]; + if (mImgPtrArray) { JUTResReference resRef; + for (u16 i = 0; i < screen->mTexRes->mCount; i++) { - s8* var1 = screen->mTexRes->getResReference(i); - ResTIMG* var2 = nullptr; - if (var1) { - var2 = (ResTIMG*)resRef.getResource(var1, 'TIMG', nullptr); - if (!var2 && J2DScreen::getDataManage()) { - var2 = (ResTIMG*)J2DScreen::getDataManage()->get(screen->mTexRes->getName(i)); + s8* resReference = screen->mTexRes->getResReference(i); + ResTIMG* imageResource = nullptr; + + if (resReference) { + imageResource = (ResTIMG*)resRef.getResource(resReference, 'TIMG', nullptr); + if (!imageResource && J2DScreen::getDataManage()) { + imageResource = (ResTIMG*)J2DScreen::getDataManage()->get(screen->mTexRes->getName(i)); } } - mImgPtrArray[i].mImg = var2; - if (var2 && var2->mPaletteFormat) { - JUTPalette* palette = new JUTPalette(GX_TLUT0, (GXTlutFmt)var2->mColorFormat, (JUTTransparency)var2->mTransparency, - var2->mPaletteEntryCount, ((u8*)var2) + var2->mPaletteOffset); + + mImgPtrArray[i].mImg = imageResource; + if (imageResource && imageResource->mPaletteFormat) { + JUTPalette* palette + = new JUTPalette(GX_TLUT0, (GXTlutFmt)imageResource->mColorFormat, (JUTTransparency)imageResource->mTransparency, + imageResource->mPaletteEntryCount, ((u8*)imageResource) + imageResource->mPaletteOffset); mImgPtrArray[i].mPalette = palette; } } @@ -656,11 +681,11 @@ ResTIMG* J2DAnmTexPattern::getResTIMG(u16 idx) const { if (!mImgPtrArray) { return nullptr; - } else { - u16 texNo; - this->getTexNo(idx, &texNo); - return mImgPtrArray[texNo].mImg; } + + u16 texNo; + this->getTexNo(idx, &texNo); + return mImgPtrArray[texNo].mImg; } /** @@ -671,11 +696,11 @@ JUTPalette* J2DAnmTexPattern::getPalette(u16 idx) const { if (!mImgPtrArray) { return nullptr; - } else { - u16 texNo; - this->getTexNo(idx, &texNo); - return mImgPtrArray[texNo].mPalette; } + + u16 texNo; + this->getTexNo(idx, &texNo); + return mImgPtrArray[texNo].mPalette; } /** @@ -703,6 +728,7 @@ void J2DAnmTevRegKey::getTevColorReg(u16 idx, GXColorS10* color) const { J3DAnmCRegKeyTable* info = &mCRegKeyTable[idx]; f32 val; + switch (info->mTables[0].mMaxFrame) { case 0: color->r = 0; @@ -720,6 +746,7 @@ void J2DAnmTevRegKey::getTevColorReg(u16 idx, GXColorS10* color) const OSf32tos16(&val, &color->r); } } + switch (info->mTables[1].mMaxFrame) { case 0: color->g = 0; @@ -737,6 +764,7 @@ void J2DAnmTevRegKey::getTevColorReg(u16 idx, GXColorS10* color) const OSf32tos16(&val, &color->g); } } + switch (info->mTables[2].mMaxFrame) { case 0: color->b = 0; @@ -754,6 +782,7 @@ void J2DAnmTevRegKey::getTevColorReg(u16 idx, GXColorS10* color) const OSf32tos16(&val, &color->b); } } + switch (info->mTables[3].mMaxFrame) { case 0: color->a = 0; @@ -798,6 +827,7 @@ void J2DAnmTevRegKey::getTevKonstReg(u16 idx, GXColor* color) const OSf32tou8(&val, &color->r); } } + switch (info->mTables[1].mMaxFrame) { case 0: color->g = 0; @@ -815,6 +845,7 @@ void J2DAnmTevRegKey::getTevKonstReg(u16 idx, GXColor* color) const OSf32tou8(&val, &color->g); } } + switch (info->mTables[2].mMaxFrame) { case 0: color->b = 0; @@ -832,6 +863,7 @@ void J2DAnmTevRegKey::getTevKonstReg(u16 idx, GXColor* color) const OSf32tou8(&val, &color->b); } } + switch (info->mTables[3].mMaxFrame) { case 0: color->a = 0; @@ -867,6 +899,7 @@ void J2DAnmTevRegKey::searchUpdateMaterialID(J2DScreen* screen) mCRegUpdateMaterialID[i] = 0xFFFF; } } + for (u16 i = 0; i < mKRegUpdateMaterialNum; i++) { int index = screen->mNameTab->getIndex(mKRegNameTab.getName(i)); if (index != -1) { @@ -879,43 +912,49 @@ void J2DAnmTevRegKey::searchUpdateMaterialID(J2DScreen* screen) } template -f32 J2DGetKeyFrameInterpolation(f32 p1, J3DAnmKeyTableBase* table, T* values) +f32 J2DGetKeyFrameInterpolation(f32 currentFrame, J3DAnmKeyTableBase* keyTable, T* keyValues) { - if (p1 < values[0]) { - return values[1]; - } else { - if (table->mType == 0) { - if (values[(table->mMaxFrame - 1) * 3] <= p1) { - return values[(table->mMaxFrame - 1) * 3 + 1]; + if (currentFrame < keyValues[0]) { + return keyValues[1]; + } + + if (keyTable->mType == 0) { + if (keyValues[(keyTable->mMaxFrame - 1) * 3] <= currentFrame) { + return keyValues[(keyTable->mMaxFrame - 1) * 3 + 1]; + } + + u32 frameCount = keyTable->mMaxFrame; + while (frameCount > 1) { + u32 halfFrameCount = frameCount / 2; + u32 upperIndex = halfFrameCount * 3; + if (currentFrame >= keyValues[upperIndex]) { + keyValues = keyValues + upperIndex; + frameCount -= halfFrameCount; } else { - u32 tmp = table->mMaxFrame; - while (tmp > 1) { - u32 halfTmp = tmp / 2; - u32 upIdx = halfTmp * 3; - if (p1 >= values[upIdx]) { - values = values + upIdx; - tmp -= halfTmp; - } else { - tmp = halfTmp; - } - } - return J2DHermiteInterpolation(p1, &values[0], &values[1], &values[2], &values[3], &values[4], &values[5]); + frameCount = halfFrameCount; } - } else if (values[(table->mMaxFrame - 1) * 4] <= p1) { - return values[(table->mMaxFrame - 1) * 4 + 1]; + } + + return J2DHermiteInterpolation(currentFrame, &keyValues[0], &keyValues[1], &keyValues[2], &keyValues[3], &keyValues[4], + &keyValues[5]); + } + + if (keyValues[(keyTable->mMaxFrame - 1) * 4] <= currentFrame) { + return keyValues[(keyTable->mMaxFrame - 1) * 4 + 1]; + } + + u32 frameCount = keyTable->mMaxFrame; + while (frameCount > 1) { + u32 halfFrameCount = frameCount / 2; + u32 upperIndex = halfFrameCount * 4; + if (currentFrame >= keyValues[upperIndex]) { + keyValues = keyValues + upperIndex; + frameCount -= halfFrameCount; } else { - u32 tmp = table->mMaxFrame; - while (tmp > 1) { - u32 halfTmp = tmp / 2; - u32 upIdx = halfTmp * 4; - if (p1 >= values[upIdx]) { - values = values + upIdx; - tmp -= halfTmp; - } else { - tmp = halfTmp; - } - } - return J2DHermiteInterpolation(p1, &values[0], &values[1], &values[3], &values[4], &values[5], &values[6]); + frameCount = halfFrameCount; } } -} + + return J2DHermiteInterpolation(currentFrame, &keyValues[0], &keyValues[1], &keyValues[3], &keyValues[4], &keyValues[5], + &keyValues[6]); +} \ No newline at end of file diff --git a/src/JSystem/J2D/J2DAnmLoader.cpp b/src/JSystem/J2D/J2DAnmLoader.cpp index da7136215..5f47e47bf 100644 --- a/src/JSystem/J2D/J2DAnmLoader.cpp +++ b/src/JSystem/J2D/J2DAnmLoader.cpp @@ -188,7 +188,7 @@ void J2DAnmKeyLoader_v15::setAnmTransform(J2DAnmTransformKey* anm, const J3DAnmT anm->_22 = data->mAnimTableNum1; anm->mFrameLength = data->mMaxFrame; anm->mAttribute = data->mAttribute; - anm->_24 = data->_09; + anm->mRotationScale = data->_09; anm->mCurrentFrame = 0; anm->mInfoTable = JSUConvertOffsetToPtr(data, (void*)data->mTableOffset); anm->mScaleVals = JSUConvertOffsetToPtr(data, (void*)data->mScaleOffset); diff --git a/src/JSystem/JParticle/JPABaseShape.cpp b/src/JSystem/JParticle/JPABaseShape.cpp index fb4bcb1be..68eb3a742 100644 --- a/src/JSystem/JParticle/JPABaseShape.cpp +++ b/src/JSystem/JParticle/JPABaseShape.cpp @@ -266,8 +266,8 @@ void JPACalcClrIdxNormal(JPAEmitterWorkData* work) { JPABaseShape* bsp = work->mResource->getBsp(); s16 keyFrame; - if (work->mEmitter->mTick < bsp->mData->mClrAnmFrmMax) { - keyFrame = work->mEmitter->mTick; + if (work->mEmitter->mCurrentFrame < bsp->mData->mClrAnmFrmMax) { + keyFrame = work->mEmitter->mCurrentFrame; } else { keyFrame = bsp->mData->mClrAnmFrmMax; } @@ -297,7 +297,7 @@ void JPACalcClrIdxNormal(JPAEmitterWorkData* work, JPABaseParticle* ptcl) void JPACalcClrIdxRepeat(JPAEmitterWorkData* work) { JPABaseShape* shape = work->mResource->getBsp(); - work->mClrKeyFrame = work->mEmitter->mTick % (shape->getClrAnmMaxFrm() + 1); + work->mClrKeyFrame = work->mEmitter->mCurrentFrame % (shape->getClrAnmMaxFrm() + 1); } /** @@ -318,13 +318,16 @@ void JPACalcClrIdxRepeat(JPAEmitterWorkData* work, JPABaseParticle* ptcl) */ void JPACalcClrIdxReverse(JPAEmitterWorkData* work) { - JPABaseShape* shape = work->mResource->getBsp(); - u32 maxFrm = shape->getClrAnmMaxFrm(); - u32 tick = work->mEmitter->mTick; - u32 uVar1 = tick / maxFrm; - tick = tick % maxFrm; - uVar1 &= 1; - work->mClrKeyFrame = tick + (uVar1) * (maxFrm - tick * 2); + JPABaseShape* shape = work->mResource->getBsp(); + u32 colourAnimLength = shape->getClrAnmMaxFrm(); + u32 tick = work->mEmitter->mCurrentFrame; + u32 colourAnimationProgress = tick / colourAnimLength; + tick = tick % colourAnimLength; + + // Progress is 0 or 1 + colourAnimationProgress &= 1; + + work->mClrKeyFrame = tick + (colourAnimationProgress) * (colourAnimLength - tick * 2); } /** @@ -333,11 +336,11 @@ void JPACalcClrIdxReverse(JPAEmitterWorkData* work) */ void JPACalcClrIdxReverse(JPAEmitterWorkData* work, JPABaseParticle* ptcl) { - JPABaseShape* shape = work->mResource->getBsp(); - int tick = ptcl->getAge() + shape->getClrLoopOfst(ptcl->mAnmRandom); - int maxFrm = shape->mData->mClrAnmFrmMax; - int rem = tick % maxFrm; - work->mClrKeyFrame = rem + ((tick / maxFrm) & 1) * (maxFrm - rem * 2); + JPABaseShape* baseShape = work->mResource->getBsp(); + int particleAgeOffset = ptcl->getAge() + baseShape->getClrLoopOfst(ptcl->mAnmRandom); + int maxFrameCount = baseShape->mData->mClrAnmFrmMax; + int remainder = particleAgeOffset % maxFrameCount; + work->mClrKeyFrame = remainder + ((particleAgeOffset / maxFrameCount) & 1) * (maxFrameCount - remainder * 2); } /** @@ -448,33 +451,56 @@ void JPAGenTexCrdMtxPrj(JPAEmitterWorkData*) * @note Address: 0x8008BC78 * @note Size: 0x198 */ -void JPAGenCalcTexCrdMtxAnm(JPAEmitterWorkData* work) +void JPAGenCalcTexCrdMtxAnm(JPAEmitterWorkData* workData) { - JPABaseShape* shape = work->mResource->getBsp(); - f32 dVar16 = work->mEmitter->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, GX_TEXMTX0, GX_MTX2x4); + // Get the base shape from the resource + JPABaseShape* baseShape = workData->mResource->getBsp(); + + // Get the current tick count from the emitter + f32 tickCount = workData->mEmitter->mCurrentFrame; + + // Calculate half of the tiling for S and T + f32 halfTilingS = 0.5f * (1.0f + baseShape->getTilingS()); + f32 halfTilingT = 0.5f * (1.0f + baseShape->getTilingT()); + + // Calculate the X and Y translations + f32 transX = (tickCount * baseShape->getIncTransX()) + baseShape->getInitTransX(); + f32 transY = (tickCount * baseShape->getIncTransY()) + baseShape->getInitTransY(); + + // Calculate the X and Y scales + f32 scaleX = (tickCount * baseShape->getIncScaleX()) + baseShape->getInitScaleX(); + f32 scaleY = (tickCount * baseShape->getIncScaleY()) + baseShape->getInitScaleY(); + + // Calculate the rotation + s32 rotation = (tickCount * baseShape->getIncRot()) + baseShape->getInitRot(); + + // Calculate the sine and cosine of the rotation + f32 sinRotation = JMASSin(rotation); + f32 cosRotation = JMASCos(rotation); + + // Initialize the transformation matrix + Mtx transformationMatrix; + + // Fill the transformation matrix with calculated values + transformationMatrix[0][0] = scaleX * cosRotation; + transformationMatrix[0][1] = -scaleX * sinRotation; + transformationMatrix[0][2] = 0.0f; + transformationMatrix[0][3] + = (halfTilingS + (scaleX * ((sinRotation * (halfTilingT + transY)) - (cosRotation * (halfTilingS + transX))))); + transformationMatrix[1][0] = scaleY * sinRotation; + transformationMatrix[1][1] = scaleY * cosRotation; + transformationMatrix[1][2] = 0.0f; + transformationMatrix[1][3] + = (halfTilingT + (-scaleY * ((sinRotation * (halfTilingS + transX)) + (cosRotation * (halfTilingT + transY))))); + transformationMatrix[2][0] = 0.0f; + transformationMatrix[2][1] = 0.0f; + transformationMatrix[2][2] = 1.0f; + transformationMatrix[2][3] = 0.0f; + + // Load the transformation matrix into the texture matrix + GXLoadTexMtxImm(transformationMatrix, GX_TEXMTX0, GX_MTX2x4); + + // Set the texture coordinate generation parameters GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX3X4, GX_TG_TEX0, GX_TEXMTX0, false, GX_PTIDENTITY); /* stwu r1, -0x70(r1) @@ -586,33 +612,55 @@ void JPAGenCalcTexCrdMtxAnm(JPAEmitterWorkData* work) * @note Address: 0x8008BE10 * @note Size: 0x170 */ -void JPALoadCalcTexCrdMtxAnm(JPAEmitterWorkData* work, JPABaseParticle* particle) +void JPALoadCalcTexCrdMtxAnm(JPAEmitterWorkData* workData, JPABaseParticle* particle) { - JPABaseShape* shape = work->mResource->getBsp(); - f32 dVar16 = particle->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); + // Get the base shape from the resource + JPABaseShape* baseShape = workData->mResource->getBsp(); + + // Get the age of the particle + f32 particleAge = particle->mAge; + + // Calculate half of the tiling for S and T + f32 halfTilingS = 0.5f * (1.0f + baseShape->getTilingS()); + f32 halfTilingT = 0.5f * (1.0f + baseShape->getTilingT()); + + // Calculate the X and Y translations + f32 translationX = (particleAge * baseShape->getIncTransX()) + baseShape->getInitTransX(); + f32 translationY = (particleAge * baseShape->getIncTransY()) + baseShape->getInitTransY(); + + // Calculate the X and Y scales + f32 scaleX = (particleAge * baseShape->getIncScaleX()) + baseShape->getInitScaleX(); + f32 scaleY = (particleAge * baseShape->getIncScaleY()) + baseShape->getInitScaleY(); + + // Calculate the rotation + s32 rotation = (particleAge * baseShape->getIncRot()) + baseShape->getInitRot(); + + // Calculate the sine and cosine of the rotation + f32 sinRotation = JMASSin(rotation); + f32 cosRotation = JMASCos(rotation); + + // Initialize the transformation matrix + Mtx transformationMatrix; + + // Fill the transformation matrix with calculated values + transformationMatrix[0][0] = scaleX * cosRotation; + transformationMatrix[0][1] = -scaleX * sinRotation; + transformationMatrix[0][2] = 0.0f; + transformationMatrix[0][3] + = (halfTilingS + (scaleX * ((sinRotation * (halfTilingT + translationY)) - (cosRotation * (halfTilingS + translationX))))); + transformationMatrix[1][0] = scaleY * sinRotation; + transformationMatrix[1][1] = scaleY * cosRotation; + transformationMatrix[1][2] = 0.0f; + transformationMatrix[1][3] + = (halfTilingT + (-scaleY * ((sinRotation * (halfTilingS + translationX)) + (cosRotation * (halfTilingT + translationY))))); + transformationMatrix[2][0] = 0.0f; + transformationMatrix[2][1] = 0.0f; + transformationMatrix[2][2] = 1.0f; + transformationMatrix[2][3] = 0.0f; + + // Load the transformation matrix into the texture matrix + GXLoadTexMtxImm(transformationMatrix, 0x1e, GX_MTX2x4); + /* stwu r1, -0x60(r1) mflr r0 @@ -744,7 +792,7 @@ void JPALoadTexAnm(JPAEmitterWorkData* work, JPABaseParticle* ptcl) void JPACalcTexIdxNormal(JPAEmitterWorkData* work) { JPABaseShape* shape = work->mResource->mBaseShape; - u32 tick = shape->getTexAnmKeyNum() - 1 < work->mEmitter->mTick ? shape->getTexAnmKeyNum() - 1 : work->mEmitter->mTick; + u32 tick = shape->getTexAnmKeyNum() - 1 < work->mEmitter->mCurrentFrame ? shape->getTexAnmKeyNum() - 1 : work->mEmitter->mCurrentFrame; work->mEmitter->mTexAnmIdx = shape->getTexIdx(tick); } @@ -766,7 +814,7 @@ void JPACalcTexIdxNormal(JPAEmitterWorkData* work, JPABaseParticle* ptcl) void JPACalcTexIdxRepeat(JPAEmitterWorkData* work) { JPABaseShape* shape = work->mResource->getBsp(); - work->mEmitter->mTexAnmIdx = shape->getTexIdx(work->mEmitter->mTick % shape->getTexAnmKeyNum()); + work->mEmitter->mTexAnmIdx = shape->getTexIdx(work->mEmitter->mCurrentFrame % shape->getTexAnmKeyNum()); } /** @@ -783,28 +831,46 @@ void JPACalcTexIdxRepeat(JPAEmitterWorkData* work, JPABaseParticle* ptcl) * @note Address: 0x8008C160 * @note Size: 0x50 */ -void JPACalcTexIdxReverse(JPAEmitterWorkData* work) +void JPACalcTexIdxReverse(JPAEmitterWorkData* workData) { - JPABaseShape* shape = work->mResource->getBsp(); - int tick = work->mEmitter->mTick; - int keyNum = (int)shape->getTexAnmKeyNum() - 1; - int div = tick / keyNum; - int rem = tick % keyNum; - work->mEmitter->mTexAnmIdx = shape->getTexIdx(rem + (div & 1) * (keyNum - rem * 2)); + // Get the base shape from the resource + JPABaseShape* baseShape = workData->mResource->getBsp(); + + // Get the current tick from the emitter + int currentTick = workData->mEmitter->mCurrentFrame; + + // Calculate the number of keys + int totalKeys = (int)baseShape->getTexAnmKeyNum() - 1; + + // Calculate the quotient and remainder of the current tick divided by the total keys + int quotient = currentTick / totalKeys; + int remainder = currentTick % totalKeys; + + // Calculate the texture animation index + workData->mEmitter->mTexAnmIdx = baseShape->getTexIdx(remainder + (quotient & 1) * (totalKeys - remainder * 2)); } /** * @note Address: 0x8008C1B0 * @note Size: 0x5C */ -void JPACalcTexIdxReverse(JPAEmitterWorkData* work, JPABaseParticle* ptcl) +void JPACalcTexIdxReverse(JPAEmitterWorkData* workData, JPABaseParticle* particle) { - JPABaseShape* shape = work->mResource->mBaseShape; - s32 tick = shape->getTexLoopOfst(ptcl->mAnmRandom) + ptcl->mAge; - int keyNum = (int)shape->getTexAnmKeyNum() - 1; - int div = tick / keyNum; - int rem = tick % keyNum; - ptcl->mTexAnmIdx = shape->getTexIdx(rem + (div & 1) * (keyNum - rem * 2)); + // Get the base shape from the resource + JPABaseShape* baseShape = workData->mResource->mBaseShape; + + // Calculate the current tick based on the particle's age and the texture loop offset + s32 currentTick = baseShape->getTexLoopOfst(particle->mAnmRandom) + particle->mAge; + + // Calculate the total number of keys + int totalKeys = (int)baseShape->getTexAnmKeyNum() - 1; + + // Calculate the quotient and remainder of the current tick divided by the total keys + int quotient = currentTick / totalKeys; + int remainder = currentTick % totalKeys; + + // Calculate the texture animation index + particle->mTexAnmIdx = baseShape->getTexIdx(remainder + (quotient & 1) * (totalKeys - remainder * 2)); } /** @@ -869,35 +935,60 @@ void loadPrj(const JPAEmitterWorkData* workData, const Mtx p2) * @note Address: 0x8008C35C * @note Size: 0x1AC */ -void loadPrjAnm(const JPAEmitterWorkData* work, const Mtx p2) +void loadPrjAnm(const JPAEmitterWorkData* workData, const Mtx transformationMatrix) { - JPABaseShape* shape = work->mResource->getBsp(); - f32 dVar16 = work->mEmitter->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; - PSMTXConcat(local_108, work->mPrjMtx, local_108); - PSMTXConcat(local_108, p2, local_108); - GXLoadTexMtxImm(local_108, 0x1e, GX_MTX3x4); + // Get the base shape from the resource + JPABaseShape* baseShape = workData->mResource->getBsp(); + + // Get the age of the emitter + f32 emitterAge = workData->mEmitter->getAge(); + + // Calculate half of the tiling for S and T + f32 halfTilingS = 0.5f * (1.0f + baseShape->getTilingS()); + f32 halfTilingT = 0.5f * (1.0f + baseShape->getTilingT()); + + // Calculate the X and Y translations + f32 translationX = (emitterAge * baseShape->getIncTransX()) + baseShape->getInitTransX(); + f32 translationY = (emitterAge * baseShape->getIncTransY()) + baseShape->getInitTransY(); + + // Calculate the X and Y scales + f32 scaleX = (emitterAge * baseShape->getIncScaleX()) + baseShape->getInitScaleX(); + f32 scaleY = (emitterAge * baseShape->getIncScaleY()) + baseShape->getInitScaleY(); + + // Calculate the rotation + s32 rotation = (emitterAge * baseShape->getIncRot()) + baseShape->getInitRot(); + + // Calculate the sine and cosine of the rotation + f32 sinRotation = JMASSin(rotation); + f32 cosRotation = JMASCos(rotation); + + // Initialize the transformation matrix + Mtx localTransformationMatrix; + + // Fill the transformation matrix with calculated values + localTransformationMatrix[0][0] = scaleX * cosRotation; + localTransformationMatrix[0][1] = -scaleX * sinRotation; + localTransformationMatrix[0][2] + = (halfTilingS + (scaleX * ((sinRotation * (halfTilingT + translationY)) - (cosRotation * (halfTilingS + translationX))))); + localTransformationMatrix[0][3] = 0.0f; + localTransformationMatrix[1][0] = scaleY * sinRotation; + localTransformationMatrix[1][1] = scaleY * cosRotation; + localTransformationMatrix[1][2] + = (halfTilingT + (-scaleY * ((sinRotation * (halfTilingS + translationX)) + (cosRotation * (halfTilingT + translationY))))); + localTransformationMatrix[1][3] = 0.0f; + localTransformationMatrix[2][0] = 0.0f; + localTransformationMatrix[2][1] = 0.0f; + localTransformationMatrix[2][2] = 1.0f; + localTransformationMatrix[2][3] = 0.0f; + + // Concatenate the local transformation matrix with the projection matrix + PSMTXConcat(localTransformationMatrix, workData->mPrjMtx, localTransformationMatrix); + + // Concatenate the local transformation matrix with the passed transformation matrix + PSMTXConcat(localTransformationMatrix, transformationMatrix, localTransformationMatrix); + + // Load the local transformation matrix into the texture matrix + GXLoadTexMtxImm(localTransformationMatrix, 0x1e, GX_MTX3x4); /* stwu r1, -0x70(r1) mflr r0 @@ -1016,15 +1107,15 @@ void loadPrjAnm(const JPAEmitterWorkData* work, const Mtx p2) void JPADrawBillboard(JPAEmitterWorkData* work, JPABaseParticle* particle) { if (particle->checkStatus(8) == 0) { - JGeometry::TVec3f local_48; - PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&local_48); + JGeometry::TVec3f position; + PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&position); Mtx mtx; mtx[0][0] = work->mGlobalPtclScl.x * particle->mParticleScaleX; - mtx[0][3] = local_48.x; + mtx[0][3] = position.x; mtx[1][1] = work->mGlobalPtclScl.y * particle->mParticleScaleY; - mtx[1][3] = local_48.y; + mtx[1][3] = position.y; mtx[2][2] = 1.0f; - mtx[2][3] = local_48.z; + mtx[2][3] = position.z; mtx[2][1] = 0.0f; mtx[2][0] = 0.0f; mtx[1][2] = 0.0f; @@ -1032,7 +1123,7 @@ void JPADrawBillboard(JPAEmitterWorkData* work, JPABaseParticle* particle) mtx[0][2] = 0.0f; mtx[0][1] = 0.0f; GXLoadPosMtxImm(mtx, 0); - p_prj[work->mPrjType](work, mtx); + p_prj[work->mProjectionType](work, mtx); GXCallDisplayList(jpa_dl, sizeof(jpa_dl)); } } @@ -1044,8 +1135,8 @@ void JPADrawBillboard(JPAEmitterWorkData* work, JPABaseParticle* particle) void JPADrawRotBillboard(JPAEmitterWorkData* work, JPABaseParticle* particle) { if (particle->checkStatus(8) == 0) { - JGeometry::TVec3f local_48; - PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&local_48); + JGeometry::TVec3f position; + PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&position); f32 sinRot = JMASSin(particle->mRotateAngle); f32 cosRot = JMASCos(particle->mRotateAngle); f32 particleX = work->mGlobalPtclScl.x * particle->mParticleScaleX; @@ -1054,18 +1145,18 @@ void JPADrawRotBillboard(JPAEmitterWorkData* work, JPABaseParticle* particle) Mtx mtx; mtx[0][0] = cosRot * particleX; mtx[0][1] = -sinRot * particleY; - mtx[0][3] = local_48.x; + mtx[0][3] = position.x; mtx[1][0] = sinRot * particleX; mtx[1][1] = cosRot * particleY; - mtx[1][3] = local_48.y; + mtx[1][3] = position.y; mtx[2][2] = 1.0f; - mtx[2][3] = local_48.z; + mtx[2][3] = position.z; mtx[2][1] = 0.0f; mtx[2][0] = 0.0f; mtx[1][2] = 0.0f; mtx[0][2] = 0.0f; GXLoadPosMtxImm(mtx, 0); - p_prj[work->mPrjType](work, mtx); + p_prj[work->mProjectionType](work, mtx); GXCallDisplayList(jpa_dl, sizeof(jpa_dl)); } } @@ -1077,24 +1168,24 @@ void JPADrawRotBillboard(JPAEmitterWorkData* work, JPABaseParticle* particle) void JPADrawYBillboard(JPAEmitterWorkData* work, JPABaseParticle* particle) { if (particle->checkStatus(8) == 0) { - JGeometry::TVec3f local_48; - PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&local_48); + JGeometry::TVec3f position; + PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&position); Mtx mtx; f32 particleY = work->mGlobalPtclScl.y * particle->mParticleScaleY; mtx[0][0] = work->mGlobalPtclScl.x * particle->mParticleScaleX; - mtx[0][3] = local_48.x; + mtx[0][3] = position.x; mtx[1][1] = work->mYBBCamMtx[1][1] * particleY; mtx[1][2] = work->mYBBCamMtx[1][2]; - mtx[1][3] = local_48.y; + mtx[1][3] = position.y; mtx[2][1] = work->mYBBCamMtx[2][1] * particleY; mtx[2][2] = work->mYBBCamMtx[2][2]; - mtx[2][3] = local_48.z; + mtx[2][3] = position.z; mtx[2][0] = 0.0f; mtx[1][0] = 0.0f; mtx[0][2] = 0.0f; mtx[0][1] = 0.0f; GXLoadPosMtxImm(mtx, 0); - p_prj[work->mPrjType](work, mtx); + p_prj[work->mProjectionType](work, mtx); GXCallDisplayList(jpa_dl, sizeof(jpa_dl)); } } @@ -1106,31 +1197,33 @@ void JPADrawYBillboard(JPAEmitterWorkData* work, JPABaseParticle* particle) void JPADrawRotYBillboard(JPAEmitterWorkData* work, JPABaseParticle* particle) { if (particle->checkStatus(8) == 0) { - JGeometry::TVec3f local_48; - PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&local_48); + JGeometry::TVec3f position; + PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&position); f32 sinRot = JMASSin(particle->mRotateAngle); f32 cosRot = JMASCos(particle->mRotateAngle); Mtx mtx; - f32 particleX = work->mGlobalPtclScl.x * particle->mParticleScaleX; - f32 particleY = work->mGlobalPtclScl.y * particle->mParticleScaleY; - f32 local_98 = (f32)(sinRot * particleX); - f32 local_94 = (f32)(cosRot * particleY); - f32 local_90 = work->mYBBCamMtx[1][1]; - f32 fVar1 = work->mYBBCamMtx[2][1]; - mtx[0][0] = (f32)(cosRot * particleX); - mtx[0][1] = (f32)(-sinRot * particleY); - mtx[0][2] = 0.0f; - mtx[0][3] = local_48.x; - mtx[1][0] = local_98 * local_90; - mtx[1][1] = local_94 * local_90; - mtx[1][2] = -fVar1; - mtx[1][3] = local_48.y; - mtx[2][0] = local_98 * fVar1; - mtx[2][1] = local_94 * fVar1; - mtx[2][2] = local_90; - mtx[2][3] = local_48.z; + f32 scaleX = work->mGlobalPtclScl.x * particle->mParticleScaleX; + f32 scaleY = work->mGlobalPtclScl.y * particle->mParticleScaleY; + f32 transformedWidth = (f32)(sinRot * scaleX); + f32 transformedHeight = (f32)(cosRot * scaleY); + + f32 boundsY11 = work->mYBBCamMtx[1][1]; + f32 boundsY21 = work->mYBBCamMtx[2][1]; + + mtx[0][0] = (f32)(cosRot * scaleX); + mtx[0][1] = (f32)(-sinRot * scaleY); + mtx[0][2] = 0.0f; + mtx[0][3] = position.x; + mtx[1][0] = transformedWidth * boundsY11; + mtx[1][1] = transformedHeight * boundsY11; + mtx[1][2] = -boundsY21; + mtx[1][3] = position.y; + mtx[2][0] = transformedWidth * boundsY21; + mtx[2][1] = transformedHeight * boundsY21; + mtx[2][2] = boundsY11; + mtx[2][3] = position.z; GXLoadPosMtxImm(mtx, 0); - p_prj[work->mPrjType](work, mtx); + p_prj[work->mProjectionType](work, mtx); GXCallDisplayList(jpa_dl, sizeof(jpa_dl)); } } @@ -1328,44 +1421,47 @@ void basePlaneTypeX(Mtx mtx, f32 xz, f32 y) * @note Address: 0x8008CCAC * @note Size: 0x350 */ -void JPADrawDirection(JPAEmitterWorkData* work, JPABaseParticle* particle) +void JPADrawDirection(JPAEmitterWorkData* emitterData, JPABaseParticle* particle) { if (particle->checkStatus(8) == 0) { - JGeometry::TVec3f local_6c; - JGeometry::TVec3f local_78; - p_direction[work->mDirType](work, particle, &local_6c); - if (!local_6c.isZero()) { - local_6c.normalize(); - local_78.cross(particle->mBaseAxis, local_6c); - if (!local_78.isZero()) { - local_78.normalize(); - particle->mBaseAxis.cross(local_6c, local_78); + JGeometry::TVec3f directionVector; + JGeometry::TVec3f crossProductVector; + p_direction[emitterData->mDirType](emitterData, particle, &directionVector); + if (!directionVector.isZero()) { + directionVector.normalize(); + crossProductVector.cross(particle->mBaseAxis, directionVector); + if (!crossProductVector.isZero()) { + crossProductVector.normalize(); + particle->mBaseAxis.cross(directionVector, crossProductVector); particle->mBaseAxis.normalize(); - Mtx local_60; - f32 fVar1 = work->mGlobalPtclScl.x * particle->mParticleScaleX; - f32 fVar2 = work->mGlobalPtclScl.y * particle->mParticleScaleY; - local_60[0][0] = particle->mBaseAxis.x; - local_60[0][1] = local_6c.x; - local_60[0][2] = local_78.x; - local_60[0][3] = particle->mPosition.x; - local_60[1][0] = particle->mBaseAxis.y; - local_60[1][1] = local_6c.y; - local_60[1][2] = local_78.y; - local_60[1][3] = particle->mPosition.y; - local_60[2][0] = particle->mBaseAxis.z; - local_60[2][1] = local_6c.z; - local_60[2][2] = local_78.z; - local_60[2][3] = particle->mPosition.z; - p_plane[work->mPlaneType](local_60, fVar1, fVar2); - PSMTXConcat(work->mPosCamMtx, local_60, local_60); - GXLoadPosMtxImm(local_60, 0); - p_prj[work->mPrjType](work, local_60); - GXCallDisplayList(p_dl[work->mDLType], sizeof(jpa_dl)); + + Mtx transformationMatrix; + + f32 scaleX = emitterData->mGlobalPtclScl.x * particle->mParticleScaleX; + f32 scaleY = emitterData->mGlobalPtclScl.y * particle->mParticleScaleY; + + transformationMatrix[0][0] = particle->mBaseAxis.x; + transformationMatrix[0][1] = directionVector.x; + transformationMatrix[0][2] = crossProductVector.x; + transformationMatrix[0][3] = particle->mPosition.x; + transformationMatrix[1][0] = particle->mBaseAxis.y; + transformationMatrix[1][1] = directionVector.y; + transformationMatrix[1][2] = crossProductVector.y; + transformationMatrix[1][3] = particle->mPosition.y; + transformationMatrix[2][0] = particle->mBaseAxis.z; + transformationMatrix[2][1] = directionVector.z; + transformationMatrix[2][2] = crossProductVector.z; + transformationMatrix[2][3] = particle->mPosition.z; + + p_plane[emitterData->mPlaneType](transformationMatrix, scaleX, scaleY); + PSMTXConcat(emitterData->mPosCamMtx, transformationMatrix, transformationMatrix); + GXLoadPosMtxImm(transformationMatrix, 0); + p_prj[emitterData->mProjectionType](emitterData, transformationMatrix); + GXCallDisplayList(p_dl[emitterData->mDLType], sizeof(jpa_dl)); } } } } - /** * @note Address: 0x8008CFFC * @note Size: 0x3FC @@ -1375,38 +1471,38 @@ void JPADrawRotDirection(JPAEmitterWorkData* work, JPABaseParticle* particle) if (particle->checkStatus(8) == 0) { f32 sinRot = JMASSin(particle->mRotateAngle); f32 cosRot = JMASCos(particle->mRotateAngle); - JGeometry::TVec3 local_6c; - JGeometry::TVec3 local_78; - p_direction[work->mDirType](work, particle, &local_6c); - if (!local_6c.isZero()) { - local_6c.normalize(); - local_78.cross(particle->mBaseAxis, local_6c); - if (!local_78.isZero()) { - local_78.normalize(); - particle->mBaseAxis.cross(local_6c, local_78); + JGeometry::TVec3 direction; + JGeometry::TVec3 crossProduct; + p_direction[work->mDirType](work, particle, &direction); + if (!direction.isZero()) { + direction.normalize(); + crossProduct.cross(particle->mBaseAxis, direction); + if (!crossProduct.isZero()) { + crossProduct.normalize(); + particle->mBaseAxis.cross(direction, crossProduct); particle->mBaseAxis.normalize(); f32 particleX = work->mGlobalPtclScl.x * particle->mParticleScaleX; f32 particleY = work->mGlobalPtclScl.y * particle->mParticleScaleY; - Mtx auStack_80; - Mtx local_60; - p_rot[work->mRotType](sinRot, cosRot, auStack_80); - p_plane[work->mPlaneType](auStack_80, particleX, particleY); - local_60[0][0] = particle->mBaseAxis.x; - local_60[0][1] = local_6c.x; - local_60[0][2] = local_78.x; - local_60[0][3] = particle->mPosition.x; - local_60[1][0] = particle->mBaseAxis.y; - local_60[1][1] = local_6c.y; - local_60[1][2] = local_78.y; - local_60[1][3] = particle->mPosition.y; - local_60[2][0] = particle->mBaseAxis.z; - local_60[2][1] = local_6c.z; - local_60[2][2] = local_78.z; - local_60[2][3] = particle->mPosition.z; - PSMTXConcat(local_60, auStack_80, auStack_80); - PSMTXConcat(work->mPosCamMtx, auStack_80, local_60); - GXLoadPosMtxImm(local_60, 0); - p_prj[work->mPrjType](work, local_60); + Mtx rotationMtx; + Mtx transformationMtx; + p_rot[work->mRotType](sinRot, cosRot, rotationMtx); + p_plane[work->mPlaneType](rotationMtx, particleX, particleY); + transformationMtx[0][0] = particle->mBaseAxis.x; + transformationMtx[0][1] = direction.x; + transformationMtx[0][2] = crossProduct.x; + transformationMtx[0][3] = particle->mPosition.x; + transformationMtx[1][0] = particle->mBaseAxis.y; + transformationMtx[1][1] = direction.y; + transformationMtx[1][2] = crossProduct.y; + transformationMtx[1][3] = particle->mPosition.y; + transformationMtx[2][0] = particle->mBaseAxis.z; + transformationMtx[2][1] = direction.z; + transformationMtx[2][2] = crossProduct.z; + transformationMtx[2][3] = particle->mPosition.z; + PSMTXConcat(transformationMtx, rotationMtx, rotationMtx); + PSMTXConcat(work->mPosCamMtx, rotationMtx, transformationMtx); + GXLoadPosMtxImm(transformationMtx, 0); + p_prj[work->mProjectionType](work, transformationMtx); GXCallDisplayList(p_dl[work->mDLType], sizeof(jpa_dl)); } } @@ -1420,32 +1516,32 @@ void JPADrawRotDirection(JPAEmitterWorkData* work, JPABaseParticle* particle) void JPADrawDBillboard(JPAEmitterWorkData* work, JPABaseParticle* particle) { if (particle->checkStatus(8) == 0) { - JGeometry::TVec3 local_70; - p_direction[work->mDirType](work, particle, &local_70); - JGeometry::TVec3 aTStack_7c; - aTStack_7c.set(work->mPosCamMtx[2][0], work->mPosCamMtx[2][1], work->mPosCamMtx[2][2]); - local_70.cross(local_70, aTStack_7c); - if (!local_70.isZero()) { - local_70.normalize(); - PSMTXMultVecSR(work->mPosCamMtx, (Vec*)&local_70, (Vec*)&local_70); - JGeometry::TVec3 local_88; - PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&local_88); + JGeometry::TVec3 direction; + p_direction[work->mDirType](work, particle, &direction); + JGeometry::TVec3 cameraPos; + cameraPos.set(work->mPosCamMtx[2][0], work->mPosCamMtx[2][1], work->mPosCamMtx[2][2]); + direction.cross(direction, cameraPos); + if (!direction.isZero()) { + direction.normalize(); + PSMTXMultVecSR(work->mPosCamMtx, (Vec*)&direction, (Vec*)&direction); + JGeometry::TVec3 particlePos; + PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&particlePos); f32 particleX = work->mGlobalPtclScl.x * particle->mParticleScaleX; f32 particleY = work->mGlobalPtclScl.y * particle->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[0][2] = 0.0f; - GXLoadPosMtxImm(local_60, 0); - p_prj[work->mPrjType](work, local_60); + Mtx transformMtx; + transformMtx[0][0] = direction.x * particleX; + transformMtx[0][1] = -direction.y * particleY; + transformMtx[0][3] = particlePos.x; + transformMtx[1][0] = direction.y * particleX; + transformMtx[1][1] = direction.x * particleY; + transformMtx[1][3] = particlePos.y; + transformMtx[2][2] = 1.0f; + transformMtx[2][3] = particlePos.z; + transformMtx[2][1] = 0.0f; + transformMtx[2][0] = 0.0f; + transformMtx[0][2] = 0.0f; + GXLoadPosMtxImm(transformMtx, 0); + p_prj[work->mProjectionType](work, transformMtx); GXCallDisplayList(jpa_dl, sizeof(jpa_dl)); } } @@ -1470,7 +1566,7 @@ void JPADrawRotation(JPAEmitterWorkData* work, JPABaseParticle* ptcl) mtx[2][3] = ptcl->mPosition.z; PSMTXConcat(work->mPosCamMtx, mtx, mtx); GXLoadPosMtxImm(mtx, 0); - p_prj[work->mPrjType](work, mtx); + p_prj[work->mProjectionType](work, mtx); GXCallDisplayList(p_dl[work->mDLType], sizeof(jpa_dl)); } } @@ -1501,12 +1597,12 @@ void JPADrawPoint(JPAEmitterWorkData* work, JPABaseParticle* ptcl) void JPADrawLine(JPAEmitterWorkData* work, JPABaseParticle* particle) { if (particle->checkStatus(8) == 0) { - JGeometry::TVec3f local_1c; - local_1c.x = particle->mPosition.x; + JGeometry::TVec3f position; + position.x = particle->mPosition.x; // JGeometry::setTVec3f(&particle->mPosition.x, &local_1c.x); - JGeometry::TVec3f local_28; - particle->getVelVec(local_28); - if (!local_28.isZero()) { + JGeometry::TVec3f direction; + particle->getVelVec(direction); + if (!direction.isZero()) { // local_28.setLength(work->mGlobalPtclScl.y * (25.0f * particle->mParticleScaleY)); // local_28.sub(local_1c, local_28); GXSetVtxDesc(GX_VA_POS, GX_DIRECT); @@ -1514,9 +1610,9 @@ void JPADrawLine(JPAEmitterWorkData* work, JPABaseParticle* particle) GXBegin(GX_LINES, GX_VTXFMT1, 2); f32 zero = 0.0f; f32 one = 1.0f; - GXPosition3f32(local_1c.x, local_1c.y, local_1c.z); + GXPosition3f32(position.x, position.y, position.z); GXTexCoord2f32(zero, zero); - GXPosition3f32(local_28.x, local_28.y, local_28.z); + GXPosition3f32(direction.x, direction.y, direction.z); GXTexCoord2f32(zero, one); GXEnd(); GXSetVtxDesc(GX_VA_POS, GX_INDEX8); diff --git a/src/JSystem/JParticle/JPADynamicsBlock.cpp b/src/JSystem/JParticle/JPADynamicsBlock.cpp index 3b00eb377..3434ef412 100644 --- a/src/JSystem/JParticle/JPADynamicsBlock.cpp +++ b/src/JSystem/JParticle/JPADynamicsBlock.cpp @@ -38,18 +38,18 @@ void JPAVolumeLine(JPAEmitterWorkData* workData) */ void JPAVolumeCircle(JPAEmitterWorkData* workData) { - s16 thetai; - f32 theta; + s16 angleInShort; + f32 angleInFloat; f32 distance; - f32 sizeXZ; - f32 temp; + f32 circleSizeInXZ; + if (workData->mEmitter->checkDynFlag(JPADYN_FixedInterval)) { - theta = (s16)((workData->mVolumeEmitIdx << 16) / workData->mCreateNumber); - thetai = theta * workData->mVolumeSweep; + angleInFloat = (s16)((workData->mVolumeEmitIdx << 16) / workData->mCreateNumber); + angleInShort = angleInFloat * workData->mVolumeSweep; workData->mVolumeEmitIdx++; } else { - theta = workData->mVolumeSweep * workData->mEmitter->getRandS16(); - thetai = theta; + angleInFloat = workData->mVolumeSweep * workData->mEmitter->getRandS16(); + angleInShort = angleInFloat; } distance = workData->mEmitter->getRandF32(); @@ -57,8 +57,8 @@ void JPAVolumeCircle(JPAEmitterWorkData* workData) distance = 1.0f - (distance * distance); } - sizeXZ = workData->mVolumeSize * (workData->mVolumeMinRad + distance * (1.0f - workData->mVolumeMinRad)); - workData->mVolumePos.set(sizeXZ * JMASSin(thetai), 0.0f, sizeXZ * JMASCos(thetai)); + circleSizeInXZ = workData->mVolumeSize * (workData->mVolumeMinRad + distance * (1.0f - workData->mVolumeMinRad)); + workData->mVolumePos.set(circleSizeInXZ * JMASSin(angleInShort), 0.0f, circleSizeInXZ * JMASCos(angleInShort)); workData->mVelOmni.mul(workData->mVolumePos, workData->mGlobalScl); workData->mVelAxis.set(workData->mVolumePos.x, 0.0f, workData->mVolumePos.z); } diff --git a/src/JSystem/JParticle/JPAEmitter.cpp b/src/JSystem/JParticle/JPAEmitter.cpp index 3bb55b3a1..a0b1f2dc8 100644 --- a/src/JSystem/JParticle/JPAEmitter.cpp +++ b/src/JSystem/JParticle/JPAEmitter.cpp @@ -56,7 +56,7 @@ void JPABaseEmitter::init(JPAEmitterManager* manager, JPAResource* resource) mEmitCount = 0.0f; initFlag(0x30); mDrawTimes = 1; - mTick = 0; + mCurrentFrame = 0; mWaitTime = 0; mRateStepTimer = 0; // mTexAnmIdx = 0; @@ -363,7 +363,7 @@ bool JPABaseEmitter::processTermination() setFlag(8); return getParticleNumber() == 0; } - if (mTick >= mMaxFrame) { + if (mCurrentFrame >= mMaxFrame) { setFlag(8); if (isFlag(0x40)) { return 0; diff --git a/src/JSystem/JParticle/JPAKeyBlock.cpp b/src/JSystem/JParticle/JPAKeyBlock.cpp index 7b875713c..129dc903f 100644 --- a/src/JSystem/JParticle/JPAKeyBlock.cpp +++ b/src/JSystem/JParticle/JPAKeyBlock.cpp @@ -7,7 +7,7 @@ */ JPAKeyBlock::JPAKeyBlock(const u8* data) : mDataStart(reinterpret_cast(data)) - , _04(reinterpret_cast(&data[0xC])) + , mKeyFrameData(reinterpret_cast(&data[0xC])) { } @@ -25,12 +25,13 @@ void JPAKeyBlock::init_jpa(const u8*, JKRHeap*) * @note Address: 0x80093A50 * @note Size: 0x94 */ -f32 JPAKeyBlock::calc(f32 p1) +f32 JPAKeyBlock::calc(f32 currentFrame) { if (mDataStart->_0B != '\0') { - int v1 = (int)_04[(mDataStart->mKeyFrameCount - 1) * 4] + 1; - int v2 = ((int)p1 / v1); - p1 = p1 - (v2 * v1); + int lastKeyFrameIndex = (int)mKeyFrameData[(mDataStart->mKeyFrameCount - 1) * 4] + 1; + int currentFrameRatio = ((int)currentFrame / lastKeyFrameIndex); + currentFrame = currentFrame - (currentFrameRatio * lastKeyFrameIndex); } - return JPACalcKeyAnmValue(p1, mDataStart->mKeyFrameCount, _04); + + return JPACalcKeyAnmValue(currentFrame, mDataStart->mKeyFrameCount, mKeyFrameData); } diff --git a/src/JSystem/JParticle/JPAMath.cpp b/src/JSystem/JParticle/JPAMath.cpp index 3a6c049c2..8b1af3dc7 100644 --- a/src/JSystem/JParticle/JPAMath.cpp +++ b/src/JSystem/JParticle/JPAMath.cpp @@ -416,24 +416,28 @@ void JPASetRMtxSTVecfromMtx(const Mtx p1, Mtx p2, JGeometry::TVec3f* vec1, JGeom * @note Address: 0x80093F60 * @note Size: 0xC8 */ -f32 JPACalcKeyAnmValue(f32 p1, u16 p2, const f32* p3) +f32 JPACalcKeyAnmValue(f32 currentFrame, u16 keyFrameCount, const f32* keyFrameData) { - if (p1 < p3[0]) { - return p3[1]; + if (currentFrame < keyFrameData[0]) { + return keyFrameData[1]; } - int ind = p2 - 1; - if (p3[ind * 4] <= p1) { - return p3[ind * 4 + 1]; + + int lastKeyFrameIndex = keyFrameCount - 1; + if (keyFrameData[lastKeyFrameIndex * 4] <= currentFrame) { + return keyFrameData[lastKeyFrameIndex * 4 + 1]; } - int x = p2; - while (x > 1) { - u32 uVar3 = x / 2; - if (p1 >= p3[uVar3 * 4]) { - p3 += uVar3 * 4; - x -= uVar3; + + int currentFrame = keyFrameCount; + while (currentFrame > 1) { + u32 halfIndex = currentFrame / 2; + if (currentFrame >= keyFrameData[halfIndex * 4]) { + keyFrameData += halfIndex * 4; + currentFrame -= halfIndex; } else { - x = uVar3; + currentFrame = halfIndex; } } - return JMAHermiteInterpolation(p1, p3[0], p3[1], p3[3], p3[4], p3[5], p3[6]); + + return JMAHermiteInterpolation(currentFrame, keyFrameData[0], keyFrameData[1], keyFrameData[3], keyFrameData[4], keyFrameData[5], + keyFrameData[6]); } diff --git a/src/JSystem/JParticle/JPAResource.cpp b/src/JSystem/JParticle/JPAResource.cpp index 3a81294cf..f985e07f2 100644 --- a/src/JSystem/JParticle/JPAResource.cpp +++ b/src/JSystem/JParticle/JPAResource.cpp @@ -1872,7 +1872,7 @@ bool JPAResource::calc(JPAEmitterWorkData* data, JPABaseEmitter* emitter) } } - emitter->mTick++; + emitter->mCurrentFrame++; return false; /* stwu r1, -0x20(r1) @@ -2345,10 +2345,10 @@ void JPAResource::drawP(JPAEmitterWorkData* data) if (flag != 4 && flag != 8) { test = false; } - data->mDLType = test; - data->mPlaneType = ((u32)data->mDLType) ? 2 : mBaseShape->mData->mFlags >> 10 & 1; - data->mPrjType = ((u32)data->mDLType) ? 0 : (u32)data->mDLType >> 0x18 & 1 + 1; - data->mpAlivePtcl = data->mEmitter->mAlivePtclChld.getFirst(); + data->mDLType = test; + data->mPlaneType = ((u32)data->mDLType) ? 2 : mBaseShape->mData->mFlags >> 10 & 1; + data->mProjectionType = ((u32)data->mDLType) ? 0 : (u32)data->mDLType >> 0x18 & 1 + 1; + data->mpAlivePtcl = data->mEmitter->mAlivePtclChld.getFirst(); setPTev(); for (int i = mDrawEmitterFuncListNum - 1; 0 <= i; i--) { @@ -2670,10 +2670,10 @@ void JPAResource::drawC(JPAEmitterWorkData* data) if (flag != 4 && flag != 8) { test = false; } - data->mDLType = test; - data->mPlaneType = ((u32)data->mDLType) ? 2 : mChildShape->mData->mFlags >> 10 & 1; - data->mPrjType = 0; - data->mpAlivePtcl = data->mEmitter->mAlivePtclChld.getFirst(); + data->mDLType = test; + data->mPlaneType = ((u32)data->mDLType) ? 2 : mChildShape->mData->mFlags >> 10 & 1; + data->mProjectionType = 0; + data->mpAlivePtcl = data->mEmitter->mAlivePtclChld.getFirst(); setCTev(data); for (int i = mDrawEmitterChildFuncListNum - 1; 0 <= i; i--) { @@ -3127,7 +3127,7 @@ void JPAResource::calcField(JPAEmitterWorkData* workData, JPABaseParticle* parti void JPAResource::calcKey(JPAEmitterWorkData* data) { for (int i = mKeyBlockNum - 1; i >= 0; i--) { - f32 calc = mKeyBlocks[i]->calc(data->mEmitter->mTick); + f32 calc = mKeyBlocks[i]->calc(data->mEmitter->mCurrentFrame); switch (mKeyBlocks[i]->mDataStart->mFlag) { case 0: diff --git a/src/JSystem/JParticle/JPAResourceLoader.cpp b/src/JSystem/JParticle/JPAResourceLoader.cpp index 35c58a759..bc9655187 100644 --- a/src/JSystem/JParticle/JPAResourceLoader.cpp +++ b/src/JSystem/JParticle/JPAResourceLoader.cpp @@ -99,6 +99,7 @@ void JPAResourceLoader::load_jpc(const u8* p1, JPAResourceManager* manager) resource->init(heap); manager->registRes(resource); } + int texDataOffset = GetTypeFromByteStream(p1, int, 0xC); for (int texDataLength, i = 0; i < GetTypeFromByteStream(p1, u16, 0xA); i++, texDataOffset += texDataLength) { const u8* texData = p1 + texDataOffset;