Fixed the GC Steering Wheel and Dance Mat identification.

This commit is contained in:
skidau 2015-01-07 23:40:41 +11:00
parent c6e2449bff
commit 99ca789b97
6 changed files with 105 additions and 10 deletions

View File

@ -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<EBufferCommands>(_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;
}

View File

@ -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;
};

View File

@ -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

View File

@ -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);

View File

@ -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<EBufferCommands>(_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);

View File

@ -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);
};