summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2025-10-03 23:08:28 -0500
committerJordan Woyak <jordan.woyak@gmail.com>2025-10-12 12:37:04 -0500
commit801f38d4e5e18c712141e93d6064f18dc9815b30 (patch)
treebb0b0692dfcc542f5476d4d432d0ff21f5246d05 /Source/Core
parent8845fbdb7e84f4707e7b664b01e381419d7deadb (diff)
DolphinQt: Add buttons to create and reset Wii remote pairings on Windows.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/HW/WiimoteReal/IOWin.cpp13
-rw-r--r--Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp79
-rw-r--r--Source/Core/DolphinQt/Config/WiimoteControllersWidget.h11
3 files changed, 96 insertions, 7 deletions
diff --git a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp
index 6f037019e7..91ed7d8d56 100644
--- a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp
+++ b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp
@@ -308,8 +308,17 @@ void WiimoteScannerWindows::FindAndAuthenticateWiimotes()
{
// The sync button method conveniently makes remotes seek reconnection on button press.
// I think the 1+2 method is effectively pointless?
- const auto pair_count =
- DiscoverAndPairWiimotes(DEFAULT_INQUIRY_LENGTH, AuthenticationMethod::SyncButton);
+ static constexpr auto auth_method = AuthenticationMethod::SyncButton;
+
+ // Windows isn't so cooperative. This helps one button click actually able to pair a remote.
+ constexpr int ITERATION_COUNT = 3;
+
+ RemoveUnusableWiimoteBluetoothDevices();
+
+ auto pair_count = 0;
+ for (int i = 0; i != ITERATION_COUNT; ++i)
+ pair_count += DiscoverAndPairWiimotes(DEFAULT_INQUIRY_LENGTH, auth_method);
+
NOTICE_LOG_FMT(WIIMOTE, "Successfully paired Wiimotes: {}", pair_count);
}
diff --git a/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp b/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp
index 1d78196907..9f7d4cdc49 100644
--- a/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp
+++ b/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp
@@ -12,6 +12,8 @@
#include <QPushButton>
#include <QRadioButton>
#include <QScreen>
+#include <QTimer>
+#include <QToolButton>
#include <QVBoxLayout>
#include <QVariant>
@@ -39,6 +41,10 @@
#include "DolphinQt/Settings.h"
#include "DolphinQt/Settings/USBDevicePicker.h"
+#if defined(_WIN32)
+#include "Core/HW//WiimoteReal/IOWin.h"
+#endif
+
WiimoteControllersWidget::WiimoteControllersWidget(QWidget* parent) : QWidget(parent)
{
CreateLayout();
@@ -191,7 +197,31 @@ void WiimoteControllersWidget::CreateLayout()
m_bluetooth_adapters_refresh = new NonDefaultQPushButton(tr("Refresh"));
m_wiimote_sync = new NonDefaultQPushButton(tr("Sync"));
m_wiimote_reset = new NonDefaultQPushButton(tr("Reset"));
- m_wiimote_refresh = new NonDefaultQPushButton(tr("Refresh"));
+
+ m_wiimote_refresh_indicator = new QLabel{};
+ m_wiimote_refresh_indicator->hide();
+ m_wiimote_refresh = new QToolButton();
+ auto* const wiimote_refresh_action = new QAction(tr("Refresh"), m_wiimote_refresh);
+ m_wiimote_refresh->setDefaultAction(wiimote_refresh_action);
+ connect(wiimote_refresh_action, &QAction::triggered, this,
+ &WiimoteControllersWidget::OnWiimoteRefreshPressed);
+ m_wiimote_refresh->setPopupMode(QToolButton::ToolButtonPopupMode::MenuButtonPopup);
+
+#if defined(_WIN32)
+ m_wiimote_refresh_indicator->setPixmap(
+ style()->standardIcon(QStyle::SP_BrowserReload).pixmap(16, 16));
+
+ auto* const wiimote_sync_action = new QAction(tr("Sync"), m_wiimote_refresh);
+ m_wiimote_refresh->addAction(wiimote_sync_action);
+ connect(wiimote_sync_action, &QAction::triggered, this,
+ &WiimoteControllersWidget::TriggerHostWiimoteSync);
+
+ auto* const wiimote_reset_action = new QAction(tr("Reset"), m_wiimote_refresh);
+ m_wiimote_refresh->addAction(wiimote_reset_action);
+ connect(wiimote_reset_action, &QAction::triggered, this,
+ &WiimoteControllersWidget::TriggerHostWiimoteReset);
+#endif
+
m_wiimote_pt_labels[0] = new QLabel(tr("Sync real Wii Remotes and pair them"));
m_wiimote_pt_labels[1] = new QLabel(tr("Reset all saved Wii Remote pairings"));
m_wiimote_emu = new QRadioButton(tr("Emulate the Wii's Bluetooth adapter"));
@@ -245,7 +275,13 @@ void WiimoteControllersWidget::CreateLayout()
m_wiimote_layout->addWidget(m_wiimote_ciface, m_wiimote_layout->rowCount(), 0, 1, -1);
int continuous_scanning_row = m_wiimote_layout->rowCount();
- m_wiimote_layout->addWidget(m_wiimote_continuous_scanning, continuous_scanning_row, 0, 1, 3);
+
+ auto* const left_of_refresh_button_layout = new QHBoxLayout;
+ left_of_refresh_button_layout->addWidget(m_wiimote_continuous_scanning);
+ left_of_refresh_button_layout->addStretch(1);
+ left_of_refresh_button_layout->addWidget(m_wiimote_refresh_indicator);
+
+ m_wiimote_layout->addLayout(left_of_refresh_button_layout, continuous_scanning_row, 0, 1, 3);
m_wiimote_layout->addWidget(m_wiimote_refresh, continuous_scanning_row, 3);
m_bluetooth_unavailable = new QLabel(tr("A supported Bluetooth device could not be found.\n"
@@ -287,8 +323,6 @@ void WiimoteControllersWidget::ConnectWidgets()
&WiimoteControllersWidget::OnBluetoothPassthroughSyncPressed);
connect(m_wiimote_reset, &QPushButton::clicked, this,
&WiimoteControllersWidget::OnBluetoothPassthroughResetPressed);
- connect(m_wiimote_refresh, &QPushButton::clicked, this,
- &WiimoteControllersWidget::OnWiimoteRefreshPressed);
for (size_t i = 0; i < m_wiimote_groups.size(); i++)
{
@@ -503,3 +537,40 @@ void WiimoteControllersWidget::SaveSettings()
SConfig::GetInstance().SaveSettings();
}
+
+#if defined(_WIN32)
+void WiimoteControllersWidget::AsyncRefreshActionHelper(std::invocable<> auto func)
+{
+ m_wiimote_refresh->setEnabled(false);
+ m_wiimote_refresh_indicator->show();
+
+ auto result = std::async(std::launch::async, std::move(func));
+
+ auto* const animation = new QTimer{this};
+ connect(animation, &QTimer::timeout, this, [this, animation, result = std::move(result)] {
+ // Spin the refresh indicator.
+ m_wiimote_refresh_indicator->setPixmap(
+ m_wiimote_refresh_indicator->pixmap().transformed(QTransform().rotate(90)));
+
+ if (result.wait_for(std::chrono::seconds{}) != std::future_status::ready)
+ return;
+
+ // When the async task is done, re-enable the button and hide the indicator.
+ animation->deleteLater();
+ m_wiimote_refresh_indicator->hide();
+ m_wiimote_refresh->setEnabled(true);
+ });
+
+ animation->start(250);
+}
+
+void WiimoteControllersWidget::TriggerHostWiimoteSync()
+{
+ AsyncRefreshActionHelper(WiimoteReal::WiimoteScannerWindows::FindAndAuthenticateWiimotes);
+}
+
+void WiimoteControllersWidget::TriggerHostWiimoteReset()
+{
+ AsyncRefreshActionHelper(WiimoteReal::WiimoteScannerWindows::RemoveRememberedWiimotes);
+}
+#endif
diff --git a/Source/Core/DolphinQt/Config/WiimoteControllersWidget.h b/Source/Core/DolphinQt/Config/WiimoteControllersWidget.h
index ef75fbbcbb..b2a082b3e2 100644
--- a/Source/Core/DolphinQt/Config/WiimoteControllersWidget.h
+++ b/Source/Core/DolphinQt/Config/WiimoteControllersWidget.h
@@ -10,10 +10,12 @@
#include "Common/WorkQueueThread.h"
#include "Core/USBUtils.h"
+class QAction;
class QCheckBox;
class QComboBox;
class QHBoxLayout;
class QGridLayout;
+class QToolButton;
class QGroupBox;
class QLabel;
class QPushButton;
@@ -48,6 +50,12 @@ private:
void ConnectWidgets();
void LoadSettings(Core::State state);
+#if defined(_WIN32)
+ void AsyncRefreshActionHelper(std::invocable<> auto);
+ void TriggerHostWiimoteSync();
+ void TriggerHostWiimoteReset();
+#endif
+
QGroupBox* m_wiimote_box;
QGridLayout* m_wiimote_layout;
std::array<QLabel*, 4> m_wiimote_labels;
@@ -70,6 +78,7 @@ private:
QCheckBox* m_wiimote_real_balance_board;
QCheckBox* m_wiimote_speaker_data;
QCheckBox* m_wiimote_ciface;
- QPushButton* m_wiimote_refresh;
+ QToolButton* m_wiimote_refresh;
+ QLabel* m_wiimote_refresh_indicator;
QLabel* m_bluetooth_unavailable;
};