match and link JUTGamePad.cpp

This commit is contained in:
SwareJonge 2023-12-06 23:14:20 +01:00
parent 8094195393
commit 754c16b92a
14 changed files with 1177 additions and 78 deletions

View File

@ -98,6 +98,17 @@ libs/JSystem/JUtility/JUTFont.cpp:
.rodata: [0x80361f38, 0x80361f50]
.sdata2: [0x80417908, 0x80417918]
libs/JSystem/JUtility/JUTGamePad.cpp:
.text: [0x8006f93c, 0x8007140c]
.ctors: [0x803160cc, 0x803160d0]
.rodata: [0x80361f50, 0x80361f70]
.data: [0x8038af50, 0x8038af80]
.bss: [0x803ae8f0, 0x803ae908]
#.bss: [0x803fa5cc, 0x803fa8f0]
.sdata: [0x80414058, 0x80414070]
.sbss: [0x80415818, 0x80415858]
.sdata2: [0x80417918, 0x80417968]
libs/JSystem/JUtility/JUTGraphFifo.cpp:
.text: [0x8007140c, 0x800715a4]
.data: [0x8038af80, 0x8038af90]

View File

@ -17446,6 +17446,7 @@ global:
0x8041580c: sConsole__12JUTException
0x80415810: msr__12JUTException
0x80415814: fpscr__12JUTException
0x80415818: mListInitialized__10JUTGamePad
0x8041581c: mPadAssign__10JUTGamePad
0x80415820: mspLGWheels__10JUTGamePad
0x80415824: sSuppressPadReset__10JUTGamePad
@ -17456,6 +17457,8 @@ global:
0x8041583c: sCallback__Q210JUTGamePad13C3ButtonReset
0x80415840: sCallbackArg__Q210JUTGamePad13C3ButtonReset
0x80415848: sThreshold__Q210JUTGamePad13C3ButtonReset
0x80415850: sResetSwitchPushing__Q210JUTGamePad13C3ButtonReset
0x80415851: sResetOccurred__Q210JUTGamePad13C3ButtonReset
0x80415854: sResetOccurredPort__Q210JUTGamePad13C3ButtonReset
0x8041585c: sCurrentFifo__12JUTGraphFifo
0x80415860: mGpStatus__12JUTGraphFifo

View File

@ -229,6 +229,16 @@ libs/JSystem/JUtility/JUTFont.cpp:
.text: [0x8001d7bc, 0x8001dae0]
.data: [0x803483c8, 0x80348410]
libs/JSystem/JUtility/JUTGamePad.cpp:
.text: [0x8001dae0, 0x8001f70c]
.ctors: [0x802d84d0, 0x802d84d4]
.data: [0x80348410, 0x80348440]
.bss: [0x8036e3a8, 0x8036e3c0]
#.bss: [0x803ae9f4, 0x803aed20]
.sdata: [0x803d3290, 0x803d32a8]
.sbss: [0x803d4b18, 0x803d4b50]
.sdata2: [0x803d6618, 0x803d6668]
libs/JSystem/JUtility/JUTGraphFifo.cpp:
.text: [0x8001f70c, 0x8001f8b0]
.data: [0x80348440, 0x80348450]

View File

@ -590,20 +590,64 @@ global:
0x803483c8: __vt__7JUTFont
# JUTGamePad.cpp
0x8001dae0: __ct__10JUTGamePadFQ210JUTGamePad8EPadPort
0x8001dc98: init__10JUTGamePadFv
0x8001dbb0: __dt__10JUTGamePadFv
0x8001dc5c: initList__10JUTGamePadFv
0x8001dc98: init__10JUTGamePadFv
0x8001dd04: clear__10JUTGamePadFv
0x8001dd10: read__10JUTGamePadFv
0x8001e0d8: assign__10JUTGamePadFv
0x8001e190: checkResetCallback__10JUTGamePadFx
0x8001e20c: update__10JUTGamePadFv
0x8001e510: checkResetSwitch__10JUTGamePadFv
0x8001e590: clear__Q210JUTGamePad7CButtonFv
0x8001e5cc: update__Q210JUTGamePad7CButtonFPC9PADStatusUl
0x8001e764: update__Q210JUTGamePad7CButtonFPC10LGPositionUl
0x8001e9ac: clear__Q210JUTGamePad6CStickFv
0x8001e9c8: update__Q210JUTGamePad6CStickFScScQ210JUTGamePad10EStickModeQ210JUTGamePad11EWhichStickUl
0x8001ec90: update__Q210JUTGamePad6CStickFScUl
0x8001ed14: getButton__Q210JUTGamePad6CStickFUl
0x8001edc8: clear__Q210JUTGamePad7CRumbleFP10JUTGamePad
0x8001ee3c: startMotor__Q210JUTGamePad7CRumbleFi
0x8001eee0: stopMotor__Q210JUTGamePad7CRumbleFib
0x8001ef9c: update__Q210JUTGamePad7CRumbleFs
0x8001f3d0: setRepeat__Q210JUTGamePad7CButtonFUlUlUl
0x8001f3ec: setButtonRepeat__10JUTGamePadFUlUlUl
0x8001f438: recalibrate__10JUTGamePadFUl
0x8001f4a0: checkCallback__19JUTGamePadLongPressFiUl
0x8001f60c: __dt__30JSUList<19JUTGamePadLongPress>Fv
0x8001f660: __ct__Q210JUTGamePad6CStickFv
0x8001f67c: __ct__Q210JUTGamePad7CButtonFv
0x8001f6b8: __dt__21JSUList<10JUTGamePad>Fv
0x80348410: sChannelMask__Q210JUTGamePad7CRumble
0x80348420: channel_mask
0x80348430: __vt__10JUTGamePad
0x803ae9f4: mPadList__10JUTGamePad
0x803aeb8c: mPadStatus__10JUTGamePad
0x803aebbc: mPadButton__10JUTGamePad
0x803aec7c: mPadMStick__10JUTGamePad
0x803aecbc: mPadSStick__10JUTGamePad
0x803aecfc: msaSIType__10JUTGamePad
0x803aed0c: sPatternList__19JUTGamePadLongPress
0x803d3290: sStickMode__10JUTGamePad
0x803d3294: sClampMode__10JUTGamePad
0x803d3298: sPressPoint__Q210JUTGamePad6CStick
0x803d329c: sReleasePoint__Q210JUTGamePad6CStick
0x803d32a0: sResetPattern__Q210JUTGamePad13C3ButtonReset
0x803d32a4: sResetMaskPattern__Q210JUTGamePad13C3ButtonReset
0x803d4b18: mListInitialized__10JUTGamePad
0x803d4b1c: mPadAssign__10JUTGamePad
0x803d4b20: mspLGWheels__10JUTGamePad
0x803d4b24: sSuppressPadReset__10JUTGamePad
0x803d4b28: sAnalogMode__10JUTGamePad
0x803d4b2c: sRumbleSupported__10JUTGamePad
0x803d4b30: mStatus__Q210JUTGamePad7CRumble
0x803d4b34: mEnabled__Q210JUTGamePad7CRumble
0x803d4b38: sCallback__Q210JUTGamePad13C3ButtonReset
0x803d4b3c: sCallbackArg__Q210JUTGamePad13C3ButtonReset
0x803d4b40: sThreshold__Q210JUTGamePad13C3ButtonReset
0x803d4b48: sResetSwitchPushing__Q210JUTGamePad13C3ButtonReset
0x803d4b49: sResetOccurred__Q210JUTGamePad13C3ButtonReset
0x803d4b4c: sResetOccurredPort__Q210JUTGamePad13C3ButtonReset
# JUTGraphFifo.cpp
0x8001f70c: __ct__12JUTGraphFifoFUl
@ -707,6 +751,8 @@ global:
0x8032db80: JUTResFONT_Ascfont_fix12
# Logitech
0x80024718: __ct__8LGWheelsFv
0x8002480c: ReadAll__8LGWheelsFv
0x80024c80: IsConnected__8LGWheelsFl
0x80024de0: PlayAutoCalibAndSpringForce__8LGWheelsFl
0x80024f1c: PlaySpringForce__8LGWheelsFlScUcs

