Cleanup J2D and JPA

This commit is contained in:
intns 2024-05-02 18:17:32 +01:00
parent 195fc21155
commit abbeaa4a02
12 changed files with 510 additions and 369 deletions

View File

@ -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
};

View File

@ -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

View File

@ -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
};

View File

@ -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<f32>(p1, &xInf->mScaleInfo, &mScaleVals[xInf->mScaleInfo.mOffset]);
transformInfo->mScale.x = J2DGetKeyFrameInterpolation<f32>(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<f32>(p1, &yInf->mScaleInfo, &mScaleVals[yInf->mScaleInfo.mOffset]);
transformInfo->mScale.y = J2DGetKeyFrameInterpolation<f32>(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<f32>(p1, &zInf->mScaleInfo, &mScaleVals[zInf->mScaleInfo.mOffset]);
transformInfo->mScale.z = J2DGetKeyFrameInterpolation<f32>(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<s32>(J2DGetKeyFrameInterpolation<s16>(p1, &xInf->mRotationInfo, &mRotationVals[xInf->mRotationInfo.mOffset]))
<< _24;
= static_cast<s32>(J2DGetKeyFrameInterpolation<s16>(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<s32>(J2DGetKeyFrameInterpolation<s16>(p1, &yInf->mRotationInfo, &mRotationVals[yInf->mRotationInfo.mOffset]))
<< _24;
= static_cast<s32>(J2DGetKeyFrameInterpolation<s16>(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<s32>(J2DGetKeyFrameInterpolation<s16>(p1, &zInf->mRotationInfo, &mRotationVals[zInf->mRotationInfo.mOffset]))
<< _24;
= static_cast<s32>(J2DGetKeyFrameInterpolation<s16>(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<f32>(p1, &xInf->mTranslationInfo, &mTranslationVals[xInf->mTranslationInfo.mOffset]);
= J2DGetKeyFrameInterpolation<f32>(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<f32>(p1, &yInf->mTranslationInfo, &mTranslationVals[yInf->mTranslationInfo.mOffset]);
= J2DGetKeyFrameInterpolation<f32>(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<f32>(p1, &zInf->mTranslationInfo, &mTranslationVals[zInf->mTranslationInfo.mOffset]);
= J2DGetKeyFrameInterpolation<f32>(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<f32>(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<f32>(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<s32>(J2DGetKeyFrameInterpolation<s16>(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<f32>(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 <class T>
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<T>(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<T>(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<T>(p1, &values[0], &values[1], &values[3], &values[4], &values[5], &values[6]);
frameCount = halfFrameCount;
}
}
}
return J2DHermiteInterpolation<T>(currentFrame, &keyValues[0], &keyValues[1], &keyValues[3], &keyValues[4], &keyValues[5],
&keyValues[6]);
}

View File

@ -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<J3DAnmTransformKeyTable>(data, (void*)data->mTableOffset);
anm->mScaleVals = JSUConvertOffsetToPtr<f32>(data, (void*)data->mScaleOffset);

View File

@ -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<f32> local_6c;
JGeometry::TVec3<f32> 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<f32> direction;
JGeometry::TVec3<f32> 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<f32> local_70;
p_direction[work->mDirType](work, particle, &local_70);
JGeometry::TVec3<f32> 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<f32> local_88;
PSMTXMultVec(work->mPosCamMtx, (Vec*)&particle->mPosition, (Vec*)&local_88);
JGeometry::TVec3<f32> direction;
p_direction[work->mDirType](work, particle, &direction);
JGeometry::TVec3<f32> 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<f32> 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);

View File

@ -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);
}

View File

@ -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;

View File

@ -7,7 +7,7 @@
*/
JPAKeyBlock::JPAKeyBlock(const u8* data)
: mDataStart(reinterpret_cast<const JPAKeyBlockData*>(data))
, _04(reinterpret_cast<const f32*>(&data[0xC]))
, mKeyFrameData(reinterpret_cast<const f32*>(&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);
}

View File

@ -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]);
}

View File

@ -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:

View File

@ -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;