Fix latency regression
On master, when polling the 1st in-game controller, Dolphin would poll all the 1st local controllers. With the 1st commit, each client waits its turn, which would dramatically increase the lag. Now with this commit, it even polls all local controllers at once, so it should have even less latency than master in a few setups. Like one player with 3 controllers and the 2nd one with just one controller.
This commit is contained in:
parent
ca9027879b
commit
1d90719abe
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<u8>(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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue