From fc4cbf9c6fa76862b153d72baddde11edb8a3958 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 22 Dec 2025 23:18:36 -0600 Subject: [PATCH] HW/WiimoteReal: Cache the enumerated Wii remote HID interface list between calls to FindWiimoteHIDDevices. --- Source/Core/Core/HW/WiimoteReal/IOWin.cpp | 41 ++++++++++++++++------- Source/Core/Core/HW/WiimoteReal/IOWin.h | 17 ++++++++++ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp index e1cf4971e9..29a7ef2d45 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp @@ -24,7 +24,6 @@ #include "Common/ScopeGuard.h" #include "Common/StringUtil.h" #include "Common/Thread.h" -#include "Common/WindowsDevice.h" #include "Core/HW/WiimoteCommon/DataReport.h" #include "Core/HW/WiimoteCommon/WiimoteConstants.h" @@ -328,7 +327,12 @@ void WiimoteScannerWindows::RemoveRememberedWiimotes() NOTICE_LOG_FMT(WIIMOTE, "Removed remembered Wiimotes: {}", forget_count); } -WiimoteScannerWindows::WiimoteScannerWindows() = default; +WiimoteScannerWindows::WiimoteScannerWindows() +{ + m_device_change_notification.Register([this](Common::DeviceChangeNotification::EventType) { + m_devices_changed.store(true, std::memory_order_release); + }); +} void WiimoteScannerWindows::Update() { @@ -576,9 +580,9 @@ int WiimoteWindows::IOWrite(const u8* buf, size_t len) return write_result; } -auto WiimoteScannerWindows::FindWiimoteHIDDevices() -> FindResults +static std::vector GetAllWiimoteHIDInterfaces() { - FindResults results; + std::vector results; // Enumerate connected HID interfaces IDs. auto class_guid = GUID_DEVINTERFACE_HID; @@ -586,14 +590,6 @@ auto WiimoteScannerWindows::FindWiimoteHIDDevices() -> FindResults for (auto* hid_iface : Common::GetDeviceInterfaceList(&class_guid, nullptr, flags)) { - // TODO: WiimoteWindows::GetId() does a redundant conversion. - const auto hid_iface_utf8 = WStringToUTF8(hid_iface); - DEBUG_LOG_FMT(WIIMOTE, "Found HID interface: {}", hid_iface_utf8); - - // Are we already using this device? - if (!IsNewWiimote(hid_iface_utf8)) - continue; - // When connected via Bluetooth, this has a proper name like "Nintendo RVL-CNT-01". const auto parent_description = GetParentDeviceDescription(hid_iface); @@ -650,6 +646,27 @@ auto WiimoteScannerWindows::FindWiimoteHIDDevices() -> FindResults } // Once here, we are confident that this is a Wii device. + results.push_back({hid_iface, is_balance_board}); + } + + return results; +} + +auto WiimoteScannerWindows::FindWiimoteHIDDevices() -> FindResults +{ + if (m_devices_changed.exchange(false, std::memory_order_acquire)) + { + m_wiimote_hid_interfaces = GetAllWiimoteHIDInterfaces(); + INFO_LOG_FMT(WIIMOTE, "Found {} HID interface(s).", m_wiimote_hid_interfaces.size()); + } + + FindResults results; + + for (auto& [hid_iface, is_balance_board] : m_wiimote_hid_interfaces) + { + // Are we already using this device? + if (!IsNewWiimote(WStringToUTF8(hid_iface))) + continue; DEBUG_LOG_FMT(WIIMOTE, "Creating WiimoteWindows"); diff --git a/Source/Core/Core/HW/WiimoteReal/IOWin.h b/Source/Core/Core/HW/WiimoteReal/IOWin.h index b8bc29a86f..aa7b426288 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOWin.h +++ b/Source/Core/Core/HW/WiimoteReal/IOWin.h @@ -6,7 +6,12 @@ #ifdef _WIN32 #include +#include +#include + #include "Common/SocketContext.h" +#include "Common/WindowsDevice.h" + #include "Core/HW/WiimoteReal/WiimoteReal.h" #include "Core/USBUtils.h" @@ -50,6 +55,12 @@ private: class WiimoteScannerWindows final : public WiimoteScannerBackend { public: + struct EnumeratedWiimoteInterface + { + std::wstring hid_iface; + std::optional is_balance_board; + }; + WiimoteScannerWindows(); bool IsReady() const override; @@ -64,6 +75,12 @@ public: private: FindResults FindWiimoteHIDDevices(); + + // This vector is updated after we receive a device change notification. + std::vector m_wiimote_hid_interfaces; + std::atomic_bool m_devices_changed{true}; + + Common::DeviceChangeNotification m_device_change_notification; }; } // namespace WiimoteReal