From b56546d8add8b5fb4c76c3e7cf8ae8eabff2b332 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Wed, 29 Apr 2020 13:27:58 +1000 Subject: [PATCH] Qt: Always poll controllers even when not running Fixes pause hotkey not unpausing when bound to controller. --- src/duckstation-qt/inputbindingwidgets.cpp | 6 -- src/duckstation-qt/qthostinterface.cpp | 75 ++++++++-------------- src/duckstation-qt/qthostinterface.h | 10 +-- 3 files changed, 28 insertions(+), 63 deletions(-) diff --git a/src/duckstation-qt/inputbindingwidgets.cpp b/src/duckstation-qt/inputbindingwidgets.cpp index 67ad82097..ab8112f3c 100644 --- a/src/duckstation-qt/inputbindingwidgets.cpp +++ b/src/duckstation-qt/inputbindingwidgets.cpp @@ -185,7 +185,6 @@ void InputButtonBindingWidget::hookControllerInput() if (!controller_interface) return; - m_host_interface->enableBackgroundControllerPolling(); controller_interface->SetHook([this](const ControllerInterface::Hook& ei) { if (ei.type == ControllerInterface::Hook::Type::Axis) { @@ -216,7 +215,6 @@ void InputButtonBindingWidget::unhookControllerInput() return; controller_interface->ClearHook(); - m_host_interface->disableBackgroundControllerPolling(); } void InputButtonBindingWidget::bindToControllerAxis(int controller_index, int axis_index, bool positive) @@ -263,7 +261,6 @@ void InputAxisBindingWidget::hookControllerInput() if (!controller_interface) return; - m_host_interface->enableBackgroundControllerPolling(); controller_interface->SetHook([this](const ControllerInterface::Hook& ei) { if (ei.type == ControllerInterface::Hook::Type::Axis) { @@ -287,7 +284,6 @@ void InputAxisBindingWidget::unhookControllerInput() return; controller_interface->ClearHook(); - m_host_interface->disableBackgroundControllerPolling(); } void InputAxisBindingWidget::bindToControllerAxis(int controller_index, int axis_index) @@ -327,7 +323,6 @@ void InputRumbleBindingWidget::hookControllerInput() if (!controller_interface) return; - m_host_interface->enableBackgroundControllerPolling(); controller_interface->SetHook([this](const ControllerInterface::Hook& ei) { if (ei.type == ControllerInterface::Hook::Type::Button && ei.value > 0.0f) { @@ -346,7 +341,6 @@ void InputRumbleBindingWidget::unhookControllerInput() return; controller_interface->ClearHook(); - m_host_interface->disableBackgroundControllerPolling(); } void InputRumbleBindingWidget::bindToControllerRumble(int controller_index) diff --git a/src/duckstation-qt/qthostinterface.cpp b/src/duckstation-qt/qthostinterface.cpp index 1e5f5bf4d..c2d0e261f 100644 --- a/src/duckstation-qt/qthostinterface.cpp +++ b/src/duckstation-qt/qthostinterface.cpp @@ -65,12 +65,15 @@ bool QtHostInterface::initializeOnThread() m_controller_interface->PollEvents(); // bind buttons/axises + createBackgroundControllerPollTimer(); + startBackgroundControllerPollTimer(); updateInputMap(); return true; } void QtHostInterface::shutdownOnThread() { + destroyBackgroundControllerPollTimer(); CommonHostInterface::Shutdown(); } @@ -396,7 +399,7 @@ void QtHostInterface::OnSystemCreated() CommonHostInterface::OnSystemCreated(); wakeThread(); - destroyBackgroundControllerPollTimer(); + stopBackgroundControllerPollTimer(); emit emulationStarted(); } @@ -407,28 +410,23 @@ void QtHostInterface::OnSystemPaused(bool paused) emit emulationPaused(paused); - if (m_background_controller_polling_enable_count > 0) - { - if (paused) - createBackgroundControllerPollTimer(); - else - destroyBackgroundControllerPollTimer(); - } - if (!paused) { wakeThread(); + stopBackgroundControllerPollTimer(); emit focusDisplayWidgetRequested(); } + else + { + startBackgroundControllerPollTimer(); + } } void QtHostInterface::OnSystemDestroyed() { HostInterface::OnSystemDestroyed(); - if (m_background_controller_polling_enable_count > 0) - createBackgroundControllerPollTimer(); - + startBackgroundControllerPollTimer(); emit emulationStopped(); } @@ -762,42 +760,6 @@ void QtHostInterface::saveScreenshot() SaveScreenshot(nullptr, true, true); } -void QtHostInterface::enableBackgroundControllerPolling() -{ - if (!isOnWorkerThread()) - { - QMetaObject::invokeMethod(this, "enableBackgroundControllerPolling", Qt::BlockingQueuedConnection); - return; - } - - if (!m_controller_interface || m_background_controller_polling_enable_count++ > 0) - return; - - if (!m_system || m_paused) - { - createBackgroundControllerPollTimer(); - - // drain the event queue so we don't get events late - m_controller_interface->PollEvents(); - } -} - -void QtHostInterface::disableBackgroundControllerPolling() -{ - if (!isOnWorkerThread()) - { - QMetaObject::invokeMethod(this, "disableBackgroundControllerPolling"); - return; - } - - Assert(m_background_controller_polling_enable_count > 0); - if (!m_controller_interface || --m_background_controller_polling_enable_count > 0) - return; - - if (!m_system || m_paused) - destroyBackgroundControllerPollTimer(); -} - void QtHostInterface::doBackgroundControllerPoll() { m_controller_interface->PollEvents(); @@ -810,7 +772,6 @@ void QtHostInterface::createBackgroundControllerPollTimer() m_background_controller_polling_timer->setSingleShot(false); m_background_controller_polling_timer->setTimerType(Qt::VeryCoarseTimer); connect(m_background_controller_polling_timer, &QTimer::timeout, this, &QtHostInterface::doBackgroundControllerPoll); - m_background_controller_polling_timer->start(BACKGROUND_CONTROLLER_POLLING_INTERVAL); } void QtHostInterface::destroyBackgroundControllerPollTimer() @@ -819,6 +780,22 @@ void QtHostInterface::destroyBackgroundControllerPollTimer() m_background_controller_polling_timer = nullptr; } +void QtHostInterface::startBackgroundControllerPollTimer() +{ + if (m_background_controller_polling_timer->isActive() || !m_controller_interface) + return; + + m_background_controller_polling_timer->start(BACKGROUND_CONTROLLER_POLLING_INTERVAL); +} + +void QtHostInterface::stopBackgroundControllerPollTimer() +{ + if (!m_background_controller_polling_timer->isActive() || !m_controller_interface) + return; + + m_background_controller_polling_timer->stop(); +} + void QtHostInterface::createThread() { m_original_thread = QThread::currentThread(); diff --git a/src/duckstation-qt/qthostinterface.h b/src/duckstation-qt/qthostinterface.h index 6a8afb6b8..82c569b5a 100644 --- a/src/duckstation-qt/qthostinterface.h +++ b/src/duckstation-qt/qthostinterface.h @@ -126,13 +126,6 @@ public Q_SLOTS: void redrawDisplayWindow(); void toggleFullscreen(); - /// Enables controller polling even without a system active. Must be matched by a call to - /// disableBackgroundControllerPolling. - void enableBackgroundControllerPolling(); - - /// Disables background controller polling. - void disableBackgroundControllerPolling(); - private Q_SLOTS: void doStopThread(); void onHostDisplayWindowResized(int width, int height); @@ -190,6 +183,8 @@ private: void createBackgroundControllerPollTimer(); void destroyBackgroundControllerPollTimer(); + void startBackgroundControllerPollTimer(); + void stopBackgroundControllerPollTimer(); void createThread(); void stopThread(); @@ -213,7 +208,6 @@ private: std::atomic_bool m_shutdown_flag{false}; QTimer* m_background_controller_polling_timer = nullptr; - u32 m_background_controller_polling_enable_count = 0; bool m_is_rendering_to_main = false; bool m_is_fullscreen = false;