diff --git a/Source/Core/Core/HW/Wiimote.cpp b/Source/Core/Core/HW/Wiimote.cpp index 4d82147948..e992cf2266 100644 --- a/Source/Core/Core/HW/Wiimote.cpp +++ b/Source/Core/Core/HW/Wiimote.cpp @@ -16,11 +16,15 @@ #include "Core/IOS/USB/Bluetooth/BTEmu.h" #include "Core/IOS/USB/Bluetooth/WiimoteDevice.h" #include "Core/Movie.h" +#include "Core/NetPlayClient.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/InputConfig.h" +// Limit the amount of wiimote connect requests, when a button is pressed in disconnected state +static std::array s_last_connect_request_counter; + namespace Wiimote { static InputConfig s_config(WIIMOTE_INI_NAME, _trans("Wii Remote"), "Wiimote"); @@ -78,7 +82,7 @@ void Initialize(InitializeMode init_mode) g_controller_interface.RegisterHotplugCallback(LoadConfig); - s_config.LoadConfig(false); + LoadConfig(); WiimoteReal::Initialize(init_mode); @@ -115,6 +119,7 @@ void ResetAllWiimotes() void LoadConfig() { s_config.LoadConfig(false); + s_last_connect_request_counter.fill(0); } void Resume() @@ -143,6 +148,31 @@ void InterruptChannel(int number, u16 channel_id, const void* data, u32 size) ->InterruptChannel(channel_id, data, size); } +bool ButtonPressed(int number) +{ + if (s_last_connect_request_counter[number] > 0) + { + --s_last_connect_request_counter[number]; + if (g_wiimote_sources[number] && NetPlay::IsNetPlayRunning()) + Wiimote::NetPlay_GetButtonPress(number, false); + return false; + } + + bool button_pressed = false; + + if (WIIMOTE_SRC_EMU & g_wiimote_sources[number]) + button_pressed = + static_cast(s_config.GetController(number))->CheckForButtonPress(); + + if (WIIMOTE_SRC_REAL & g_wiimote_sources[number]) + button_pressed = WiimoteReal::CheckForButtonPress(number); + + if (g_wiimote_sources[number] && NetPlay::IsNetPlayRunning()) + button_pressed = Wiimote::NetPlay_GetButtonPress(number, button_pressed); + + return button_pressed; +} + // This function is called periodically by the Core to update Wiimote state. void Update(int number, bool connected) { @@ -155,11 +185,13 @@ void Update(int number, bool connected) } else { - if (WIIMOTE_SRC_EMU & g_wiimote_sources[number]) - static_cast(s_config.GetController(number))->ConnectOnInput(); - - if (WIIMOTE_SRC_REAL & g_wiimote_sources[number]) - WiimoteReal::ConnectOnInput(number); + if (ButtonPressed(number)) + { + Connect(number, true); + // arbitrary value so it doesn't try to send multiple requests before Dolphin can react + // if Wii Remotes are polled at 200Hz then this results in one request being sent per 500ms + s_last_connect_request_counter[number] = 100; + } } } diff --git a/Source/Core/Core/HW/Wiimote.h b/Source/Core/Core/HW/Wiimote.h index 4b8f3a1a91..1c637f4998 100644 --- a/Source/Core/Core/HW/Wiimote.h +++ b/Source/Core/Core/HW/Wiimote.h @@ -76,7 +76,9 @@ ControllerEmu::ControlGroup* GetTurntableGroup(int number, WiimoteEmu::Turntable void ControlChannel(int number, u16 channel_id, const void* data, u32 size); void InterruptChannel(int number, u16 channel_id, const void* data, u32 size); +bool ButtonPressed(int number); void Update(int number, bool connected); +bool NetPlay_GetButtonPress(int wiimote, bool pressed); } namespace WiimoteReal diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 0b4ceafc3f..3b50522f59 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -27,7 +27,6 @@ #include "Core/HW/WiimoteEmu/Attachment/Turntable.h" #include "Core/HW/WiimoteEmu/MatrixMath.h" #include "Core/HW/WiimoteReal/WiimoteReal.h" -#include "Core/Host.h" #include "Core/Movie.h" #include "Core/NetPlayClient.h" @@ -251,8 +250,7 @@ void Wiimote::Reset() m_adpcm_state.step = 127; } -Wiimote::Wiimote(const unsigned int index) - : m_index(index), ir_sin(0), ir_cos(1), m_last_connect_request_counter(0) +Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1) { // ---- set up all the controls ---- @@ -933,26 +931,14 @@ void Wiimote::InterruptChannel(const u16 channel_id, const void* data, u32 size) } } -void Wiimote::ConnectOnInput() +bool Wiimote::CheckForButtonPress() { - if (m_last_connect_request_counter > 0) - { - --m_last_connect_request_counter; - return; - } - u16 buttons = 0; const auto lock = GetStateLock(); m_buttons->GetState(&buttons, button_bitmasks); m_dpad->GetState(&buttons, dpad_bitmasks); - if (buttons != 0 || m_extension->IsButtonPressed()) - { - ::Wiimote::Connect(m_index, true); - // arbitrary value so it doesn't try to send multiple requests before Dolphin can react - // if Wii Remotes are polled at 200Hz then this results in one request being sent per 500ms - m_last_connect_request_counter = 100; - } + return (buttons != 0 || m_extension->IsButtonPressed()); } void Wiimote::LoadDefaults(const ControllerInterface& ciface) diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index 44ea750605..09ae20b56c 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -201,7 +201,7 @@ public: void Update(); void InterruptChannel(const u16 channel_id, const void* data, u32 size); void ControlChannel(const u16 channel_id, const void* data, u32 size); - void ConnectOnInput(); + bool CheckForButtonPress(); void Reset(); void DoState(PointerWrap& p); @@ -328,9 +328,6 @@ private: u8 unk_9; } m_reg_speaker; - // limits the amount of connect requests we send when a button is pressed in disconnected state - u8 m_last_connect_request_counter; - #pragma pack(pop) }; } diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp index c3a54bdeb9..8df0c29665 100644 --- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp @@ -26,7 +26,6 @@ #include "Core/HW/WiimoteReal/IOWin.h" #include "Core/HW/WiimoteReal/IOdarwin.h" #include "Core/HW/WiimoteReal/IOhidapi.h" -#include "Core/Host.h" #include "InputCommon/InputConfig.h" #include "SFML/Network.hpp" @@ -51,9 +50,7 @@ std::mutex g_wiimotes_mutex; Wiimote* g_wiimotes[MAX_BBMOTES]; WiimoteScanner g_wiimote_scanner; -Wiimote::Wiimote() - : m_index(), m_last_input_report(), m_channel(0), m_last_connect_request_counter(0), - m_rumble_state() +Wiimote::Wiimote() : m_index(), m_last_input_report(), m_channel(0), m_rumble_state() { } @@ -365,14 +362,8 @@ void Wiimote::Update() } } -void Wiimote::ConnectOnInput() +bool Wiimote::CheckForButtonPress() { - if (m_last_connect_request_counter > 0) - { - --m_last_connect_request_counter; - return; - } - const Report& rpt = ProcessReadQueue(); if (rpt.size() >= 4) { @@ -391,15 +382,14 @@ void Wiimote::ConnectOnInput() // check any button without checking accelerometer data if ((rpt[2] & 0x1F) != 0 || (rpt[3] & 0x9F) != 0) { - ::Wiimote::Connect(m_index, true); - // see WiimoteEmu::Wiimote::ConnectOnInput(), same idea here - m_last_connect_request_counter = 100; + return true; } break; default: break; } } + return false; } void Wiimote::Prepare() @@ -897,15 +887,16 @@ void Update(int wiimote_number) ::Wiimote::Connect(wiimote_number, false); } -void ConnectOnInput(int wiimote_number) +bool CheckForButtonPress(int wiimote_number) { if (!g_wiimotes_mutex.try_lock()) - return; + return false; if (g_wiimotes[wiimote_number]) - g_wiimotes[wiimote_number]->ConnectOnInput(); + return g_wiimotes[wiimote_number]->CheckForButtonPress(); g_wiimotes_mutex.unlock(); + return false; } bool IsValidDeviceName(const std::string& name) diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h index 09bcf8c279..2c213a9dec 100644 --- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h @@ -36,7 +36,7 @@ public: void ControlChannel(const u16 channel, const void* const data, const u32 size); void InterruptChannel(const u16 channel, const void* const data, const u32 size); void Update(); - void ConnectOnInput(); + bool CheckForButtonPress(); Report& ProcessReadQueue(); @@ -83,7 +83,6 @@ protected: int m_index; Report m_last_input_report; u16 m_channel; - u8 m_last_connect_request_counter; // If true, the Wiimote will be really disconnected when it is disconnected by Dolphin. // In any other case, data reporting is not paused to allow reconnecting on any button press. // This is not enabled on all platforms as connecting a Wiimote can be a pain on some platforms. @@ -159,7 +158,7 @@ extern Wiimote* g_wiimotes[MAX_BBMOTES]; void InterruptChannel(int wiimote_number, u16 channel_id, const void* data, u32 size); void ControlChannel(int wiimote_number, u16 channel_id, const void* data, u32 size); void Update(int wiimote_number); -void ConnectOnInput(int wiimote_number); +bool CheckForButtonPress(int wiimote_number); void ChangeWiimoteSource(unsigned int index, int source); diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index 6774e323c6..b0c7f6fd16 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -1280,6 +1280,27 @@ bool WiimoteEmu::Wiimote::NetPlay_GetWiimoteData(int wiimote, u8* data, u8 size, 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) +{ + std::lock_guard lk(crit_netplay_client); + + // Use the reporting mode 0 for the button pressed event, the real ones start at RT_REPORT_CORE + u8 data[2] = {static_cast(pressed), 0}; + + if (netplay_client) + { + if (netplay_client->WiimoteUpdate(wiimote, data, 2, 0)) + { + return data[0]; + } + PanicAlertT("Netplay has desynced in NetPlay_GetButtonPress()"); + return false; + } + + return pressed; +} + // called from ---CPU--- thread // so all players' games get the same time //