View File

@ -95,7 +95,7 @@ public:
return *this;
}
T *getObject() { return mLink->getObject(); }
T *getObject() const { return mLink->getObject(); }
bool operator==(JSULink<T> const *other) const { return mLink == other; }
bool operator!=(JSULink<T> const *other) const { return mLink != other; }
@ -128,9 +128,10 @@ public:
return *this;
}
T &operator*() { return *getObject(); }
// Investigate where and if this actually exists
//T &operator*() { return *getObject(); }
T *operator->() { return getObject(); }
T *operator->() const { return mLink->getObject(); }
// private:
JSULink<T> *mLink;
@ -146,7 +147,7 @@ public:
T *getObject() const { return (T *)mData; }
JSUList<T> *getList() const { return (JSUList<T> *)JSUPtrLink::getList(); } // fabricated, offcial name: getSupervisor
JSULink<T> *getNext() const { return (JSULink<T> *)JSUPtrLink::getNext(); }
JSULink<T> *getNext() const { return (JSULink<T> *)mNext; }
JSULink<T> *getPrev() const { return (JSULink<T> *)JSUPtrLink::getPrev(); }
~JSULink() {

View File

@ -5,12 +5,49 @@
#include <dolphin/os.h>
#include <dolphin/pad.h>
#include "JSystem/Logitech/Wheels.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JKernel/JKRDisposer.h"
typedef void (*JUTResetBtnCb)(int, void*);
// this currently is need to match testButton and testTrigger, if the entire file uses o4,p is unknown to me
#pragma push
#pragma optimize_for_size off
class JUTGamePadRecordBase
{
public:
JUTGamePadRecordBase();
virtual ~JUTGamePadRecordBase();
virtual void read(PADStatus *status) = 0;
virtual void write(PADStatus *) = 0;
bool mActive;
/* more that are unknown */
bool isActive() const { return this->mActive; }
};
struct JUTGamePadLongPress
{
static JSUList<JUTGamePadLongPress> sPatternList;
void checkCallback(int port, u32 timer);
u32 getMaskPattern() const { return mMaskPattern; }
u32 getPattern() const { return mPattern; }
bool isValid() const { return mValid; }
u8 _0[0x10];
bool mValid;
bool _11;
u32 mPattern;
u32 mMaskPattern;
u32 _1C;
bool _20[PAD_CONTROLLER_NUM];
OSTime mTimer[PAD_CONTROLLER_NUM];
bool _48[PAD_CONTROLLER_NUM];
void (*mCallback)(int, JUTGamePadLongPress *, int);
int _50;
};
typedef void (*JUTResetBtnCb)(int, void*);
class JUTGamePad : public JKRDisposer
{
public:
@ -55,96 +92,298 @@ public:
Clamped
};
enum EWhichStick
enum EClampMode
{
WhichStick_ControlStick,
WhichStick_CStick
NoClamp,
Clamp,
ClampCircle
};
enum EWhichStick
{
WhichStick_MainStick,
WhichStick_SubStick
};
JUTGamePad();
JUTGamePad(EPadPort port);
virtual ~JUTGamePad();
void assign();
void checkResetSwitch();
void checkResetCallback(OSTime time);
void clearForReset();
static void init();
void initList();
void read();
u32 read();
static bool recalibrate(u32);
void setButtonRepeat(u32, u32, u32);
void update();
void clear();
static void setResetCallback(JUTResetBtnCb callback, void *param_0)
static void checkResetSwitch();
static bool mListInitialized;
static u8 mPadAssign[PAD_CONTROLLER_NUM];
static u32 sSuppressPadReset;
static bool sErrorReport;
static u32 sAnalogMode;
static u32 sRumbleSupported;
static s32 msaSIType[PAD_CONTROLLER_NUM]; // check type?
static void setAnalogMode(u32 mode)
{
JUTGamePad::sAnalogMode = mode;
PADSetAnalogMode(mode);
}
static void setResetCallback(JUTResetBtnCb callback, void *arg)
{
C3ButtonReset::sCallback = callback;
C3ButtonReset::sCallbackArg = param_0;
C3ButtonReset::sCallbackArg = arg;
}
bool testButton(u32 mask) const {
return mButtons.mInput & mask;
static void clearResetOccurred()
{
C3ButtonReset::sResetOccurred = false;
}
bool testTrigger(u32 mask) const {
return mButtons.mFrameInput & mask;
static EClampMode getClampMode()
{
return JUTGamePad::sClampMode;
}
static s8 getPortStatus(EPadPort port)
{
JUT_ASSERT(0 <= port && port < 4);
return mPadStatus[port].err;
}
bool isPushing3ButtonReset() const
{
bool pushing = false;
if (this->mPortNum != -1 && this->mButtonReset.mReset != false)
{
pushing = true;
}
return pushing;
}
int getErrorStatus() const
{
return this->mErrorStatus;
}
u8 getAnalogR() const
{
return this->mButtons.mAnalogR;
}
f32 getAnalogRf() const
{
return this->mButtons.mAnalogRf;
}
u8 getAnalogL() const
{
return this->mButtons.mAnalogL;
}
f32 getAnalogLf() const
{
return this->mButtons.mAnalogLf;
}
u8 getAnalogB() const
{
return this->mButtons.mAnalogB;
}
u8 getAnalogA() const
{
return this->mButtons.mAnalogA;
}
int getSubStickAngle() const
{
return this->mSubStick.mAngle;
}
f32 getSubStickValue() const
{
return this->mSubStick.mValue;
}
f32 getSubStickY() const
{
return this->mSubStick.mY;
}
f32 getSubStickX() const
{
return this->mSubStick.mX;
}
int getMainStickAngle() const
{
return this->mMainStick.mAngle;
}
f32 getMainStickValue() const
{
return this->mMainStick.mValue;
}
f32 getMainStickY() const
{
return this->mMainStick.mY;
}
f32 getMainStickX() const
{
return this->mMainStick.mX;
}
u32 getTrigger() const
{
return this->mButtons.mTrigger;
}
u32 getButton() const
{
return this->mButtons.mButton;
}
u32 getRelease() const
{
return this->mButtons.mRelease;
}
u32 getRepeat() const
{
return this->mButtons.mRepeat;
}
bool testButton(u32 mask) const
{
return this->mButtons.mButton & mask;
}
bool testTrigger(u32 mask) const
{
return this->mButtons.mTrigger & mask;
}
int getPortNum() const
{
return this->mPortNum;
}
JUTGamePadRecordBase *getPadRecord() const
{
return this->mPadRecord;
}
JUTGamePadRecordBase *getPadReplay() const
{
return this->mPadReplay;
}
inline void stopMotorHard() {
CRumble::stopMotorHard(this->mPortNum);
}
class CButton
{
public:
CButton();
CButton() { this->clear(); };
void clear();
void update(const PADStatus*, u32);
void setRepeat(u32, u32, u32);
void update(const PADStatus *padStatus, u32 buttons);
void update(const LGPosition *padStatus, u32 buttons);
void setRepeat(u32 mask, u32 delay, u32 frequency);
u32 mInput; // _0
u32 mFrameInput;
u32 _8;
u8 mAnalogA; // _C
u8 mAnalogB; // _D
u8 mTriggerL; // _E
u8 mTriggerR; // _F
f32 mAnalogL; // _10
f32 mAnalogR; // _14
u32 _18;
u32 _1C;
u32 _20;
u32 _24;
u32 _28;
u32 _2C;
u32 mButton; // buttons held down
u32 mTrigger; // buttons newly pressed this frame
u32 mRelease; // buttons released this frame
u8 mAnalogA; //
u8 mAnalogB; //
u8 mAnalogL; // left trigger percent
u8 mAnalogR; // right trigger percent
f32 mAnalogLf; // left trigger analog percent
f32 mAnalogRf; // right trigger analog percent
u32 mRepeat; // buttons currently marked as "repeated" triggers when held
u32 mRepeatTimer; // frames since current button combo has been held
u32 mRepeatLastButton; // last buttons pressed
u32 mRepeatMask; // button mask to allow repeating trigger inputs
u32 mRepeatDelay; // delay before beginning repeated input
u32 mRepeatFrequency; // repeat input every X frames
};
class CStick
{
public:
CStick();
CStick() {
clear();
}
void clear();
u32 update(s8 x, s8 y, JUTGamePad::EStickMode, JUTGamePad::EWhichStick);
u32 update(s8 x, s8 y, JUTGamePad::EStickMode, JUTGamePad::EWhichStick); // old or non mkdd version?
u32 update(s8 x, s8 y, JUTGamePad::EStickMode, JUTGamePad::EWhichStick, u32);
u32 getButton();
u32 update(s8, u32);
u32 getButton(u32);
f32 mStickX;
f32 mStickY;
f32 mLengthFromNeutral;
u16 mAngle;
u16 _E; // i assume unused
f32 mX;
f32 mY;
f32 mValue;
s16 mAngle;
s8 mAnalogX;
s8 mAnalogY;
};
class CRumble
{
public:
void clear(JUTGamePad*);
static void stopMotor(s32);
static void stopMotorHard(s32);
void update(u16);
enum ERumble
{
Rumble0,
Rumble1,
Rumble2
};
CRumble(JUTGamePad *gamePad) { this->clear(gamePad); }
static u8 mStatus[PAD_CONTROLLER_NUM];
static u32 mEnabled;
static void startMotor(int port);
static void stopMotor(int port, bool hard);
static void stopMotorHard(int port)
{
stopMotor(port, true);
}
static bool isEnabledPort(int port) {
return (0 <= port && port < 4) ? isEnabled(sChannelMask[port]) : false;
}
static bool isEnabled(u32 channel)
{
return (JUTGamePad::CRumble::mEnabled & channel) ? true : false;
}
void clear();
void clear(JUTGamePad *gamePad);
void update(s16);
void setEnable(u32);
u32 _0;
u32 _4;
u32 _8;
u32 _C;
static u32 sChannelMask[4];
u32 mFrame;
u32 mLength;
u8 *mData;
u32 mFrameCount;
u8 *_10;
};
class C3ButtonReset {
@ -160,7 +399,6 @@ public:
static bool sResetOccurred;
static bool sResetSwitchPushing;
private:
bool mReset;
};
@ -175,32 +413,31 @@ public:
return ret;
}
static LGWheels* getLGWheels() { return mspLGWheels; }
static PADStatus *getPadStatus(int idx) { return &mPadStatus[idx]; }
static LGWheels *mspLGWheels;
static JSUList<JUTGamePad> mPadList;
static CButton mPadButton[PAD_CONTROLLER_NUM];
static CStick mPadMStick[PAD_CONTROLLER_NUM];
static CStick mPadSStick[PAD_CONTROLLER_NUM];
static EStickMode sStickMode;
static EClampMode sClampMode;
static f32 sPressPoint;
static f32 sReleasePoint;
static PADStatus mPadStatus[PAD_CONTROLLER_NUM];
static PADStatus mPadStatus[4];
CButton mButtons; // _18
CStick mControlStick; // _48
CStick mCStick; // _58
CRumble mRumble; // _68
u16 mPort; // _78
u8 mPortConnected; // _7A
JSUPtrLink mPtrLink; // _7C
u32 _8C;
u32 _90;
u32 _94;
u32 _98;
u8 mResetFlag; // _9C
u8 _9D; // padding?
u8 _9E; // ^^
u8 _9F; // ^^
OSTime mResetTime; // _A0
CButton mButtons; // _18
CStick mMainStick; // _48
CStick mSubStick; // _58
CRumble mRumble; // _68
s16 mPortNum; // _7C
s8 mErrorStatus; // _7E
JSULink<JUTGamePad> mLink; // _80
JUTGamePadRecordBase *mPadRecord;
JUTGamePadRecordBase *mPadReplay;
C3ButtonReset mButtonReset; // _98
OSTime mResetTime; // _A0
};
#pragma pop
#endif

View File

@ -3,6 +3,8 @@
#include "types.h"
#include <dolphin/lg.h>
class LGWheels
{ // Autogenerated
public:
@ -51,5 +53,10 @@ public:
// void SameFrontalCollisionForceParams(s32, s16);
// void StopDirtRoadEffect(s32);
// void StopSurfaceEffect(s32);
}; // class LGWheels
LGPosition &getPosition(int idx) {return mPosition[idx]; }
LGPosition mPosition[4];
u8 _28[0x1440]; // TODO
}; // Size: 0x1468
#endif // LOGITECH_WHEELS_H

