Netplay: Completely rewrite Wiimote syncing logic to be similar to the GameCube controller one.

This commit is contained in:
Admiral H. Curtiss 2022-09-23 03:21:52 +02:00
parent f8518b2ff6
commit aade584180
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
10 changed files with 216 additions and 184 deletions

View File

@ -498,9 +498,6 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
if (core_parameter.bWii && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED)) if (core_parameter.bWii && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED))
{ {
Wiimote::LoadConfig(); Wiimote::LoadConfig();
if (NetPlay::IsNetPlayRunning())
NetPlay::SetupWiimotes();
} }
FreeLook::LoadInputConfig(); FreeLook::LoadInputConfig();

View File

@ -94,8 +94,6 @@ ControllerEmu::ControlGroup* GetDrawsomeTabletGroup(int number,
WiimoteEmu::DrawsomeTabletGroup group); WiimoteEmu::DrawsomeTabletGroup group);
ControllerEmu::ControlGroup* GetTaTaConGroup(int number, WiimoteEmu::TaTaConGroup group); ControllerEmu::ControlGroup* GetTaTaConGroup(int number, WiimoteEmu::TaTaConGroup group);
ControllerEmu::ControlGroup* GetShinkansenGroup(int number, WiimoteEmu::ShinkansenGroup group); ControllerEmu::ControlGroup* GetShinkansenGroup(int number, WiimoteEmu::ShinkansenGroup group);
bool NetPlay_GetButtonPress(int wiimote, bool pressed);
} // namespace Wiimote } // namespace Wiimote
namespace WiimoteReal namespace WiimoteReal

View File

