diff --git a/include/JSystem/J3D/J3DGraphAnimator/J3DNode.hpp b/include/JSystem/J3D/J3DGraphAnimator/J3DNode.hpp index a10873d1..001767b1 100644 --- a/include/JSystem/J3D/J3DGraphAnimator/J3DNode.hpp +++ b/include/JSystem/J3D/J3DGraphAnimator/J3DNode.hpp @@ -25,6 +25,7 @@ class J3DNode { J3DNode* getYounger() { return mYounger; } void setYounger(J3DNode* pYounger) { mYounger = pYounger; } void setCallBack(J3DNodeCallBack callback) { mCallBack = callback; } + void setCallBackUserData(void* data) { mCallBackUserData = data; } J3DNodeCallBack getCallBack() { return mCallBack; } J3DNode* getChild() { return mChild; } diff --git a/include/MarioUtil/MtxUtil.hpp b/include/MarioUtil/MtxUtil.hpp index 135b74e8..55cbf7bd 100644 --- a/include/MarioUtil/MtxUtil.hpp +++ b/include/MarioUtil/MtxUtil.hpp @@ -66,7 +66,7 @@ class TMtxTimeLag : public TMtxEffectBase { /* 0x40 */ TDeParams mParams; }; -void TMtxTimeLagCallBack(J3DNode*, int); +int TMtxTimeLagCallBack(J3DNode*, int); class TMtxSwingRZ : public TMtxEffectBase { public: @@ -105,7 +105,7 @@ class TMtxSwingRZ : public TMtxEffectBase { /* 0x20 */ TDeParams mParams; }; -void TMtxSwingRZCallBack(J3DNode*, int); +int TMtxSwingRZCallBack(J3DNode*, int); class TMtxSwingRZReverseXZ : public TMtxSwingRZ { public: @@ -113,19 +113,37 @@ class TMtxSwingRZReverseXZ : public TMtxSwingRZ { : TMtxSwingRZ(prm) { } - void calc(MtxPtr); }; -void TMtxSwingRZReverseXZCallBack(J3DNode*, int); +int TMtxSwingRZReverseXZCallBack(J3DNode*, int); class TMultiMtxEffect { public: void setup(J3DModel*, const char*); void setUserArea(); + + // Unused void add(); + + // Unused void remove(); + // Fabricated + void flagOn() + { + for (int i = 0; i < mNumBones; ++i) { + mMtxEffectTbl[i]->mFlags |= 1; + } + } + // Fabricated + void flagOff() + { + for (int i = 0; i < mNumBones; ++i) { + mMtxEffectTbl[i]->mFlags &= ~1; + } + } + /* 0x00 */ u16 mNumBones; // number of bones to be manipulated /* 0x04 */ u8* mMtxEffectType; // array of TMtxEffectBase types /* 0x08 */ u16* mBoneIDs; // array of bone IDs to be manipulated diff --git a/include/Player/MarioCap.hpp b/include/Player/MarioCap.hpp index 419a7bde..a28b251f 100644 --- a/include/Player/MarioCap.hpp +++ b/include/Player/MarioCap.hpp @@ -2,9 +2,19 @@ #define MARIOCAP_HPP #include +#include +#include +#include class TMarioCap { public: + enum E_CAP_MODEL { + E_CAP_MODEL_NOTHING = 0, + E_CAP_MODEL_HAT = 1, + E_CAP_MODEL_HELMET = 2, + E_CAP_MODEL_SUNGLASSES = 4, + }; + TMarioCap(TMario*); virtual void perform(unsigned long, JDrama::TGraphics*); @@ -16,12 +26,42 @@ class TMarioCap { // Unused void addDirty(); + // Fabricated + bool isModelActive(u16 type) { return unk4 & type ? true : false; } + + // Fabricated + void setModelActive(u16 type) { unk4 |= type; } + + // Fabricated + void setModelInactive(u16 type) { unk4 &= ~type; } + + // Fabricated + void onFlagAllShapes(J3DModelData* modelData) + { + for (u16 i = 0; i < modelData->getShapeNum(); ++i) { + modelData->getShapeNodePointer(i)->onFlag(1); + } + } + + // Fabricated + void offFlagAllShapes(J3DModelData* modelData) + { + for (u16 i = 0; i < modelData->getShapeNum(); ++i) { + modelData->getShapeNodePointer(i)->offFlag(1); + } + } + public: - /* 0x4 */ u16 unk4; // Flag for which hat is active + /* 0x4 */ u16 unk4; // E_CAP_MODEL flag /* 0x6 */ u16 unk6; - /* 0x8 */ u32 unk8; - /* 0xC */ u32 unkC; - /* 0x10 */ u32 unk10[0x28]; + /* 0x8 */ TMario* mMario; + /* 0xC */ J3DModel* unkC; // current model? + /* 0x10 */ J3DModel* unk10[4]; // ma_cap1.bmd model + /* 0x20 */ TMultiMtxEffect* unk20; + /* 0x24 */ TMultiMtxEffect* unk24; + /* 0x28 */ TMirrorActor* unk28[2]; + /* 0x30 */ TTrembleModelEffect* unk30; + /* 0x34 */ f32 unk34; }; #endif diff --git a/include/Player/MarioMain.hpp b/include/Player/MarioMain.hpp index 02a33c97..a8ebadde 100644 --- a/include/Player/MarioMain.hpp +++ b/include/Player/MarioMain.hpp @@ -1205,7 +1205,14 @@ class TMario : public TTakeActor, public TDrawSyncCallback { /* 0x122 */ u16 unk122; - /* 0x124 */ char unk124[0x2BC - 0x124]; + /* 0x124 */ u32 unk124; + /* 0x128 */ u32 unk128; + /* 0x12C */ u32 unk12C; + /* 0x130 */ u32 unk130; + /* 0x134 */ f32 unk134; + /* 0x138 */ char unk138[0x29C - 0x138]; + /* 0x29C */ JGeometry::TVec3 unk29C; + /* 0x2A8 */ char unk2A8[0x2BC - 0x2A8]; /* 0x2BC */ f32 unk2BC; /* 0x2C0 */ char unk2C0[0x37C - 0x2C0]; /* 0x37C */ u16 unk37C; diff --git a/src/MarioUtil/MtxUtil.cpp b/src/MarioUtil/MtxUtil.cpp index 8b137891..a853325e 100644 --- a/src/MarioUtil/MtxUtil.cpp +++ b/src/MarioUtil/MtxUtil.cpp @@ -1 +1,61 @@ +#include +#include +#include +#include + +void TMultiMtxEffect::setup(J3DModel* model, const char* prmLocation) +{ + mModel = model; + mMtxEffectTbl = new TMtxEffectBase*[mNumBones << 2]; + + for (u16 i = 0; i < mNumBones; ++i) { + char* path = new char[0x40]; + snprintf(path, 0x40, "/%s/MtxEffect%d.prm", prmLocation, mBoneIDs[i]); + + switch (mMtxEffectType[i]) { + case TMTX_EFFECT_TIME_LAG: + TMtxTimeLag* timeLag = new TMtxTimeLag(path); + model->getModelData() + ->getJointNodePointer(mBoneIDs[i]) + ->setCallBack(TMtxTimeLagCallBack); + model->getModelData() + ->getJointNodePointer(mBoneIDs[i]) + ->setCallBackUserData(timeLag); + mMtxEffectTbl[i] = timeLag; + break; + case TMTX_EFFECT_SWING_RZ: + TMtxSwingRZ* swingRz = new TMtxSwingRZ(path); + model->getModelData() + ->getJointNodePointer(mBoneIDs[i]) + ->setCallBack(TMtxSwingRZCallBack); + model->getModelData() + ->getJointNodePointer(mBoneIDs[i]) + ->setCallBackUserData(swingRz); + mMtxEffectTbl[i] = swingRz; + break; + case TMTX_EFFECT_SWING_RZ_REVERSE_XZ: + TMtxSwingRZ* swingRzReverse = new TMtxSwingRZ(path); + model->getModelData() + ->getJointNodePointer(mBoneIDs[i]) + ->setCallBack(TMtxSwingRZReverseXZCallBack); + model->getModelData() + ->getJointNodePointer(mBoneIDs[i]) + ->setCallBackUserData(swingRzReverse); + mMtxEffectTbl[i] = swingRzReverse; + break; + } + } + for (u16 i = 0; i < mNumBones; ++i) { + mMtxEffectTbl[i]->mFlags |= 2; + } +} + +void TMultiMtxEffect::setUserArea() +{ + for (u16 i = 0; i < mNumBones; i++) { + mModel->getModelData() + ->getJointNodePointer(mBoneIDs[i]) + ->setCallBackUserData(mMtxEffectTbl[i]); + } +} diff --git a/src/Player/MarioAutodemo.cpp b/src/Player/MarioAutodemo.cpp index 2c939c65..2ca791ad 100644 --- a/src/Player/MarioAutodemo.cpp +++ b/src/Player/MarioAutodemo.cpp @@ -97,7 +97,7 @@ BOOL TMario::jumpingDemoCommon(u32 playerStatus, int animationId, f32 velocity) BOOL TMario::warpIn() { // Missing stack space - volatile u32 padding[10]; + // volatile u32 padding[10]; mActionTimer += 1; const JGeometry::TVec3& gatePosOffset = ((TModelGate*)mHolder)->unkAC; JGeometry::TVec3 holderPosOffset(((TModelGate*)mHolder)->unkAC); diff --git a/src/Player/MarioCap.cpp b/src/Player/MarioCap.cpp index 4fcafa8e..328dd16a 100644 --- a/src/Player/MarioCap.cpp +++ b/src/Player/MarioCap.cpp @@ -1,8 +1,239 @@ #include +#include +#include +#include +#include +#include +#include + +const char cDirtyFileName[] = "/scene/map/pollution/H_ma_rak.bti"; +const char cDirtyTexName[] = "H_ma_rak_dummy"; + +TMarioCap::TMarioCap(TMario* mario) +{ + // Unused stack space + // volatile u32 padding[51]; + mMario = mario; + + J3DModelData* maCap1ModelData = J3DModelLoaderDataBase::load( + JKRFileLoader::getGlbResource("/mario/bmd/ma_cap1.bmd"), 0x10100000); + // Might be an inlined function? + maCap1ModelData->getTexture()->setResTIMG( + 0, *mMario->mModel->unk8->getModelData()->getTexture()->getResTIMG(0)); + DCFlushRange(maCap1ModelData->getTexture()->mResources, 0x20); + unk10[0] = new J3DModel(maCap1ModelData, 0, 1); + + J3DModelData* maCap3ModelData = J3DModelLoaderDataBase::load( + JKRFileLoader::getGlbResource("/mario/bmd/ma_cap3.bmd"), 0x10100000); + // I could see this being an inlined + maCap3ModelData->getTexture()->setResTIMG( + 0, *mMario->mModel->unk8->getModelData()->getTexture()->getResTIMG(0)); + DCFlushRange(maCap3ModelData->getTexture()->mResources, 0x20); + unk10[1] = new J3DModel(maCap3ModelData, 0, 1); + + if (mMario->mBodyPollutionTex != 0) { + for (int i = 0; i < 2; ++i) { + SMS_ChangeTextureAll(unk10[i]->getModelData(), cDirtyTexName, + *mMario->mBodyPollutionTex); + SMS_MakeDLAndLock(unk10[i]); + } + } + + J3DModelData* diverHelmModelData = J3DModelLoaderDataBase::load( + JKRFileLoader::getGlbResource("/mario/bmd/diver_helm.bmd"), 0x10100000); + unk10[2] = new J3DModel(diverHelmModelData, 0, 1); + + J3DModelData* maGlass1 = J3DModelLoaderDataBase::load( + JKRFileLoader::getGlbResource("/mario/bmd/ma_glass1.bmd"), 0x10100000); + unk10[3] = new J3DModel(maGlass1, 0, 1); + + // Mmmh, nintendo plz? I hope this is forgotten and not a check to crash the + // game if it is missing this bone + unk10[2]->getModelData()->unkB0->getIndex("null_airtube"); + MtxPtr mtx = mMario->mModel->unk8->getAnmMtx(mMario->mBoneIDs[11]); + + unk10[0]->setAnmMtx(0, mtx); + unk10[0]->calc(); + unk10[1]->setAnmMtx(0, mtx); + unk10[1]->calc(); + mMario->mModel->unk8->setAnmMtx(mMario->mBoneIDs[10], + unk10[2]->getBaseTRMtx()); + unk10[2]->calc(); + + unk20 = new TMultiMtxEffect(); + unk24 = new TMultiMtxEffect(); + + // This feels very wrong + // Probably some inline constructor? + unk20->mNumBones = 1; + u16* unk20unk8Ptr = new u16[1]; + unk20unk8Ptr[0] = 1; + unk20->mBoneIDs = unk20unk8Ptr; + u8* unk20unk4Ptr = new u8[1]; + unk20unk4Ptr[0] = TMTX_EFFECT_TIME_LAG; + unk20->mMtxEffectType = unk20unk4Ptr; + unk20->setup(unk10[0], "Mario/MarioCap"); + + unk24->mNumBones = 1; + u16* unk24unk8Ptr = new u16[1]; + unk24unk8Ptr[0] = 1; + unk24->mBoneIDs = unk24unk8Ptr; + u8* unk24unk4Ptr = new u8[1]; + unk24unk4Ptr[0] = TMTX_EFFECT_TIME_LAG; + unk24->mMtxEffectType = unk24unk4Ptr; + unk24->setup(unk10[1], "Mario/MarioCap"); + + setModelActive(E_CAP_MODEL_HAT); + unkC = unk10[0]; + + // TMultiMtxEffect stuff + unk30 = new TTrembleModelEffect(); + unk30->init(unk10[0]); + unk34 = 4.0f; + + for (int idx = 0; idx < 2; idx++) { + for (int matIdx = 0; + matIdx < unk10[idx]->getModelData()->getMaterialNum(); matIdx++) { + SMS_InitPacket_OneTevKColorAndFog(unk10[idx], matIdx, GX_KCOLOR0, + nullptr); + } + } +} + +void TMarioCap::createMirrorCap() +{ + for (int i = 0; i < 2; ++i) { + unk28[i] = new TMirrorActor("マリオ帽子in鏡"); + unk28[i]->init(unk10[i], 4); + } +} + +void TMarioCap::perform(unsigned long param_1, JDrama::TGraphics* param_2) +{ + // Unused stack space + // volatile u32 padding[42]; + + if ((param_1 & 2) != 0) { + if (mMario->unk0FA == 0x12D) { + J3DFrameCtrl* frameCtrl = mMario->getMotionFrameCtrl(); + if (frameCtrl->getCurrentFrame() < 157.0f) { + unkC = unk10[1]; + onFlagAllShapes(unk10[0]->mModelData); + offFlagAllShapes(unk10[1]->mModelData); + } else { + unkC = unk10[0]; + offFlagAllShapes(unk10[0]->mModelData); + onFlagAllShapes(unk10[1]->mModelData); + } + } else if (isModelActive(E_CAP_MODEL_HAT)) { + unkC = unk10[0]; + offFlagAllShapes(unk10[0]->mModelData); + onFlagAllShapes(unk10[1]->mModelData); + + bool doTremble = false; + + // Missing a copy of TVec3, i still suspect that operations should + // do a copy + f32 distance = (mMario->mPosition - mMario->unk29C).length(); + if (mMario->mAction == 0x810446 && distance > 20.0f) { + doTremble = true; + } + if (mMario->mAction == 0x281089A) { + doTremble = true; + } + if (mMario->mAction == 0x81089B) { + doTremble = true; + } + + // Probably inline check + if (((mMario->mAction & 0x800) ? true : false) + && distance > 20.0f) { + doTremble = true; + } + if (mMario->mAction == 0x891) { + doTremble = false; + } + + if (doTremble == true) { + unk30->clash(unk34); + } else { + unk30->clash(0.0f); + } + } else { + + unkC = unk10[1]; + onFlagAllShapes(unk10[0]->mModelData); + offFlagAllShapes(unk10[1]->mModelData); + } + + if (mMario->checkFlag(MARIO_FLAG_HELMET_FLW_CAMERA)) { + setModelActive(E_CAP_MODEL_HELMET); + } + + if (isModelActive(E_CAP_MODEL_HELMET)) { + + J3DModelData* modelData = unk10[2]->mModelData; + for (u16 i = 0; i < modelData->getShapeNum(); ++i) { + modelData->getShapeNodePointer(i)->onFlag(1); + } + } else { + J3DModelData* modelData = unk10[2]->mModelData; + for (u16 i = 0; i < modelData->getShapeNum(); ++i) { + modelData->getShapeNodePointer(i)->offFlag(1); + } + } + + if (isModelActive(E_CAP_MODEL_SUNGLASSES)) { + unk10[3]->update(); + } + unkC->update(); + unk10[2]->update(); + + for (u16 i = 0; i < unkC->getModelData()->getMaterialNum(); i++) { + J3DGXColor* color + = unkC->getModelData()->getMaterialNodePointer(i)->getTevKColor( + 0); + + color->color.a = mMario->unk134; + } + } + + if ((param_1 & 4) != 0) { + unkC->viewCalc(); + // Likely inline + if (isModelActive(E_CAP_MODEL_HELMET)) { + unk10[2]->viewCalc(); + } + if (isModelActive(E_CAP_MODEL_SUNGLASSES)) { + unk10[3]->viewCalc(); + } + } + + if ((param_1 & 0x200) != 0) { + unkC->entry(); + if (isModelActive(2)) { + unk10[2]->entry(); + } + if (isModelActive(4)) { + unk10[3]->entry(); + } + } + + if ((param_1 & 0x10000000) != 0 && isModelActive(E_CAP_MODEL_HAT)) { + unk30->movement(); + } +} + +void TMarioCap::mtxEffectHide() +{ + unk20->flagOff(); + unk24->flagOff(); +} + +void TMarioCap::mtxEffectShow() +{ + unk20->flagOn(); + unk24->flagOn(); +} -TMarioCap::TMarioCap(TMario*) { } -void TMarioCap::createMirrorCap() { } -void TMarioCap::perform(unsigned long, JDrama::TGraphics*) { } -void TMarioCap::mtxEffectHide() { } -void TMarioCap::mtxEffectShow() { } void TMarioCap::addDirty() { }