diff --git a/include/d/d_cs_game.h b/include/d/d_cs_game.h index 4050fddf..1cc48960 100644 --- a/include/d/d_cs_game.h +++ b/include/d/d_cs_game.h @@ -126,9 +126,14 @@ public: virtual int create() override; virtual int doDelete() override; + static dCsGame_c *GetInstance() { + return sInstance; + } + void setSomething(int); - static dCsGame_c *sInstance; + bool fn_801BF5E0() const; + bool fn_801BF630() const; /// @brief Item cursor. class lytItemCursor_c { @@ -168,6 +173,7 @@ public: /* 0x4C */ d2d::LytBase_c *mpLyt; /* 0x50 */ f32 field_0x50; /* 0x54 */ f32 field_0x54; + /* 0x58 */ u8 field_0x58[0x68 - 0x58]; // idk }; /// @brief Dowsing cursor. @@ -197,6 +203,7 @@ public: /* 0xB8 */ f32 field_0xB8; /* 0xBC */ f32 field_0xBC; /* 0xC0 */ f32 field_0xC0; + /* 0xC4 */ u8 field_0xC4[0xD8 - 0xC4]; }; /// @brief Slingshot cursor. @@ -254,6 +261,7 @@ public: /* 0x04 */ UI_STATE_MGR_DECLARE(lytCrawShotCsr_c); /* 0x40 */ d2d::AnmGroups mAnm; /* 0x4C */ d2d::LytBase_c *mpLyt; + /* 0x50 */ u8 field_0x50[0x6C - 0x50]; }; /// @brief Gust Bellows cursor. @@ -277,6 +285,7 @@ public: /* 0x04 */ UI_STATE_MGR_DECLARE(lytVacuumCsr_c); /* 0x40 */ d2d::AnmGroups mAnm; /* 0x4C */ d2d::LytBase_c *mpLyt; + /* 0x50 */ u8 field_0x50[0x5C - 0x50]; /* 0x5C */ u8 field_0x5C; }; @@ -301,12 +310,15 @@ public: mpResAcc = resAcc; } + bool isCursorActive() const { + return mCursorActive; + } void setField0x9A0(u8 val) { - field_0x9A0 = val; + mCursorActive = val; } void setNextCursorType(CursorType_e cs) { - field_0x9A8 = 1; + mNextCursor = 1; mNextCursorType = cs; } @@ -327,6 +339,7 @@ public: /* 0x048 */ EffectsStruct mEffects; /* 0x07C */ EffectRelated mEffectRelated; + /* 0x080 */ u8 field_0x80[0xC8 - 0x80]; /* 0x0C8 */ m2d::ResAccIf_c *mpResAcc; /* 0x0CC */ d2d::LytBase_c mLyt; /* 0x15C */ dCsGameAnmGroups_c mAnmGroups; @@ -334,17 +347,23 @@ public: /* 0x72C */ lytBowCsr_c mBow; /* 0x794 */ lytDowsingCsr_c mDowsing; /* 0x86C */ lytPachinkoCsr_c mPachinko; - /* 0x8C0 */ lytCrawShotCsr_c mCrawShot; + /* 0x8C8 */ lytCrawShotCsr_c mCrawShot; /* 0x934 */ lytVacuumCsr_c mVacuum; - /* 0x990 */ u8 field_0x990; - /* 0x99C */ u8 field_0x99C; - /* 0x9A0 */ u8 field_0x9A0; - /* 0x9A8 */ u8 field_0x9A8; + /* 0x994 */ u8 field_0x994[0x99C - 0x994]; // seemingly not used + /* 0x99C */ bool mCursorTrail; + /* 0x99D */ u8 field_0x99D[0x9A0 - 0x99D]; // Havent seen this range be set + /* 0x9A0 */ bool mCursorActive; + /* 0x9A1 */ bool field_0x9A1; // Compares to mCursorActive to change state + /* 0x9A2 */ bool field_0x9A2; // A way of signalling Lyt non-normal state. + /* 0x9A4 */ CursorType_e mActiveCursorType; + /* 0x9A8 */ bool mNextCursor; /* 0x9AC */ CursorType_e mNextCursorType; }; void setNextCursorType(lytItemCursor_c::CursorType_e); + static dCsGame_c *sInstance; + /* 0x068 */ m2d::ResAccIf_c mCursorResAcc; /* 0x11C */ m2d::ResAccIf_c mMain2DResAcc; /* 0x1D0 */ dCursorInterfaceGame_c mCursorIf; diff --git a/include/d/d_pad.h b/include/d/d_pad.h index 29e10e48..f53a81c9 100644 --- a/include/d/d_pad.h +++ b/include/d/d_pad.h @@ -30,6 +30,7 @@ class ex_c { }; public: + void fn_80056790(s32 chan); void fn_80056AF0(s32 chan); void fn_80056B90(s32 chan); void fn_80056CE0(s32 chan); @@ -39,7 +40,7 @@ public: void fn_80056E60(s32 chan); // Deals with Mpls Calibration Stop void resetState(s32 chan); - void fn_800572A0(); + void fn_800572A0(s32 chan); static bool isLowBattery(); static bool isOutOfBattery(); @@ -62,6 +63,8 @@ public: void getUnifiedWpadStatus(s32 chan); void fn_800593D0(); + void updateStatus(s32 chan); + static ex_c *getInstance() { return m_current_ex; } @@ -85,10 +88,7 @@ public: /* 0x0045 */ bool field_0x45; /* 0x0046 */ bool field_0x46; /* 0x0047 */ bool field_0x47; - /* 0x0048 */ bool field_0x48; - /* 0x0049 */ bool field_0x49; - /* 0x004A */ bool field_0x4A; - /* 0x004B */ bool field_0x4B; + /* 0x0048 */ s32 field_0x48; /* 0x004C */ bool mSpeakerSetup; /* 0x004D */ bool mSpeakerShutdown; /* 0x004E */ bool mIncorrectDeviceType; @@ -108,16 +108,17 @@ public: /* 0x008C */ mVec3_c field_0x8C; /* 0x0098 */ motion_c mMotion; /* 0x1174 */ motion_c mFSMotion; - /* 0x2250 */ u8 _0x2250[0x2268 - 0x2250]; - /* 0x2268 */ mVec3_c field_0x2268; - /* 0x2274 */ mVec3_c field_0x2274; + /* 0x2250 */ mVec3_c mMPLSSpeed; + /* 0x225C */ mVec3_c mMPLSBasisX; + /* 0x2268 */ mVec3_c mMPLSBasisY; + /* 0x2274 */ mVec3_c mMPLSBasisZ; /* 0x2280 */ s32 mState; /* 0x2284 */ s32 field_0x2284; /* 0x2288 */ s32 field_0x2288; /* 0x228C */ KPADUnifiedWpadStatus mStatus; - /* 0x22C0 */ u8 _0x22C0[0x22CE - 0x22C4]; + /* 0x22C4 */ u8 _0x22C4[0x22CE - 0x22C4]; /* 0x22CE */ bool field_0x22CE; - /* 0x22CF */ u8 _0x22CF[0x22D0 - 0x22CF]; + /* 0x22CF */ bool field_0x22CF; /* 0x22D0 */ u8 field_0x22D0; /* 0x22D1 */ u8 field_0x22D1; /* 0x22D4 */ s32 field_0x22D4; diff --git a/include/d/d_pause.h b/include/d/d_pause.h new file mode 100644 index 00000000..a42c5a87 --- /dev/null +++ b/include/d/d_pause.h @@ -0,0 +1,23 @@ +#ifndef D_PAUSE_H +#define D_PAUSE_H + +#include "common.h" + +// reference to NSMBW PauseManage_c (im adding back the d) +class dPauseManager_c { +public: + static dPauseManager_c *GetInstance() { + return sInstance; + } + bool getField_0x25() const { + return field_0x25; + } + +private: + /* 0x00 */ u8 _00[0x25 - 0x00]; + /* 0x25 */ bool field_0x25; + + static dPauseManager_c *sInstance; +}; + +#endif diff --git a/include/egg/core/eggController.h b/include/egg/core/eggController.h index c0dd6715..16d7e8bd 100644 --- a/include/egg/core/eggController.h +++ b/include/egg/core/eggController.h @@ -23,6 +23,7 @@ enum eCoreDevType { cDEV_FREESTYLE = WPAD_DEV_FREESTYLE, cDEV_CLASSIC = WPAD_DEV_CLASSIC, + cDEV_MPLS = WPAD_DEV_MOTION_PLUS, cDEV_MPLS_PT_FS = WPAD_DEV_MPLS_PT_FS, cDEV_FUTURE = WPAD_DEV_FUTURE, diff --git a/include/egg/math/eggVector.h b/include/egg/math/eggVector.h index 34ccb324..d6ce59aa 100644 --- a/include/egg/math/eggVector.h +++ b/include/egg/math/eggVector.h @@ -122,7 +122,7 @@ struct Vector3f : public nw4r::math::VEC3 { return Vector3f(-x, -y, -z); } - void set(const EGG::Vector3f& other) { + void set(const EGG::Vector3f &other) { x = other.x; y = other.y; z = other.z; @@ -132,7 +132,9 @@ struct Vector3f : public nw4r::math::VEC3 { return squaredLength() <= Math::epsilon(); } - void setZero() { x = y = z = 0.0f; }; + void setZero() { + x = y = z = 0.0f; + }; f32 normalise(); @@ -169,6 +171,9 @@ public: Vector2f operator-(const Vector2f &v) { return Vector2f(x - v.x, y - v.y); } + f32 length() const { + return Math::sqrt(squaredLength()); + } f32 squaredLength() const { return (x * x + y * y); } diff --git a/include/egg/prim/eggBuffer.h b/include/egg/prim/eggBuffer.h index 9158bf28..49be7862 100644 --- a/include/egg/prim/eggBuffer.h +++ b/include/egg/prim/eggBuffer.h @@ -3,6 +3,7 @@ #include "common.h" #include "egg/core/eggHeap.h" +#include "egg/prim/eggAssert.h" namespace EGG { @@ -95,11 +96,13 @@ private: void checkRange(int i) const { if (!isRangeValid(i)) { errRangeOver(); +#line 174 + EGG_ASSERT_MSG(false, "TBuffer::checkRange %d (0<=x<%d)\n", i, mSize); } } bool isRangeValid(int i) const { - return i >= 0 && i < mSize; + return 0 <= i && i < mSize; } private: diff --git a/include/m/m_pad.h b/include/m/m_pad.h index a692edcd..07f172cb 100644 --- a/include/m/m_pad.h +++ b/include/m/m_pad.h @@ -41,12 +41,20 @@ inline int getCurrentCoreID() { return g_currentCoreId; } +inline bool isMpls(const int i) { + return g_padMg->getDevType(i) == EGG::cDEV_MPLS; +} +inline bool isMplsPtFS(const int i) { + return g_padMg->getDevType(i) == EGG::cDEV_MPLS_PT_FS; +} + // Defined in dPad, referenced in both mPad and dPad extern "C" void async_info_callback(s32 chan, s32 result); void create(); void beginPad(); void endPad(); + }; // namespace mPad #endif diff --git a/include/m/m_vec.h b/include/m/m_vec.h index 24339d74..9b04d150 100644 --- a/include/m/m_vec.h +++ b/include/m/m_vec.h @@ -239,7 +239,7 @@ public: void rotY(const mAng &angle); void rotZ(const mAng &angle); - void CopyTo(nw4r::math::VEC3 *p) const { + void CopyTo(Vec *p) const { p->x = x; p->y = y; p->z = z; @@ -280,13 +280,24 @@ public: mVec2_c() {} ~mVec2_c() {} + /// @brief Assignment operator + mVec2_c &operator=(const mVec2_c &r) { + set(r.x, r.y); + return *this; + } + mVec2_c(const mVec2_c &other) { set(other.x, other.y); } - + mVec2_c(const EGG::Vector2f &other) { + set(other.x, other.y); + } mVec2_c(f32 fx, f32 fy) { set(fx, fy); } + s16 ang() const { + return cM::atan2s(x, y); + } }; #endif diff --git a/include/rvl/KPAD/KPAD.h b/include/rvl/KPAD/KPAD.h index 7c916fff..6b069111 100644 --- a/include/rvl/KPAD/KPAD.h +++ b/include/rvl/KPAD/KPAD.h @@ -61,7 +61,12 @@ typedef struct KPADStatus { s8 dpd_valid_fg; // at 0x5E u8 data_format; // at 0x5F KPADEXStatus ex_status; // at 0x60 - u8 _0xB0[0xF0 - 0xB0]; // at 0xB0 + Vec mpls_rot; // at 0xB0 // made up + Vec field_0xBC; // at 0xBC // made up + Vec mpls_basis_x; // at 0xC8 // made up + Vec mpls_basis_y; // at 0xD4 // made up + Vec mpls_basis_z; // at 0xE0 // made up + UNKWORD field_0xEC; } KPADStatus; typedef struct KPADUnifiedWpadStatus { @@ -110,7 +115,9 @@ void KPADSetMplsZeroDriftMode(s32 chan, s32); void KPADEnableMplsDirRevise(s32 chan); void KPADDisableMplsDirRevise(s32 chan); void KPADSetMplsDirReviseParam(s32 chan, f32); + void KPADEnableMplsAccRevise(s32 chan); +void KPADDisableMplsAccRevise(s32 chan); void KPADSetMplsAccReviseParam(s32 chan, f32, f32); void KPADEnableMplsDpdRevise(s32 chan); diff --git a/src/d/d_cs_game.cpp b/src/d/d_cs_game.cpp index da22bbef..6725a09d 100644 --- a/src/d/d_cs_game.cpp +++ b/src/d/d_cs_game.cpp @@ -164,6 +164,10 @@ int dCsGame_c::doDelete() { return SUCCEEDED; } +bool dCsGame_c::fn_801BF5E0() const { + return mCursor.isCursorActive() & !fn_801BF630(); +} + void dCsGame_c::setNextCursorType(lytItemCursor_c::CursorType_e cs) { mCursor.setNextCursorType(cs); } @@ -177,7 +181,7 @@ void dCsGame_c::lytItemCursor_c::initializeState_Bow() { mBow.select(); } void dCsGame_c::lytItemCursor_c::executeState_Bow() { - field_0x990 = 1; + mCursorTrail = 1; mBow.execute(); } void dCsGame_c::lytItemCursor_c::finalizeState_Bow() {} @@ -194,14 +198,14 @@ void dCsGame_c::lytItemCursor_c::initializeState_Vacuum() { mVacuum.enter(); } void dCsGame_c::lytItemCursor_c::executeState_Vacuum() { - field_0x99C = 1; + mCursorTrail = 1; mVacuum.execute(); } void dCsGame_c::lytItemCursor_c::finalizeState_Vacuum() {} void dCsGame_c::lytItemCursor_c::initializeState_Pachinko() {} void dCsGame_c::lytItemCursor_c::executeState_Pachinko() { - field_0x99C = 1; + mCursorTrail = 1; mPachinko.execute(); } void dCsGame_c::lytItemCursor_c::finalizeState_Pachinko() {} @@ -210,7 +214,7 @@ void dCsGame_c::lytItemCursor_c::initializeState_HookShot() { mCrawShot.enter(); } void dCsGame_c::lytItemCursor_c::executeState_HookShot() { - field_0x99C = 1; + mCursorTrail = 1; mCrawShot.execute(); } void dCsGame_c::lytItemCursor_c::finalizeState_HookShot() {} diff --git a/src/d/d_pad.cpp b/src/d/d_pad.cpp index 5b90deef..7b822be2 100644 --- a/src/d/d_pad.cpp +++ b/src/d/d_pad.cpp @@ -2,7 +2,12 @@ #include "common.h" #include "d/a/d_a_player.h" +#include "d/d_cs_game.h" #include "d/d_gfx.h" +#include "d/d_pause.h" +#include "d/d_reset.h" +#include "d/lyt/d_lyt_control_game.h" +#include "d/lyt/meter/d_lyt_meter.h" #include "d/snd/d_snd_player_mgr.h" #include "egg/core/eggController.h" #include "egg/core/eggHeap.h" @@ -105,6 +110,7 @@ void centerPos(mVec2_c &in, mVec2_c &out) { out.y = dGfx_c::getCurrentScreenHeightF() * -0.5f * (1.f + in.y) + dGfx_c::getCurrentScreenTopF(); } +extern "C" void fn_801940C0(); void beginPad_BR() { mPad::beginPad(); @@ -114,14 +120,15 @@ void beginPad_BR() { WPADSetAcceptConnection(1); } - for (int i = 0; i < 4; ++i) { + // Forces only first controller to be active + for (int i = 1; i < 4; ++i) { if (mPad::getCore(i)->isConnected()) { WPADDisconnect(i); } } dPad::ex_c &ex = ex_c::m_ex[0]; - ex.fn_800572A0(); + ex.fn_800572A0(0); if (mPad::getCore(0)->isConnected()) { ex.getUnifiedWpadStatus(0); ex.fn_80059300(0); @@ -144,59 +151,122 @@ void beginPad_BR() { const dAcPy_c *player = dAcPy_c::GetLink(); if (player && player->isAttacking()) { mMtx_c m; - m.XrotS(mAng::deg2short(-30.f)); + mVec3_c baseX; + mVec3_c baseY; mVec3_c baseZ; KPADVec kpadvec; - baseZ.x = m.m[0][2]; - baseZ.y = m.m[1][2]; + m.XrotS(mAng::deg2short(-30.f)); baseZ.z = m.m[2][2]; - kpadvec[2].x = m.m[0][2]; - kpadvec[2].y = m.m[1][2]; - kpadvec[2].z = m.m[2][2]; - mVec3_c tmpCross; - VECCrossProduct(ex.field_0x2268, baseZ, tmpCross); + baseZ.y = m.m[1][2]; + baseZ.x = m.m[0][2]; + kpadvec[2].x = baseZ.x; + kpadvec[2].y = baseZ.y; + kpadvec[2].z = baseZ.z; - if (0.05f < VECMag(tmpCross)) { - tmpCross.normalize(); - kpadvec[0].x = tmpCross.x; - kpadvec[0].y = tmpCross.y; - kpadvec[0].z = tmpCross.z; + VECCrossProduct(ex_c::m_ex[0].mMPLSBasisY, baseZ, baseX); + if (VECMag(baseX) > 0.05f) { + baseX.normalize(); + kpadvec[0].z = baseX.z; + kpadvec[0].y = baseX.y; + kpadvec[0].x = baseX.x; } else { - kpadvec[0].x = baseZ.x; - kpadvec[0].y = baseZ.y; - kpadvec[0].z = baseZ.z; + baseX = baseZ; + kpadvec[0].z = baseX.z; + kpadvec[0].y = baseX.y; + kpadvec[0].x = baseX.x; } - tmpCross.x = kpadvec[0].x; - tmpCross.y = kpadvec[0].y; - tmpCross.z = kpadvec[0].z; - mVec3_c tmpCross2; - VECCrossProduct(baseZ, tmpCross, tmpCross2); - if (VECMag(tmpCross2) > 0.05f) { - tmpCross2.normalize(); - kpadvec[1].x = tmpCross2.x; - kpadvec[1].y = tmpCross2.y; - kpadvec[1].z = tmpCross2.z; + VECCrossProduct(baseZ, baseX, baseY); + if (VECMag(baseY) > 0.05f) { + baseY.normalize(); + kpadvec[1].z = baseY.z; + kpadvec[1].y = baseY.y; + kpadvec[1].x = baseY.x; } else { - kpadvec[1].x = baseZ.x; - kpadvec[1].y = baseZ.y; - kpadvec[1].z = baseZ.z; + baseY = baseZ; + kpadvec[1].z = baseY.z; + kpadvec[1].y = baseY.y; + kpadvec[1].x = baseY.x; } - tmpCross2.x = kpadvec[1].x; - tmpCross2.y = kpadvec[1].y; - tmpCross2.z = kpadvec[1].z; KPADSetMplsDirReviseBase(0, kpadvec); - KPADEnableMplsDpdRevise(0); + enableMplsDirRevise(0); } else { disableMplsDirRevise(0); } KPADEnableMplsAccRevise(0); KPADSetMplsAccReviseParam(0, 0.03f, 0.4f); + + if ((dCsGame_c::GetInstance() && dCsGame_c::GetInstance()->fn_801BF5E0() && !ex.field_0x22D0) || + ((dAcPy_c::GetLink() && + dAcPy_c::GetLink()->checkActionFlagsCont(0x400 | 0x100 | 0x80 | 0x40 | 0x10 | 0x4 | 0x2 | 0x1) && + !dAcPy_c::GetLink()->vt_0x1C0() && !dLytMeter_c::GetMain()->getField_0x1377F()) || + ex.field_0x22CF)) { + if (dLytControlGame_c::getInstance() && dLytControlGame_c::getInstance()->isStateNormal()) { + if (!(dPauseManager_c::GetInstance() && dPauseManager_c::GetInstance()->getField_0x25())) { + KPADDisableMplsDpdRevise(0); + KPADDisableMplsAccRevise(0); + } + } + KPADDisableMplsDirRevise(0); + } + if (ex.field_0x47 || ex.field_0x48 != 0) { + KPADEnableMplsAccRevise(0); + KPADSetMplsAccReviseParam(0, 1.f, 0.6f); + if (--ex.field_0x48 < 0) { + ex.field_0x48 = 0; + } + } + + ex.field_0x22CF = false; + ex.mFSStick.x = mPad::getCore(0)->getFreeStickX(); + ex.mFSStick.y = mPad::getCore(0)->getFreeStickY(); + ex.mFSStickDistance = ex.mFSStick.length(); + ex.mFSStickAngle = -ex.mFSStick.ang(); + + ex.fn_800593D0(); + + bool isMpls = mPad::isMpls(0) || mPad::isMplsPtFS(0); + if (isMpls) { + ex.mMPLSSpeed.copyFrom(&mPad::getCore(0)->getCoreStatus()->mpls_rot); + ex.mMPLSBasisX.copyFrom(&mPad::getCore(0)->getCoreStatus()->mpls_basis_x); + ex.mMPLSBasisY.copyFrom(&mPad::getCore(0)->getCoreStatus()->mpls_basis_y); + ex.mMPLSBasisZ.copyFrom(&mPad::getCore(0)->getCoreStatus()->mpls_basis_z); + } else { + ex.mMPLSSpeed.set(0.f, 0.f, 0.f); + ex.mMPLSBasisX = mVec3_c::Ex; + ex.mMPLSBasisY = mVec3_c::Ey; + ex.mMPLSBasisZ = mVec3_c::Ez; + } + + ex.fn_80056790(0); + + if (ex.field_0x50) { + ex.mDpdPos = ex.field_0x8; + } else { + if (mPad::getCore(0)->getDpdValidFlag() > 0) { + ex.mDpdPos = mPad::getCore(0)->getDpdRawPos(); + // ex.mDpdPos.set(v.x, v.y); + } else { + ex.mDpdPos.set(-2.f, -2.f); + } + } + centerPos(ex.mDpdPos, ex.field_0x8); + ex.updateStatus(0); } ex_c::m_current_ex = &ex_c::m_ex[mPad::getCurrentCoreID()]; + + if (dReset::Manage_c::GetInstance()->isSoftResetOrSafetyWait()) { + for (int i = 0; i < 4; ++i) { + EGG::CoreController *core = mPad::g_core[i]; + core->getCoreStatus()->hold &= EGG::cCORE_BUTTON_HOME; + core->getCoreStatus()->trig &= EGG::cCORE_BUTTON_HOME; + core->getCoreStatus()->release &= EGG::cCORE_BUTTON_HOME; + } + } + fn_801940C0(); } void endPad_BR() {