@ -156,6 +156,9 @@ void Wiimote::HandleExtensionSwap(ExtensionNumber desired_extension_number,
if (m_is_motion_plus_attached && !desired_motion_plus) if (m_is_motion_plus_attached && !desired_motion_plus)
{ {
INFO_LOG_FMT(WIIMOTE, "Detaching Motion Plus (Wiimote {} in slot {})", m_index,
m_bt_device_index);
// M+ is attached and it's not wanted, so remove it. // M+ is attached and it's not wanted, so remove it.
m_extension_port.AttachExtension(GetNoneExtension()); m_extension_port.AttachExtension(GetNoneExtension());
m_is_motion_plus_attached = false; m_is_motion_plus_attached = false;
@ -180,6 +183,9 @@ void Wiimote::HandleExtensionSwap(ExtensionNumber desired_extension_number,
} }
else else
{ {
INFO_LOG_FMT(WIIMOTE, "Attaching Motion Plus (Wiimote {} in slot {})", m_index,
m_bt_device_index);
// No extension attached so attach M+. // No extension attached so attach M+.
m_is_motion_plus_attached = true; m_is_motion_plus_attached = true;
m_extension_port.AttachExtension(&m_motion_plus); m_extension_port.AttachExtension(&m_motion_plus);
@ -194,12 +200,18 @@ void Wiimote::HandleExtensionSwap(ExtensionNumber desired_extension_number,
// A different extension is wanted (either by user or by the M+ logic above) // A different extension is wanted (either by user or by the M+ logic above)
if (GetActiveExtensionNumber() != ExtensionNumber::NONE) if (GetActiveExtensionNumber() != ExtensionNumber::NONE)
{ {
INFO_LOG_FMT(WIIMOTE, "Detaching Extension (Wiimote {} in slot {})", m_index,
m_bt_device_index);
// First we must detach the current extension. // First we must detach the current extension.
// The next call will change to the new extension if needed. // The next call will change to the new extension if needed.
m_active_extension = ExtensionNumber::NONE; m_active_extension = ExtensionNumber::NONE;
} }
else else
{ {
INFO_LOG_FMT(WIIMOTE, "Switching to Extension {} (Wiimote {} in slot {})",
desired_extension_number, m_index, m_bt_device_index);
m_active_extension = desired_extension_number; m_active_extension = desired_extension_number;
} }

View File

@ -21,7 +21,6 @@
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/HW/Wiimote.h" #include "Core/HW/Wiimote.h"
#include "Core/Movie.h" #include "Core/Movie.h"
#include "Core/NetPlayClient.h"
#include "Core/HW/WiimoteCommon/WiimoteConstants.h" #include "Core/HW/WiimoteCommon/WiimoteConstants.h"
#include "Core/HW/WiimoteCommon/WiimoteHid.h" #include "Core/HW/WiimoteCommon/WiimoteHid.h"
@ -634,15 +633,6 @@ void Wiimote::SendDataReport(const DesiredWiimoteState& target_state)
GetExtensionEncryptionKey()); GetExtensionEncryptionKey());
} }
if (NetPlay::IsNetPlayRunning())
{
NetPlay_GetWiimoteData(m_index, rpt_builder.GetDataPtr(), rpt_builder.GetDataSize(),
u8(m_reporting_mode));
// TODO: clean up how m_status.buttons is updated.
rpt_builder.GetCoreData(&m_status.buttons);
}
Movie::CheckWiimoteStatus(m_bt_device_index, rpt_builder, m_active_extension, Movie::CheckWiimoteStatus(m_bt_device_index, rpt_builder, m_active_extension,
GetExtensionEncryptionKey()); GetExtensionEncryptionKey());

View File

@ -210,8 +210,6 @@ private:
Extension* GetActiveExtension() const; Extension* GetActiveExtension() const;
Extension* GetNoneExtension() const; Extension* GetNoneExtension() const;
bool NetPlay_GetWiimoteData(int wiimote, u8* data, u8 size, u8 reporting_mode);
// TODO: Kill this nonsensical function used for TAS: // TODO: Kill this nonsensical function used for TAS:
EncryptionKey GetExtensionEncryptionKey() const; EncryptionKey GetExtensionEncryptionKey() const;

View File

@ -22,6 +22,8 @@
#include "Core/HW/WiimoteEmu/DesiredWiimoteState.h" #include "Core/HW/WiimoteEmu/DesiredWiimoteState.h"
#include "Core/IOS/Device.h" #include "Core/IOS/Device.h"
#include "Core/IOS/IOS.h" #include "Core/IOS/IOS.h"
#include "Core/NetPlayClient.h"
#include "Core/NetPlayProto.h"
#include "Core/SysConf.h" #include "Core/SysConf.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/ControllerInterface/ControllerInterface.h"
@ -59,7 +61,9 @@ BluetoothEmuDevice::BluetoothEmuDevice(Kernel& ios, const std::string& device_na
DEBUG_LOG_FMT(IOS_WIIMOTE, "Wii Remote {} BT ID {:x},{:x},{:x},{:x},{:x},{:x}", i, tmp_bd[0], DEBUG_LOG_FMT(IOS_WIIMOTE, "Wii Remote {} BT ID {:x},{:x},{:x},{:x},{:x},{:x}", i, tmp_bd[0],
tmp_bd[1], tmp_bd[2], tmp_bd[3], tmp_bd[4], tmp_bd[5]); tmp_bd[1], tmp_bd[2], tmp_bd[3], tmp_bd[4], tmp_bd[5]);
m_wiimotes[i] = std::make_unique<WiimoteDevice>(this, tmp_bd, i); const unsigned int hid_source_number =
NetPlay::IsNetPlayRunning() ? NetPlay::NetPlay_GetLocalWiimoteForSlot(i) : i;
m_wiimotes[i] = std::make_unique<WiimoteDevice>(this, tmp_bd, hid_source_number);
} }
bt_dinf.num_registered = MAX_BBMOTES; bt_dinf.num_registered = MAX_BBMOTES;
@ -348,6 +352,21 @@ void BluetoothEmuDevice::Update()
for (size_t i = 0; i < m_wiimotes.size(); ++i) for (size_t i = 0; i < m_wiimotes.size(); ++i)
next_call[i] = m_wiimotes[i]->PrepareInput(&wiimote_states[i]); next_call[i] = m_wiimotes[i]->PrepareInput(&wiimote_states[i]);
if (NetPlay::IsNetPlayRunning())
{
for (size_t i = 0; i < 4; ++i)
{
if (next_call[i] != WiimoteDevice::NextUpdateInputCall::None)
{
WiimoteEmu::SerializedWiimoteState serialized_state =
WiimoteEmu::SerializeDesiredState(wiimote_states[i]);
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.");
}
}
}
for (size_t i = 0; i < m_wiimotes.size(); ++i) for (size_t i = 0; i < m_wiimotes.size(); ++i)
m_wiimotes[i]->UpdateInput(next_call[i], wiimote_states[i]); m_wiimotes[i]->UpdateInput(next_call[i], wiimote_states[i]);

View File

