From a34a011f4e1b55f16029d6b6903c6938d494a740 Mon Sep 17 00:00:00 2001 From: Joshua Andrew Date: Sun, 13 Aug 2023 13:48:51 -0400 Subject: [PATCH] `WPadButton.o` 100% --- csv/System.csv | 64 +++++------ data/Game.json | 2 +- data/json/System.json | 2 +- docs/PROGRESS.md | 2 +- docs/lib/System.md | 4 +- docs/lib/System/WPadButton.md | 60 +++++----- docs/lib/System/WPadHolder.md | 8 +- include/Game/System/WPad.h | 36 ++++++ include/Game/System/WPadButton.h | 45 ++++++++ include/Game/System/WPadHolder.h | 14 +++ libs/RVL_SDK/include/revolution.h | 1 + libs/RVL_SDK/include/revolution/kpad.h | 65 +++++++++++ prog.png | Bin 25369 -> 25291 bytes source/Game/System/WPadButton.cpp | 151 +++++++++++++++++++++++++ source/Game/System/WPadHolder.cpp | 21 ++++ 15 files changed, 404 insertions(+), 71 deletions(-) create mode 100644 include/Game/System/WPad.h create mode 100644 include/Game/System/WPadButton.h create mode 100644 include/Game/System/WPadHolder.h create mode 100644 libs/RVL_SDK/include/revolution/kpad.h create mode 100644 source/Game/System/WPadButton.cpp create mode 100644 source/Game/System/WPadHolder.cpp diff --git a/csv/System.csv b/csv/System.csv index f22953ee..fd838c33 100644 --- a/csv/System.csv +++ b/csv/System.csv @@ -910,38 +910,38 @@ update__16WPadAccelerationFv,WPadAcceleration.o,System.a,false updateRotate__16WPadAccelerationFv,WPadAcceleration.o,System.a,false updateAccAverage__16WPadAccelerationFv,WPadAcceleration.o,System.a,false updateIsStable__16WPadAccelerationFv,WPadAcceleration.o,System.a,false -__ct__10WPadButtonFPC4WPad,WPadButton.o,System.a,false -update__10WPadButtonFv,WPadButton.o,System.a,false -testButtonUp__10WPadButtonCFv,WPadButton.o,System.a,false -testButtonDown__10WPadButtonCFv,WPadButton.o,System.a,false -testButtonLeft__10WPadButtonCFv,WPadButton.o,System.a,false -testButtonRight__10WPadButtonCFv,WPadButton.o,System.a,false -testButtonA__10WPadButtonCFv,WPadButton.o,System.a,false -testButtonB__10WPadButtonCFv,WPadButton.o,System.a,false -testButtonMinus__10WPadButtonCFv,WPadButton.o,System.a,false -testButtonPlus__10WPadButtonCFv,WPadButton.o,System.a,false -testButton1__10WPadButtonCFv,WPadButton.o,System.a,false -testButton2__10WPadButtonCFv,WPadButton.o,System.a,false -testButtonC__10WPadButtonCFv,WPadButton.o,System.a,false -testButtonZ__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerUp__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerDown__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerLeft__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerRight__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerA__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerB__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerMinus__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerHome__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerPlus__10WPadButtonCFv,WPadButton.o,System.a,false -testTrigger1__10WPadButtonCFv,WPadButton.o,System.a,false -testTrigger2__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerC__10WPadButtonCFv,WPadButton.o,System.a,false -testTriggerZ__10WPadButtonCFv,WPadButton.o,System.a,false -testReleaseZ__10WPadButtonCFv,WPadButton.o,System.a,false -isChangeAnyState__10WPadButtonCFv,WPadButton.o,System.a,false -__ct__16WPadReadDataInfoFv,WPadHolder.o,System.a,false -getKPadStatus__16WPadReadDataInfoCFUl,WPadHolder.o,System.a,false -getValidStatusCount__16WPadReadDataInfoCFv,WPadHolder.o,System.a,false +__ct__10WPadButtonFPC4WPad,WPadButton.o,System.a,true +update__10WPadButtonFv,WPadButton.o,System.a,true +testButtonUp__10WPadButtonCFv,WPadButton.o,System.a,true +testButtonDown__10WPadButtonCFv,WPadButton.o,System.a,true +testButtonLeft__10WPadButtonCFv,WPadButton.o,System.a,true +testButtonRight__10WPadButtonCFv,WPadButton.o,System.a,true +testButtonA__10WPadButtonCFv,WPadButton.o,System.a,true +testButtonB__10WPadButtonCFv,WPadButton.o,System.a,true +testButtonMinus__10WPadButtonCFv,WPadButton.o,System.a,true +testButtonPlus__10WPadButtonCFv,WPadButton.o,System.a,true +testButton1__10WPadButtonCFv,WPadButton.o,System.a,true +testButton2__10WPadButtonCFv,WPadButton.o,System.a,true +testButtonC__10WPadButtonCFv,WPadButton.o,System.a,true +testButtonZ__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerUp__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerDown__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerLeft__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerRight__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerA__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerB__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerMinus__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerHome__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerPlus__10WPadButtonCFv,WPadButton.o,System.a,true +testTrigger1__10WPadButtonCFv,WPadButton.o,System.a,true +testTrigger2__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerC__10WPadButtonCFv,WPadButton.o,System.a,true +testTriggerZ__10WPadButtonCFv,WPadButton.o,System.a,true +testReleaseZ__10WPadButtonCFv,WPadButton.o,System.a,true +isChangeAnyState__10WPadButtonCFv,WPadButton.o,System.a,true +__ct__16WPadReadDataInfoFv,WPadHolder.o,System.a,true +getKPadStatus__16WPadReadDataInfoCFUl,WPadHolder.o,System.a,true +getValidStatusCount__16WPadReadDataInfoCFv,WPadHolder.o,System.a,true __ct__10WPadHolderFv,WPadHolder.o,System.a,false updateReadDataOnly__10WPadHolderFv,WPadHolder.o,System.a,false updateProjectPadData__10WPadHolderFv,WPadHolder.o,System.a,false diff --git a/data/Game.json b/data/Game.json index 79b85bae..a74997ef 100644 --- a/data/Game.json +++ b/data/Game.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, "label": "Game", - "message": "11.12%", + "message": "11.137%", "color": "blue" } \ No newline at end of file diff --git a/data/json/System.json b/data/json/System.json index 2ba6a6c0..ec621349 100644 --- a/data/json/System.json +++ b/data/json/System.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, "label": "System", - "message": "12.523%", + "message": "12.971%", "color": "696969" } \ No newline at end of file diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index f6ef6d9c..0ec20555 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -22,5 +22,5 @@ | [Scene](https://github.com/shibbo/Petari/blob/master/docs/lib/Scene.md) | 12.230081906180192% | | [Screen](https://github.com/shibbo/Petari/blob/master/docs/lib/Screen.md) | 3.9020947950289457% | | [Speaker](https://github.com/shibbo/Petari/blob/master/docs/lib/Speaker.md) | 49.743881616391576% | -| [System](https://github.com/shibbo/Petari/blob/master/docs/lib/System.md) | 12.523141381662281% | +| [System](https://github.com/shibbo/Petari/blob/master/docs/lib/System.md) | 12.971353405437005% | | [Util](https://github.com/shibbo/Petari/blob/master/docs/lib/Util.md) | 9.661178747499052% | diff --git a/docs/lib/System.md b/docs/lib/System.md index 8aae4917..fb504ba4 100644 --- a/docs/lib/System.md +++ b/docs/lib/System.md @@ -58,8 +58,8 @@ | [StationedFileInfo.o](https://github.com/shibbo/Petari/blob/master/docs/lib/System/StationedFileInfo.md) | 100.0% | 1 / 1 | 100.0% | :white_check_mark: | [WPad.o](https://github.com/shibbo/Petari/blob/master/docs/lib/System/WPad.md) | 0.0% | 0 / 21 | 0.0% | :x: | [WPadAcceleration.o](https://github.com/shibbo/Petari/blob/master/docs/lib/System/WPadAcceleration.md) | 0.0% | 0 / 9 | 0.0% | :x: -| [WPadButton.o](https://github.com/shibbo/Petari/blob/master/docs/lib/System/WPadButton.md) | 0.0% | 0 / 29 | 0.0% | :x: -| [WPadHolder.o](https://github.com/shibbo/Petari/blob/master/docs/lib/System/WPadHolder.md) | 0.0% | 0 / 19 | 0.0% | :x: +| [WPadButton.o](https://github.com/shibbo/Petari/blob/master/docs/lib/System/WPadButton.md) | 100.0% | 29 / 29 | 100.0% | :white_check_mark: +| [WPadHolder.o](https://github.com/shibbo/Petari/blob/master/docs/lib/System/WPadHolder.md) | 8.450704225352112% | 3 / 19 | 15.789473684210526% | :eight_pointed_black_star: | [WPadHVSwing.o](https://github.com/shibbo/Petari/blob/master/docs/lib/System/WPadHVSwing.md) | 0.0% | 0 / 4 | 0.0% | :x: | [WPadInfoChecker.o](https://github.com/shibbo/Petari/blob/master/docs/lib/System/WPadInfoChecker.md) | 0.0% | 0 / 6 | 0.0% | :x: | [WPadLeaveWatcher.o](https://github.com/shibbo/Petari/blob/master/docs/lib/System/WPadLeaveWatcher.md) | 0.0% | 0 / 5 | 0.0% | :x: diff --git a/docs/lib/System/WPadButton.md b/docs/lib/System/WPadButton.md index 3cb122d5..34781db4 100644 --- a/docs/lib/System/WPadButton.md +++ b/docs/lib/System/WPadButton.md @@ -5,36 +5,36 @@ | :white_check_mark: | Function is completed. -# 0 / 29 Completed -- (0.0%) +# 29 / 29 Completed -- (100.0%) # WPadButton.o | Symbol | Decompiled? | | ------------- | ------------- | -| `__ct__10WPadButtonFPC4WPad` | :x: | -| `update__10WPadButtonFv` | :x: | -| `testButtonUp__10WPadButtonCFv` | :x: | -| `testButtonDown__10WPadButtonCFv` | :x: | -| `testButtonLeft__10WPadButtonCFv` | :x: | -| `testButtonRight__10WPadButtonCFv` | :x: | -| `testButtonA__10WPadButtonCFv` | :x: | -| `testButtonB__10WPadButtonCFv` | :x: | -| `testButtonMinus__10WPadButtonCFv` | :x: | -| `testButtonPlus__10WPadButtonCFv` | :x: | -| `testButton1__10WPadButtonCFv` | :x: | -| `testButton2__10WPadButtonCFv` | :x: | -| `testButtonC__10WPadButtonCFv` | :x: | -| `testButtonZ__10WPadButtonCFv` | :x: | -| `testTriggerUp__10WPadButtonCFv` | :x: | -| `testTriggerDown__10WPadButtonCFv` | :x: | -| `testTriggerLeft__10WPadButtonCFv` | :x: | -| `testTriggerRight__10WPadButtonCFv` | :x: | -| `testTriggerA__10WPadButtonCFv` | :x: | -| `testTriggerB__10WPadButtonCFv` | :x: | -| `testTriggerMinus__10WPadButtonCFv` | :x: | -| `testTriggerHome__10WPadButtonCFv` | :x: | -| `testTriggerPlus__10WPadButtonCFv` | :x: | -| `testTrigger1__10WPadButtonCFv` | :x: | -| `testTrigger2__10WPadButtonCFv` | :x: | -| `testTriggerC__10WPadButtonCFv` | :x: | -| `testTriggerZ__10WPadButtonCFv` | :x: | -| `testReleaseZ__10WPadButtonCFv` | :x: | -| `isChangeAnyState__10WPadButtonCFv` | :x: | +| `__ct__10WPadButtonFPC4WPad` | :white_check_mark: | +| `update__10WPadButtonFv` | :white_check_mark: | +| `testButtonUp__10WPadButtonCFv` | :white_check_mark: | +| `testButtonDown__10WPadButtonCFv` | :white_check_mark: | +| `testButtonLeft__10WPadButtonCFv` | :white_check_mark: | +| `testButtonRight__10WPadButtonCFv` | :white_check_mark: | +| `testButtonA__10WPadButtonCFv` | :white_check_mark: | +| `testButtonB__10WPadButtonCFv` | :white_check_mark: | +| `testButtonMinus__10WPadButtonCFv` | :white_check_mark: | +| `testButtonPlus__10WPadButtonCFv` | :white_check_mark: | +| `testButton1__10WPadButtonCFv` | :white_check_mark: | +| `testButton2__10WPadButtonCFv` | :white_check_mark: | +| `testButtonC__10WPadButtonCFv` | :white_check_mark: | +| `testButtonZ__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerUp__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerDown__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerLeft__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerRight__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerA__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerB__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerMinus__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerHome__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerPlus__10WPadButtonCFv` | :white_check_mark: | +| `testTrigger1__10WPadButtonCFv` | :white_check_mark: | +| `testTrigger2__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerC__10WPadButtonCFv` | :white_check_mark: | +| `testTriggerZ__10WPadButtonCFv` | :white_check_mark: | +| `testReleaseZ__10WPadButtonCFv` | :white_check_mark: | +| `isChangeAnyState__10WPadButtonCFv` | :white_check_mark: | diff --git a/docs/lib/System/WPadHolder.md b/docs/lib/System/WPadHolder.md index 54f2a18d..f2857e92 100644 --- a/docs/lib/System/WPadHolder.md +++ b/docs/lib/System/WPadHolder.md @@ -5,13 +5,13 @@ | :white_check_mark: | Function is completed. -# 0 / 19 Completed -- (0.0%) +# 3 / 19 Completed -- (15.789473684210526%) # WPadHolder.o | Symbol | Decompiled? | | ------------- | ------------- | -| `__ct__16WPadReadDataInfoFv` | :x: | -| `getKPadStatus__16WPadReadDataInfoCFUl` | :x: | -| `getValidStatusCount__16WPadReadDataInfoCFv` | :x: | +| `__ct__16WPadReadDataInfoFv` | :white_check_mark: | +| `getKPadStatus__16WPadReadDataInfoCFUl` | :white_check_mark: | +| `getValidStatusCount__16WPadReadDataInfoCFv` | :white_check_mark: | | `__ct__10WPadHolderFv` | :x: | | `updateReadDataOnly__10WPadHolderFv` | :x: | | `updateProjectPadData__10WPadHolderFv` | :x: | diff --git a/include/Game/System/WPad.h b/include/Game/System/WPad.h new file mode 100644 index 00000000..b06551a2 --- /dev/null +++ b/include/Game/System/WPad.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +class WPadButton; +class WPadPointer; +class WPadAcceleration; +class WPadHVSwing; +class WPadRumble; +class WPadStick; +class WPadLeaveWatcher; +class WPadInfoChecker; + +class WPad { +public: + WPad(s32); + + KPADStatus* getKPadStatus(u32) const; + + s32 mChannel; // _0 + u32 _4; + WPadButton* mButtons; // _8 + WPadPointer* mPointer; // _C + WPadAcceleration* _10; + WPadHVSwing* _14; + WPadRumble* _18; + WPadRumble* _1C; + WPadStick* mStick; // _20 + WPadAcceleration* _24; + WPadHVSwing* _28; + WPadLeaveWatcher* mLeaveWatcher; // _2C + WPadInfoChecker* mChecker; // _30 + u8 _34; + u8 _35; + u8 _36; +}; \ No newline at end of file diff --git a/include/Game/System/WPadButton.h b/include/Game/System/WPadButton.h new file mode 100644 index 00000000..dbb8732b --- /dev/null +++ b/include/Game/System/WPadButton.h @@ -0,0 +1,45 @@ +#pragma once + +#include "Game/System/WPad.h" + +class WPadButton { +public: + WPadButton(const WPad *); + + void update(); + bool testButtonUp() const; + bool testButtonDown() const; + bool testButtonLeft() const; + bool testButtonRight() const; + bool testButtonA() const; + bool testButtonB() const; + bool testButtonMinus() const; + bool testButtonPlus() const; + bool testButton1() const; + bool testButton2() const; + bool testButtonC() const; + bool testButtonZ() const; + bool testTriggerUp() const; + bool testTriggerDown() const; + bool testTriggerLeft() const; + bool testTriggerRight() const; + bool testTriggerA() const; + bool testTriggerB() const; + bool testTriggerMinus() const; + bool testTriggerHome() const; + bool testTriggerPlus() const; + bool testTrigger1() const; + bool testTrigger2() const; + bool testTriggerC() const; + bool testTriggerZ() const; + bool testReleaseZ() const; + bool isChangeAnyState() const; + + const WPad* mPad; // _0 + u32 mHold; // _4 + u32 _8; + u32 mRelease; // _C + u32 _10; + f32 mDelaySec; // _14 + f32 mPulseSec; // _18 +}; \ No newline at end of file diff --git a/include/Game/System/WPadHolder.h b/include/Game/System/WPadHolder.h new file mode 100644 index 00000000..ce11b451 --- /dev/null +++ b/include/Game/System/WPadHolder.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +class WPadReadDataInfo { +public: + WPadReadDataInfo(); + + KPADStatus* getKPadStatus(u32) const; + u32 getValidStatusCount() const; + + KPADStatus* mStatusArray; // _0 + u32 mValidStatusCount; // _4 +}; \ No newline at end of file diff --git a/libs/RVL_SDK/include/revolution.h b/libs/RVL_SDK/include/revolution.h index e4d44e41..44acf50b 100644 --- a/libs/RVL_SDK/include/revolution.h +++ b/libs/RVL_SDK/include/revolution.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/libs/RVL_SDK/include/revolution/kpad.h b/libs/RVL_SDK/include/revolution/kpad.h new file mode 100644 index 00000000..6c8882f1 --- /dev/null +++ b/libs/RVL_SDK/include/revolution/kpad.h @@ -0,0 +1,65 @@ +#ifndef KPAD_H +#define KPAD_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct Vec2 { + f32 x; + f32 y; +}; + +typedef union KPADEXStatus { + struct { + Vec2 stick; + Vec acc; + f32 acc_value; + f32 acc_speed; + } fs; + + struct { + u32 hold; + u32 trig; + u32 release; + Vec2 lstick; + Vec2 rstick; + f32 ltrigger; + f32 rtrigger; + } cl; +} KPADEXStatus; + +typedef struct KPADStatus { + u32 hold; + u32 trig; + u32 release; + Vec acc; + f32 acc_value; + f32 acc_speed; + Vec2 pos; + Vec2 vec; + f32 speed; + Vec2 horizon; + Vec2 hori_vec; + f32 hori_speed; + f32 dist; + f32 dist_vec; + f32 dist_speed; + Vec2 acc_vertical; + u8 dev_type; + s8 wpad_err; + s8 dpd_valid_fg; + u8 data_format; + KPADEXStatus ex_status; +} KPADStatus; + +void KPADSetBtnRepeat(s32, f32, f32); + +#ifdef __cplusplus +} +#endif + +#endif // KPAD_H \ No newline at end of file diff --git a/prog.png b/prog.png index 32fb6923acf10cfccb0ebab028b617d5ffe6b13f..f556eeaf5779a41153fff37477d1ffb6ba411c91 100644 GIT binary patch literal 25291 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 diff --git a/source/Game/System/WPadButton.cpp b/source/Game/System/WPadButton.cpp new file mode 100644 index 00000000..1cd0d2c8 --- /dev/null +++ b/source/Game/System/WPadButton.cpp @@ -0,0 +1,151 @@ +#include "Game/System/WPadButton.h" + +WPadButton::WPadButton(const WPad* pPad) { + mPad = pPad; + mHold = 0; + _8 = 0; + mRelease = 0; + _10 = 0; + mDelaySec = 0.41666666; + mPulseSec = 0.16666667; + KPADSetBtnRepeat(mPad->mChannel, mDelaySec, mPulseSec); +} + +void WPadButton::update() { + KPADStatus* status = mPad->getKPadStatus(0); + + if (status != nullptr) { + u32 v3; + if (mHold != 0) { + _8 = status->trig & ~mHold & 0xFFFF; + } + else { + _8 = status->trig; + } + + if (!status->wpad_err || status->wpad_err == -2) { + mHold = status->hold; + mRelease = status->release; + } + + _10 = _8; + + if ((status->hold & 0x80000000) != 0) { + _10 = _8 | mHold; + } + } +} + +bool WPadButton::testButtonUp() const { + return (mHold >> 3) & 0x1; +} + +bool WPadButton::testButtonDown() const { + return (mHold >> 2) & 0x1; +} + +bool WPadButton::testButtonLeft() const { + return mHold & 0x1; +} + +bool WPadButton::testButtonRight() const { + return (mHold >> 1) & 0x1; +} + +bool WPadButton::testButtonA() const { + return (mHold >> 11) & 0x1; +} + +bool WPadButton::testButtonB() const { + return (mHold >> 10) & 0x1; +} + +bool WPadButton::testButtonMinus() const { + return (mHold >> 12) & 0x1; +} + +bool WPadButton::testButtonPlus() const { + return (mHold >> 4) & 0x1; +} + +bool WPadButton::testButton1() const { + return (mHold >> 9) & 0x1; +} + +bool WPadButton::testButton2() const { + return (mHold >> 8) & 0x1; +} + +bool WPadButton::testButtonC() const { + return (mHold >> 14) & 0x1; +} + +bool WPadButton::testButtonZ() const { + return (mHold >> 13) & 0x1; +} + +bool WPadButton::testTriggerUp() const { + return (mHold >> 3) & 0x1; +} + +bool WPadButton::testTriggerDown() const { + return (mHold >> 2) & 0x1; +} + +bool WPadButton::testTriggerLeft() const { + return _8 & 0x1; +} + +bool WPadButton::testTriggerRight() const { + return (_8 >> 1) & 0x1; +} + +bool WPadButton::testTriggerA() const { + return (_8 >> 11) & 0x1; +} + +bool WPadButton::testTriggerB() const { + return (_8 >> 10) & 0x1; +} + +bool WPadButton::testTriggerMinus() const { + return (_8 >> 12) & 0x1; +} + +bool WPadButton::testTriggerHome() const { + return (_8 >> 15) & 0x1; +} + +bool WPadButton::testTriggerPlus() const { + return (_8 >> 4) & 0x1; +} + +bool WPadButton::testTrigger1() const { + return (_8 >> 9) & 0x1; +} + +bool WPadButton::testTrigger2() const { + return (_8 >> 8) & 0x1; +} + +bool WPadButton::testTriggerC() const { + return (_8 >> 14) & 0x1; +} + +bool WPadButton::testTriggerZ() const { + return (_8 >> 13) & 0x1; +} + +bool WPadButton::testReleaseZ() const { + return (mRelease >> 13) & 0x1; +} + +bool WPadButton::isChangeAnyState() const { + bool result = false; + + if (_8 || mRelease) { + result = true; + } + + return result; +} \ No newline at end of file diff --git a/source/Game/System/WPadHolder.cpp b/source/Game/System/WPadHolder.cpp new file mode 100644 index 00000000..d774ff9f --- /dev/null +++ b/source/Game/System/WPadHolder.cpp @@ -0,0 +1,21 @@ +#include "Game/System/WPadHolder.h" +#include "Game/Util.h" + +WPadReadDataInfo::WPadReadDataInfo() { + mStatusArray = nullptr; + mValidStatusCount = 0; + mStatusArray = new KPADStatus[0x78]; + MR::zeroMemory(mStatusArray, sizeof(KPADStatus) * 0x78); +} + +KPADStatus* WPadReadDataInfo::getKPadStatus(u32 idx) const { + if (idx >= mValidStatusCount) { + return nullptr; + } + + return &mStatusArray[idx]; +} + +u32 WPadReadDataInfo::getValidStatusCount() const { + return mValidStatusCount; +} \ No newline at end of file