diff --git a/Source/Core/Core/HW/Wiimote.cpp b/Source/Core/Core/HW/Wiimote.cpp index 7f911b04b4..8740f956cc 100644 --- a/Source/Core/Core/HW/Wiimote.cpp +++ b/Source/Core/Core/HW/Wiimote.cpp @@ -6,6 +6,7 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" +#include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "Core/ConfigManager.h" @@ -137,21 +138,29 @@ void Pause() // An L2CAP packet is passed from the Core to the Wiimote on the HID CONTROL channel. void ControlChannel(int number, u16 channel_id, const void* data, u32 size) { - if (g_wiimote_sources[number]) + if (WIIMOTE_SRC_EMU == g_wiimote_sources[number]) { static_cast(s_config.GetController(number)) ->ControlChannel(channel_id, data, size); } + else + { + WiimoteReal::ControlChannel(number, channel_id, data, size); + } } // An L2CAP packet is passed from the Core to the Wiimote on the HID INTERRUPT channel. void InterruptChannel(int number, u16 channel_id, const void* data, u32 size) { - if (g_wiimote_sources[number]) + if (WIIMOTE_SRC_EMU == g_wiimote_sources[number]) { static_cast(s_config.GetController(number)) ->InterruptChannel(channel_id, data, size); } + else + { + WiimoteReal::InterruptChannel(number, channel_id, data, size); + } } bool ButtonPressed(int number) @@ -215,6 +224,26 @@ unsigned int GetAttached() void DoState(PointerWrap& p) { for (int i = 0; i < MAX_BBMOTES; ++i) - static_cast(s_config.GetController(i))->DoState(p); + { + auto state_wiimote_source = u8(g_wiimote_sources[i]); + p.Do(state_wiimote_source); + + if (WIIMOTE_SRC_EMU == state_wiimote_source) + { + // Sync complete state of emulated wiimotes. + static_cast(s_config.GetController(i))->DoState(p); + } + + if (p.GetMode() == PointerWrap::MODE_READ) + { + // If using a real wiimote or the save-state source does not match the current source, + // then force a reconnection on load. + if (WIIMOTE_SRC_REAL == g_wiimote_sources[i] || state_wiimote_source != g_wiimote_sources[i]) + { + Connect(i, false); + Connect(i, true); + } + } + } } } // namespace Wiimote diff --git a/Source/Core/Core/HW/Wiimote.h b/Source/Core/Core/HW/Wiimote.h index a9e9405696..f238406b45 100644 --- a/Source/Core/Core/HW/Wiimote.h +++ b/Source/Core/Core/HW/Wiimote.h @@ -4,6 +4,9 @@ #pragma once +#include +#include + #include "Common/Common.h" #include "Common/CommonTypes.h" @@ -45,7 +48,7 @@ enum WIIMOTE_SRC_REAL = 2, }; -extern unsigned int g_wiimote_sources[MAX_BBMOTES]; +extern std::array, MAX_BBMOTES> g_wiimote_sources; namespace Wiimote { diff --git a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp index 8bb39e5106..30f0871042 100644 --- a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp @@ -590,9 +590,6 @@ void Wiimote::DoState(PointerWrap& p) p.Do(m_shake_step); p.DoMarker("Wiimote"); - - if (p.GetMode() == PointerWrap::MODE_READ) - RealState(); } ExtensionNumber Wiimote::GetActiveExtensionNumber() const @@ -600,14 +597,4 @@ ExtensionNumber Wiimote::GetActiveExtensionNumber() const return m_active_extension; } -void Wiimote::RealState() -{ - using namespace WiimoteReal; - - if (g_wiimotes[m_index]) - { - g_wiimotes[m_index]->SetChannel(m_reporting_channel); - } -} - } // namespace WiimoteEmu diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 10f1326f6d..e17553bebb 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -20,6 +20,7 @@ #include "Core/Config/WiimoteInputSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" +#include "Core/HW/Wiimote.h" #include "Core/Movie.h" #include "Core/NetPlayClient.h" @@ -30,7 +31,6 @@ #include "Core/HW/WiimoteEmu/Extension/Guitar.h" #include "Core/HW/WiimoteEmu/Extension/Nunchuk.h" #include "Core/HW/WiimoteEmu/Extension/Turntable.h" -#include "Core/HW/WiimoteReal/WiimoteReal.h" #include "InputCommon/ControllerEmu/Control/Input.h" #include "InputCommon/ControllerEmu/Control/Output.h" @@ -503,14 +503,6 @@ void Wiimote::ControlChannel(const u16 channel_id, const void* data, u32 size) m_reporting_channel = channel_id; - // FYI: ControlChannel is piped through WiimoteEmu before WiimoteReal just so we can sync the - // channel on state load. This is ugly. - if (WIIMOTE_SRC_REAL == g_wiimote_sources[m_index]) - { - WiimoteReal::ControlChannel(m_index, channel_id, data, size); - return; - } - const auto& hidp = *reinterpret_cast(data); DEBUG_LOG(WIIMOTE, "Emu ControlChannel (page: %i, type: 0x%02x, param: 0x%02x)", m_index, @@ -559,14 +551,6 @@ void Wiimote::InterruptChannel(const u16 channel_id, const void* data, u32 size) m_reporting_channel = channel_id; - // FYI: InterruptChannel is piped through WiimoteEmu before WiimoteReal just so we can sync the - // channel on state load. This is ugly. - if (WIIMOTE_SRC_REAL == g_wiimote_sources[m_index]) - { - WiimoteReal::InterruptChannel(m_index, channel_id, data, size); - return; - } - const auto& hidp = *reinterpret_cast(data); switch (hidp.type) diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index 863bb8a1e1..1ff17505db 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -35,12 +35,6 @@ class Output; class Tilt; } // namespace ControllerEmu -// Needed for friendship: -namespace WiimoteReal -{ -class Wiimote; -} // namespace WiimoteReal - namespace WiimoteEmu { enum class WiimoteGroup @@ -87,8 +81,6 @@ void UpdateCalibrationDataChecksum(T& data, int cksum_bytes) class Wiimote : public ControllerEmu::EmulatedController { - friend class WiimoteReal::Wiimote; - public: enum : u8 { @@ -173,8 +165,6 @@ private: void SendDataReport(); bool ProcessReadDataRequest(); - void RealState(); - void SetRumble(bool on); void CallbackInterruptChannel(const u8* data, u32 size); diff --git a/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm index 5436692076..6e35ddb808 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm @@ -284,7 +284,7 @@ void WiimoteDarwin::DisablePowerAssertionInternal() for (int i = 0; i < MAX_WIIMOTES; i++) { - wm = static_cast(WiimoteReal::g_wiimotes[i]); + wm = static_cast(WiimoteReal::g_wiimotes[i].get()); if (!wm) continue; if ([device isEqual:wm->m_btd]) @@ -325,7 +325,7 @@ void WiimoteDarwin::DisablePowerAssertionInternal() for (int i = 0; i < MAX_WIIMOTES; i++) { - wm = static_cast(WiimoteReal::g_wiimotes[i]); + wm = static_cast(WiimoteReal::g_wiimotes[i].get()); if (!wm) continue; if ([device isEqual:wm->m_btd]) diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp index b7dab2fefe..3f61902a92 100644 --- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp @@ -19,8 +19,8 @@ #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/HW/Wiimote.h" +#include "Core/HW/WiimoteCommon/DataReport.h" #include "Core/HW/WiimoteCommon/WiimoteHid.h" -#include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "Core/HW/WiimoteReal/IOAndroid.h" #include "Core/HW/WiimoteReal/IOLinux.h" #include "Core/HW/WiimoteReal/IOWin.h" @@ -30,14 +30,14 @@ #include "SFML/Network.hpp" -unsigned int g_wiimote_sources[MAX_BBMOTES]; +std::array, MAX_BBMOTES> g_wiimote_sources; namespace WiimoteReal { using namespace WiimoteCommon; -static void TryToConnectBalanceBoard(Wiimote*); -static void TryToConnectWiimote(Wiimote*); +static void TryToConnectBalanceBoard(std::unique_ptr); +static void TryToConnectWiimote(std::unique_ptr); static void HandleWiimoteDisconnect(int index); static bool g_real_wiimotes_initialized = false; @@ -49,18 +49,19 @@ static std::mutex s_known_ids_mutex; std::mutex g_wiimotes_mutex; -Wiimote* g_wiimotes[MAX_BBMOTES]; +std::unique_ptr g_wiimotes[MAX_BBMOTES]; WiimoteScanner g_wiimote_scanner; -Wiimote::Wiimote() : m_index(), m_last_input_report(), m_channel(0), m_rumble_state() -{ -} - void Wiimote::Shutdown() { + std::lock_guard lk(s_known_ids_mutex); + s_known_ids.erase(GetId()); + StopThread(); ClearReadQueue(); m_write_reports.Clear(); + + NOTICE_LOG(WIIMOTE, "Disconnected real wiimote."); } // to be called from CPU thread @@ -70,9 +71,31 @@ void Wiimote::WriteReport(Report rpt) { bool const new_rumble_state = (rpt[2] & 0x1) != 0; - // If this is a rumble report and the rumble state didn't change, ignore. - if (rpt[1] == u8(OutputReportID::Rumble) && new_rumble_state == m_rumble_state) - return; + switch (WiimoteCommon::OutputReportID(rpt[1])) + { + case OutputReportID::Rumble: + // If this is a rumble report and the rumble state didn't change, we can drop this report. + if (new_rumble_state == m_rumble_state) + return; + break; + + case OutputReportID::SpeakerEnable: + m_speaker_enable = (rpt[2] & 0x4) != 0; + break; + + case OutputReportID::SpeakerMute: + m_speaker_mute = (rpt[2] & 0x4) != 0; + break; + + case OutputReportID::ReportMode: + // Force non-continuous reporting for less BT traffic. + // We duplicate reports to maintain 200hz anyways. + rpt[2] &= ~0x4; + break; + + default: + break; + } m_rumble_state = new_rumble_state; } @@ -82,42 +105,27 @@ void Wiimote::WriteReport(Report rpt) } // to be called from CPU thread -void Wiimote::QueueReport(u8 rpt_id, const void* data, unsigned int size) +void Wiimote::QueueReport(WiimoteCommon::OutputReportID rpt_id, const void* data, unsigned int size) { auto const queue_data = static_cast(data); Report rpt(size + 2); rpt[0] = WR_SET_REPORT | BT_OUTPUT; - rpt[1] = rpt_id; + rpt[1] = u8(rpt_id); std::copy_n(queue_data, size, rpt.begin() + 2); WriteReport(std::move(rpt)); } -void Wiimote::DisableDataReporting() +void Wiimote::ResetDataReporting() { m_last_input_report.clear(); - // This accomplishes very little: + // "core" reporting in non-continuous mode is a wiimote's initial state. + // FYI: This also disables rumble. OutputReportMode rpt = {}; rpt.mode = InputReportID::ReportCore; rpt.continuous = 0; - rpt.rumble = 0; - QueueReport(u8(OutputReportID::ReportMode), &rpt, sizeof(rpt)); -} - -void Wiimote::EnableDataReporting(u8 mode) -{ - m_last_input_report.clear(); - - OutputReportMode rpt = {}; - rpt.mode = InputReportID(mode); - rpt.continuous = 1; - QueueReport(u8(OutputReportID::ReportMode), &rpt, sizeof(rpt)); -} - -void Wiimote::SetChannel(u16 channel) -{ - m_channel = channel; + QueueReport(OutputReportID::ReportMode, &rpt, sizeof(rpt)); } void Wiimote::ClearReadQueue() @@ -136,7 +144,13 @@ void Wiimote::ControlChannel(const u16 channel, const void* const data, const u3 if (channel == 99) { if (m_really_disconnect) + { DisconnectInternal(); + } + else + { + EmuStop(); + } } else { @@ -164,8 +178,6 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const data, const auto const report_data = static_cast(data); Report rpt(report_data, report_data + size); - WiimoteEmu::Wiimote* const wm = - static_cast(::Wiimote::GetConfig()->GetController(m_index)); // Convert output DATA packets to SET_REPORT packets. // Nintendo Wiimotes work without this translation, but 3rd @@ -187,10 +199,9 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const data, const } } else if (rpt[1] == u8(OutputReportID::SpeakerData) && - (!SConfig::GetInstance().m_WiimoteEnableSpeaker || - (!wm->m_status.speaker || wm->m_speaker_mute))) + (!SConfig::GetInstance().m_WiimoteEnableSpeaker || !m_speaker_enable || m_speaker_mute)) { - // Translate speaker data reports into rumble reports. + // Translate undesired speaker data reports into rumble reports. rpt[1] = u8(OutputReportID::Rumble); // Keep only the rumble bit. rpt[2] &= 0x1; @@ -379,6 +390,8 @@ bool Wiimote::CheckForButtonPress() if (rpt.size() >= 4) { const auto mode = InputReportID(rpt[1]); + + // TODO: Button data could also be pulled out of non-data reports if really wanted. if (DataReportBuilder::IsValidMode(mode)) { auto builder = MakeDataReportManipulator(mode, rpt.data() + 2); @@ -423,49 +436,26 @@ bool Wiimote::PrepareOnThread() void Wiimote::EmuStart() { - DisableDataReporting(); + ResetDataReporting(); EnablePowerAssertionInternal(); } void Wiimote::EmuStop() { m_channel = 0; - - DisableDataReporting(); - - NOTICE_LOG(WIIMOTE, "Stopping Wiimote data reporting."); - + ResetDataReporting(); DisablePowerAssertionInternal(); } void Wiimote::EmuResume() { - WiimoteEmu::Wiimote* const wm = - static_cast(::Wiimote::GetConfig()->GetController(m_index)); - m_last_input_report.clear(); - OutputReportMode rpt = {}; - rpt.mode = wm->m_reporting_mode; - rpt.continuous = 1; - QueueReport(u8(OutputReportID::ReportMode), &rpt, sizeof(rpt)); - - NOTICE_LOG(WIIMOTE, "Resuming Wiimote data reporting."); - EnablePowerAssertionInternal(); } void Wiimote::EmuPause() { - m_last_input_report.clear(); - - OutputReportMode rpt = {}; - rpt.mode = InputReportID::ReportCore; - rpt.continuous = 0; - QueueReport(u8(OutputReportID::ReportMode), &rpt, sizeof(rpt)); - - NOTICE_LOG(WIIMOTE, "Pausing Wiimote data reporting."); - DisablePowerAssertionInternal(); } @@ -569,25 +559,43 @@ void WiimoteScanner::ThreadFunc() if (m_scan_mode.load() == WiimoteScanMode::DO_NOT_SCAN) continue; + if (!g_real_wiimotes_initialized) + continue; + + // Does stuff needed to detect disconnects on Windows + for (const auto& backend : m_backends) + backend->Update(); + + if (0 == CalculateWantedWiimotes() && 0 == CalculateWantedBB()) + continue; + for (const auto& backend : m_backends) { - if (CalculateWantedWiimotes() != 0 || CalculateWantedBB() != 0) + std::vector found_wiimotes; + Wiimote* found_board = nullptr; + backend->FindWiimotes(found_wiimotes, found_board); { - std::vector found_wiimotes; - Wiimote* found_board = nullptr; - backend->FindWiimotes(found_wiimotes, found_board); + std::lock_guard wm_lk(g_wiimotes_mutex); + + for (auto* wiimote : found_wiimotes) { - if (!g_real_wiimotes_initialized) - continue; - std::lock_guard lk(g_wiimotes_mutex); - std::for_each(found_wiimotes.begin(), found_wiimotes.end(), TryToConnectWiimote); - if (found_board) - TryToConnectBalanceBoard(found_board); + { + std::lock_guard lk(s_known_ids_mutex); + s_known_ids.insert(wiimote->GetId()); + } + + TryToConnectWiimote(std::unique_ptr(wiimote)); + } + + if (found_board) + { + { + std::lock_guard lk(s_known_ids_mutex); + s_known_ids.insert(found_board->GetId()); + } + + TryToConnectBalanceBoard(std::unique_ptr(found_board)); } - } - else - { - backend->Update(); // Does stuff needed to detect disconnects on Windows } } @@ -687,12 +695,17 @@ void LoadSettings() secname += static_cast('1' + i); IniFile::Section& sec = *inifile.GetOrCreateSection(secname); - sec.Get("Source", &g_wiimote_sources[i], i ? WIIMOTE_SRC_NONE : WIIMOTE_SRC_EMU); + unsigned int source = 0; + sec.Get("Source", &source, i ? WIIMOTE_SRC_NONE : WIIMOTE_SRC_EMU); + g_wiimote_sources[i] = source; } std::string secname("BalanceBoard"); IniFile::Section& sec = *inifile.GetOrCreateSection(secname); - sec.Get("Source", &g_wiimote_sources[WIIMOTE_BALANCE_BOARD], WIIMOTE_SRC_NONE); + + unsigned int bb_source = 0; + sec.Get("Source", &bb_source, WIIMOTE_SRC_NONE); + g_wiimote_sources[WIIMOTE_BALANCE_BOARD] = bb_source; } // config dialog calls this when some settings change @@ -700,7 +713,6 @@ void Initialize(::Wiimote::InitializeMode init_mode) { if (!g_real_wiimotes_initialized) { - s_known_ids.clear(); g_wiimote_scanner.StartThread(); } @@ -776,83 +788,70 @@ void ChangeWiimoteSource(unsigned int index, int source) } g_wiimote_sources[index] = source; + { - // kill real connection (or swap to different slot) + // Kill real wiimote connection (if any) (or swap to different slot) std::lock_guard lk(g_wiimotes_mutex); - - Wiimote* wm = g_wiimotes[index]; - - if (wm) + if (auto removed_wiimote = std::move(g_wiimotes[index])) { - g_wiimotes[index] = nullptr; - // First see if we can use this real Wiimote in another slot. - TryToConnectWiimote(wm); + // See if we can use this real Wiimote in another slot. + // Otherwise it will be disconnected. + TryToConnectWiimote(std::move(removed_wiimote)); } - - // else, just disconnect the Wiimote - HandleWiimoteDisconnect(index); } - // reconnect to the emulator + // Reconnect to the emulator. Core::RunAsCPUThread([index, previous_source, source] { if (previous_source != WIIMOTE_SRC_NONE) ::Wiimote::Connect(index, false); - if (source & WIIMOTE_SRC_EMU) + + if (source == WIIMOTE_SRC_EMU) ::Wiimote::Connect(index, true); }); } -// Called from the Wiimote scanner thread -static bool TryToConnectWiimoteToSlot(Wiimote* wm, unsigned int i) +// Called from the Wiimote scanner thread (or UI thread on source change) +static bool TryToConnectWiimoteToSlot(std::unique_ptr& wm, unsigned int i) { - if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] && !g_wiimotes[i]) + if (WIIMOTE_SRC_REAL != g_wiimote_sources[i] || g_wiimotes[i]) + return false; + + if (!wm->Connect(i)) { - if (wm->Connect(i)) - { - NOTICE_LOG(WIIMOTE, "Connected to Wiimote %i.", i + 1); - g_wiimotes[i] = wm; - Core::RunAsCPUThread([i] { ::Wiimote::Connect(i, true); }); - std::lock_guard lk(s_known_ids_mutex); - s_known_ids.insert(wm->GetId()); - } - return true; + ERROR_LOG(WIIMOTE, "Failed to connect real wiimote."); + return false; } - return false; + + g_wiimotes[i] = std::move(wm); + Core::RunAsCPUThread([i] { ::Wiimote::Connect(i, true); }); + + NOTICE_LOG(WIIMOTE, "Connected real wiimote to slot %i.", i + 1); + + return true; } -static void TryToConnectWiimote(Wiimote* wm) +static void TryToConnectWiimote(std::unique_ptr wm) { for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) { if (TryToConnectWiimoteToSlot(wm, i)) - { - wm = nullptr; - break; - } + return; } - delete wm; + + NOTICE_LOG(WIIMOTE, "No open slot for real wiimote."); } -static void TryToConnectBalanceBoard(Wiimote* wm) +static void TryToConnectBalanceBoard(std::unique_ptr wm) { if (TryToConnectWiimoteToSlot(wm, WIIMOTE_BALANCE_BOARD)) - { - wm = nullptr; - } - delete wm; + return; + + NOTICE_LOG(WIIMOTE, "No open slot for real balance board."); } static void HandleWiimoteDisconnect(int index) { - Wiimote* wm = nullptr; - std::swap(wm, g_wiimotes[index]); - if (wm) - { - std::lock_guard lk(s_known_ids_mutex); - s_known_ids.erase(wm->GetId()); - delete wm; - NOTICE_LOG(WIIMOTE, "Disconnected Wiimote %i.", index + 1); - } + g_wiimotes[index] = nullptr; } // This is called from the GUI thread diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h index 01e1001f57..e5673eaf78 100644 --- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include #include @@ -105,19 +106,19 @@ public: void Prepare(); bool PrepareOnThread(); - void DisableDataReporting(); - void EnableDataReporting(u8 mode); - void SetChannel(u16 channel); + void ResetDataReporting(); - void QueueReport(u8 rpt_id, const void* data, unsigned int size); + void QueueReport(WiimoteCommon::OutputReportID rpt_id, const void* data, unsigned int size); int GetIndex() const; protected: - Wiimote(); - int m_index; - Report m_last_input_report; - u16 m_channel; + Wiimote() = default; + + int m_index = 0; + Report m_last_input_report = {}; + u16 m_channel = 0; + // 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. @@ -133,7 +134,12 @@ private: void ThreadFunc(); - bool m_rumble_state; + // We track the speaker state to convert unnecessary speaker data into rumble reports. + bool m_speaker_enable = false; + bool m_speaker_mute = false; + + // And we track the rumble state to drop unnecessary rumble reports. + bool m_rumble_state = false; std::thread m_wiimote_thread; // Whether to keep running the thread. @@ -188,7 +194,7 @@ private: extern std::mutex g_wiimotes_mutex; extern WiimoteScanner g_wiimote_scanner; -extern Wiimote* g_wiimotes[MAX_BBMOTES]; +extern std::unique_ptr 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); diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index c616ee923b..28bf23d3dd 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -74,7 +74,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 104; // Last changed in PR 7806 +static const u32 STATE_VERSION = 105; // Last changed in PR 7871 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list, @@ -177,10 +177,6 @@ static void DoState(PointerWrap& p) g_video_backend->DoState(p); p.DoMarker("video_backend"); - if (SConfig::GetInstance().bWii) - Wiimote::DoState(p); - p.DoMarker("Wiimote"); - PowerPC::DoState(p); p.DoMarker("PowerPC"); // CoreTiming needs to be restored before restoring Hardware because @@ -189,6 +185,9 @@ static void DoState(PointerWrap& p) p.DoMarker("CoreTiming"); HW::DoState(p); p.DoMarker("HW"); + if (SConfig::GetInstance().bWii) + Wiimote::DoState(p); + p.DoMarker("Wiimote"); Movie::DoState(p); p.DoMarker("Movie"); Gecko::DoState(p); diff --git a/Source/Core/DolphinQt/Config/ControllersWindow.cpp b/Source/Core/DolphinQt/Config/ControllersWindow.cpp index 75d99495a8..fb5813bdc1 100644 --- a/Source/Core/DolphinQt/Config/ControllersWindow.cpp +++ b/Source/Core/DolphinQt/Config/ControllersWindow.cpp @@ -496,11 +496,8 @@ void ControllersWindow::SaveSettings() for (size_t i = 0; i < m_wiimote_groups.size(); i++) { const int index = m_wiimote_boxes[i]->currentIndex(); - g_wiimote_sources[i] = index; m_wiimote_buttons[i]->setEnabled(index != 0 && index != 2); - - if (Core::IsRunning()) - WiimoteReal::ChangeWiimoteSource(static_cast(i), index); + WiimoteReal::ChangeWiimoteSource(static_cast(i), index); } UICommon::SaveWiimoteSources();