@ -10,8 +10,10 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <span>
#include <sstream> #include <sstream>
#include <thread> #include <thread>
#include <tuple>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
@ -54,6 +56,7 @@
#include "Core/HW/Sram.h" #include "Core/HW/Sram.h"
#include "Core/HW/WiiSave.h" #include "Core/HW/WiiSave.h"
#include "Core/HW/WiiSaveStructs.h" #include "Core/HW/WiiSaveStructs.h"
#include "Core/HW/WiimoteEmu/DesiredWiimoteState.h"
#include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h"
#include "Core/HW/WiimoteReal/WiimoteReal.h" #include "Core/HW/WiimoteReal/WiimoteReal.h"
#include "Core/IOS/FS/FileSystem.h" #include "Core/IOS/FS/FileSystem.h"
@ -695,20 +698,29 @@ void NetPlayClient::OnPadHostData(sf::Packet& packet)
void NetPlayClient::OnWiimoteData(sf::Packet& packet) void NetPlayClient::OnWiimoteData(sf::Packet& packet)
{ {
PadIndex map; while (!packet.endOfPacket())
WiimoteInput nw; {
u8 size; PadIndex map;
packet >> map;
packet >> map >> nw.report_id >> size; WiimoteEmu::SerializedWiimoteState pad;
packet >> pad.length;
ASSERT(pad.length <= pad.data.size());
if (pad.length <= pad.data.size())
{
for (size_t i = 0; i < pad.length; ++i)
packet >> pad.data[i];
}
else
{
pad.length = 0;
}
nw.data.resize(size); // Trusting server for good map value (>=0 && <4)
for (auto& byte : nw.data) // add to pad buffer
packet >> byte; m_wiimote_buffer.at(map).Push(pad);
m_wii_pad_event.Set();
// Trusting server for good map value (>=0 && <4) }
// add to Wiimote buffer
m_wiimote_buffer.at(map).Push(nw);
m_wii_pad_event.Set();
} }
void NetPlayClient::OnPadBuffer(sf::Packet& packet) void NetPlayClient::OnPadBuffer(sf::Packet& packet)
@ -886,9 +898,6 @@ void NetPlayClient::OnStartGame(sf::Packet& packet)
packet >> m_net_settings.save_data_region; packet >> m_net_settings.save_data_region;
packet >> m_net_settings.sync_codes; packet >> m_net_settings.sync_codes;
for (int& extension : m_net_settings.wiimote_extension)
packet >> extension;
packet >> m_net_settings.golf_mode; packet >> m_net_settings.golf_mode;
packet >> m_net_settings.use_fma; packet >> m_net_settings.use_fma;
packet >> m_net_settings.hide_remote_gbas; packet >> m_net_settings.hide_remote_gbas;
@ -1619,15 +1628,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 WiimoteInput& nw) void NetPlayClient::AddWiimoteStateToPacket(int in_game_pad,
const WiimoteEmu::SerializedWiimoteState& state,
sf::Packet& packet)
{ {
sf::Packet packet;
packet << MessageID::WiimoteData;
packet << static_cast<PadIndex>(in_game_pad); packet << static_cast<PadIndex>(in_game_pad);
packet << static_cast<u8>(nw.report_id); packet << state.length;
packet << static_cast<u8>(nw.data.size()); for (size_t i = 0; i < state.length; ++i)
packet.append(nw.data.data(), nw.data.size()); packet << state.data[i];
SendAsync(std::move(packet));
} }
// called from ---GUI--- thread // called from ---GUI--- thread
@ -2042,79 +2050,43 @@ u64 NetPlayClient::GetInitialRTCValue() const
return m_initial_rtc; return m_initial_rtc;
} }
bool NetPlayClient::WaitForWiimoteBuffer(int _number) // called from ---CPU--- thread
bool NetPlayClient::WiimoteUpdate(int wiimote_number,
WiimoteEmu::SerializedWiimoteState* target_state)
{ {
while (m_wiimote_buffer[_number].Size() == 0) {
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), ", "));
if (local_wiimote < 4)
{
sf::Packet packet;
packet << MessageID::WiimoteData;
if (AddLocalWiimoteToBuffer(local_wiimote, *target_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()) if (!m_is_running.IsSet())
{ {
return false; return false;
} }
// wait for receiving thread to push some data
m_wii_pad_event.Wait(); m_wii_pad_event.Wait();
} }
return true; m_wiimote_buffer[wiimote_number].Pop(*target_state);
}
// called from ---CPU--- thread DEBUG_LOG_FMT(NETPLAY, "Exiting WiimoteUpdate() with wiimote_number {}, target_state [{:02x}]",
bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const std::size_t size, u8 reporting_mode) wiimote_number,
{ fmt::join(std::span(target_state->data.data(), target_state->length), ", "));
WiimoteInput nw;
nw.report_id = reporting_mode;
{
std::lock_guard lkp(m_crit.players);
// Only send data, if this Wiimote is mapped to this player
if (m_wiimote_map[_number] == m_local_player->pid)
{
nw.data.assign(data, data + size);
// TODO: add a seperate setting for wiimote buffer?
while (m_wiimote_buffer[_number].Size() <= m_target_buffer_size * 200 / 120)
{
// add to buffer
m_wiimote_buffer[_number].Push(nw);
SendWiimoteState(_number, nw);
}
}
} // unlock players
if (!WaitForWiimoteBuffer(_number))
return false;
m_wiimote_buffer[_number].Pop(nw);
// If the reporting mode has changed, we just need to pop through the buffer,
// until we reach a good input
if (nw.report_id != reporting_mode)
{
u32 tries = 0;
while (nw.report_id != reporting_mode)
{
if (!WaitForWiimoteBuffer(_number))
return false;
m_wiimote_buffer[_number].Pop(nw);
++tries;
if (tries > m_target_buffer_size * 200 / 120)
break;
}
// If it still mismatches, it surely desynced
if (nw.report_id != reporting_mode)
{
PanicAlertFmtT("Netplay has desynced. There is no way to recover from this.");
return false;
}
}
ASSERT(nw.data.size() == size);
std::copy(nw.data.begin(), nw.data.end(), data);
return true; return true;
} }
@ -2171,6 +2143,28 @@ bool NetPlayClient::PollLocalPad(const int local_pad, sf::Packet& packet)
return data_added; return data_added;
} }
bool NetPlayClient::AddLocalWiimoteToBuffer(const int local_wiimote,
const WiimoteEmu::SerializedWiimoteState& state,
sf::Packet& packet)
{
const int ingame_pad = LocalWiimoteToInGameWiimote(local_wiimote);
bool data_added = false;
// adjust the buffer either up or down
// inserting multiple padstates or dropping states
while (m_wiimote_buffer[ingame_pad].Size() <= m_target_buffer_size)
{
// add to buffer
m_wiimote_buffer[ingame_pad].Push(state);
// add to packet
AddWiimoteStateToPacket(ingame_pad, state, packet);
data_added = true;
}
return data_added;
}
void NetPlayClient::SendPadHostPoll(const PadIndex pad_num) void NetPlayClient::SendPadHostPoll(const PadIndex pad_num)
{ {
// Here we handle polling for the Host Input Authority and Golf modes. Pad data is "polled" from // Here we handle polling for the Host Input Authority and Golf modes. Pad data is "polled" from
@ -2335,25 +2329,25 @@ int NetPlayClient::NumLocalPads() const
})); }));
} }
int NetPlayClient::InGamePadToLocalPad(int ingame_pad) const static int InGameToLocal(int ingame_pad, const PadMappingArray& pad_map, PlayerId local_player_pid)
{ {
// not our pad // not our pad
if (m_pad_map[ingame_pad] != m_local_player->pid) if (pad_map[ingame_pad] != local_player_pid)
return 4; return 4;
int local_pad = 0; int local_pad = 0;
int pad = 0; int pad = 0;
for (; pad < ingame_pad; pad++) for (; pad < ingame_pad; ++pad)
{ {
if (m_pad_map[pad] == m_local_player->pid) if (pad_map[pad] == local_player_pid)
local_pad++; local_pad++;
} }
return local_pad; return local_pad;
} }
int NetPlayClient::LocalPadToInGamePad(int local_pad) const static int LocalToInGame(int local_pad, const PadMappingArray& pad_map, PlayerId local_player_pid)
{ {
// Figure out which in-game pad maps to which local pad. // Figure out which in-game pad maps to which local pad.
// The logic we have here is that the local slots always // The logic we have here is that the local slots always
@ -2362,7 +2356,7 @@ int NetPlayClient::LocalPadToInGamePad(int local_pad) const
int ingame_pad = 0; int ingame_pad = 0;
for (; ingame_pad < 4; ingame_pad++) for (; ingame_pad < 4; ingame_pad++)
{ {
if (m_pad_map[ingame_pad] == m_local_player->pid) if (pad_map[ingame_pad] == local_player_pid)
local_pad_count++; local_pad_count++;
if (local_pad_count == local_pad) if (local_pad_count == local_pad)
@ -2372,6 +2366,26 @@ int NetPlayClient::LocalPadToInGamePad(int local_pad) const
return ingame_pad; return ingame_pad;
} }
int NetPlayClient::InGamePadToLocalPad(int ingame_pad) const
{
return InGameToLocal(ingame_pad, m_pad_map, m_local_player->pid);
}
int NetPlayClient::LocalPadToInGamePad(int local_pad) const
{
return LocalToInGame(local_pad, m_pad_map, m_local_player->pid);
}
int NetPlayClient::InGameWiimoteToLocalWiimote(int ingame_wiimote) const
{
return InGameToLocal(ingame_wiimote, m_wiimote_map, m_local_player->pid);
}
int NetPlayClient::LocalWiimoteToInGameWiimote(int local_wiimote) const
{
return LocalToInGame(local_wiimote, m_wiimote_map, m_local_player->pid);
}
bool NetPlayClient::PlayerHasControllerMapped(const PlayerId pid) const bool NetPlayClient::PlayerHasControllerMapped(const PlayerId pid) const
{ {
const auto mapping_matches_player_id = [pid](const PlayerId& mapping) { return mapping == pid; }; const auto mapping_matches_player_id = [pid](const PlayerId& mapping) { return mapping == pid; };
@ -2385,6 +2399,11 @@ bool NetPlayClient::IsLocalPlayer(const PlayerId pid) const
return pid == m_local_player->pid; return pid == m_local_player->pid;
} }
const PlayerId& NetPlayClient::GetLocalPlayerId() const
{
return m_local_player->pid;
}
void NetPlayClient::SendGameStatus() void NetPlayClient::SendGameStatus()
{ {
sf::Packet packet; sf::Packet packet;
@ -2580,23 +2599,6 @@ void SendPowerButtonEvent()
netplay_client->SendPowerButtonEvent(); netplay_client->SendPowerButtonEvent();
} }
void SetupWiimotes()
{
ASSERT(IsNetPlayRunning());
const NetSettings& netplay_settings = netplay_client->GetNetSettings();
const PadMappingArray& wiimote_map = netplay_client->GetWiimoteMapping();
for (size_t i = 0; i < netplay_settings.wiimote_extension.size(); i++)
{
if (wiimote_map[i] > 0)
{
static_cast<ControllerEmu::Attachments*>(
static_cast<WiimoteEmu::Wiimote*>(Wiimote::GetConfig()->GetController(int(i)))
->GetWiimoteGroup(WiimoteEmu::WiimoteGroup::Attachments))
->SetSelectedAttachment(netplay_settings.wiimote_extension[i]);
}
}
}
std::string GetGBASavePath(int pad_num) std::string GetGBASavePath(int pad_num)
{ {
std::lock_guard lk(crit_netplay_client); std::lock_guard lk(crit_netplay_client);
@ -2679,37 +2681,51 @@ bool SerialInterface::CSIDevice_GCController::NetPlay_GetInput(int pad_num, GCPa
return false; return false;
} }
bool WiimoteEmu::Wiimote::NetPlay_GetWiimoteData(int wiimote, u8* data, u8 size, u8 reporting_mode) bool NetPlay::NetPlay_GetWiimoteData(int wiimote, WiimoteEmu::SerializedWiimoteState* target_state)
{ {
std::lock_guard lk(NetPlay::crit_netplay_client); std::lock_guard lk(crit_netplay_client);
if (NetPlay::netplay_client) if (netplay_client)
return NetPlay::netplay_client->WiimoteUpdate(wiimote, data, size, reporting_mode); return netplay_client->WiimoteUpdate(wiimote, target_state);
return false; return false;
} }
// Sync the info whether a button was pressed or not. Used for the reconnect on button press feature unsigned int NetPlay::NetPlay_GetLocalWiimoteForSlot(unsigned int slot)
bool Wiimote::NetPlay_GetButtonPress(int wiimote, bool pressed)
{ {
std::lock_guard lk(NetPlay::crit_netplay_client); if (slot >= std::tuple_size_v<PadMappingArray>)
return slot;
// Use the reporting mode 0 for the button pressed event, the real ones start at RT_REPORT_CORE std::lock_guard lk(crit_netplay_client);
static const u8 BUTTON_PRESS_REPORTING_MODE = 0;
if (NetPlay::netplay_client) if (!netplay_client)
return slot;
const auto& mapping = netplay_client->GetWiimoteMapping();
const auto& local_player_id = netplay_client->GetLocalPlayerId();
std::array<unsigned int, std::tuple_size_v<std::decay_t<decltype(mapping)>>> slot_map;
size_t player_count = 0;
for (size_t i = 0; i < mapping.size(); ++i)
{ {
std::array<u8, 1> data = {u8(pressed)}; if (mapping[i] == local_player_id)
if (NetPlay::netplay_client->WiimoteUpdate(wiimote, data.data(), data.size(),
BUTTON_PRESS_REPORTING_MODE))
{ {
return data[0]; slot_map[i] = static_cast<unsigned int>(player_count);
++player_count;
}
}
for (size_t i = 0; i < mapping.size(); ++i)
{
if (mapping[i] != local_player_id)
{
slot_map[i] = static_cast<unsigned int>(player_count);
++player_count;
} }
PanicAlertFmtT("Netplay has desynced in NetPlay_GetButtonPress()");
return false;
} }
return pressed; INFO_LOG_FMT(NETPLAY, "Wiimote slot map: [{}]", fmt::join(slot_map, ", "));
return slot_map[slot];
} }
// called from ---CPU--- thread // called from ---CPU--- thread

View File

@ -35,6 +35,11 @@ namespace UICommon
class GameFile; class GameFile;
} }
namespace WiimoteEmu
{
struct SerializedWiimoteState;
}
namespace NetPlay namespace NetPlay
{ {
class NetPlayUI class NetPlayUI
@ -129,7 +134,7 @@ public:
std::string GetCurrentGolfer(); std::string GetCurrentGolfer();
// Send and receive pads values // Send and receive pads values
bool WiimoteUpdate(int _number, u8* data, std::size_t size, u8 reporting_mode); bool WiimoteUpdate(int wiimote_number, WiimoteEmu::SerializedWiimoteState* target_state);
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;
@ -142,11 +147,14 @@ public:
int NumLocalPads() const; int NumLocalPads() const;
int InGamePadToLocalPad(int ingame_pad) const; int InGamePadToLocalPad(int ingame_pad) const;
int LocalPadToInGamePad(int localPad) const; int LocalPadToInGamePad(int local_pad) const;
int InGameWiimoteToLocalWiimote(int ingame_wiimote) const;
int LocalWiimoteToInGameWiimote(int local_wiimote) const;
bool PlayerHasControllerMapped(PlayerId pid) const; bool PlayerHasControllerMapped(PlayerId pid) const;
bool LocalPlayerHasControllerMapped() const; bool LocalPlayerHasControllerMapped() const;
bool IsLocalPlayer(PlayerId pid) const; bool IsLocalPlayer(PlayerId pid) const;
const PlayerId& GetLocalPlayerId() const;
static void SendTimeBase(); static void SendTimeBase();
bool DoAllPlayersHaveGame(); bool DoAllPlayersHaveGame();
@ -182,7 +190,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<WiimoteInput>, 4> m_wiimote_buffer; std::array<Common::SPSCQueue<WiimoteEmu::SerializedWiimoteState>, 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{};
@ -242,9 +250,13 @@ private:
bool PollLocalPad(int local_pad, sf::Packet& packet); bool PollLocalPad(int local_pad, sf::Packet& packet);
void SendPadHostPoll(PadIndex pad_num); void SendPadHostPoll(PadIndex pad_num);
bool AddLocalWiimoteToBuffer(int local_wiimote, const WiimoteEmu::SerializedWiimoteState& state,
sf::Packet& packet);
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 WiimoteInput& nw); void AddWiimoteStateToPacket(int in_game_pad, const WiimoteEmu::SerializedWiimoteState& np,
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();
bool Connect(); bool Connect();
@ -253,8 +265,6 @@ private:
void DisplayPlayersPing(); void DisplayPlayersPing();
u32 GetPlayersMaxPing() const; u32 GetPlayersMaxPing() const;
bool WaitForWiimoteBuffer(int _number);
void OnData(sf::Packet& packet); void OnData(sf::Packet& packet);
void OnPlayerJoin(sf::Packet& packet); void OnPlayerJoin(sf::Packet& packet);
void OnPlayerLeave(sf::Packet& packet); void OnPlayerLeave(sf::Packet& packet);
@ -335,4 +345,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);
unsigned int NetPlay_GetLocalWiimoteForSlot(unsigned int slot);
} // namespace NetPlay } // namespace NetPlay

View File

@ -101,7 +101,6 @@ struct NetSettings
bool strict_settings_sync = false; bool strict_settings_sync = false;
bool sync_codes = false; bool sync_codes = false;
std::string save_data_region; std::string save_data_region;
std::array<int, 4> wiimote_extension{};
bool golf_mode = false; bool golf_mode = false;
bool use_fma = false; bool use_fma = false;
bool hide_remote_gbas = false; bool hide_remote_gbas = false;
@ -228,11 +227,6 @@ enum : u8
CHANNEL_COUNT CHANNEL_COUNT
}; };
struct WiimoteInput
{
u8 report_id = 0;
std::vector<u8> data;
};
using PlayerId = u8; using PlayerId = u8;
using FrameNum = u32; using FrameNum = u32;
using PadIndex = s8; using PadIndex = s8;
@ -260,7 +254,6 @@ std::string GetPlayerMappingString(PlayerId pid, const PadMappingArray& pad_map,
bool IsNetPlayRunning(); bool IsNetPlayRunning();
void SetSIPollBatching(bool state); void SetSIPollBatching(bool state);
void SendPowerButtonEvent(); void SendPowerButtonEvent();
void SetupWiimotes();
std::string GetGBASavePath(int pad_num); std::string GetGBASavePath(int pad_num);
PadDetails GetPadDetails(int pad_num); PadDetails GetPadDetails(int pad_num);
} // namespace NetPlay } // namespace NetPlay

