Core/NetPlay: Fix Wii Remote syncing.

This commit is contained in:
Jordan Woyak 2020-09-27 12:36:19 -05:00
parent 960750003e
commit 8f8509afc3
3 changed files with 31 additions and 27 deletions

View File

@ -5,6 +5,7 @@
#include "Core/NetPlayClient.h" #include "Core/NetPlayClient.h"
#include <algorithm> #include <algorithm>
#include <cassert>
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
@ -518,14 +519,12 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
case NP_MSG_WIIMOTE_DATA: case NP_MSG_WIIMOTE_DATA:
{ {
PadIndex map; PadIndex map;
NetWiimote nw; WiimoteInput nw;
u8 size; u8 size;
packet >> map >> size; packet >> map >> nw.report_id >> size;
nw.data.resize(size);
nw.resize(size); for (auto& byte : nw.data)
packet >> byte;
for (unsigned int i = 0; i < size; ++i)
packet >> nw[i];
// Trusting server for good map value (>=0 && <4) // Trusting server for good map value (>=0 && <4)
// add to Wiimote buffer // add to Wiimote buffer
@ -1463,17 +1462,14 @@ void NetPlayClient::AddPadStateToPacket(const int in_game_pad, const GCPadStatus
} }
// called from ---CPU--- thread // called from ---CPU--- thread
void NetPlayClient::SendWiimoteState(const int in_game_pad, const NetWiimote& nw) void NetPlayClient::SendWiimoteState(const int in_game_pad, const WiimoteInput& nw)
{ {
sf::Packet packet; sf::Packet packet;
packet << static_cast<MessageId>(NP_MSG_WIIMOTE_DATA); packet << static_cast<MessageId>(NP_MSG_WIIMOTE_DATA);
packet << static_cast<PadIndex>(in_game_pad); packet << static_cast<PadIndex>(in_game_pad);
packet << static_cast<u8>(nw.size()); packet << static_cast<u8>(nw.report_id);
for (auto it : nw) packet << static_cast<u8>(nw.data.size());
{ packet.append(nw.data.data(), nw.data.size());
packet << it;
}
SendAsync(std::move(packet)); SendAsync(std::move(packet));
} }
@ -1945,16 +1941,17 @@ u64 NetPlayClient::GetInitialRTCValue() const
} }
// called from ---CPU--- thread // called from ---CPU--- thread
bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size, u8 reporting_mode) bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const std::size_t size, u8 reporting_mode)
{ {
NetWiimote nw; WiimoteInput nw;
nw.report_id = reporting_mode;
{ {
std::lock_guard<std::recursive_mutex> lkp(m_crit.players); std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
// Only send data, if this Wiimote is mapped to this player // Only send data, if this Wiimote is mapped to this player
if (m_wiimote_map[_number] == m_local_player->pid) if (m_wiimote_map[_number] == m_local_player->pid)
{ {
nw.assign(data, data + size); nw.data.assign(data, data + size);
// TODO: add a seperate setting for wiimote buffer? // TODO: add a seperate setting for wiimote buffer?
while (m_wiimote_buffer[_number].Size() <= m_target_buffer_size * 200 / 120) while (m_wiimote_buffer[_number].Size() <= m_target_buffer_size * 200 / 120)
@ -1983,10 +1980,10 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size, u8 repor
// If the reporting mode has changed, we just need to pop through the buffer, // If the reporting mode has changed, we just need to pop through the buffer,
// until we reach a good input // until we reach a good input
if (nw[1] != reporting_mode) if (nw.report_id != reporting_mode)
{ {
u32 tries = 0; u32 tries = 0;
while (nw[1] != reporting_mode) while (nw.report_id != reporting_mode)
{ {
while (m_wiimote_buffer[_number].Size() == 0) while (m_wiimote_buffer[_number].Size() == 0)
{ {
@ -2007,14 +2004,15 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size, u8 repor
} }
// If it still mismatches, it surely desynced // If it still mismatches, it surely desynced
if (nw[1] != reporting_mode) if (nw.report_id != reporting_mode)
{ {
PanicAlertT("Netplay has desynced. There is no way to recover from this."); PanicAlertT("Netplay has desynced. There is no way to recover from this.");
return false; return false;
} }
} }
memcpy(data, nw.data(), size); assert(nw.data.size() == size);
std::copy(nw.data.begin(), nw.data.end(), data);
return true; return true;
} }
@ -2496,11 +2494,13 @@ bool Wiimote::NetPlay_GetButtonPress(int wiimote, bool pressed)
std::lock_guard<std::mutex> lk(NetPlay::crit_netplay_client); std::lock_guard<std::mutex> lk(NetPlay::crit_netplay_client);
// Use the reporting mode 0 for the button pressed event, the real ones start at RT_REPORT_CORE // Use the reporting mode 0 for the button pressed event, the real ones start at RT_REPORT_CORE
u8 data[2] = {static_cast<u8>(pressed), 0}; static const u8 BUTTON_PRESS_REPORTING_MODE = 0;
if (NetPlay::netplay_client) if (NetPlay::netplay_client)
{ {
if (NetPlay::netplay_client->WiimoteUpdate(wiimote, data, 2, 0)) std::array<u8, 1> data = {u8(pressed)};
if (NetPlay::netplay_client->WiimoteUpdate(wiimote, data.data(), data.size(),
BUTTON_PRESS_REPORTING_MODE))
{ {
return data[0]; return data[0];
} }

View File

@ -118,7 +118,7 @@ public:
std::string GetCurrentGolfer(); std::string GetCurrentGolfer();
// Send and receive pads values // Send and receive pads values
bool WiimoteUpdate(int _number, u8* data, const u8 size, u8 reporting_mode); bool WiimoteUpdate(int _number, u8* data, std::size_t size, u8 reporting_mode);
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;
@ -167,7 +167,7 @@ protected:
Common::SPSCQueue<AsyncQueueEntry, false> m_async_queue; Common::SPSCQueue<AsyncQueueEntry, false> m_async_queue;
std::array<Common::SPSCQueue<GCPadStatus>, 4> m_pad_buffer; std::array<Common::SPSCQueue<GCPadStatus>, 4> m_pad_buffer;
std::array<Common::SPSCQueue<NetWiimote>, 4> m_wiimote_buffer; std::array<Common::SPSCQueue<WiimoteInput>, 4> m_wiimote_buffer;
std::array<GCPadStatus, 4> m_last_pad_status{}; std::array<GCPadStatus, 4> m_last_pad_status{};
std::array<bool, 4> m_first_pad_status_received{}; std::array<bool, 4> m_first_pad_status_received{};
@ -230,7 +230,7 @@ private:
void UpdateDevices(); void UpdateDevices();
void AddPadStateToPacket(int in_game_pad, const GCPadStatus& np, sf::Packet& packet); void AddPadStateToPacket(int in_game_pad, const GCPadStatus& np, sf::Packet& packet);
void SendWiimoteState(int in_game_pad, const NetWiimote& nw); void SendWiimoteState(int in_game_pad, const WiimoteInput& nw);
unsigned int OnData(sf::Packet& packet); unsigned int OnData(sf::Packet& packet);
void Send(const sf::Packet& packet, u8 channel_id = DEFAULT_CHANNEL); void Send(const sf::Packet& packet, u8 channel_id = DEFAULT_CHANNEL);
void Disconnect(); void Disconnect();

View File

@ -204,7 +204,11 @@ constexpr u8 CHANNEL_COUNT = 2;
constexpr u8 DEFAULT_CHANNEL = 0; constexpr u8 DEFAULT_CHANNEL = 0;
constexpr u8 CHUNKED_DATA_CHANNEL = 1; constexpr u8 CHUNKED_DATA_CHANNEL = 1;
using NetWiimote = std::vector<u8>; struct WiimoteInput
{
u8 report_id;
std::vector<u8> data;
};
using MessageId = u8; using MessageId = u8;
using PlayerId = u8; using PlayerId = u8;
using FrameNum = u32; using FrameNum = u32;