Netplay: Completely rewrite Wiimote syncing logic to be similar to the GameCube controller one.
This commit is contained in:
parent
f8518b2ff6
commit
aade584180
|
@ -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))
|
||||
{
|
||||
Wiimote::LoadConfig();
|
||||
|
||||
if (NetPlay::IsNetPlayRunning())
|
||||
NetPlay::SetupWiimotes();
|
||||
}
|
||||
|
||||
FreeLook::LoadInputConfig();
|
||||
|
|
|
@ -94,8 +94,6 @@ ControllerEmu::ControlGroup* GetDrawsomeTabletGroup(int number,
|
|||
WiimoteEmu::DrawsomeTabletGroup group);
|
||||
ControllerEmu::ControlGroup* GetTaTaConGroup(int number, WiimoteEmu::TaTaConGroup group);
|
||||
ControllerEmu::ControlGroup* GetShinkansenGroup(int number, WiimoteEmu::ShinkansenGroup group);
|
||||
|
||||
bool NetPlay_GetButtonPress(int wiimote, bool pressed);
|
||||
} // namespace Wiimote
|
||||
|
||||
namespace WiimoteReal
|
||||
|
|
|
@ -156,6 +156,9 @@ void Wiimote::HandleExtensionSwap(ExtensionNumber desired_extension_number,
|
|||
|
||||
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_extension_port.AttachExtension(GetNoneExtension());
|
||||
m_is_motion_plus_attached = false;
|
||||
|
@ -180,6 +183,9 @@ void Wiimote::HandleExtensionSwap(ExtensionNumber desired_extension_number,
|
|||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG_FMT(WIIMOTE, "Attaching Motion Plus (Wiimote {} in slot {})", m_index,
|
||||
m_bt_device_index);
|
||||
|
||||
// No extension attached so attach M+.
|
||||
m_is_motion_plus_attached = true;
|
||||
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)
|
||||
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.
|
||||
// The next call will change to the new extension if needed.
|
||||
m_active_extension = ExtensionNumber::NONE;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "Core/Core.h"
|
||||
#include "Core/HW/Wiimote.h"
|
||||
#include "Core/Movie.h"
|
||||
#include "Core/NetPlayClient.h"
|
||||
|
||||
#include "Core/HW/WiimoteCommon/WiimoteConstants.h"
|
||||
#include "Core/HW/WiimoteCommon/WiimoteHid.h"
|
||||
|
@ -634,15 +633,6 @@ void Wiimote::SendDataReport(const DesiredWiimoteState& target_state)
|
|||
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,
|
||||
GetExtensionEncryptionKey());
|
||||
|
||||
|
|
|
@ -210,8 +210,6 @@ private:
|
|||
Extension* GetActiveExtension() const;
|
||||
Extension* GetNoneExtension() const;
|
||||
|
||||
bool NetPlay_GetWiimoteData(int wiimote, u8* data, u8 size, u8 reporting_mode);
|
||||
|
||||
// TODO: Kill this nonsensical function used for TAS:
|
||||
EncryptionKey GetExtensionEncryptionKey() const;
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "Core/HW/WiimoteEmu/DesiredWiimoteState.h"
|
||||
#include "Core/IOS/Device.h"
|
||||
#include "Core/IOS/IOS.h"
|
||||
#include "Core/NetPlayClient.h"
|
||||
#include "Core/NetPlayProto.h"
|
||||
#include "Core/SysConf.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],
|
||||
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;
|
||||
|
@ -348,6 +352,21 @@ void BluetoothEmuDevice::Update()
|
|||
for (size_t i = 0; i < m_wiimotes.size(); ++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)
|
||||
m_wiimotes[i]->UpdateInput(next_call[i], wiimote_states[i]);
|
||||
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <span>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
|
@ -54,6 +56,7 @@
|
|||
#include "Core/HW/Sram.h"
|
||||
#include "Core/HW/WiiSave.h"
|
||||
#include "Core/HW/WiiSaveStructs.h"
|
||||
#include "Core/HW/WiimoteEmu/DesiredWiimoteState.h"
|
||||
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
|
||||
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
||||
#include "Core/IOS/FS/FileSystem.h"
|
||||
|
@ -695,20 +698,29 @@ void NetPlayClient::OnPadHostData(sf::Packet& packet)
|
|||
|
||||
void NetPlayClient::OnWiimoteData(sf::Packet& packet)
|
||||
{
|
||||
PadIndex map;
|
||||
WiimoteInput nw;
|
||||
u8 size;
|
||||
while (!packet.endOfPacket())
|
||||
{
|
||||
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);
|
||||
for (auto& byte : nw.data)
|
||||
packet >> byte;
|
||||
|
||||
// Trusting server for good map value (>=0 && <4)
|
||||
// add to Wiimote buffer
|
||||
m_wiimote_buffer.at(map).Push(nw);
|
||||
m_wii_pad_event.Set();
|
||||
// Trusting server for good map value (>=0 && <4)
|
||||
// add to pad buffer
|
||||
m_wiimote_buffer.at(map).Push(pad);
|
||||
m_wii_pad_event.Set();
|
||||
}
|
||||
}
|
||||
|
||||
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.sync_codes;
|
||||
|
||||
for (int& extension : m_net_settings.wiimote_extension)
|
||||
packet >> extension;
|
||||
|
||||
packet >> m_net_settings.golf_mode;
|
||||
packet >> m_net_settings.use_fma;
|
||||
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
|
||||
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<u8>(nw.report_id);
|
||||
packet << static_cast<u8>(nw.data.size());
|
||||
packet.append(nw.data.data(), nw.data.size());
|
||||
SendAsync(std::move(packet));
|
||||
packet << state.length;
|
||||
for (size_t i = 0; i < state.length; ++i)
|
||||
packet << state.data[i];
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
|
@ -2042,79 +2050,43 @@ u64 NetPlayClient::GetInitialRTCValue() const
|
|||
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())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// wait for receiving thread to push some data
|
||||
m_wii_pad_event.Wait();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
m_wiimote_buffer[wiimote_number].Pop(*target_state);
|
||||
|
||||
// called from ---CPU--- thread
|
||||
bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const std::size_t size, u8 reporting_mode)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2171,6 +2143,28 @@ bool NetPlayClient::PollLocalPad(const int local_pad, sf::Packet& packet)
|
|||
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)
|
||||
{
|
||||
// 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
|
||||
if (m_pad_map[ingame_pad] != m_local_player->pid)
|
||||
if (pad_map[ingame_pad] != local_player_pid)
|
||||
return 4;
|
||||
|
||||
int local_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++;
|
||||
}
|
||||
|
||||
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.
|
||||
// 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;
|
||||
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++;
|
||||
|
||||
if (local_pad_count == local_pad)
|
||||
|
@ -2372,6 +2366,26 @@ int NetPlayClient::LocalPadToInGamePad(int local_pad) const
|
|||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
const PlayerId& NetPlayClient::GetLocalPlayerId() const
|
||||
{
|
||||
return m_local_player->pid;
|
||||
}
|
||||
|
||||
void NetPlayClient::SendGameStatus()
|
||||
{
|
||||
sf::Packet packet;
|
||||
|
@ -2580,23 +2599,6 @@ void 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::lock_guard lk(crit_netplay_client);
|
||||
|
@ -2679,37 +2681,51 @@ bool SerialInterface::CSIDevice_GCController::NetPlay_GetInput(int pad_num, GCPa
|
|||
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)
|
||||
return NetPlay::netplay_client->WiimoteUpdate(wiimote, data, size, reporting_mode);
|
||||
if (netplay_client)
|
||||
return netplay_client->WiimoteUpdate(wiimote, target_state);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sync the info whether a button was pressed or not. Used for the reconnect on button press feature
|
||||
bool Wiimote::NetPlay_GetButtonPress(int wiimote, bool pressed)
|
||||
unsigned int NetPlay::NetPlay_GetLocalWiimoteForSlot(unsigned int slot)
|
||||
{
|
||||
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
|
||||
static const u8 BUTTON_PRESS_REPORTING_MODE = 0;
|
||||
std::lock_guard lk(crit_netplay_client);
|
||||
|
||||
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 (NetPlay::netplay_client->WiimoteUpdate(wiimote, data.data(), data.size(),
|
||||
BUTTON_PRESS_REPORTING_MODE))
|
||||
if (mapping[i] == local_player_id)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -35,6 +35,11 @@ namespace UICommon
|
|||
class GameFile;
|
||||
}
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
struct SerializedWiimoteState;
|
||||
}
|
||||
|
||||
namespace NetPlay
|
||||
{
|
||||
class NetPlayUI
|
||||
|
@ -129,7 +134,7 @@ public:
|
|||
std::string GetCurrentGolfer();
|
||||
|
||||
// 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);
|
||||
|
||||
u64 GetInitialRTCValue() const;
|
||||
|
@ -142,11 +147,14 @@ public:
|
|||
int NumLocalPads() 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 LocalPlayerHasControllerMapped() const;
|
||||
bool IsLocalPlayer(PlayerId pid) const;
|
||||
const PlayerId& GetLocalPlayerId() const;
|
||||
|
||||
static void SendTimeBase();
|
||||
bool DoAllPlayersHaveGame();
|
||||
|
@ -182,7 +190,7 @@ protected:
|
|||
Common::SPSCQueue<AsyncQueueEntry, false> m_async_queue;
|
||||
|
||||
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<bool, 4> m_first_pad_status_received{};
|
||||
|
@ -242,9 +250,13 @@ private:
|
|||
bool PollLocalPad(int local_pad, sf::Packet& packet);
|
||||
void SendPadHostPoll(PadIndex pad_num);
|
||||
|
||||
bool AddLocalWiimoteToBuffer(int local_wiimote, const WiimoteEmu::SerializedWiimoteState& state,
|
||||
sf::Packet& packet);
|
||||
|
||||
void UpdateDevices();
|
||||
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 Disconnect();
|
||||
bool Connect();
|
||||
|
@ -253,8 +265,6 @@ private:
|
|||
void DisplayPlayersPing();
|
||||
u32 GetPlayersMaxPing() const;
|
||||
|
||||
bool WaitForWiimoteBuffer(int _number);
|
||||
|
||||
void OnData(sf::Packet& packet);
|
||||
void OnPlayerJoin(sf::Packet& packet);
|
||||
void OnPlayerLeave(sf::Packet& packet);
|
||||
|
@ -335,4 +345,6 @@ private:
|
|||
|
||||
void NetPlay_Enable(NetPlayClient* const np);
|
||||
void NetPlay_Disable();
|
||||
bool NetPlay_GetWiimoteData(int wiimote, WiimoteEmu::SerializedWiimoteState* target_state);
|
||||
unsigned int NetPlay_GetLocalWiimoteForSlot(unsigned int slot);
|
||||
} // namespace NetPlay
|
||||
|
|
|
@ -101,7 +101,6 @@ struct NetSettings
|
|||
bool strict_settings_sync = false;
|
||||
bool sync_codes = false;
|
||||
std::string save_data_region;
|
||||
std::array<int, 4> wiimote_extension{};
|
||||
bool golf_mode = false;
|
||||
bool use_fma = false;
|
||||
bool hide_remote_gbas = false;
|
||||
|
@ -228,11 +227,6 @@ enum : u8
|
|||
CHANNEL_COUNT
|
||||
};
|
||||
|
||||
struct WiimoteInput
|
||||
{
|
||||
u8 report_id = 0;
|
||||
std::vector<u8> data;
|
||||
};
|
||||
using PlayerId = u8;
|
||||
using FrameNum = u32;
|
||||
using PadIndex = s8;
|
||||
|
@ -260,7 +254,6 @@ std::string GetPlayerMappingString(PlayerId pid, const PadMappingArray& pad_map,
|
|||
bool IsNetPlayRunning();
|
||||
void SetSIPollBatching(bool state);
|
||||
void SendPowerButtonEvent();
|
||||
void SetupWiimotes();
|
||||
std::string GetGBASavePath(int pad_num);
|
||||
PadDetails GetPadDetails(int pad_num);
|
||||
} // namespace NetPlay
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "Core/HW/Sram.h"
|
||||
#include "Core/HW/WiiSave.h"
|
||||
#include "Core/HW/WiiSaveStructs.h"
|
||||
#include "Core/HW/WiimoteEmu/DesiredWiimoteState.h"
|
||||
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
|
||||
#include "Core/HW/WiimoteReal/WiimoteReal.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)
|
||||
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;
|
||||
spac << MessageID::WiimoteData;
|
||||
spac << map;
|
||||
spac << size;
|
||||
for (const u8& byte : data)
|
||||
spac << byte;
|
||||
|
||||
while (!packet.endOfPacket())
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -1518,16 +1525,6 @@ bool NetPlayServer::StartGame()
|
|||
spac << region;
|
||||
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.use_fma;
|
||||
spac << m_settings.hide_remote_gbas;
|
||||
|
|
Loading…
Reference in New Issue