From f6178769c0a75768f4699b7ccb96d2a5ce06e19e Mon Sep 17 00:00:00 2001 From: robojumper Date: Wed, 23 Jul 2025 00:15:55 +0200 Subject: [PATCH] pad fixes and stuff --- config/SOUE01/splits.txt | 2 +- config/SOUE01/symbols.txt | 51 +++-- include/d/d_hbm.h | 12 +- include/d/d_pad.h | 74 ++++--- include/rvl/KPAD/KPAD.h | 4 + src/d/d_cursor_hit_check.cpp | 2 +- src/d/d_pad.cpp | 407 ++++++++++++++++++++++++++--------- src/d/d_pad_ex.cpp | 4 +- src/d/d_reset.cpp | 9 +- src/d/d_sc_title.cpp | 3 +- 10 files changed, 400 insertions(+), 168 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 29005b8f..a84b06a7 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -238,7 +238,7 @@ d/d_pad.cpp: .sdata start:0x80571C60 end:0x80571C68 .sbss start:0x805751E0 end:0x805751E8 .sdata2 start:0x80576F60 end:0x80577008 - .bss start:0x80597A80 end:0x805A06B0 + .bss start:0x80597A70 end:0x805A06B0 d/d_pad_ex.cpp: .text start:0x80059620 end:0x80059CE0 align:16 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 4b7399a8..b7e88bb8 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -2244,11 +2244,11 @@ dMain__Execute = .text:0x80055030; // type:function size:0x14 dMain__main01 = .text:0x80055050; // type:function size:0x28 main = .text:0x80055080; // type:function size:0xE4 scope:global control_mpls_callback__4dPadFll = .text:0x80055170; // type:function size:0x38 -checkDeviceType__4dPadFUl = .text:0x800551B0; // type:function size:0x24 +isDeviceTypeMpls__4dPadFUl = .text:0x800551B0; // type:function size:0x24 initMpls__4dPadFl = .text:0x800551E0; // type:function size:0x8C create__4dPadFv = .text:0x80055270; // type:function size:0xBC setMpls__4dPadFbl = .text:0x80055330; // type:function size:0x98 -centerPos__4dPadFR7mVec2_cR7mVec2_c = .text:0x800553D0; // type:function size:0x50 +convertDpdPosToScreenPos__4dPadFR7mVec2_cR7mVec2_c = .text:0x800553D0; // type:function size:0x50 beginPad_BR__4dPadFv = .text:0x80055420; // type:function size:0x73C getStateID__86sStateMgr_c<17dLytControlGame_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80055B60; // type:function size:0x10 errRangeOver__Q23EGG29TBufferCFv = .text:0x80055B70; // type:function size:0x4 @@ -2261,7 +2261,7 @@ __ct__Q24dPad4ex_cFv = .text:0x80055C60; // type:function size:0x284 fn_80055EF0__Q24dPad4ex_cFl = .text:0x80055EF0; // type:function size:0x3B4 fn_800562B0__Q24dPad4ex_cFlR7mVec3_c = .text:0x800562B0; // type:function size:0x74 fn_80056330__Q24dPad4ex_cFl = .text:0x80056330; // type:function size:0x24C -fn_80056580__Q24dPad4ex_cFlR7mVec2_c = .text:0x80056580; // type:function size:0xEC +fn_80056580__Q24dPad4ex_cFlRC7mVec2_c = .text:0x80056580; // type:function size:0xEC centerCursor__Q24dPad4ex_cFlb = .text:0x80056670; // type:function size:0x114 fn_80056790__Q24dPad4ex_cFl = .text:0x80056790; // type:function size:0x334 setField_0x70__Q24dPad4ex_cF4mAng = .text:0x80056AD0; // type:function size:0xC @@ -2270,23 +2270,23 @@ fn_80056AF0__Q24dPad4ex_cFl = .text:0x80056AF0; // type:function size:0x90 checkWPADProbeStable__Q24dPad4ex_cFv = .text:0x80056B80; // type:function size:0x10 fn_80056B90__Q24dPad4ex_cFl = .text:0x80056B90; // type:function size:0x14C fn_80056CE0__Q24dPad4ex_cFl = .text:0x80056CE0; // type:function size:0xBC -fn_80056DA0__Q24dPad4ex_cFl = .text:0x80056DA0; // type:function size:0x48 -fn_80056DF0__Q24dPad4ex_cFl = .text:0x80056DF0; // type:function size:0x60 +startMplsCalibration__Q24dPad4ex_cFl = .text:0x80056DA0; // type:function size:0x48 +workMplsCalibration__Q24dPad4ex_cFl = .text:0x80056DF0; // type:function size:0x60 fn_80056E50__Q24dPad4ex_cFv = .text:0x80056E50; // type:function size:0x8 -fn_80056E60__Q24dPad4ex_cFl = .text:0x80056E60; // type:function size:0x4C +stopMplsCalibration__Q24dPad4ex_cFl = .text:0x80056E60; // type:function size:0x4C centerCursor__Q24dPad4ex_cFl = .text:0x80056EB0; // type:function size:0x38 -resetState__Q24dPad4ex_cFl = .text:0x80056EF0; // type:function size:0xC -fn_80056F00__Q24dPad4ex_cFl = .text:0x80056F00; // type:function size:0x24 -fn_80056F30__Q24dPad4ex_cFl = .text:0x80056F30; // type:function size:0xC -fn_80056F40__Q24dPad4ex_cFl = .text:0x80056F40; // type:function size:0xC8 -fn_80057010__Q24dPad4ex_cFl = .text:0x80057010; // type:function size:0x10 -fn_80057020__Q24dPad4ex_cFl = .text:0x80057020; // type:function size:0x80 -fn_800570A0__Q24dPad4ex_cFl = .text:0x800570A0; // type:function size:0x10 -fn_800570B0__Q24dPad4ex_cFl = .text:0x800570B0; // type:function size:0x4 -fn_800570C0__Q24dPad4ex_cFl = .text:0x800570C0; // type:function size:0x40 -fn_80057100__Q24dPad4ex_cFl = .text:0x80057100; // type:function size:0xA8 -fn_800571B0__Q24dPad4ex_cFl = .text:0x800571B0; // type:function size:0xC -fn_800571C0__Q24dPad4ex_cFl = .text:0x800571C0; // type:function size:0xD4 +gotoStateWaitForConnect__Q24dPad4ex_cFl = .text:0x80056EF0; // type:function size:0xC +executeStateWaitForConnect__Q24dPad4ex_cFl = .text:0x80056F00; // type:function size:0x24 +gotoStateWaitForLeaveHbm__Q24dPad4ex_cFl = .text:0x80056F30; // type:function size:0xC +executeStateWaitForLeaveHbm__Q24dPad4ex_cFl = .text:0x80056F40; // type:function size:0xC8 +gotoState2__Q24dPad4ex_cFl = .text:0x80057010; // type:function size:0x10 +executeState2__Q24dPad4ex_cFl = .text:0x80057020; // type:function size:0x80 +gotoState3__Q24dPad4ex_cFl = .text:0x800570A0; // type:function size:0x10 +executeState3__Q24dPad4ex_cFl = .text:0x800570B0; // type:function size:0x4 +gotoState4__Q24dPad4ex_cFl = .text:0x800570C0; // type:function size:0x40 +executeState4__Q24dPad4ex_cFl = .text:0x80057100; // type:function size:0xA8 +gotoState5__Q24dPad4ex_cFl = .text:0x800571B0; // type:function size:0xC +executeState5__Q24dPad4ex_cFl = .text:0x800571C0; // type:function size:0xD4 fn_800572A0__Q24dPad4ex_cFl = .text:0x800572A0; // type:function size:0xC8 init__Q34dPad4ex_c5acc_cFv = .text:0x80057370; // type:function size:0x30C getEntryField_0xB40__Q34dPad4ex_c5acc_cFl = .text:0x80057680; // type:function size:0x4C @@ -2307,9 +2307,9 @@ fn_800589F0__Q34dPad4ex_c5acc_cFv = .text:0x800589F0; // type:function size:0x8 fn_80058A00__Q34dPad4ex_c5acc_cFv = .text:0x80058A00; // type:function size:0xD8 fn_80058AE0__Q34dPad4ex_c5acc_cFlb = .text:0x80058AE0; // type:function size:0x70 getMtx__Q34dPad4ex_c6mpls_cCFv = .text:0x80058B50; // type:function size:0x6C -fn_80058BC0__Q24dPad4ex_cFv = .text:0x80058BC0; // type:function size:0x58 -fn_80058C20__Q24dPad4ex_cFv = .text:0x80058C20; // type:function size:0x68 -fn_80058C90__Q24dPad4ex_cFv = .text:0x80058C90; // type:function size:0x20 +isMissingMpls__Q24dPad4ex_cFv = .text:0x80058BC0; // type:function size:0x58 +isMissingNunchuk__Q24dPad4ex_cFv = .text:0x80058C20; // type:function size:0x68 +fn_80058C90__Q24dPad4ex_cFl = .text:0x80058C90; // type:function size:0x20 isLowBattery__Q24dPad4ex_cFv = .text:0x80058CB0; // type:function size:0x2C isOutOfBattery__Q24dPad4ex_cFv = .text:0x80058CE0; // type:function size:0x28 resetInfo__Q24dPad4ex_cFv = .text:0x80058D10; // type:function size:0x3C @@ -2346,7 +2346,7 @@ fn_80059350__Q24dPad4ex_cFl = .text:0x80059350; // type:function size:0x18 fn_80059370__Q24dPad4ex_cFl = .text:0x80059370; // type:function size:0x18 fn_80059390__Q24dPad4ex_cFl = .text:0x80059390; // type:function size:0x18 getUnifiedWpadStatus__Q24dPad4ex_cFl = .text:0x800593B0; // type:function size:0x14 -fn_800593D0__Q24dPad4ex_cFv = .text:0x800593D0; // type:function size:0x6C +calcFSStickDirMask__Q24dPad4ex_cFv = .text:0x800593D0; // type:function size:0x6C setNoSleep__Q24dPad4ex_cFv = .text:0x80059440; // type:function size:0x8 setAutoSleepTime__Q24dPad4ex_cFv = .text:0x80059450; // type:function size:0x2C __sinit_\d_pad_cpp = .text:0x80059480; // type:function size:0x58 scope:local @@ -2392,7 +2392,7 @@ up__Q23EGG14CoreControllerCFUl = .text:0x80059A60; // type:function size:0x1C upAll__Q23EGG14CoreControllerCFUl = .text:0x80059A80; // type:function size:0x14 getUpA__4dPadFv = .text:0x80059AA0; // type:function size:0x18 getDpdPos__4dPadFv = .text:0x80059AC0; // type:function size:0x8 -getDpdStableMaybe__4dPadFv = .text:0x80059AD0; // type:function size:0xC +getDpdPosScreen__4dPadFv = .text:0x80059AD0; // type:function size:0xC getFSStick__4dPadFv = .text:0x80059AE0; // type:function size:0xC getFSStickX__4dPadFv = .text:0x80059AF0; // type:function size:0xC getFSStickY__4dPadFv = .text:0x80059B00; // type:function size:0xC @@ -41309,10 +41309,9 @@ layoutResHeap__5dHeap = .sbss:0x805751C0; // type:object size:0x4 data:4byte fontHeap__5dHeap = .sbss:0x805751C4; // type:object size:0x4 data:4byte HBMHeap__5dHeap = .sbss:0x805751C8; // type:object size:0x4 data:4byte lbl_805751D0 = .sbss:0x805751D0; // type:object size:0x8 data:4byte -dMain__g_InitialTime = .sbss:0x805751D8; // type:object size:0x4 data:4byte -g_InitialTime+4 = .sbss:0x805751DC; // type:object size:0x4 data:4byte +dMain__g_InitialTime = .sbss:0x805751D8; // type:object size:0x8 data:4byte m_connected__Q24dPad4ex_c = .sbss:0x805751E0; // type:object size:0x4 -lbl_805751E8 = .sbss:0x805751E8; // type:object size:0x8 data:4byte +sInstance__15dPauseManager_c = .sbss:0x805751E8; // type:object size:0x8 data:4byte LINK_ROT = .sbss:0x805751F0; // type:object size:0x2 data:2byte LINK_ROT_2 = .sbss:0x805751F4; // type:object size:0x2 data:2byte lbl_805751F6 = .sbss:0x805751F6; // type:object size:0x1 data:byte diff --git a/include/d/d_hbm.h b/include/d/d_hbm.h index 34b8c551..aa0a42a6 100644 --- a/include/d/d_hbm.h +++ b/include/d/d_hbm.h @@ -4,6 +4,12 @@ namespace dHbm { class Manage_c { public: + enum ManageState_e { + HBM_MANAGE_NOT_LOADED = 0, + HBM_MANAGE_INACTIVE = 1, + HBM_MANAGE_ACTIVE = 2, + }; + static void CreateInstance(); static Manage_c *GetInstance(); @@ -37,15 +43,15 @@ public: mFlags &= ~flags; } - UNKWORD getField_0x210() const { - return field_0x210; + ManageState_e getState() const { + return mState; } private: static Manage_c *s_pInstance; /* 0x000 */ u8 _0x00[0x210 - 0x000]; - /* 0x210 */ UNKWORD field_0x210; + /* 0x210 */ ManageState_e mState; /* 0x218 */ UNKWORD field_0x214; /* 0x218 */ u32 mFlags; }; diff --git a/include/d/d_pad.h b/include/d/d_pad.h index ec992c05..590c9096 100644 --- a/include/d/d_pad.h +++ b/include/d/d_pad.h @@ -77,30 +77,37 @@ public: void fn_80056B90(s32 chan); void fn_80056CE0(s32 chan); - void fn_80056DA0(s32 chan); // Deals with Mpls Calibration Start - void fn_80056DF0(s32 chan); // Deals with Mpls Calibration Work + void startMplsCalibration(s32 chan); + void workMplsCalibration(s32 chan); f32 fn_80056E50(); - void fn_80056E60(s32 chan); // Deals with Mpls Calibration Stop + void stopMplsCalibration(s32 chan); void centerCursor(s32 chan); - void resetState(s32 chan); - void fn_80056F00(s32 chan); - void fn_80056F30(s32 chan); // Sets State to 1 - void fn_80056F40(s32 chan); - void fn_80057010(s32 chan); // Sets State to 2 (EnableMPLS) - void fn_80057020(s32 chan); - void fn_800570A0(s32 chan); // Sets State to 3 (Disconnect) - void fn_800570B0(s32 chan); // Sets State to 1 - void fn_800570C0(s32 chan); // Sets State to 4 - void fn_80057100(s32 chan); - void fn_800571B0(s32 chan); // Sets State to 5 - void fn_800571C0(s32 chan); + void gotoStateWaitForConnect(s32 chan); + void executeStateWaitForConnect(s32 chan); + void gotoStateWaitForLeaveHbm(s32 chan); + void executeStateWaitForLeaveHbm(s32 chan); + void gotoState2(s32 chan); // (EnableMPLS) + void executeState2(s32 chan); + void gotoState3(s32 chan); // (Disconnect) + void executeState3(s32 chan); // Sets State to 1 + void gotoState4(s32 chan); + void executeState4(s32 chan); + void gotoState5(s32 chan); + void executeState5(s32 chan); void fn_800572A0(s32 chan); // State Handling - static bool fn_80058BC0(); - static bool fn_80058C20(); - static void fn_80058C90(); + /** + * Is the Wiimote missing MotionPlus? This means the Wiimote neither has + * a builtin Mpls nor a passthrough Mpls attached. + */ + static bool isMissingMpls(); + /** + * Is the Wiimote known to not have an attached Nunchuk? + */ + static bool isMissingNunchuk(); + static void fn_80058C90(s32 chan); static bool isLowBattery(); static bool isOutOfBattery(); @@ -117,7 +124,7 @@ public: static f32 fn_80058FE0(); static void fn_80058FF0(); static void fn_80059000(); - static void fn_80059010(); + static bool fn_80059010(); static void fn_800590A0(); static bool fn_800590B0(); static bool fn_800590E0(); @@ -142,7 +149,7 @@ public: static bool fn_80059370(s32 chan); static bool fn_80059390(s32 chan); void getUnifiedWpadStatus(s32 chan); - void fn_800593D0(); + void calcFSStickDirMask(); static void setNoSleep(); static void setAutoSleepTime(); @@ -153,9 +160,18 @@ public: return m_current_ex; } + enum ExState_e { + EX_STATE_WAITING_FOR_CONNECT = 0, + EX_STATE_WAITING_FOR_LEAVE_HBM = 1, + EX_STATE_2 = 2, + EX_STATE_3 = 3, + EX_STATE_4 = 4, + EX_STATE_5 = 5, + }; + public: /* 0x0000 */ mVec2_c mDpdPos; - /* 0x0008 */ mVec2_c field_0x8; + /* 0x0008 */ mVec2_c mDpdPosScreen; /* 0x0010 */ mVec2_c mFSStick; /* 0x0018 */ f32 mFSStickDistance; /* 0x001C */ mAng mFSStickAngle; @@ -165,16 +181,16 @@ public: /* 0x002C */ WPADDeviceType mWPADDeviceType; /* 0x0030 */ u32 mWPADDeviceTypeStable; /* 0x0034 */ s32 mWPADDeviceTypeStableTimer; - /* 0x0038 */ s32 field_0x38; + /* 0x0038 */ s32 mConnectedStableTimer; /* 0x003C */ s32 field_0x3C; /* 0x0040 */ f32 field_0x40; /* 0x0044 */ bool field_0x44; /* 0x0045 */ bool field_0x45; /* 0x0046 */ bool field_0x46; - /* 0x0047 */ bool field_0x47; + /* 0x0047 */ bool mIsCalibrating; /* 0x0048 */ s32 field_0x48; - /* 0x004C */ bool mSpeakerSetup; - /* 0x004D */ bool mSpeakerShutdown; + /* 0x004C */ bool mDidConnect; + /* 0x004D */ bool mDidDisconnect; /* 0x004E */ bool mIncorrectDeviceType; /* 0x004F */ bool field_0x4F; /* 0x0050 */ bool field_0x50; @@ -201,14 +217,14 @@ public: /* 0x2250 */ mVec3_c mMPLSVelocity; /* 0x225C */ mpls_c mMPLS; /* 0x2280 */ s32 mState; - /* 0x2284 */ s32 field_0x2284; + /* 0x2284 */ s32 mOutOfHbmStableTimer; /* 0x2288 */ s32 field_0x2288; /* 0x228C */ KPADUnifiedWpadStatus mStatus; /* 0x22CE */ bool field_0x22CE; /* 0x22CF */ bool field_0x22CF; /* 0x22D0 */ u8 field_0x22D0; - /* 0x22D1 */ u8 field_0x22D1; - /* 0x22D4 */ s32 field_0x22D4; + /* 0x22D1 */ bool mFSStickMaskChanged; + /* 0x22D4 */ u32 mFSStickMask; /* 0x22D8 */ u8 field_0x22D8; static WPADInfo m_info[2][4]; @@ -292,7 +308,7 @@ bool getUpMinus(); bool getUpPlus(); mVec2_c &getDpdPos(); -mVec2_c &getDpdStableMaybe(); +mVec2_c &getDpdPosScreen(); mVec2_c &getFSStick(); f32 getFSStickX(); f32 getFSStickY(); diff --git a/include/rvl/KPAD/KPAD.h b/include/rvl/KPAD/KPAD.h index 4cd1ed91..79b733d9 100644 --- a/include/rvl/KPAD/KPAD.h +++ b/include/rvl/KPAD/KPAD.h @@ -108,6 +108,10 @@ void KPADSetReviseMode(s32 chan, s32); void KPADEnableMpls(s32 chan, s32); void KPADDisableMpls(s32 chan); +void KPADStartMplsCalibration(s32 chan); +f32 KPADWorkMplsCalibration(s32 chan); +void KPADStopMplsCalibration(s32 chan); + s32 KPADGetMplsWorkSize(); void KPADSetMplsWorkarea(void *); void KPADSetControlMplsCallback(s32 chan, KPADConnectCallback cb); diff --git a/src/d/d_cursor_hit_check.cpp b/src/d/d_cursor_hit_check.cpp index c50b1c60..47535182 100644 --- a/src/d/d_cursor_hit_check.cpp +++ b/src/d/d_cursor_hit_check.cpp @@ -259,5 +259,5 @@ void dCursorHitCheckLyt_c::gatherBoundings(dCsCheckLyt_BoundingData **pEnd, nw4r } mVec2_c &dCursorInterface_c::getCursorPos() { - return dPad::ex_c::getInstance()->field_0x8; + return dPad::ex_c::getInstance()->mDpdPosScreen; } diff --git a/src/d/d_pad.cpp b/src/d/d_pad.cpp index ba658d7c..dfc4b534 100644 --- a/src/d/d_pad.cpp +++ b/src/d/d_pad.cpp @@ -4,6 +4,7 @@ #include "d/a/d_a_player.h" #include "d/d_cs_game.h" #include "d/d_gfx.h" +#include "d/d_hbm.h" #include "d/d_pause.h" #include "d/d_reset.h" #include "d/lyt/d_lyt_control_game.h" @@ -56,7 +57,7 @@ void control_mpls_callback(s32 idx, s32 code) { } } -bool checkDeviceType(u32 type) { +bool isDeviceTypeMpls(u32 type) { switch (type) { case WPAD_DEV_MOTION_PLUS: case WPAD_DEV_MPLS_PT_FS: @@ -92,7 +93,7 @@ void create() { ex_c::m_ex[i].mMotion.init(); KPADSetReviseMode(i, 1); KPADSetControlMplsCallback(i, control_mpls_callback); - ex_c::m_ex[i].resetState(i); + ex_c::m_ex[i].gotoStateWaitForConnect(i); } fn_80194080(); } @@ -112,7 +113,7 @@ void setMpls(bool enable, s32 chan) { } } -void centerPos(mVec2_c &in, mVec2_c &out) { +void convertDpdPosToScreenPos(mVec2_c &in, mVec2_c &out) { out.x = dGfx_c::getWidth4x3F() * 0.5f * (1.f + in.x) + dGfx_c::getWidth4x3LeftF(); out.y = dGfx_c::getCurrentScreenHeightF() * -0.5f * (1.f + in.y) + dGfx_c::getCurrentScreenTopF(); } @@ -142,7 +143,7 @@ void beginPad_BR() { ex.fn_80056AF0(0); ex.fn_80056B90(0); ex.fn_80056CE0(0); - ex.fn_80056DF0(0); + ex.workMplsCalibration(0); bool isDpdReviseEnabled = KPADIsEnableMplsDpdRevise(0) >= 0.f; if (ex.field_0x22CE) { if (isDpdReviseEnabled) { @@ -218,7 +219,7 @@ void beginPad_BR() { } KPADDisableMplsDirRevise(0); } - if (ex.field_0x47 || ex.field_0x48 != 0) { + if (ex.mIsCalibrating || ex.field_0x48 != 0) { KPADEnableMplsAccRevise(0); KPADSetMplsAccReviseParam(0, 1.f, 0.6f); if (--ex.field_0x48 < 0) { @@ -232,7 +233,7 @@ void beginPad_BR() { ex.mFSStickDistance = ex.mFSStick.length(); ex.mFSStickAngle = -ex.mFSStick.ang(); - ex.fn_800593D0(); + ex.calcFSStickDirMask(); bool isMpls = mPad::isMpls(0) || mPad::isMplsPtFS(0); if (isMpls) { @@ -250,7 +251,8 @@ void beginPad_BR() { ex.fn_80056790(0); if (ex.field_0x50) { - ex.mDpdPos = ex.field_0x8; + // TODO: These two vectors use entirely different spaces... + ex.mDpdPos = ex.field_0x5C; } else { if (mPad::getCore(0)->getDpdValidFlag() > 0) { ex.mDpdPos = mPad::getCore(0)->getDpdRawPos(); @@ -259,7 +261,7 @@ void beginPad_BR() { ex.mDpdPos.set(-2.f, -2.f); } } - centerPos(ex.mDpdPos, ex.field_0x8); + convertDpdPosToScreenPos(ex.mDpdPos, ex.mDpdPosScreen); ex.updateStatus(0); } @@ -284,12 +286,12 @@ void connectCallback(const EGG::CoreControllerConnectArg &rArg) { switch (rArg.result) { case WPAD_ERR_OK: { dSndPlayerMgr_c::GetInstance()->setup(rArg.chan); - ex_c::m_ex[rArg.chan].mSpeakerSetup = true; + ex_c::m_ex[rArg.chan].mDidConnect = true; break; } case WPAD_ERR_NO_CONTROLLER: { dSndPlayerMgr_c::GetInstance()->shutdown(rArg.chan); - ex_c::m_ex[rArg.chan].mSpeakerShutdown = true; + ex_c::m_ex[rArg.chan].mDidDisconnect = true; break; } } @@ -309,7 +311,7 @@ void disableMplsDirRevise(s32 chan) { ex_c::ex_c() : mDpdPos(0.f, 0.f), - field_0x8(0.f, 0.f), + mDpdPosScreen(0.f, 0.f), mFSStick(0.f, 0.f), mFSStickDistance(0.f), mFSStickAngle(0), @@ -319,16 +321,16 @@ ex_c::ex_c() mWPADDeviceType(0), mWPADDeviceTypeStable(0xFF), mWPADDeviceTypeStableTimer(0), - field_0x38(0), + mConnectedStableTimer(0), field_0x3C(0), field_0x40(0.f), field_0x44(false), field_0x45(false), field_0x46(false), - field_0x47(false), + mIsCalibrating(false), field_0x48(0), - mSpeakerSetup(false), - mSpeakerShutdown(false), + mDidConnect(false), + mDidDisconnect(false), mIncorrectDeviceType(true), field_0x4F(false), field_0x50(true), @@ -351,13 +353,13 @@ ex_c::ex_c() field_0x80(0.f, 1.f, 0.f), field_0x8C(0.f, 0.f, 1.f), mState(0), - field_0x2284(0), + mOutOfHbmStableTimer(0), field_0x2288(0), field_0x22CE(0), field_0x22CF(0), field_0x22D0(0), - field_0x22D1(0), - field_0x22D4(0), + mFSStickMaskChanged(false), + mFSStickMask(0), field_0x22D8(0) { memset(&mStatus, 0, sizeof(mStatus)); } @@ -365,13 +367,15 @@ ex_c::ex_c() void ex_c::fn_80055EF0(s32 chan) { const s32 readLen = mPad::getCore(chan)->getReadLength(); - // I dont understand this loop - Nonmatching garbage - for (int i = 0; i < readLen; i++) { - mMotion.field_0x000[i] = mMotion.field_0x5A0[i]; - mFSMotion.field_0x000[i] = mFSMotion.field_0x5A0[i]; + for (int i = 120 - 1; i >= readLen; i--) { + mMotion.field_0x000[i] = mMotion.field_0x000[i - readLen]; + mMotion.field_0xB40[i] = mMotion.field_0xB40[i - readLen]; + mFSMotion.field_0x000[i] = mFSMotion.field_0x000[i - readLen]; + mFSMotion.field_0xB40[i] = mFSMotion.field_0xB40[i - readLen]; } - for (int i = 0; i < readLen; ++i) { + // Missing an implicit != 0 check before the loop + for (int i = 0; i < readLen; i++) { EGG::CoreStatus status = *mPad::getCore(chan)->getCoreStatus(i); mMotion.field_0x000[i].copyFrom(&status.acc); mMotion.field_0xB40[i] = status.acc_value; @@ -452,7 +456,7 @@ void ex_c::centerCursor(s32 chan, bool b) { if (dAcPy_c::GetLink() && dAcPy_c::GetLink()->checkActionFlagsCont(0x2) && acc.z < -0.9f) { tmp = true; } - field_0x53 = tmp; + field_0x53 = dAcPy_c::GetLink() && dAcPy_c::GetLink()->checkActionFlagsCont(0x2) && acc.z < -0.9f; fn_800562B0(chan, field_0x8C); fn_80056330(chan); @@ -464,20 +468,24 @@ void ex_c::centerCursor(s32 chan, bool b) { field_0x51 = 0; field_0x5C.set(0.f, 0.f); mDpdPos.set(0.f, 0.f); - centerPos(mDpdPos, field_0x8); + convertDpdPosToScreenPos(mDpdPos, mDpdPosScreen); } } void ex_c::fn_80056790(s32 chan) {} -void ex_c::setField_0x70(mAng ang) {} +void ex_c::setField_0x70(mAng ang) { + field_0x70 = ang; +} -void ex_c::setField_0x70() {} +void ex_c::setField_0x70() { + field_0x70.set(0x1200); +} void ex_c::fn_80056AF0(s32 chan) { - if (mSpeakerSetup) { - mSpeakerSetup = false; - field_0x38 = 90; + if (mDidConnect) { + mDidConnect = false; + mConnectedStableTimer = 90; field_0x44 = true; m_ex[chan].field_0x46 = true; @@ -485,8 +493,8 @@ void ex_c::fn_80056AF0(s32 chan) { } else { field_0x44 = false; } - if (mSpeakerShutdown) { - mSpeakerShutdown = false; + if (mDidDisconnect) { + mDidDisconnect = false; field_0x45 = true; m_ex[chan].mWPADDeviceTypeStable = WPAD_DEV_UNKNOWN; } else { @@ -515,10 +523,10 @@ void ex_c::fn_80056B90(s32 chan) { if (mWPADProbeStableTimer >= 5) { mWPADProbeResultStable = mWPADProbeResult; } - if (field_0x38 > 0) { - field_0x38--; - if (field_0x38 < 0) { - field_0x38 = 0; + if (mConnectedStableTimer > 0) { + mConnectedStableTimer--; + if (mConnectedStableTimer < 0) { + mConnectedStableTimer = 0; } } @@ -535,11 +543,11 @@ void ex_c::fn_80056B90(s32 chan) { mWPADDeviceTypeStable = mWPADDeviceType; } - if (!checkDeviceType(mWPADDeviceTypeStable)) { + if (!isDeviceTypeMpls(mWPADDeviceTypeStable)) { mIncorrectDeviceType = true; field_0x6C = 0; } - if (checkDeviceType(mWPADDeviceTypeStable) && field_0x6C < 8) { + if (isDeviceTypeMpls(mWPADDeviceTypeStable) && field_0x6C < 8) { field_0x6C++; } } @@ -567,55 +575,162 @@ void ex_c::fn_80056CE0(s32 chan) { } } -void ex_c::fn_80056DA0(s32 chan) {} - -void ex_c::fn_80056DF0(s32 chan) {} - -f32 ex_c::fn_80056E50() {} - -void ex_c::fn_80056E60(s32 chan) {} - -void ex_c::centerCursor(s32 chan) {} - -void ex_c::resetState(s32 chan) {} - -void ex_c::fn_80056F00(s32 chan) {} - -void ex_c::fn_80056F30(s32 chan) { - mState = 1; +void ex_c::startMplsCalibration(s32 chan) { + KPADStartMplsCalibration(chan); + mIsCalibrating = true; + field_0x40 = 1.0f; + field_0x48 = 0; } -void ex_c::fn_80056F40(s32 chan) {} +void ex_c::workMplsCalibration(s32 chan) { + if (!mIsCalibrating) { + return; + } -void ex_c::fn_80057010(s32 chan) { - mState = 2; + field_0x40 = KPADWorkMplsCalibration(chan); + if (field_0x40 == 0.0f) { + mIsCalibrating = false; + field_0x48 = 60; + } +} + +f32 ex_c::fn_80056E50() { + return field_0x40; +} + +void ex_c::stopMplsCalibration(s32 chan) { + mIsCalibrating = false; + field_0x40 = 0.0f; + KPADStopMplsCalibration(chan); + field_0x48 = 0; +} + +void ex_c::centerCursor(s32 chan) { + centerCursor(chan, false); + field_0x48 = 0; +} + +void ex_c::gotoStateWaitForConnect(s32 chan) { + mState = EX_STATE_WAITING_FOR_CONNECT; +} + +void ex_c::executeStateWaitForConnect(s32 chan) { + if (mPad::getCore(chan)->isConnected()) { + gotoStateWaitForLeaveHbm(chan); + } +} + +void ex_c::gotoStateWaitForLeaveHbm(s32 chan) { + mState = EX_STATE_WAITING_FOR_LEAVE_HBM; +} + +void ex_c::executeStateWaitForLeaveHbm(s32 chan) { + if (dHbm::Manage_c::GetInstance()->getState() == dHbm::Manage_c::HBM_MANAGE_ACTIVE) { + // If we are in HBM, set some sort of cooldown + mOutOfHbmStableTimer = 110; + field_0x4F = true; + } + + if (mPad::getCore(chan)->isConnected()) { + if (ex_c::checkWPADProbeStable() && + dHbm::Manage_c::GetInstance()->getState() != dHbm::Manage_c::HBM_MANAGE_ACTIVE) { + // If we're not in HBM anymore, advance state + gotoState2(chan); + } + } + + if (!mPad::getCore(chan)->isConnected()) { + gotoStateWaitForConnect(chan); + } +} + +void ex_c::gotoState2(s32 chan) { + mState = EX_STATE_2; setMpls(true, chan); } -void ex_c::fn_80057020(s32 chan) {} +void ex_c::executeState2(s32 chan) { + if (fn_80059350(chan) || fn_80059370(chan)) { + gotoState4(chan); + } else if (fn_80059390(chan)) { + gotoState5(chan); + } +} -void ex_c::fn_800570A0(s32 chan) { - mState = 3; +void ex_c::gotoState3(s32 chan) { + mState = EX_STATE_3; WPADDisconnect(chan); } -void ex_c::fn_800570B0(s32 chan) { - fn_80056F30(chan); +void ex_c::executeState3(s32 chan) { + gotoStateWaitForLeaveHbm(chan); } -void ex_c::fn_800570C0(s32 chan) { - mState = 4; +void ex_c::gotoState4(s32 chan) { + mState = EX_STATE_4; + setMpls(false, chan); + field_0x2288 = 0; } -void ex_c::fn_80057100(s32 chan) {} - -void ex_c::fn_800571B0(s32 chan) { - mState = 5; +void ex_c::executeState4(s32 chan) { + if (fn_80059390(chan)) { + if (dHbm::Manage_c::GetInstance()->getState() == dHbm::Manage_c::HBM_MANAGE_ACTIVE) { + gotoStateWaitForLeaveHbm(chan); + } else { + gotoState2(chan); + } + } else { + if (dHbm::Manage_c::GetInstance()->getState() != dHbm::Manage_c::HBM_MANAGE_ACTIVE) { + if (field_0x2288 > 120) { + gotoState3(chan); + } else { + field_0x2288++; + } + } + } } -void ex_c::fn_800571C0(s32 chan) {} +void ex_c::gotoState5(s32 chan) { + mState = EX_STATE_5; +} -void ex_c::fn_800572A0(s32 chan) {} +void ex_c::executeState5(s32 chan) { + if (!mPad::getCore(chan)->isConnected()) { + setMpls(false, chan); + gotoStateWaitForConnect(chan); + } else { + if (fn_80059330(chan) || fn_80059350(chan) || fn_80059370(chan)) { + setMpls(false, chan); + } + } + if (!mMplsEnabled) { + gotoStateWaitForLeaveHbm(chan); + } + + if (dHbm::Manage_c::GetInstance()->getState() == dHbm::Manage_c::HBM_MANAGE_ACTIVE) { + field_0x4F = false; + } +} + +void ex_c::fn_800572A0(s32 chan) { + switch (mState) { + case EX_STATE_WAITING_FOR_CONNECT: executeStateWaitForConnect(chan); break; + case EX_STATE_WAITING_FOR_LEAVE_HBM: executeStateWaitForLeaveHbm(chan); break; + case EX_STATE_2: executeState2(chan); break; + case EX_STATE_3: executeState3(chan); break; + case EX_STATE_4: executeState4(chan); break; + case EX_STATE_5: executeState5(chan); break; + } + + if (mState != EX_STATE_WAITING_FOR_LEAVE_HBM && + dHbm::Manage_c::GetInstance()->getState() != dHbm::Manage_c::HBM_MANAGE_ACTIVE) { + if (mOutOfHbmStableTimer > 0) { + mOutOfHbmStableTimer--; + } else { + mOutOfHbmStableTimer = 0; + } + } +} void ex_c::acc_c::init() { for (int i = 0; i < 120; ++i) { @@ -675,7 +790,9 @@ void ex_c::acc_c::fn_80058540(s32 chan, bool) {} void ex_c::acc_c::fn_80058990(u32 mask, bool) {} -bool ex_c::acc_c::fn_800589F0() {} +bool ex_c::acc_c::fn_800589F0() { + return true; +} f32 ex_c::acc_c::fn_80058A00() {} @@ -690,9 +807,46 @@ mMtx_c ex_c::mpls_c::getMtx() const { return m; } -bool ex_c::fn_80058BC0() {} -bool ex_c::fn_80058C20() {} -void ex_c::fn_80058C90() {} +bool ex_c::isMissingMpls() { + if (m_current_ex->mConnectedStableTimer != 0) { + return false; + } + + if (m_current_ex->mOutOfHbmStableTimer != 0) { + return false; + } + + return !isDeviceTypeMpls(m_current_ex->mWPADDeviceTypeStable); +} + +bool ex_c::isMissingNunchuk() { + if (m_current_ex->mConnectedStableTimer != 0) { + return false; + } + + if (m_current_ex->mOutOfHbmStableTimer != 0) { + return false; + } + + if (m_current_ex->mState != EX_STATE_5) { + return false; + } + + if (m_current_ex->mWPADDeviceTypeStable == WPAD_DEV_FREESTYLE) { + return false; + } + + if (m_current_ex->mWPADDeviceTypeStable == WPAD_DEV_MPLS_PT_FS) { + return false; + } + + return true; +} + +void ex_c::fn_80058C90(s32 chan) { + m_ex[chan].field_0x46 = 1; + m_ex[chan].field_0x3C = 1; +} bool ex_c::isLowBattery() { return getBatteryLevel() == 1; @@ -759,15 +913,7 @@ s32 ex_c::getBatteryLevel(s32 chan) { } void ex_c::setInfo(s32 chan, const WPADInfo *pInfo) { - m_info[0][chan].dpd = pInfo->dpd; - m_info[0][chan].speaker = pInfo->speaker; - m_info[0][chan].attach = pInfo->attach; - m_info[0][chan].lowBat = pInfo->lowBat; - m_info[0][chan].nearempty = pInfo->nearempty; - m_info[0][chan].battery = pInfo->battery; - m_info[0][chan].led = pInfo->led; - m_info[0][chan].protocol = pInfo->protocol; - m_info[0][chan].firmware = pInfo->firmware; + m_info[0][chan] = *pInfo; m_connected[chan] = true; } @@ -775,26 +921,87 @@ f32 ex_c::fn_80058F50() { return m_current_ex->mMotion.fn_80058A00(); } -bool ex_c::fn_80058F60() {} +bool ex_c::fn_80058F60() { + if (m_current_ex->field_0x6C < 8) { + return true; + } -f32 ex_c::fn_80058FE0() {} + if (!m_current_ex->mMotion.fn_800589F0()) { + return true; + } -void ex_c::fn_80058FF0() {} + m_current_ex->mIncorrectDeviceType = false; + m_current_ex->startMplsCalibration(mPad::getCurrentCoreID()); + m_current_ex->fn_80058C90(mPad::getCurrentCoreID()); + initMpls(mPad::getCurrentCoreID()); -void ex_c::fn_80059000() {} + return false; +} -void ex_c::fn_80059010() {} +f32 ex_c::fn_80058FE0() { + return m_current_ex->fn_80056E50(); +} -void ex_c::fn_800590A0() {} +void ex_c::fn_80058FF0() { + m_current_ex->stopMplsCalibration(mPad::getCurrentCoreID()); +} -bool ex_c::fn_800590B0() {} +void ex_c::fn_80059000() { + m_current_ex->centerCursor(mPad::getCurrentCoreID()); +} -bool ex_c::fn_800590E0() {} +bool ex_c::fn_80059010() { + if (!mPad::getCore()->isConnected()) { + return false; + } -void ex_c::fn_800590F0() {} + if (isMissingMpls()) { + return false; + } + + if (m_current_ex->mOutOfHbmStableTimer != 0) { + return false; + } + + if (isMissingNunchuk()) { + return false; + } + + if (m_current_ex->field_0x6C >= 8) { + return m_current_ex->mIncorrectDeviceType; + } + + return false; +} + +void ex_c::fn_800590A0() { + m_current_ex->mIncorrectDeviceType = true; +} + +bool ex_c::fn_800590B0() { + bool ret = false; + switch (m_current_ex->mState) { + case EX_STATE_WAITING_FOR_LEAVE_HBM: + case EX_STATE_2: + case EX_STATE_3: + case EX_STATE_4: + // TODO - one uneliminated dead branch in here + ret = m_current_ex->mState == EX_STATE_4 || m_current_ex->mState == EX_STATE_2 || + m_current_ex->mState == EX_STATE_WAITING_FOR_LEAVE_HBM; + } + return ret; +} + +bool ex_c::fn_800590E0() { + return m_current_ex->field_0x4F; +} + +void ex_c::fn_800590F0() { + m_current_ex->field_0x4F = false; +} bool ex_c::fn_80059100() { - fn_80059110(mPad::g_currentCoreId); + return fn_80059110(mPad::g_currentCoreId); } bool ex_c::fn_80059110(s32 chan) { @@ -867,18 +1074,18 @@ void ex_c::getUnifiedWpadStatus(s32 chan) { KPADGetUnifiedWpadStatus(chan, &mStatus, 1); } -void ex_c::fn_800593D0() { - field_0x22D1 = 0; +void ex_c::calcFSStickDirMask() { + mFSStickMaskChanged = false; if (mFSStickDistance < 0.8f) { - field_0x22D4 = 0; + mFSStickMask = 0; return; } - u32 prev22D4 = field_0x22D4; + u32 prevFSStickMask = mFSStickMask; s32 ang = mFSStickAngle; ang = ((ang + 0x11000) / 0x2000) % 8; - field_0x22D4 = 1 << ang; - if (field_0x22D4 != 0 && field_0x22D4 != prev22D4) { - field_0x22D1 = 1; + mFSStickMask = 1 << ang; + if (mFSStickMask != 0 && mFSStickMask != prevFSStickMask) { + mFSStickMaskChanged = true; } } diff --git a/src/d/d_pad_ex.cpp b/src/d/d_pad_ex.cpp index d4e66ddc..8fd5d711 100644 --- a/src/d/d_pad_ex.cpp +++ b/src/d/d_pad_ex.cpp @@ -212,8 +212,8 @@ bool getUpPlus() { mVec2_c &getDpdPos() { return ex_c::m_current_ex->mDpdPos; } -mVec2_c &getDpdStableMaybe() { - return ex_c::m_current_ex->field_0x8; +mVec2_c &getDpdPosScreen() { + return ex_c::m_current_ex->mDpdPosScreen; } mVec2_c &getFSStick() { return ex_c::m_current_ex->mFSStick; diff --git a/src/d/d_reset.cpp b/src/d/d_reset.cpp index 0437cec2..4f2910f2 100644 --- a/src/d/d_reset.cpp +++ b/src/d/d_reset.cpp @@ -113,8 +113,8 @@ void Manage_c::BootComplete(bool complete) { bool Manage_c::CanExecSoftReset() const { return mMode == SoftReset && mpFader->getStatus() == EGG::Fader::STATUS_PREPARE_IN && field_0x60 == 0 && - dHbm::Manage_c::GetInstance()->getField_0x210() != 2 && dSndPlayerMgr_c::GetInstance()->fn_8035E2E0() && - FileManager::GetInstance()->getField_0xA84D() != 1; + dHbm::Manage_c::GetInstance()->getState() != dHbm::Manage_c::HBM_MANAGE_ACTIVE && + dSndPlayerMgr_c::GetInstance()->fn_8035E2E0() && FileManager::GetInstance()->getField_0xA84D() != 1; } void Manage_c::SetSoftResetFinish() { @@ -234,7 +234,8 @@ void Manage_c::ModeProc() { if (mMode != DiskWait && mMode != SafetyWait) { ModeRequest(DiskWait); } - } else if (mMode == Normal && dHbm::Manage_c::GetInstance()->getField_0x210() == 2) { + } else if (mMode == Normal && + dHbm::Manage_c::GetInstance()->getState() == dHbm::Manage_c::HBM_MANAGE_ACTIVE) { ModeRequest(HbmWait); } static void (Manage_c::*const procs[6])() = { @@ -393,7 +394,7 @@ void Manage_c::ModeProc_HbmWait() { DiskCheckModeRequest(true); doFade = true; } else { - if (dHbm::Manage_c::GetInstance()->getField_0x210() != 2) { + if (dHbm::Manage_c::GetInstance()->getState() != dHbm::Manage_c::HBM_MANAGE_ACTIVE) { if (mShutdown) { ModeRequestSafetyWait(Shutdown); } else if (mRestart) { diff --git a/src/d/d_sc_title.cpp b/src/d/d_sc_title.cpp index a17cd63a..8aaa9a1a 100644 --- a/src/d/d_sc_title.cpp +++ b/src/d/d_sc_title.cpp @@ -67,7 +67,6 @@ dScTitle_c::~dScTitle_c() { } extern "C" u32 TITLE_SCREEN_CHANGE; -extern "C" void fn_80058C90(s32); static const char *const sFileSelect = "FileSelect"; static const char *const sSkb = "SoftwareKeyboard"; @@ -91,7 +90,7 @@ int dScTitle_c::create() { dSys::setFrameRate(2); dSys::setClearColor(mColor(0x00000000)); dPad::ex_c::setAutoSleepTime(); - fn_80058C90(0); + dPad::ex_c::fn_80058C90(0); SaveRelated::create(); field_0x2AD = 0; LayoutArcManager::GetInstance()->loadLayoutArcFromDisk(sFileSelect, nullptr);