diff --git a/Source/Core/Core/Src/HW/SI.cpp b/Source/Core/Core/Src/HW/SI.cpp index 65a0f15d4e..715c20a969 100644 --- a/Source/Core/Core/Src/HW/SI.cpp +++ b/Source/Core/Core/Src/HW/SI.cpp @@ -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; diff --git a/Source/Core/Core/Src/HW/SI_Device.cpp b/Source/Core/Core/Src/HW/SI_Device.cpp index 8eed040eec..8a41711214 100644 --- a/Source/Core/Core/Src/HW/SI_Device.cpp +++ b/Source/Core/Core/Src/HW/SI_Device.cpp @@ -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);} }; ////////////////////////////////////////////////////////////////////////// diff --git a/Source/Core/Core/Src/HW/SI_Device.h b/Source/Core/Core/Src/HW/SI_Device.h index ed2e086b28..c3bd8dd118 100644 --- a/Source/Core/Core/Src/HW/SI_Device.h +++ b/Source/Core/Core/Src/HW/SI_Device.h @@ -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 diff --git a/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp b/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp index 4f91c175da..7d72d0d163 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp @@ -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); } diff --git a/Source/Core/Core/Src/HW/SI_DeviceGBA.h b/Source/Core/Core/Src/HW/SI_DeviceGBA.h index 6a5a781185..432e435ad9 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGBA.h +++ b/Source/Core/Core/Src/HW/SI_DeviceGBA.h @@ -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 diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp b/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp index 1749ec8ad8..3bcd3ac290 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp @@ -18,6 +18,7 @@ #include #include +#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(_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; diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCController.h b/Source/Core/Core/Src/HW/SI_DeviceGCController.h index e68415afd8..2b2bdf5008 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGCController.h +++ b/Source/Core/Core/Src/HW/SI_DeviceGCController.h @@ -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