mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 12:35:27 +00:00
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
|
||||
if (tmpStatus.WR)
|
||||
{
|
||||
g_Channel[0].m_pDevice->SendCommand(g_Channel[0].m_Out.Hex);
|
||||
g_Channel[1].m_pDevice->SendCommand(g_Channel[1].m_Out.Hex);
|
||||
g_Channel[2].m_pDevice->SendCommand(g_Channel[2].m_Out.Hex);
|
||||
g_Channel[3].m_pDevice->SendCommand(g_Channel[3].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_Poll.EN1);
|
||||
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_Poll.EN3);
|
||||
|
||||
g_StatusReg.WR = 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;}
|
||||
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;
|
||||
|
||||
// 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
|
||||
|
@ -145,7 +145,7 @@ CSIDevice_GBA::GetData(u32& _Hi, u32& _Low)
|
||||
// SendCommand
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
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);
|
||||
}
|
||||
|
@ -84,6 +84,6 @@ public:
|
||||
virtual bool GetData(u32& _Hi, u32& _Low);
|
||||
|
||||
// Send a command directly
|
||||
virtual void SendCommand(u32 _Cmd);
|
||||
virtual void SendCommand(u32 _Cmd, u8 _Poll);
|
||||
};
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "SI.h"
|
||||
#include "SI_Device.h"
|
||||
#include "SI_DeviceGCController.h"
|
||||
|
||||
@ -44,8 +45,8 @@ CSIDevice_GCController::CSIDevice_GCController(int _iDeviceNumber) :
|
||||
m_origin.uSubStickStickY = 0x80;
|
||||
m_origin.uTrigger_L = 0x1F; // 0-30 is the lower deadzone
|
||||
m_origin.uTrigger_R = 0x1F;
|
||||
// I'm borrowing this variable for the PadAnalogMode
|
||||
m_origin.unk_1 = 3; // Mode 3 as default
|
||||
// Dunno if we need to do this, game/lib should set it?
|
||||
m_Mode = 0x03; // PadAnalogMode 3 as default
|
||||
}
|
||||
|
||||
int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength)
|
||||
@ -54,14 +55,14 @@ int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength)
|
||||
ISIDevice::RunBuffer(_pBuffer, _iLength);
|
||||
|
||||
int iPosition = 0;
|
||||
while(iPosition < _iLength)
|
||||
while (iPosition < _iLength)
|
||||
{
|
||||
// Read the command
|
||||
EBufferCommands command = static_cast<EBufferCommands>(_pBuffer[iPosition ^ 3]);
|
||||
iPosition++;
|
||||
|
||||
// Handle it
|
||||
switch(command)
|
||||
switch (command)
|
||||
{
|
||||
case CMD_RESET:
|
||||
{
|
||||
@ -144,31 +145,58 @@ CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Thankfully changing mode does not change the high bits ;)
|
||||
_Hi = (u32)((u8)PadStatus.stickY);
|
||||
_Hi |= (u32)((u8)PadStatus.stickX << 8);
|
||||
_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 |= 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);
|
||||
_Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4);
|
||||
_Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 8);
|
||||
_Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 12);
|
||||
_Low |= (u32)((u8)(PadStatus.substickY) << 16);
|
||||
_Low |= (u32)((u8)(PadStatus.substickX) << 24);
|
||||
_Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits
|
||||
_Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits
|
||||
_Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 8); // Top 4 bits
|
||||
_Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 12); // Top 4 bits
|
||||
_Low |= (u32)((u8)(PadStatus.substickY) << 16); // All 8 bits
|
||||
_Low |= (u32)((u8)(PadStatus.substickX) << 24); // All 8 bits
|
||||
}
|
||||
else
|
||||
else if (m_Mode == 1)
|
||||
{
|
||||
// Mode 3
|
||||
_Low = (u8)PadStatus.triggerRight;
|
||||
_Low |= (u32)((u8)PadStatus.triggerLeft << 8);
|
||||
_Low |= (u32)((u8)PadStatus.substickY << 16);
|
||||
_Low |= (u32)((u8)PadStatus.substickX << 24);
|
||||
_Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits
|
||||
_Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits
|
||||
_Low |= (u32)((u8)PadStatus.triggerRight << 8); // All 8 bits
|
||||
_Low |= (u32)((u8)PadStatus.triggerLeft << 16); // All 8 bits
|
||||
_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
|
||||
|
||||
@ -179,28 +207,29 @@ CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||
// SendCommand
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CSIDevice_GCController::SendCommand(u32 _Cmd)
|
||||
CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll)
|
||||
{
|
||||
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber);
|
||||
UCommand command(_Cmd);
|
||||
|
||||
switch(command.Command)
|
||||
switch (command.Command)
|
||||
{
|
||||
// Costis sent it in some demos :)
|
||||
case 0x00:
|
||||
break;
|
||||
|
||||
case CMD_RUMBLE:
|
||||
case CMD_WRITE:
|
||||
{
|
||||
unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard
|
||||
unsigned int uStrength = command.Parameter2;
|
||||
if (pad->PAD_Rumble)
|
||||
pad->PAD_Rumble(ISIDevice::m_iDeviceNumber, uType, uStrength);
|
||||
|
||||
// Set PadAnalogMode. Hopefully this will not be confused with rumble messages. Most games
|
||||
// seems to always use uStrength = 3 for all rumble messages.
|
||||
if (command.Parameter1 == 0 && command.Parameter2 == 0)
|
||||
m_origin.unk_1 = 0;
|
||||
if (!_Poll)
|
||||
{
|
||||
m_Mode = command.Parameter2;
|
||||
ERROR_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -55,24 +55,25 @@ private:
|
||||
|
||||
enum EDirectCommands
|
||||
{
|
||||
CMD_RUMBLE = 0x40
|
||||
CMD_WRITE = 0x40
|
||||
};
|
||||
|
||||
union UCommand
|
||||
{
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
{
|
||||
unsigned Parameter1 : 8;
|
||||
unsigned Parameter2 : 8;
|
||||
unsigned Command : 8;
|
||||
unsigned : 8;
|
||||
};
|
||||
UCommand() {Hex = 0;}
|
||||
UCommand() {Hex = 0;}
|
||||
UCommand(u32 _iValue) {Hex = _iValue;}
|
||||
};
|
||||
|
||||
SOrigin m_origin;
|
||||
u8 m_Mode;
|
||||
|
||||
public:
|
||||
|
||||
@ -89,6 +90,6 @@ public:
|
||||
virtual bool GetData(u32& _Hi, u32& _Low);
|
||||
|
||||
// Send a command directly
|
||||
virtual void SendCommand(u32 _Cmd);
|
||||
virtual void SendCommand(u32 _Cmd, u8 _Poll);
|
||||
};
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user