tp/include/JSystem/JUtility/JUTGamePad.h

272 lines
7.8 KiB
C++

#ifndef JUTGAMEPAD_H
#define JUTGAMEPAD_H
#include "JSystem/JKernel/JKRDisposer.h"
#include "JSystem/JUtility/JUTAssert.h"
#include <dolphin.h>
typedef void (*callbackFn)(int, void*);
/**
* @ingroup jsystem-jutility
*
*/
struct JUTGamePadRecordBase {
virtual ~JUTGamePadRecordBase() {}
virtual void getStatus(PADStatus* pad) = 0;
virtual void write(PADStatus* pad) = 0;
bool isActive() const { return mActive; }
/* 0x4 */ bool mActive;
};
/**
* @ingroup jsystem-jutility
*
*/
struct JUTGamePad : public JKRDisposer {
public:
enum EStickMode {
EStickMode1 = 1,
};
enum EWhichStick {
EMainStick,
ESubStick,
};
enum EPadPort {
EPortInvalid = -1,
EPort1,
EPort2,
EPort3,
EPort4,
};
enum EClampMode {
EClampNone,
EClampStick,
EClampCircle,
};
JUTGamePad(JUTGamePad::EPadPort port);
virtual ~JUTGamePad();
void initList();
static BOOL init();
void clear();
static u32 read();
void assign();
void checkResetCallback(OSTime holdTime);
void update();
void stopPatternedRumble() { mRumble.stopPatternedRumble(mPortNum); }
static void checkResetSwitch();
static void clearForReset();
static JUTGamePad* getGamePad(int port);
static bool recalibrate(u32 mask);
static void setAnalogMode(u32 mode) {
sAnalogMode = mode;
PADSetAnalogMode(mode);
}
static void clearResetOccurred() { C3ButtonReset::sResetOccurred = false; }
static void setResetCallback(callbackFn callback, void* arg) {
C3ButtonReset::sCallback = callback;
C3ButtonReset::sCallbackArg = arg;
}
u32 getButton() const { return mButton.mButton; }
u32 getTrigger() const { return mButton.mTrigger; }
f32 getMainStickX() const { return mMainStick.mPosX; }
f32 getMainStickY() const { return mMainStick.mPosY; }
f32 getMainStickValue() const { return mMainStick.mValue; }
s16 getMainStickAngle() const { return mMainStick.mAngle; }
f32 getSubStickX() const { return mSubStick.mPosX; }
f32 getSubStickY() const { return mSubStick.mPosY; }
f32 getSubStickValue() const { return mSubStick.mValue; }
s16 getSubStickAngle() const { return mSubStick.mAngle; }
u8 getAnalogA() const { return mButton.mAnalogA; }
u8 getAnalogB() const { return mButton.mAnalogB; }
u8 getAnalogL() const { return mButton.mAnalogL; }
u8 getAnalogR() const { return mButton.mAnalogR; }
s8 getErrorStatus() const { return mErrorStatus; }
s16 getPortNum() const { return mPortNum; }
JUTGamePadRecordBase* getPadReplay() const { return mPadReplay; }
JUTGamePadRecordBase* getPadRecord() const { return mPadRecord; }
u32 testTrigger(u32 button) const { return mButton.mTrigger & button; }
bool isPushing3ButtonReset() const {
return mPortNum != EPortInvalid && mButtonReset.mReset != false;
}
void stopMotorWave() { mRumble.stopPatternedRumbleAtThePeriod(); }
void stopMotor() { mRumble.stopMotor(mPortNum, false); }
void stopMotorHard() { mRumble.stopMotorHard(mPortNum); }
static s8 getPortStatus(u32 port) { return mPadStatus[port].err; }
struct CButton {
CButton() { clear(); }
void clear();
void update(const PADStatus* padStatus, u32 stickStatus);
void setRepeat(u32 mask, u32 delay, u32 rate);
/* 0x00 */ u32 mButton;
/* 0x04 */ u32 mTrigger; // Pressed Buttons
/* 0x08 */ u32 mRelease; // Released Buttons
/* 0x0C */ u8 mAnalogA;
/* 0x0D */ u8 mAnalogB;
/* 0x0E */ u8 mAnalogL;
/* 0x0F */ u8 mAnalogR;
/* 0x10 */ f32 mAnalogLf;
/* 0x14 */ f32 mAnalogRf;
/* 0x18 */ u32 mRepeat;
/* 0x1C */ u32 mRepeatCount;
/* 0x20 */ u32 mRepeatStart;
/* 0x24 */ u32 mRepeatMask;
/* 0x28 */ u32 mRepeatDelay;
/* 0x2C */ u32 mRepeatRate;
}; // Size: 0x30
struct C3ButtonReset {
C3ButtonReset() { mReset = false; }
static u32 sResetPattern;
static u32 sResetMaskPattern;
static callbackFn sCallback;
static void* sCallbackArg;
static OSTime sThreshold;
static s32 sResetOccurredPort;
static bool sResetOccurred;
static bool sResetSwitchPushing;
/* 0x0 */ bool mReset;
}; // Size: 0x4
struct CStick {
static f32 sPressPoint;
static f32 sReleasePoint;
CStick() { clear(); }
void clear();
void clear(JUTGamePad* pad);
u32 update(s8 x, s8 u, JUTGamePad::EStickMode mode, JUTGamePad::EWhichStick stick,
u32 buttons);
u32 getButton(u32 buttons);
/* 0x0 */ f32 mPosX;
/* 0x4 */ f32 mPosY;
/* 0x8 */ f32 mValue;
/* 0xC */ s16 mAngle;
/* 0xE */ s8 mRawX;
/* 0xF */ s8 mRawY;
}; // Size: 0x10
void stopMotorWaveHard() { mRumble.stopPatternedRumble(mPortNum); }
struct CRumble {
CRumble(JUTGamePad* pad) { clear(pad); }
static u32 sChannelMask[4];
static bool mStatus[4];
static u32 mEnabled;
enum ERumble {
VAL_0 = 0,
VAL_1 = 1,
VAL_2 = 2,
};
void clear();
void clear(JUTGamePad* pad);
static void startMotor(int port);
static void stopMotor(int port, bool hard_stop);
void update(s16 port);
void triggerPatternedRumble(u32 length);
void startPatternedRumble(void* data, ERumble rumble, u32 length);
void stopPatternedRumble(s16 port);
void stopPatternedRumbleAtThePeriod();
static void setEnabled(u32 mask);
void stopMotorHard(int port) { stopMotor(port, true); }
static bool isEnabled(u32 mask) { return mEnabled & mask; }
static bool isEnabledPort(int port) {
JUT_ASSERT(250, 0 <= port && port < 4);
return isEnabled(sChannelMask[port]);
}
/* 0x00 */ u32 mFrame;
/* 0x04 */ u32 mLength;
/* 0x08 */ u8* mPattern;
/* 0x0C */ u32 mFrameCount;
/* 0x10 */ u8* field_0x10;
}; // Size: 0x14
void startMotorWave(void* data, CRumble::ERumble rumble, u32 length) {
mRumble.startPatternedRumble(data, rumble, length);
}
static JSUList<JUTGamePad> mPadList;
static bool mListInitialized;
static PADStatus mPadStatus[4];
static CButton mPadButton[4];
static CStick mPadMStick[4];
static CStick mPadSStick[4];
static EStickMode sStickMode;
static int sClampMode;
static u8 mPadAssign[4];
static u32 sSuppressPadReset;
static s32 sAnalogMode;
static u32 sRumbleSupported;
/* 0x18 */ CButton mButton;
/* 0x48 */ CStick mMainStick;
/* 0x58 */ CStick mSubStick;
/* 0x68 */ CRumble mRumble;
/* 0x7C */ s16 mPortNum;
/* 0x7E */ s8 mErrorStatus;
/* 0x80 */ JSULink<JUTGamePad> mLink;
/* 0x90 */ JUTGamePadRecordBase* mPadRecord;
/* 0x94 */ JUTGamePadRecordBase* mPadReplay;
/* 0x98 */ C3ButtonReset mButtonReset;
/* 0x9C */ u8 field_0x9c[4];
/* 0xA0 */ OSTime mResetHoldStartTime;
/* 0xA8 */ u8 field_0xa8;
};
/**
* @ingroup jsystem-jutility
*
*/
struct JUTGamePadLongPress {
static JSUList<JUTGamePadLongPress> sPatternList;
void checkCallback(int port, u32 hold_time);
u32 getMaskPattern() const { return mMaskPattern; }
u32 getPattern() const { return mPattern; }
bool isValid() const { return mValid; }
/* 0x00 */ u8 field_0x0[0x10];
/* 0x10 */ bool mValid;
/* 0x11 */ bool field_0x11;
/* 0x14 */ u32 mPattern;
/* 0x18 */ u32 mMaskPattern;
/* 0x1C */ u32 mThreshold;
/* 0x20 */ bool mLongPressStatus[4];
/* 0x28 */ OSTime mStartHoldTime[4];
/* 0x48 */ bool field_0x48[4];
/* 0x4C */ void (*mCallback)(s32, JUTGamePadLongPress*, s32);
/* 0x50 */ s32 field_0x50;
};
#endif /* JUTGAMEPAD_H */