View File

@ -11,7 +11,7 @@ extern "C"
// This file presumably was for a logitech steering wheel, as it is some sort of controller handler
struct LGPosition { // seems really similar to PADStatus but is slightly different
u16 input;
u16 button;
s8 _2;
s8 steerDirection;
u8 gasPedal;

View File

@ -5,6 +5,8 @@
extern u32 __PADFixBits;
#define PAD_CONTROLLER_NUM 4
#define PAD_SPEC_0 0
#define PAD_SPEC_1 1
#define PAD_SPEC_2 2
@ -40,6 +42,14 @@ extern u32 __PADFixBits;
#define PAD_BUTTON_Y 0x0800
#define PAD_BUTTON_MENU 0x1000
#define PAD_BUTTON_START 0x1000
#define PAD_SUBSTICK_LEFT 0x10000
#define PAD_SUBSTICK_RIGHT 0x20000
#define PAD_SUBSTICK_DOWN 0x40000
#define PAD_SUBSTICK_UP 0x80000
#define PAD_STICK_LEFT 0x1000000
#define PAD_STICK_RIGHT 0x2000000
#define PAD_STICK_DOWN 0x4000000
#define PAD_STICK_UP 0x8000000
#define PAD_CHAN0_BIT 0x80000000
#define PAD_CHAN1_BIT 0x40000000

View File

@ -22,7 +22,7 @@ JKRArchive *JKRArchive::check_mount_already(long entryNum, JKRHeap *pHeap)
{
if (iterator->getVolumeType() == 'RARC')
{
JKRArchive *archive = (JKRArchive *)iterator.getObject(); // in TP debug it calls operator-> ?
JKRArchive *archive = (JKRArchive *)iterator.operator->();
if (archive->mEntryNum == entryNum && archive->mHeap == heap)
{
archive->mMountCount++;

View File

@ -0,0 +1,772 @@
#include "JSystem/JUtility/JUTGamePad.h"
#include "JSystem/JKernel/JKRHeap.h"
#include <math.h>
#include <std/math.h>
u32 JUTGamePad::CRumble::sChannelMask[PAD_CONTROLLER_NUM] = {
0x80000000 >> 0,
0x80000000 >> 1,
0x80000000 >> 2,
0x80000000 >> 3};
static u32 channel_mask[PAD_CONTROLLER_NUM] = {
0x80000000 >> 0,
0x80000000 >> 1,
0x80000000 >> 2,
0x80000000 >> 3};
JUTGamePad::EStickMode JUTGamePad::sStickMode = Clamped;
JUTGamePad::EClampMode JUTGamePad::sClampMode = Clamp;
f32 JUTGamePad::sPressPoint = 0.5f;
f32 JUTGamePad::sReleasePoint = 0.25f;
u32 JUTGamePad::C3ButtonReset::sResetPattern = START | X | B;
u32 JUTGamePad::C3ButtonReset::sResetMaskPattern = 0xFFFF;
JSUList<JUTGamePad> JUTGamePad::mPadList(false);
PADStatus JUTGamePad::mPadStatus[PAD_CONTROLLER_NUM];
JUTGamePad::CButton JUTGamePad::mPadButton[PAD_CONTROLLER_NUM];
JUTGamePad::CStick JUTGamePad::mPadMStick[PAD_CONTROLLER_NUM];
JUTGamePad::CStick JUTGamePad::mPadSStick[PAD_CONTROLLER_NUM];
s32 JUTGamePad::msaSIType[PAD_CONTROLLER_NUM];
bool JUTGamePad::mListInitialized = false;
u8 JUTGamePad::mPadAssign[PAD_CONTROLLER_NUM];
LGWheels *JUTGamePad::mspLGWheels;
u32 JUTGamePad::sSuppressPadReset = 0;
bool JUTGamePad::sErrorReport = false;
u32 JUTGamePad::sAnalogMode = 0;
u32 JUTGamePad::sRumbleSupported = 0;
u8 JUTGamePad::CRumble::mStatus[PAD_CONTROLLER_NUM];
u32 JUTGamePad::CRumble::mEnabled = 0;
JUTResetBtnCb JUTGamePad::C3ButtonReset::sCallback = nullptr;
void *JUTGamePad::C3ButtonReset::sCallbackArg = nullptr;
OSTime JUTGamePad::C3ButtonReset::sThreshold = (OSTime)(OS_TIMER_CLOCK / 60) * 30;
bool JUTGamePad::C3ButtonReset::sResetSwitchPushing = false;
bool JUTGamePad::C3ButtonReset::sResetOccurred = false;
s32 JUTGamePad::C3ButtonReset::sResetOccurredPort = 0;
JSUList<JUTGamePadLongPress> JUTGamePadLongPress::sPatternList(false);
JUTGamePad::JUTGamePad(EPadPort port)
: mButtons(),
mMainStick(),
mSubStick(),
mRumble(this),
mLink(this),
mButtonReset()
{
mPortNum = port;
if (mPortNum >= 0)
{
mPadAssign[port]++;
}
initList();
JUTGamePad::mPadList.append(&mLink);
update();
mPadRecord = nullptr;
mPadReplay = nullptr;
clear();
}
JUTGamePad::JUTGamePad()
: mButtons(),
mMainStick(),
mSubStick(),
mRumble(this),
mLink(this),
mButtonReset()
{
mPortNum = -1;
initList();
JUTGamePad::mPadList.append(&mLink);
mPadRecord = nullptr;
mPadReplay = nullptr;
clear();
}
JUTGamePad::~JUTGamePad()
{
if (mPortNum >= 0)
{
mPadAssign[mPortNum]--;
mPortNum = -1;
}
JUTGamePad::mPadList.remove(&mLink);
}
void JUTGamePad::initList()
{
if (!JUTGamePad::mListInitialized)
{
JUTGamePad::mPadList.initiate();
JUTGamePad::mListInitialized = true;
}
}
void JUTGamePad::init()
{
PADSetSpec(5);
JUTGamePad::sAnalogMode = 3;
PADSetAnalogMode(3);
PADInit();
if (mspLGWheels == nullptr)
mspLGWheels = new (JKRGetSystemHeap(), 0) LGWheels();
}
void JUTGamePad::clear()
{
mButtonReset.mReset = false;
}
u32 JUTGamePad::read()
{
sRumbleSupported = PADRead(mPadStatus);
mspLGWheels->ReadAll();
switch (sClampMode)
{
case 1:
PADClamp(mPadStatus);
break;
case 2:
PADClampCircle(mPadStatus);
break;
}
u32 mask_tmp;
u32 mask = 0;
for (int i = 0; i < PAD_CONTROLLER_NUM; i++)
{
u32 stick_buttons;
u32 siType = SIProbe(i);
msaSIType[i] = siType;
switch (siType)
{
case SI_TYPE_GC:
if(mspLGWheels->IsConnected(i))
{
LGPosition *lgPosition = &mspLGWheels->mPosition[i];
stick_buttons = mPadMStick[i].update(lgPosition->steerDirection, mPadButton[i].mButton) << 24;
mPadButton[i].update(lgPosition, stick_buttons);
}
break;
case SI_GC_CONTROLLER:
case SI_GC_WAVEBIRD:
mask_tmp = 0x80000000 >> i;
if (mPadStatus[i].err == PAD_ERR_NONE)
{
PADStatus *padStatus = &mPadStatus[i];
stick_buttons = (mPadMStick[i].update(padStatus->stickX, padStatus->stickY,
sStickMode, WhichStick_MainStick, mPadButton[i].mButton)
<< 0x18);
stick_buttons |= (mPadSStick[i].update(padStatus->substickX, padStatus->substickY,
sStickMode, WhichStick_SubStick, mPadButton[i].mButton)
<< 0x10);
mPadButton[i].update(padStatus, stick_buttons);
}
else if (mPadStatus[i].err == PAD_ERR_NO_CONTROLLER)
{
mPadMStick[i].update(0, 0, sStickMode, WhichStick_MainStick, 0);
mPadSStick[i].update(0, 0, sStickMode, WhichStick_SubStick, 0);
mPadButton[i].update((PADStatus*)0, 0);
if (!(sSuppressPadReset & (mask_tmp)))
{
mask |= mask_tmp;
}
}
else
{
#ifdef DEBUG
if (sErrorReport)
OSReport("game pad read error (%d)\n", mPadStatus[i].err);
#endif
mPadButton[i].mTrigger = 0;
mPadButton[i].mRelease = 0;
mPadButton[i].mRepeat = 0;
}
break;
default:
break;
}
}
JSUListIterator<JUTGamePad> pad = (mPadList.getFirst());
for (; pad != mPadList.getEnd(); ++pad)
{
if (pad->getPadReplay() && pad->getPadReplay()->isActive())
{
PADStatus status;
pad->getPadReplay()->read(&status);
u32 stick = pad->mMainStick.update(status.stickX, status.stickY, sStickMode,
WhichStick_MainStick, pad->mButtons.mButton)
<< 0x18;
stick |= pad->mSubStick.update(status.substickX, status.substickY, sStickMode,
WhichStick_SubStick, pad->mButtons.mButton)
<< 0x10;
pad->mButtons.update(&status, stick);
}
else
{
if (pad->mPortNum == -1)
pad->assign();
if (pad->mPortNum != -999)
pad->update();
}
if (pad->getPadRecord() && pad->getPadRecord()->isActive())
{
if (pad->mPortNum >= 0)
{
int portNum = pad->mPortNum;
if (mPadStatus[portNum].err == 0)
pad->getPadRecord()->write(&mPadStatus[portNum]);
}
}
}
if (mask != 0)
{
PADReset(mask);
}
checkResetSwitch();
return sRumbleSupported;
}
void JUTGamePad::assign()
{
for (s32 i = 0; i < PAD_CONTROLLER_NUM; i++)
{
if (JUTGamePad::mPadStatus[i].err == 0 && JUTGamePad::mPadAssign[i] == 0)
{
mPortNum = i;
JUTGamePad::mPadAssign[i] = 1;
JUTGamePad::mPadButton[i].setRepeat(mButtons.mRepeatMask, mButtons.mRepeatDelay, mButtons.mRepeatFrequency);
mRumble.clear(this);
break;
}
}
}
void JUTGamePad::checkResetCallback(OSTime time)
{
if (mPortNum >= 0 && time >= JUTGamePad::C3ButtonReset::sThreshold)
{
JUTGamePad::C3ButtonReset::sResetOccurred = true;
JUTGamePad::C3ButtonReset::sResetOccurredPort = mPortNum;
if (JUTGamePad::C3ButtonReset::sCallback)
{
(*JUTGamePad::C3ButtonReset::sCallback)(mPortNum, JUTGamePad::C3ButtonReset::sCallbackArg);
}
}
}
void JUTGamePad::update()
{
if (mPortNum >= 0)
{
mButtons = JUTGamePad::mPadButton[mPortNum];
mMainStick = JUTGamePad::mPadMStick[mPortNum];
mSubStick = JUTGamePad::mPadSStick[mPortNum];
mErrorStatus = JUTGamePad::mPadStatus[mPortNum].err;
if (JUTGamePad::C3ButtonReset::sResetPattern != (mButtons.mButton & JUTGamePad::C3ButtonReset::sResetMaskPattern))
{
mButtonReset.mReset = false;
}
else if (JUTGamePad::C3ButtonReset::sResetOccurred == false)
{
if (mButtonReset.mReset == true)
{
s64 diff = OSGetTime() - mResetTime;
checkResetCallback(diff);
}
else
{
mButtonReset.mReset = true;
mResetTime = OSGetTime();
}
}
JSUListIterator<JUTGamePadLongPress> pad = JUTGamePadLongPress::sPatternList.getFirst();
for (; pad != JUTGamePadLongPress::sPatternList.getEnd(); ++pad)
{
if (mPortNum >= 0 && mPortNum < 4)
{
if (pad->isValid())
{
if ((mButtons.mButton & pad->getMaskPattern()) == pad->getPattern())
{
if (pad->_20[mPortNum] == true)
{
s64 diff = OSGetTime() - pad->mTimer[mPortNum];
pad->checkCallback(mPortNum, diff);
continue;
}
pad->_20[mPortNum] = true;
pad->mTimer[mPortNum] = OSGetTime();
continue;
}
pad->_20[mPortNum] = false;
}
}
}
mRumble.update(mPortNum);
}
}
void JUTGamePad::checkResetSwitch()
{
if (!JUTGamePad::C3ButtonReset::sResetOccurred)
{
if (OSGetResetSwitchState() != 0)
{
JUTGamePad::C3ButtonReset::sResetSwitchPushing = true;
}
else
{
if (JUTGamePad::C3ButtonReset::sResetSwitchPushing == true)
{
JUTGamePad::C3ButtonReset::sResetOccurred = true;
JUTGamePad::C3ButtonReset::sResetOccurredPort = -1;
if (*JUTGamePad::C3ButtonReset::sCallback != nullptr)
{
(*JUTGamePad::C3ButtonReset::sCallback)(-1, JUTGamePad::C3ButtonReset::sCallbackArg);
}
}
JUTGamePad::C3ButtonReset::sResetSwitchPushing = false;
}
}
}
void JUTGamePad::CButton::clear()
{
mButton = 0;
mTrigger = 0;
mRelease = 0;
mRepeat = 0;
mAnalogA = 0;
mAnalogB = 0;
mAnalogL = 0;
mAnalogR = 0;
mRepeatTimer = 0;
mRepeatLastButton = 0;
mRepeatMask = 0;
mRepeatDelay = 0;
mRepeatFrequency = 0;
}
void JUTGamePad::CButton::update(const PADStatus *padStatus, u32 stick_buttons)
{
u32 tempButtons;
u32 buttons;
if (padStatus != nullptr)
{
tempButtons = padStatus->button;
}
else
{
tempButtons = 0;
}
buttons = stick_buttons | tempButtons;
mRepeat = 0;
if (mRepeatDelay != 0)
{
if (mRepeatMask != 0)
{
u32 repeatButtons = buttons & mRepeatMask;
mRepeat = 0;
if (repeatButtons == 0)
{
mRepeatLastButton = 0;
mRepeatTimer = 0;
}
else if (mRepeatLastButton == repeatButtons)
{
mRepeatTimer++;
if (
mRepeatTimer == mRepeatDelay ||
(mRepeatTimer > mRepeatDelay && ((mRepeatTimer - mRepeatDelay) % mRepeatFrequency) == 0))
{
mRepeat = repeatButtons;
}
}
else
{
mRepeat = repeatButtons & (mRepeatLastButton ^ 0xFFFFFFFF);
mRepeatLastButton = repeatButtons;
mRepeatTimer = 0;
}
}
}
mTrigger = buttons & (buttons ^ mButton);
mRelease = mButton & (buttons ^ mButton);
mButton = buttons;
mRepeat |= (mRepeatMask ^ 0xFFFFFFFF) & mTrigger;
if (padStatus != nullptr)
{
mAnalogA = padStatus->analogA;
mAnalogB = padStatus->analogB;
mAnalogL = padStatus->triggerLeft;
mAnalogR = padStatus->triggerRight;
}
else
{
mAnalogA = 0;
mAnalogB = 0;
mAnalogL = 0;
mAnalogR = 0;
}
mAnalogLf = (f32)(int)mAnalogL / 150.0f;
mAnalogRf = (f32)(int)mAnalogR / 150.0f;
}
void JUTGamePad::CButton::update(const LGPosition *lgPosition, u32 mask)
{
if (lgPosition->button & PAD_BUTTON_A)
mask |= PAD_BUTTON_A;
if (lgPosition->button & PAD_BUTTON_B)
mask |= PAD_BUTTON_B;
if (lgPosition->button & PAD_BUTTON_X)
mask |= PAD_BUTTON_X;
if (lgPosition->button & PAD_BUTTON_Y)
mask |= PAD_BUTTON_Y;
if (lgPosition->button & PAD_BUTTON_START)
mask |= PAD_BUTTON_START;
if (lgPosition->button & PAD_TRIGGER_L)
mask |= PAD_TRIGGER_L;
if (lgPosition->button & PAD_TRIGGER_R)
mask |= PAD_TRIGGER_R;
if (lgPosition->button & PAD_TRIGGER_Z)
mask |= PAD_TRIGGER_Z;
if (lgPosition->button & PAD_BUTTON_LEFT)
mask |= (PAD_BUTTON_LEFT | PAD_STICK_LEFT);
if (lgPosition->button & PAD_BUTTON_RIGHT)
mask |= (PAD_BUTTON_RIGHT | PAD_STICK_RIGHT);
if (lgPosition->button & PAD_BUTTON_DOWN)
mask |= (PAD_BUTTON_DOWN | PAD_STICK_DOWN);
if (lgPosition->button & PAD_BUTTON_UP)
mask |= (PAD_BUTTON_UP | PAD_STICK_UP);
if (lgPosition->gasPedal == 255)
mask |= PAD_BUTTON_A;
if (lgPosition->brakePedal == 255)
mask |= PAD_BUTTON_B;
if (mRepeatDelay != 0 && mRepeatMask != 0)
{
u32 pressedButtons = mask & mRepeatMask;
mRepeat = 0;
if(pressedButtons == 0) {
mRepeatLastButton = 0;
mRepeatTimer = 0;
}
else if (mRepeatLastButton == pressedButtons)
{
mRepeatTimer++;
if (mRepeatTimer == mRepeatDelay || (mRepeatTimer > mRepeatDelay && !((mRepeatTimer - mRepeatDelay) % mRepeatFrequency)))
mRepeat = pressedButtons;
}
else {
mRepeat = pressedButtons & (mRepeatLastButton ^ 0xffffffff);
mRepeatLastButton = pressedButtons;
mRepeatTimer = 0;
}
}
mTrigger = mask & (mask ^mButton);
mRelease = mButton & (mask ^ mButton);
mButton = mask;
mRepeat = mRepeat | (mRepeatMask ^ 0xffffffff) & mTrigger;
mAnalogA = lgPosition->gasPedal;
mAnalogB = lgPosition->brakePedal;
mAnalogL = lgPosition->analogL;
mAnalogR = lgPosition->analogR;
mAnalogLf = mAnalogL / 255.0f;
mAnalogRf = mAnalogR / 255.0f;
}
void JUTGamePad::CStick::clear()
{
mX = 0.0f;
mY = 0.0f;
mValue = 0.0f;
mAngle = 0;
}
u32 JUTGamePad::CStick::update(s8 x, s8 y, EStickMode stickMode, EWhichStick whichStick, u32 mask)
{
s32 clamp;
switch (getClampMode())
{
case Clamp:
clamp = whichStick == WhichStick_MainStick ? 54 : 42;
break;
case ClampCircle:
clamp = whichStick == WhichStick_MainStick ? 38 : 29;
break;
default:
clamp = whichStick == WhichStick_MainStick ? 69 : 57;
break;
}
mAnalogX = x;
mAnalogY = y;
mX = (f32)x / clamp;
mY = (f32)y / clamp;
mValue = std::sqrtf(mX * mX + mY * mY); // calls real sqrtf
if (mValue > 1.0f)
{
if (stickMode == Clamped)
{
mX /= mValue;
mY /= mValue;
}
mValue = 1.0f;
}
if (mValue > 0.0f)
{
if (mY == 0.0f)
{
if (mX > 0.0f)
{
mAngle = 0x4000;
}
else
{
mAngle = -0x4000;
}
}
else
{
mAngle = atan2f(mX, -mY) * 10430.379f; //((f32)0x8000 / F_PI);
}
}
return getButton(mask >> (whichStick == WhichStick_MainStick ? 0x18 : 0x10));
}
u32 JUTGamePad::CStick::update(s8 x, u32 mask)
{
mAnalogX = x;
if (mAnalogX < -127)
mAnalogX = -127;
mAnalogY = 0;
mX = x / 127.0f;
mY = 0.0f;
mValue = mX;
return getButton(mask >> 24);
}
u32 JUTGamePad::CStick::getButton(u32 mask)
{
u32 button = mask & 0xf;
if (-sReleasePoint < mX && mX < sReleasePoint)
{
button &= ~(DPAD_LEFT | DPAD_RIGHT);
}
else if (mX <= -sPressPoint)
{
button &= ~DPAD_RIGHT;
button |= DPAD_LEFT;
}
else if (mX >= sPressPoint)
{
button &= ~DPAD_LEFT;
button |= DPAD_RIGHT;
}
if (-sReleasePoint < mY && mY < sReleasePoint)
{
button &= ~(DPAD_DOWN | DPAD_UP);
}
else if (mY <= -sPressPoint)
{
button &= ~DPAD_UP;
button |= DPAD_DOWN;
}
else if (mY >= sPressPoint)
{
button &= ~DPAD_DOWN;
button |= DPAD_UP;
}
return button;
}
void JUTGamePad::CRumble::clear()
{
mFrame = 0;
mLength = 0;
mData = nullptr;
mFrameCount = 0;
_10 = 0;
JUTGamePad::CRumble::mEnabled = 0xF0000000;
}
void JUTGamePad::CRumble::clear(JUTGamePad *gamePad)
{
if (0 <= (s16)gamePad->getPortNum() && (s16)gamePad->getPortNum() < PAD_CONTROLLER_NUM)
{
JUTGamePad::CRumble::mStatus[(s16)gamePad->getPortNum()] = 0;
gamePad->stopMotorHard();
}
clear();
}
void JUTGamePad::CRumble::startMotor(int port)
{
if (JUTGamePad::CRumble::isEnabledPort(port))
{
PADControlMotor(port, PAD_MOTOR_RUMBLE);
JUTGamePad::CRumble::mStatus[port] = 1;
}
}
void JUTGamePad::CRumble::stopMotor(int port, bool hard)
{
if (JUTGamePad::CRumble::isEnabledPort(port))
{
PADControlMotor(port, (u8)(hard ? PAD_MOTOR_STOP_HARD : PAD_MOTOR_STOP));
JUTGamePad::CRumble::mStatus[port] = 0;
}
}
static bool getNumBit(u8 *data, int bit)
{
u8 numBit = ((0x80 >> (bit & 7)) & data[bit >> 3] );
return numBit != 0;
}
void JUTGamePad::CRumble::update(s16 port)
{
if (!isEnabledPort(port))
{
mFrame = 0;
mLength = 0;
mData = nullptr;
mFrameCount = 0;
_10 = 0;
}
if (mLength != 0)
{
if (mFrame >= mLength)
{
JUTGamePad::CRumble::stopMotorHard(port);
mLength = 0;
}
else
{
if (mFrameCount == 0)
{
if (JUTGamePad::CRumble::mStatus[port] == 0)
{
JUTGamePad::CRumble::startMotor(port);
}
return;
}
bool enable = getNumBit(mData, mFrame % mFrameCount);
bool status = !JUTGamePad::CRumble::mStatus[port];
if (enable && !status)
{
JUTGamePad::CRumble::startMotor(port);
}
else if (!enable)
{
bool hardstop = getNumBit(_10, mFrame % mFrameCount);
if (status)
JUTGamePad::CRumble::stopMotor(port, hardstop);
else if (hardstop)
{
JUTGamePad::CRumble::stopMotor(port, true);
}
}
}
mFrame++;
}
}
void JUTGamePad::CButton::setRepeat(u32 repeatMask, u32 repeatDelay, u32 repeatFreq)
{
mRepeatLastButton = 0;
mRepeatTimer = 0;
mRepeatMask = repeatMask;
mRepeatDelay = repeatDelay;
mRepeatFrequency = repeatFreq;
}
void JUTGamePad::setButtonRepeat(u32 repeatMask, u32 repeatDelay, u32 repeatFreq)
{
mButtons.setRepeat(repeatMask, repeatDelay, repeatFreq);
if (mPortNum >= 0)
mPadButton[mPortNum].setRepeat(repeatMask, repeatDelay, repeatFreq);
}
bool JUTGamePad::recalibrate(u32 channels)
{
for (int i = 0; i < PAD_CONTROLLER_NUM; i++)
{
if ((JUTGamePad::sSuppressPadReset & channel_mask[i]) != 0)
{
channels &= channel_mask[i] ^ 0xFFFFFFFF;
}
}
BOOL res = PADRecalibrate(channels);
return res;
}
void JUTGamePadLongPress::checkCallback(int port, u32 timer)
{
if (port >= 0)
{
// assert not present in mkdd debug? interesting
// JUT_ASSERT(0 <= port && port < 4)
if (timer >= _1C)
{
_11 = true;
_48[port] = true;
if (mCallback)
{
mCallback(port, this, _50);
}
}
}
}

View File

@ -76,6 +76,8 @@ double __kernel_tan(double, double, int);
int __ieee754_rem_pio2(double, double*);
static inline float atan2f(float y, float x) { return atan2(y, x); }
// float sqrtf(float);
#ifdef __cplusplus

View File

@ -76,7 +76,7 @@ void KartGamePad::compress(const LGPosition &lgPosition, KartPadData *kartPadDat
if (stickX < -15)
stickX = -15;
u16 input = lgPosition.input;
u16 input = lgPosition.button;
ConvertBtn(buttons, input, A, KARTBTN_A);
ConvertBtn(buttons, input, B, KARTBTN_B);
ConvertBtn(buttons, input, X, KARTBTN_X);
@ -135,7 +135,7 @@ void KartGamePad::expand(const KartPadData &kartPadData)
padStatus.triggerRight = 0;
padStatus.button = btn;
u32 btnret = mControlStick.update(padStatus.stickX, padStatus.stickY, sStickMode, WhichStick_ControlStick, mButtons.mInput) << 24;
u32 btnret = mMainStick.update(padStatus.stickX, padStatus.stickY, sStickMode, WhichStick_MainStick, mButtons.mButton) << 24;
mButtons.update(&padStatus, btnret);
}