Netplay: Implement batching for Wiimotes.

This commit is contained in:
Admiral H. Curtiss
2022-09-25 04:02:53 +02:00
parent aade584180
commit a1563f2def
3 changed files with 50 additions and 31 deletions

View File

@ -354,14 +354,28 @@ void BluetoothEmuDevice::Update()
if (NetPlay::IsNetPlayRunning()) if (NetPlay::IsNetPlayRunning())
{ {
std::array<WiimoteEmu::SerializedWiimoteState, MAX_BBMOTES> serialized;
std::array<NetPlay::NetPlayClient::WiimoteDataBatchEntry, MAX_BBMOTES> batch;
size_t batch_count = 0;
for (size_t i = 0; i < 4; ++i) 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<int>(i);
++batch_count;
}
if (batch_count > 0)
{
NetPlay::NetPlay_GetWiimoteData(
std::span<NetPlay::NetPlayClient::WiimoteDataBatchEntry>(batch.data(), batch_count));
for (size_t i = 0; i < batch_count; ++i)
{ {
WiimoteEmu::SerializedWiimoteState serialized_state = const int wiimote = batch[i].wiimote;
WiimoteEmu::SerializeDesiredState(wiimote_states[i]); if (!WiimoteEmu::DeserializeDesiredState(&wiimote_states[wiimote], serialized[wiimote]))
NetPlay::NetPlay_GetWiimoteData(static_cast<int>(i), &serialized_state);
if (!WiimoteEmu::DeserializeDesiredState(&wiimote_states[i], serialized_state))
PanicAlertFmtT("Received invalid Wii Remote data from Netplay."); PanicAlertFmtT("Received invalid Wii Remote data from Netplay.");
} }
} }

View File

@ -2051,42 +2051,41 @@ u64 NetPlayClient::GetInitialRTCValue() const
} }
// called from ---CPU--- thread // called from ---CPU--- thread
bool NetPlayClient::WiimoteUpdate(int wiimote_number, bool NetPlayClient::WiimoteUpdate(const std::span<WiimoteDataBatchEntry>& entries)
WiimoteEmu::SerializedWiimoteState* target_state)
{ {
for (const WiimoteDataBatchEntry& entry : entries)
{ {
const int local_wiimote = InGameWiimoteToLocalWiimote(wiimote_number); const int local_wiimote = InGameWiimoteToLocalWiimote(entry.wiimote);
DEBUG_LOG_FMT( DEBUG_LOG_FMT(NETPLAY,
NETPLAY, "Entering WiimoteUpdate() with wiimote {}, local_wiimote {}, state [{:02x}]",
"Entering WiimoteUpdate() with wiimote_number {}, local_wiimote {}, target_state [{:02x}]", entry.wiimote, local_wiimote,
wiimote_number, local_wiimote, fmt::join(std::span(entry.state->data.data(), entry.state->length), ", "));
fmt::join(std::span(target_state->data.data(), target_state->length), ", "));
if (local_wiimote < 4) if (local_wiimote < 4)
{ {
sf::Packet packet; sf::Packet packet;
packet << MessageID::WiimoteData; packet << MessageID::WiimoteData;
if (AddLocalWiimoteToBuffer(local_wiimote, *target_state, packet)) if (AddLocalWiimoteToBuffer(local_wiimote, *entry.state, packet))
SendAsync(std::move(packet)); SendAsync(std::move(packet));
} }
}
// Now, we either use the data pushed earlier, or wait for the // Now, we either use the data pushed earlier, or wait for the
// other clients to send it to us // other clients to send it to us
while (m_wiimote_buffer[wiimote_number].Size() == 0) while (m_wiimote_buffer[entry.wiimote].Size() == 0)
{
if (!m_is_running.IsSet())
{ {
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; return true;
} }
@ -2681,12 +2680,12 @@ bool SerialInterface::CSIDevice_GCController::NetPlay_GetInput(int pad_num, GCPa
return false; return false;
} }
bool NetPlay::NetPlay_GetWiimoteData(int wiimote, WiimoteEmu::SerializedWiimoteState* target_state) bool NetPlay::NetPlay_GetWiimoteData(const std::span<NetPlayClient::WiimoteDataBatchEntry>& entries)
{ {
std::lock_guard lk(crit_netplay_client); std::lock_guard lk(crit_netplay_client);
if (netplay_client) if (netplay_client)
return netplay_client->WiimoteUpdate(wiimote, target_state); return netplay_client->WiimoteUpdate(entries);
return false; return false;
} }

View File

@ -9,6 +9,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <span>
#include <string> #include <string>
#include <thread> #include <thread>
#include <unordered_map> #include <unordered_map>
@ -134,7 +135,12 @@ public:
std::string GetCurrentGolfer(); std::string GetCurrentGolfer();
// Send and receive pads values // 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<WiimoteDataBatchEntry>& entries);
bool GetNetPads(int pad_nb, bool from_vi, GCPadStatus* pad_status); bool GetNetPads(int pad_nb, bool from_vi, GCPadStatus* pad_status);
u64 GetInitialRTCValue() const; u64 GetInitialRTCValue() const;
@ -345,6 +351,6 @@ private:
void NetPlay_Enable(NetPlayClient* const np); void NetPlay_Enable(NetPlayClient* const np);
void NetPlay_Disable(); void NetPlay_Disable();
bool NetPlay_GetWiimoteData(int wiimote, WiimoteEmu::SerializedWiimoteState* target_state); bool NetPlay_GetWiimoteData(const std::span<NetPlayClient::WiimoteDataBatchEntry>& entries);
unsigned int NetPlay_GetLocalWiimoteForSlot(unsigned int slot); unsigned int NetPlay_GetLocalWiimoteForSlot(unsigned int slot);
} // namespace NetPlay } // namespace NetPlay