diff --git a/Source/Core/Core/HW/SI_DeviceDanceMat.cpp b/Source/Core/Core/HW/SI_DeviceDanceMat.cpp index ca12a9e343..aee323a914 100644 --- a/Source/Core/Core/HW/SI_DeviceDanceMat.cpp +++ b/Source/Core/Core/HW/SI_DeviceDanceMat.cpp @@ -7,6 +7,24 @@ CSIDevice_DanceMat::CSIDevice_DanceMat(SIDevices device, int _iDeviceNumber) : CSIDevice_GCController(device, _iDeviceNumber) {} +int CSIDevice_DanceMat::RunBuffer(u8* _pBuffer, int _iLength) +{ + // Read the command + EBufferCommands command = static_cast(_pBuffer[3]); + + if (command == CMD_RESET) + { + ISIDevice::RunBuffer(_pBuffer, _iLength); + *(u32*)&_pBuffer[0] = SI_DANCEMAT; + } + else + { + return CSIDevice_GCController::RunBuffer(_pBuffer, _iLength); + } + + return _iLength; +} + u32 CSIDevice_DanceMat::MapPadStatus(const GCPadStatus& pad_status) { // Map the dpad to the blue arrows, the buttons to the orange arrows @@ -36,6 +54,12 @@ u32 CSIDevice_DanceMat::MapPadStatus(const GCPadStatus& pad_status) return (u32)(map << 16) | 0x8080; } -void CSIDevice_DanceMat::HandleButtonCombos(const GCPadStatus& pad_status) +bool CSIDevice_DanceMat::GetData(u32& _Hi, u32& _Low) { + CSIDevice_GCController::GetData(_Hi, _Low); + + // Identifies the dance mat + _Low = 0x8080ffff; + + return true; } diff --git a/Source/Core/Core/HW/SI_DeviceDanceMat.h b/Source/Core/Core/HW/SI_DeviceDanceMat.h index 16711d254f..9599c9eda2 100644 --- a/Source/Core/Core/HW/SI_DeviceDanceMat.h +++ b/Source/Core/Core/HW/SI_DeviceDanceMat.h @@ -10,6 +10,7 @@ class CSIDevice_DanceMat : public CSIDevice_GCController { public: CSIDevice_DanceMat(SIDevices device, int _iDeviceNumber); + virtual int RunBuffer(u8* _pBuffer, int _iLength) override; virtual u32 MapPadStatus(const GCPadStatus& pad_status) override; - virtual void HandleButtonCombos(const GCPadStatus& pad_status) override; + virtual bool GetData(u32& _Hi, u32& _Low) override; }; diff --git a/Source/Core/Core/HW/SI_DeviceGCController.cpp b/Source/Core/Core/HW/SI_DeviceGCController.cpp index a656b7f878..ffb911b06f 100644 --- a/Source/Core/Core/HW/SI_DeviceGCController.cpp +++ b/Source/Core/Core/HW/SI_DeviceGCController.cpp @@ -118,14 +118,7 @@ int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength) return _iLength; } - -// GetData - -// Return true on new data (max 7 Bytes and 6 bits ;) -// [00?SYXBA] [1LRZUDRL] [x] [y] [cx] [cy] [l] [r] -// |\_ ERR_LATCH (error latched - check SISR) -// |_ ERR_STATUS (error on last GetData or SendCmd?) -bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) +GCPadStatus CSIDevice_GCController::GetPadStatus() { GCPadStatus PadStatus; memset(&PadStatus, 0, sizeof(PadStatus)); @@ -157,6 +150,19 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); } + return PadStatus; +} + +// GetData + +// Return true on new data (max 7 Bytes and 6 bits ;) +// [00?SYXBA] [1LRZUDRL] [x] [y] [cx] [cy] [l] [r] +// |\_ ERR_LATCH (error latched - check SISR) +// |_ ERR_STATUS (error on last GetData or SendCmd?) +bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) +{ + GCPadStatus PadStatus = GetPadStatus(); + _Hi = MapPadStatus(PadStatus); // Low bits are packed differently per mode diff --git a/Source/Core/Core/HW/SI_DeviceGCController.h b/Source/Core/Core/HW/SI_DeviceGCController.h index 62d946d780..3b0346cbeb 100644 --- a/Source/Core/Core/HW/SI_DeviceGCController.h +++ b/Source/Core/Core/HW/SI_DeviceGCController.h @@ -91,6 +91,7 @@ public: // Return true on new data virtual bool GetData(u32& _Hi, u32& _Low) override; + virtual GCPadStatus GetPadStatus(); virtual u32 MapPadStatus(const GCPadStatus& pad_status); virtual void HandleButtonCombos(const GCPadStatus& pad_status); diff --git a/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.cpp b/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.cpp index cd13c3fd55..e0d43b2b0a 100644 --- a/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.cpp +++ b/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.cpp @@ -9,6 +9,67 @@ CSIDevice_GCSteeringWheel::CSIDevice_GCSteeringWheel(SIDevices device, int _iDev : CSIDevice_GCController(device, _iDeviceNumber) {} +int CSIDevice_GCSteeringWheel::RunBuffer(u8* _pBuffer, int _iLength) +{ + // For debug logging only + ISIDevice::RunBuffer(_pBuffer, _iLength); + + // Read the command + EBufferCommands command = static_cast(_pBuffer[3]); + + // Handle it + switch (command) + { + case CMD_RESET: + *(u32*)&_pBuffer[0] = SI_GC_STEERING; + break; + + // Seen in F-Zero GX + case CMD_MOTOR_OFF: + break; + + // DEFAULT + default: + { + return CSIDevice_GCController::RunBuffer(_pBuffer, _iLength); + } + break; + } + + return _iLength; +} + +bool CSIDevice_GCSteeringWheel::GetData(u32& _Hi, u32& _Low) +{ + if (m_Mode == 6) + { + GCPadStatus PadStatus = GetPadStatus(); + + _Hi = (u32)((u8)PadStatus.stickX); // Steering + _Hi |= 0x800; // Pedal connected flag + _Hi |= (u32)((u16)(PadStatus.button | PAD_USE_ORIGIN) << 16); + + _Low = (u8)PadStatus.triggerRight; // All 8 bits + _Low |= (u32)((u8)PadStatus.triggerLeft << 8); // All 8 bits + + // The GC Steering Wheel appears to have combined pedals + // (both the Accelerate and Brake pedals are mapped to a single axis) + // We use the stickY axis for the pedals. + if (PadStatus.stickY < 128) + _Low |= (u32)((u8)(255 - ((PadStatus.stickY & 0x7f) * 2)) << 16); // All 8 bits (Brake) + if (PadStatus.stickY >= 128) + _Low |= (u32)((u8)((PadStatus.stickY & 0x7f) * 2) << 24); // All 8 bits (Accelerate) + + HandleButtonCombos(PadStatus); + } + else + { + return CSIDevice_GCController::GetData(_Hi, _Low); + } + + return true; +} + void CSIDevice_GCSteeringWheel::SendCommand(u32 _Cmd, u8 _Poll) { UCommand command(_Cmd); diff --git a/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.h b/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.h index b5853713fa..791e30aca9 100644 --- a/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.h +++ b/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.h @@ -26,5 +26,7 @@ private: public: CSIDevice_GCSteeringWheel(SIDevices device, int _iDeviceNumber); + virtual int RunBuffer(u8* _pBuffer, int _iLength); + virtual bool GetData(u32& _Hi, u32& _Low); virtual void SendCommand(u32 _Cmd, u8 _Poll); };