diff --git a/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp b/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp index bb42ff812a..2f955164bf 100644 --- a/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp +++ b/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp @@ -8,7 +8,7 @@ #include "Common/MsgHandler.h" #include "Common/Logging/Log.h" #include "Core/ConfigManager.h" -#include "Core/NetPlayClient.h" +#include "Core/NetPlayProto.h" #include "Core/HW/GCPad.h" #include "Core/HW/SI_DeviceGCAdapter.h" #include "InputCommon/GCAdapter.h" @@ -27,13 +27,9 @@ GCPadStatus CSIDevice_GCAdapter::GetPadStatus() GCPadStatus PadStatus; memset(&PadStatus, 0, sizeof(PadStatus)); - if (NetPlay::IsNetPlayRunning()) - { - const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); - if (numPAD < 4) - GCAdapter::Input(numPAD, &PadStatus); - } - else + // For netplay, the local controllers are polled in GetNetPads(), and + // the remote controllers receive their status there as well + if (!NetPlay::IsNetPlayRunning()) { GCAdapter::Input(ISIDevice::m_iDeviceNumber, &PadStatus); } diff --git a/Source/Core/Core/HW/SI_DeviceGCController.cpp b/Source/Core/Core/HW/SI_DeviceGCController.cpp index cd06dc65ee..572e49c8b8 100644 --- a/Source/Core/Core/HW/SI_DeviceGCController.cpp +++ b/Source/Core/Core/HW/SI_DeviceGCController.cpp @@ -8,7 +8,7 @@ #include "Common/Logging/Log.h" #include "Core/CoreTiming.h" #include "Core/Movie.h" -#include "Core/NetPlayClient.h" +#include "Core/NetPlayProto.h" #include "Core/HW/GCPad.h" #include "Core/HW/ProcessorInterface.h" #include "Core/HW/SI_Device.h" @@ -145,13 +145,9 @@ GCPadStatus CSIDevice_GCController::GetPadStatus() GCPadStatus PadStatus; memset(&PadStatus, 0, sizeof(PadStatus)); - if (NetPlay::IsNetPlayRunning()) - { - const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); - if (numPAD < 4) - Pad::GetStatus(numPAD, &PadStatus); - } - else + // For netplay, the local controllers are polled in GetNetPads(), and + // the remote controllers receive their status there as well + if (!NetPlay::IsNetPlayRunning()) { Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); } diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index 229658cd5a..a8992e1a21 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -19,6 +19,7 @@ #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "Core/HW/WiimoteReal/WiimoteReal.h" #include "Core/IPC_HLE/WII_IPC_HLE_Device_usb.h" +#include "InputCommon/GCAdapter.h" static std::mutex crit_netplay_client; static NetPlayClient * netplay_client = nullptr; @@ -864,31 +865,43 @@ bool NetPlayClient::GetNetPads(const u8 pad_nb, GCPadStatus* pad_status) // // The slot number is the "local" pad number, and what player // it actually means is the "in-game" pad number. - // - // GetNetPads() gets called for all "in-game" pads with the their - // status. For the pads, which are mapped locally, the status is - // polled in GetPadStatus() earlier, and here it is send to the - // other clients. For all "in-game" pads, which are mapped to - // the others, the passed over status is ignored. Instead we - // wait for the other clients to send the status to this client. - // If this in-game pad is mapped to this client, then update - // with the status polled earlier in GetPadStatus() - if (m_pad_map[pad_nb] == m_local_player->pid) + // When the 1st in-game pad is polled, we assume the others will + // will be polled as well. To reduce latency, we poll all local + // controllers at once and then send the status to the other + // clients. + if (IsFirstInGamePad(pad_nb)) { - // adjust the buffer either up or down - // inserting multiple padstates or dropping states - while (m_pad_buffer[pad_nb].Size() <= m_target_buffer_size) + const u8 num_local_pads = NumLocalPads(); + for (u8 local_pad = 0; local_pad < num_local_pads; local_pad++) { - // add to buffer - m_pad_buffer[pad_nb].Push(*pad_status); + switch (SConfig::GetInstance().m_SIDevice[local_pad]) + { + case SIDEVICE_WIIU_ADAPTER: + GCAdapter::Input(local_pad, pad_status); + break; + case SIDEVICE_GC_CONTROLLER: + default: + Pad::GetStatus(local_pad, pad_status); + break; + } - // send - SendPadState(pad_nb, *pad_status); + u8 ingame_pad = LocalPadToInGamePad(local_pad); + + // adjust the buffer either up or down + // inserting multiple padstates or dropping states + while (m_pad_buffer[ingame_pad].Size() <= m_target_buffer_size) + { + // add to buffer + m_pad_buffer[ingame_pad].Push(*pad_status); + + // send + SendPadState(ingame_pad, *pad_status); + } } } - // Now, we either use the data we just pushed, or wait for the + // Now, we either use the data pushed earlier, or wait for the // other clients to send it to us while (!m_pad_buffer[pad_nb].Pop(*pad_status)) { @@ -1061,6 +1074,20 @@ bool NetPlayClient::LocalPlayerHasControllerMapped() const std::any_of(m_wiimote_map.begin(), m_wiimote_map.end(), mapping_matches_player_id); } +bool NetPlayClient::IsFirstInGamePad(u8 ingame_pad) const +{ + return std::none_of(m_pad_map.begin(), m_pad_map.begin() + ingame_pad, [](auto mapping) { + return mapping > 0; + }); +} + +u8 NetPlayClient::NumLocalPads() const +{ + return static_cast(std::count_if(m_pad_map.begin(), m_pad_map.end(), [this](auto mapping) { + return mapping == m_local_player->pid; + })); +} + u8 NetPlayClient::InGamePadToLocalPad(u8 ingame_pad) { // not our pad diff --git a/Source/Core/Core/NetPlayClient.h b/Source/Core/Core/NetPlayClient.h index 3c9222e087..285db13b5b 100644 --- a/Source/Core/Core/NetPlayClient.h +++ b/Source/Core/Core/NetPlayClient.h @@ -75,8 +75,11 @@ public: void OnConnectReady(ENetAddress addr) override; void OnConnectFailed(u8 reason) override; + bool IsFirstInGamePad(u8 ingame_pad) const; + u8 NumLocalPads() const; + + u8 InGamePadToLocalPad(u8 ingame_pad); u8 LocalPadToInGamePad(u8 localPad); - u8 InGamePadToLocalPad(u8 localPad); u8 LocalWiimoteToInGameWiimote(u8 local_pad);