diff --git a/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp b/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp index c9b766c467..e68176ac3e 100644 --- a/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp +++ b/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp @@ -8,6 +8,7 @@ #include "Common/MsgHandler.h" #include "Common/Logging/Log.h" #include "Core/ConfigManager.h" +#include "Core/NetPlayProto.h" #include "Core/HW/GCPad.h" #include "Core/HW/SI_DeviceGCAdapter.h" #include "InputCommon/GCAdapter.h" @@ -33,6 +34,27 @@ GCPadStatus CSIDevice_GCAdapter::GetPadStatus() return PadStatus; } +int CSIDevice_GCAdapter::RunBuffer(u8* buffer, int length) +{ + if (!NetPlay::IsNetPlayRunning()) + { + // The previous check is a hack to prevent a netplay desync due to + // SI devices being different and returning different values on + // RunBuffer(); the corresponding code in GCAdapter.cpp has the same + // check. + + // This returns an error value if there is no controller plugged + // into this port on the hardware gc adapter, exposing it to the game. + if (!GCAdapter::DeviceConnected(ISIDevice::m_iDeviceNumber)) + { + TSIDevices device = SI_NONE; + memcpy(buffer, &device, sizeof(device)); + return 4; + } + } + return CSIDevice_GCController::RunBuffer(buffer, length); +} + void CSIDevice_GCController::Rumble(u8 numPad, ControlState strength) { SIDevices device = SConfig::GetInstance().m_SIDevice[numPad]; diff --git a/Source/Core/Core/HW/SI_DeviceGCAdapter.h b/Source/Core/Core/HW/SI_DeviceGCAdapter.h index 16b94bf2ff..f073f318bf 100644 --- a/Source/Core/Core/HW/SI_DeviceGCAdapter.h +++ b/Source/Core/Core/HW/SI_DeviceGCAdapter.h @@ -14,4 +14,5 @@ public: CSIDevice_GCAdapter(SIDevices device, int _iDeviceNumber); GCPadStatus GetPadStatus() override; + int RunBuffer(u8* buffer, int length) override; }; diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index eceed1ed0b..df71a8d846 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -12,6 +12,7 @@ #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/CoreTiming.h" +#include "Core/NetPlayProto.h" #include "Core/HW/SI.h" #include "Core/HW/SystemTimers.h" @@ -417,8 +418,11 @@ void Input(int chan, GCPadStatus* pad) pad->triggerLeft = controller_payload_copy[1 + (9 * chan) + 7]; pad->triggerRight = controller_payload_copy[1 + (9 * chan) + 8]; } - else + else if (!NetPlay::IsNetPlayRunning()) { + // This is a hack to prevent a netplay desync due to SI devices + // being different and returning different values. + // The corresponding code in DeviceGCAdapter has the same check pad->button = PAD_ERR_STATUS; } }