correct handling of pad modes
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3325 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
47c69e5f5a
commit
4380898080
|
@ -452,10 +452,10 @@ void Write32(const u32 _iValue, const u32 _iAddress)
|
||||||
// send command to devices
|
// send command to devices
|
||||||
if (tmpStatus.WR)
|
if (tmpStatus.WR)
|
||||||
{
|
{
|
||||||
g_Channel[0].m_pDevice->SendCommand(g_Channel[0].m_Out.Hex);
|
g_Channel[0].m_pDevice->SendCommand(g_Channel[0].m_Out.Hex, g_Poll.EN0);
|
||||||
g_Channel[1].m_pDevice->SendCommand(g_Channel[1].m_Out.Hex);
|
g_Channel[1].m_pDevice->SendCommand(g_Channel[1].m_Out.Hex, g_Poll.EN1);
|
||||||
g_Channel[2].m_pDevice->SendCommand(g_Channel[2].m_Out.Hex);
|
g_Channel[2].m_pDevice->SendCommand(g_Channel[2].m_Out.Hex, g_Poll.EN2);
|
||||||
g_Channel[3].m_pDevice->SendCommand(g_Channel[3].m_Out.Hex);
|
g_Channel[3].m_pDevice->SendCommand(g_Channel[3].m_Out.Hex, g_Poll.EN3);
|
||||||
|
|
||||||
g_StatusReg.WR = 0;
|
g_StatusReg.WR = 0;
|
||||||
g_StatusReg.WRST0 = 0;
|
g_StatusReg.WRST0 = 0;
|
||||||
|
|
|
@ -72,7 +72,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetData(u32& _Hi, u32& _Low) {INFO_LOG(SERIALINTERFACE, "SI DUMMY %i GetData", this->m_iDeviceNumber); return false;}
|
bool GetData(u32& _Hi, u32& _Low) {INFO_LOG(SERIALINTERFACE, "SI DUMMY %i GetData", this->m_iDeviceNumber); return false;}
|
||||||
void SendCommand(u32 _Cmd) {INFO_LOG(SERIALINTERFACE, "SI DUMMY %i SendCommand: %08x", this->m_iDeviceNumber, _Cmd);}
|
void SendCommand(u32 _Cmd, u8 _Poll){INFO_LOG(SERIALINTERFACE, "SI DUMMY %i SendCommand: %08x", this->m_iDeviceNumber, _Cmd);}
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
virtual bool GetData(u32& _Hi, u32& _Low) = 0;
|
virtual bool GetData(u32& _Hi, u32& _Low) = 0;
|
||||||
|
|
||||||
// Send a command directly (no detour per buffer)
|
// Send a command directly (no detour per buffer)
|
||||||
virtual void SendCommand(u32 _Cmd) = 0;
|
virtual void SendCommand(u32 _Cmd, u8 _Poll) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// SI Device IDs
|
// SI Device IDs
|
||||||
|
|
|
@ -145,7 +145,7 @@ CSIDevice_GBA::GetData(u32& _Hi, u32& _Low)
|
||||||
// SendCommand
|
// SendCommand
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
void
|
void
|
||||||
CSIDevice_GBA::SendCommand(u32 _Cmd)
|
CSIDevice_GBA::SendCommand(u32 _Cmd, u8 _Poll)
|
||||||
{
|
{
|
||||||
INFO_LOG(SERIALINTERFACE, "GBA %i SendCommand: (0x%08x)", this->m_iDeviceNumber, _Cmd);
|
INFO_LOG(SERIALINTERFACE, "GBA %i SendCommand: (0x%08x)", this->m_iDeviceNumber, _Cmd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,6 @@ public:
|
||||||
virtual bool GetData(u32& _Hi, u32& _Low);
|
virtual bool GetData(u32& _Hi, u32& _Low);
|
||||||
|
|
||||||
// Send a command directly
|
// Send a command directly
|
||||||
virtual void SendCommand(u32 _Cmd);
|
virtual void SendCommand(u32 _Cmd, u8 _Poll);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "SI.h"
|
||||||
#include "SI_Device.h"
|
#include "SI_Device.h"
|
||||||
#include "SI_DeviceGCController.h"
|
#include "SI_DeviceGCController.h"
|
||||||
|
|
||||||
|
@ -44,8 +45,8 @@ CSIDevice_GCController::CSIDevice_GCController(int _iDeviceNumber) :
|
||||||
m_origin.uSubStickStickY = 0x80;
|
m_origin.uSubStickStickY = 0x80;
|
||||||
m_origin.uTrigger_L = 0x1F; // 0-30 is the lower deadzone
|
m_origin.uTrigger_L = 0x1F; // 0-30 is the lower deadzone
|
||||||
m_origin.uTrigger_R = 0x1F;
|
m_origin.uTrigger_R = 0x1F;
|
||||||
// I'm borrowing this variable for the PadAnalogMode
|
// Dunno if we need to do this, game/lib should set it?
|
||||||
m_origin.unk_1 = 3; // Mode 3 as default
|
m_Mode = 0x03; // PadAnalogMode 3 as default
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength)
|
int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength)
|
||||||
|
@ -54,14 +55,14 @@ int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength)
|
||||||
ISIDevice::RunBuffer(_pBuffer, _iLength);
|
ISIDevice::RunBuffer(_pBuffer, _iLength);
|
||||||
|
|
||||||
int iPosition = 0;
|
int iPosition = 0;
|
||||||
while(iPosition < _iLength)
|
while (iPosition < _iLength)
|
||||||
{
|
{
|
||||||
// Read the command
|
// Read the command
|
||||||
EBufferCommands command = static_cast<EBufferCommands>(_pBuffer[iPosition ^ 3]);
|
EBufferCommands command = static_cast<EBufferCommands>(_pBuffer[iPosition ^ 3]);
|
||||||
iPosition++;
|
iPosition++;
|
||||||
|
|
||||||
// Handle it
|
// Handle it
|
||||||
switch(command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case CMD_RESET:
|
case CMD_RESET:
|
||||||
{
|
{
|
||||||
|
@ -144,31 +145,58 @@ CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Thankfully changing mode does not change the high bits ;)
|
||||||
_Hi = (u32)((u8)PadStatus.stickY);
|
_Hi = (u32)((u8)PadStatus.stickY);
|
||||||
_Hi |= (u32)((u8)PadStatus.stickX << 8);
|
_Hi |= (u32)((u8)PadStatus.stickX << 8);
|
||||||
_Hi |= (u32)((u16)PadStatus.button << 16);
|
_Hi |= (u32)((u16)PadStatus.button << 16);
|
||||||
_Hi |= 0x00800000; // F|RES: means that the pad must be "combined" with the origin to match the "final" OSPad-Struct
|
_Hi |= 0x00800000; // F|RES: means that the pad must be "combined" with the origin to match the "final" OSPad-Struct
|
||||||
//_Hi |= 0x20000000; // ?
|
//_Hi |= 0x20000000; // ?
|
||||||
|
|
||||||
if (m_origin.unk_1 == 0)
|
// Low bits are packed differently per mode
|
||||||
|
if (m_Mode == 0 || m_Mode == 5 || m_Mode == 6 || m_Mode == 7)
|
||||||
{
|
{
|
||||||
// Mode 0, 5, 6, 7
|
_Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits
|
||||||
_Low = (u8)(PadStatus.analogB >> 4);
|
_Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits
|
||||||
_Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4);
|
_Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 8); // Top 4 bits
|
||||||
_Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 8);
|
_Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 12); // Top 4 bits
|
||||||
_Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 12);
|
_Low |= (u32)((u8)(PadStatus.substickY) << 16); // All 8 bits
|
||||||
_Low |= (u32)((u8)(PadStatus.substickY) << 16);
|
_Low |= (u32)((u8)(PadStatus.substickX) << 24); // All 8 bits
|
||||||
_Low |= (u32)((u8)(PadStatus.substickX) << 24);
|
|
||||||
}
|
}
|
||||||
else
|
else if (m_Mode == 1)
|
||||||
{
|
{
|
||||||
// Mode 3
|
_Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits
|
||||||
_Low = (u8)PadStatus.triggerRight;
|
_Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits
|
||||||
_Low |= (u32)((u8)PadStatus.triggerLeft << 8);
|
_Low |= (u32)((u8)PadStatus.triggerRight << 8); // All 8 bits
|
||||||
_Low |= (u32)((u8)PadStatus.substickY << 16);
|
_Low |= (u32)((u8)PadStatus.triggerLeft << 16); // All 8 bits
|
||||||
_Low |= (u32)((u8)PadStatus.substickX << 24);
|
_Low |= (u32)((u8)PadStatus.substickY << 24); // Top 4 bits
|
||||||
|
_Low |= (u32)((u8)PadStatus.substickX << 28); // Top 4 bits
|
||||||
|
}
|
||||||
|
else if (m_Mode == 2)
|
||||||
|
{
|
||||||
|
_Low = (u8)(PadStatus.analogB); // All 8 bits
|
||||||
|
_Low |= (u32)((u8)(PadStatus.analogA) << 8); // All 8 bits
|
||||||
|
_Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 16); // Top 4 bits
|
||||||
|
_Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 20); // Top 4 bits
|
||||||
|
_Low |= (u32)((u8)PadStatus.substickY << 24); // Top 4 bits
|
||||||
|
_Low |= (u32)((u8)PadStatus.substickX << 28); // Top 4 bits
|
||||||
|
}
|
||||||
|
else if (m_Mode == 3)
|
||||||
|
{
|
||||||
|
// Analog A/B are always 0
|
||||||
|
_Low = (u8)PadStatus.triggerRight; // All 8 bits
|
||||||
|
_Low |= (u32)((u8)PadStatus.triggerLeft << 8); // All 8 bits
|
||||||
|
_Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits
|
||||||
|
_Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits
|
||||||
|
}
|
||||||
|
else if (m_Mode == 4)
|
||||||
|
{
|
||||||
|
_Low = (u8)(PadStatus.analogB); // All 8 bits
|
||||||
|
_Low |= (u32)((u8)(PadStatus.analogA) << 8); // All 8 bits
|
||||||
|
// triggerLeft/Right are always 0
|
||||||
|
_Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits
|
||||||
|
_Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SetMic(PadStatus.MicButton); // This is dumb and should not be here
|
SetMic(PadStatus.MicButton); // This is dumb and should not be here
|
||||||
|
|
||||||
|
@ -179,28 +207,29 @@ CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||||
// SendCommand
|
// SendCommand
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
void
|
void
|
||||||
CSIDevice_GCController::SendCommand(u32 _Cmd)
|
CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll)
|
||||||
{
|
{
|
||||||
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber);
|
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber);
|
||||||
UCommand command(_Cmd);
|
UCommand command(_Cmd);
|
||||||
|
|
||||||
switch(command.Command)
|
switch (command.Command)
|
||||||
{
|
{
|
||||||
// Costis sent it in some demos :)
|
// Costis sent it in some demos :)
|
||||||
case 0x00:
|
case 0x00:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_RUMBLE:
|
case CMD_WRITE:
|
||||||
{
|
{
|
||||||
unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard
|
unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard
|
||||||
unsigned int uStrength = command.Parameter2;
|
unsigned int uStrength = command.Parameter2;
|
||||||
if (pad->PAD_Rumble)
|
if (pad->PAD_Rumble)
|
||||||
pad->PAD_Rumble(ISIDevice::m_iDeviceNumber, uType, uStrength);
|
pad->PAD_Rumble(ISIDevice::m_iDeviceNumber, uType, uStrength);
|
||||||
|
|
||||||
// Set PadAnalogMode. Hopefully this will not be confused with rumble messages. Most games
|
if (!_Poll)
|
||||||
// seems to always use uStrength = 3 for all rumble messages.
|
{
|
||||||
if (command.Parameter1 == 0 && command.Parameter2 == 0)
|
m_Mode = command.Parameter2;
|
||||||
m_origin.unk_1 = 0;
|
ERROR_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ private:
|
||||||
|
|
||||||
enum EDirectCommands
|
enum EDirectCommands
|
||||||
{
|
{
|
||||||
CMD_RUMBLE = 0x40
|
CMD_WRITE = 0x40
|
||||||
};
|
};
|
||||||
|
|
||||||
union UCommand
|
union UCommand
|
||||||
|
@ -73,6 +73,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
SOrigin m_origin;
|
SOrigin m_origin;
|
||||||
|
u8 m_Mode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -89,6 +90,6 @@ public:
|
||||||
virtual bool GetData(u32& _Hi, u32& _Low);
|
virtual bool GetData(u32& _Hi, u32& _Low);
|
||||||
|
|
||||||
// Send a command directly
|
// Send a command directly
|
||||||
virtual void SendCommand(u32 _Cmd);
|
virtual void SendCommand(u32 _Cmd, u8 _Poll);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue