From a1563f2defe1cbc96853bc475b5442c610c01417 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sun, 25 Sep 2022 04:02:53 +0200 Subject: [PATCH] Netplay: Implement batching for Wiimotes. --- Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp | 24 +++++++--- Source/Core/Core/NetPlayClient.cpp | 47 ++++++++++---------- Source/Core/Core/NetPlayClient.h | 10 ++++- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp index 4bf1b12cd8..dea42fd589 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp +++ b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp @@ -354,14 +354,28 @@ void BluetoothEmuDevice::Update() if (NetPlay::IsNetPlayRunning()) { + std::array serialized; + std::array batch; + size_t batch_count = 0; for (size_t i = 0; i < 4; ++i) { - if (next_call[i] != WiimoteDevice::NextUpdateInputCall::None) + if (next_call[i] == WiimoteDevice::NextUpdateInputCall::None) + continue; + serialized[i] = WiimoteEmu::SerializeDesiredState(wiimote_states[i]); + batch[batch_count].state = &serialized[i]; + batch[batch_count].wiimote = static_cast(i); + ++batch_count; + } + + if (batch_count > 0) + { + NetPlay::NetPlay_GetWiimoteData( + std::span(batch.data(), batch_count)); + + for (size_t i = 0; i < batch_count; ++i) { - WiimoteEmu::SerializedWiimoteState serialized_state = - WiimoteEmu::SerializeDesiredState(wiimote_states[i]); - NetPlay::NetPlay_GetWiimoteData(static_cast(i), &serialized_state); - if (!WiimoteEmu::DeserializeDesiredState(&wiimote_states[i], serialized_state)) + const int wiimote = batch[i].wiimote; + if (!WiimoteEmu::DeserializeDesiredState(&wiimote_states[wiimote], serialized[wiimote])) PanicAlertFmtT("Received invalid Wii Remote data from Netplay."); } } diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index 059ab101a6..825ff7777a 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -2051,42 +2051,41 @@ u64 NetPlayClient::GetInitialRTCValue() const } // called from ---CPU--- thread -bool NetPlayClient::WiimoteUpdate(int wiimote_number, - WiimoteEmu::SerializedWiimoteState* target_state) +bool NetPlayClient::WiimoteUpdate(const std::span& entries) { + for (const WiimoteDataBatchEntry& entry : entries) { - const int local_wiimote = InGameWiimoteToLocalWiimote(wiimote_number); - DEBUG_LOG_FMT( - NETPLAY, - "Entering WiimoteUpdate() with wiimote_number {}, local_wiimote {}, target_state [{:02x}]", - wiimote_number, local_wiimote, - fmt::join(std::span(target_state->data.data(), target_state->length), ", ")); + const int local_wiimote = InGameWiimoteToLocalWiimote(entry.wiimote); + DEBUG_LOG_FMT(NETPLAY, + "Entering WiimoteUpdate() with wiimote {}, local_wiimote {}, state [{:02x}]", + entry.wiimote, local_wiimote, + fmt::join(std::span(entry.state->data.data(), entry.state->length), ", ")); if (local_wiimote < 4) { sf::Packet packet; packet << MessageID::WiimoteData; - if (AddLocalWiimoteToBuffer(local_wiimote, *target_state, packet)) + if (AddLocalWiimoteToBuffer(local_wiimote, *entry.state, packet)) SendAsync(std::move(packet)); } - } - // Now, we either use the data pushed earlier, or wait for the - // other clients to send it to us - while (m_wiimote_buffer[wiimote_number].Size() == 0) - { - if (!m_is_running.IsSet()) + // Now, we either use the data pushed earlier, or wait for the + // other clients to send it to us + while (m_wiimote_buffer[entry.wiimote].Size() == 0) { - return false; + if (!m_is_running.IsSet()) + { + return false; + } + + m_wii_pad_event.Wait(); } - m_wii_pad_event.Wait(); + m_wiimote_buffer[entry.wiimote].Pop(*entry.state); + + DEBUG_LOG_FMT(NETPLAY, "Exiting WiimoteUpdate() with wiimote {}, state [{:02x}]", entry.wiimote, + fmt::join(std::span(entry.state->data.data(), entry.state->length), ", ")); } - m_wiimote_buffer[wiimote_number].Pop(*target_state); - - DEBUG_LOG_FMT(NETPLAY, "Exiting WiimoteUpdate() with wiimote_number {}, target_state [{:02x}]", - wiimote_number, - fmt::join(std::span(target_state->data.data(), target_state->length), ", ")); return true; } @@ -2681,12 +2680,12 @@ bool SerialInterface::CSIDevice_GCController::NetPlay_GetInput(int pad_num, GCPa return false; } -bool NetPlay::NetPlay_GetWiimoteData(int wiimote, WiimoteEmu::SerializedWiimoteState* target_state) +bool NetPlay::NetPlay_GetWiimoteData(const std::span& entries) { std::lock_guard lk(crit_netplay_client); if (netplay_client) - return netplay_client->WiimoteUpdate(wiimote, target_state); + return netplay_client->WiimoteUpdate(entries); return false; } diff --git a/Source/Core/Core/NetPlayClient.h b/Source/Core/Core/NetPlayClient.h index c8a3da91ef..262f726d3d 100644 --- a/Source/Core/Core/NetPlayClient.h +++ b/Source/Core/Core/NetPlayClient.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -134,7 +135,12 @@ public: std::string GetCurrentGolfer(); // Send and receive pads values - bool WiimoteUpdate(int wiimote_number, WiimoteEmu::SerializedWiimoteState* target_state); + struct WiimoteDataBatchEntry + { + int wiimote; + WiimoteEmu::SerializedWiimoteState* state; + }; + bool WiimoteUpdate(const std::span& entries); bool GetNetPads(int pad_nb, bool from_vi, GCPadStatus* pad_status); u64 GetInitialRTCValue() const; @@ -345,6 +351,6 @@ private: void NetPlay_Enable(NetPlayClient* const np); void NetPlay_Disable(); -bool NetPlay_GetWiimoteData(int wiimote, WiimoteEmu::SerializedWiimoteState* target_state); +bool NetPlay_GetWiimoteData(const std::span& entries); unsigned int NetPlay_GetLocalWiimoteForSlot(unsigned int slot); } // namespace NetPlay