View File

@ -52,6 +52,7 @@
#include "Core/HW/Sram.h" #include "Core/HW/Sram.h"
#include "Core/HW/WiiSave.h" #include "Core/HW/WiiSave.h"
#include "Core/HW/WiiSaveStructs.h" #include "Core/HW/WiiSaveStructs.h"
#include "Core/HW/WiimoteEmu/DesiredWiimoteState.h"
#include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h"
#include "Core/HW/WiimoteReal/WiimoteReal.h" #include "Core/HW/WiimoteReal/WiimoteReal.h"
#include "Core/IOS/ES/ES.h" #include "Core/IOS/ES/ES.h"
@ -827,27 +828,33 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)
if (player.current_game != m_current_game) if (player.current_game != m_current_game)
break; break;
PadIndex map;
u8 size;
packet >> map >> size;
std::vector<u8> data(size);
for (u8& byte : data)
packet >> byte;
// If the data is not from the correct player,
// then disconnect them.
if (m_wiimote_map.at(map) != player.pid)
{
return 1;
}
// relay to clients
sf::Packet spac; sf::Packet spac;
spac << MessageID::WiimoteData; spac << MessageID::WiimoteData;
spac << map;
spac << size; while (!packet.endOfPacket())
for (const u8& byte : data) {
spac << byte; PadIndex map;
packet >> map;
// If the data is not from the correct player,
// then disconnect them.
if (m_wiimote_map.at(map) != player.pid)
{
return 1;
}
WiimoteEmu::SerializedWiimoteState pad;
packet >> pad.length;
if (pad.length > pad.data.size())
return 1;
for (size_t i = 0; i < pad.length; ++i)
packet >> pad.data[i];
spac << map;
spac << pad.length;
for (size_t i = 0; i < pad.length; ++i)
spac << pad.data[i];
}
SendToClients(spac, player.pid); SendToClients(spac, player.pid);
} }
@ -1518,16 +1525,6 @@ bool NetPlayServer::StartGame()
spac << region; spac << region;
spac << m_settings.sync_codes; spac << m_settings.sync_codes;
for (size_t i = 0; i < m_settings.wiimote_extension.size(); i++)
{
const int extension =
static_cast<ControllerEmu::Attachments*>(
static_cast<WiimoteEmu::Wiimote*>(Wiimote::GetConfig()->GetController(int(i)))
->GetWiimoteGroup(WiimoteEmu::WiimoteGroup::Attachments))
->GetSelectedAttachment();
spac << extension;
}
spac << m_settings.golf_mode; spac << m_settings.golf_mode;
spac << m_settings.use_fma; spac << m_settings.use_fma;
spac << m_settings.hide_remote_gbas; spac << m_settings.hide_remote_gbas;