From d217e797f29b2d727bd7a45dcacd15603b739aa6 Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 1 Jul 2017 13:17:18 -0700 Subject: [PATCH 1/4] move Movie::DoFrameStep to Core::DoFrameStep --- Source/Core/Core/Core.cpp | 25 +++++++++++++++++++++++++ Source/Core/Core/Core.h | 2 ++ Source/Core/Core/Movie.cpp | 24 ------------------------ Source/Core/Core/Movie.h | 1 - Source/Core/DolphinQt2/MainWindow.cpp | 2 +- Source/Core/DolphinWX/FrameTools.cpp | 2 +- 6 files changed, 29 insertions(+), 27 deletions(-) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 422de26688..6cc3356c3f 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -103,6 +103,7 @@ static StoppedCallbackFunc s_on_stopped_callback; static std::thread s_cpu_thread; static bool s_request_refresh_info = false; static bool s_is_throttler_temp_disabled = false; +static bool s_frame_step = false; struct HostJob { @@ -473,6 +474,7 @@ static void EmuThread(std::unique_ptr boot) // For a time this acts as the CPU thread... DeclareAsCPUThread(); + s_frame_step = false; Movie::Init(*boot); Common::ScopeGuard movie_guard{Movie::Shutdown}; @@ -859,6 +861,12 @@ void Callback_VideoCopiedToXFB(bool video_update) s_drawn_frame++; Movie::FrameUpdate(); + + if (s_frame_step) + { + s_frame_step = false; + CPU::Break(); + } } void UpdateTitle() @@ -1024,4 +1032,21 @@ void HostDispatchJobs() } } +// NOTE: Host Thread +void DoFrameStep() +{ + if (GetState() == State::Paused) + { + // if already paused, frame advance for 1 frame + s_frame_step = true; + RequestRefreshInfo(); + SetState(State::Running); + } + else if (!s_frame_step) + { + // if not paused yet, pause immediately instead + SetState(State::Paused); + } +} + } // Core diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h index e604843a2c..7787023371 100644 --- a/Source/Core/Core/Core.h +++ b/Source/Core/Core/Core.h @@ -105,4 +105,6 @@ void QueueHostJob(std::function job, bool run_during_stop = false); // WM_USER_JOB_DISPATCH will be sent when something is added to the queue. void HostDispatchJobs(); +void DoFrameStep(); + } // namespace diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index b1d1e094a2..b9c6f9867d 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -63,7 +63,6 @@ namespace Movie { -static bool s_bFrameStep = false; static bool s_bReadOnly = true; static u32 s_rerecords = 0; static PlayMode s_playMode = MODE_NONE; @@ -192,11 +191,6 @@ void FrameUpdate() s_totalFrames = s_currentFrame; s_totalLagCount = s_currentLagCount; } - if (s_bFrameStep) - { - s_bFrameStep = false; - CPU::Break(); - } s_bPolled = false; } @@ -215,7 +209,6 @@ void Init(const BootParameters& boot) s_current_file_name.clear(); s_bPolled = false; - s_bFrameStep = false; s_bSaveConfig = false; if (IsPlayingInput()) { @@ -274,23 +267,6 @@ void SetPolledDevice() s_bPolled = true; } -// NOTE: Host Thread -void DoFrameStep() -{ - if (Core::GetState() == Core::State::Paused) - { - // if already paused, frame advance for 1 frame - s_bFrameStep = true; - Core::RequestRefreshInfo(); - Core::SetState(Core::State::Running); - } - else if (!s_bFrameStep) - { - // if not paused yet, pause immediately instead - Core::SetState(Core::State::Paused); - } -} - // NOTE: Host Thread void SetReadOnly(bool bEnabled) { diff --git a/Source/Core/Core/Movie.h b/Source/Core/Core/Movie.h index 08107f92c6..343790ccb3 100644 --- a/Source/Core/Core/Movie.h +++ b/Source/Core/Core/Movie.h @@ -148,7 +148,6 @@ bool IsUsingBongo(int controller); void ChangePads(bool instantly = false); void ChangeWiiPads(bool instantly = false); -void DoFrameStep(); void SetReadOnly(bool bEnabled); bool BeginRecordingInput(int controllers); diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index 0331104e01..f4dee4f7e0 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -450,7 +450,7 @@ void MainWindow::Reset() void MainWindow::FrameAdvance() { - Movie::DoFrameStep(); + Core::DoFrameStep(); EmulationPaused(); } diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index d505ce14d3..89726223dc 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -446,7 +446,7 @@ void CFrame::OnFrameStep(wxCommandEvent& event) { bool wasPaused = Core::GetState() == Core::State::Paused; - Movie::DoFrameStep(); + Core::DoFrameStep(); bool isPaused = Core::GetState() == Core::State::Paused; if (isPaused && !wasPaused) // don't update on unpause, otherwise the status would be wrong when From 22a9a08b2454b48ea017e8733e69caf63f3717dd Mon Sep 17 00:00:00 2001 From: Michael M Date: Sat, 1 Jul 2017 14:08:58 -0700 Subject: [PATCH 2/4] Add Core::State::Starting --- Source/Core/Core/Core.cpp | 3 +++ Source/Core/Core/Core.h | 3 ++- Source/Core/InputCommon/GCAdapter.cpp | 2 +- Source/Core/InputCommon/GCAdapter_Android.cpp | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 6cc3356c3f..d3d34e1ee4 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -700,6 +700,9 @@ State GetState() return State::Running; } + if (s_is_booting.IsSet()) + return State::Starting; + return State::Uninitialized; } diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h index 7787023371..a796f0addf 100644 --- a/Source/Core/Core/Core.h +++ b/Source/Core/Core/Core.h @@ -31,7 +31,8 @@ enum class State Uninitialized, Paused, Running, - Stopping + Stopping, + Starting, }; bool Init(std::unique_ptr boot); diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index 685329a693..7a897affdc 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -179,7 +179,7 @@ void Init() if (s_handle != nullptr) return; - if (Core::GetState() != Core::State::Uninitialized) + if (Core::GetState() != Core::State::Uninitialized && Core::GetState() != Core::State::Starting) { if ((CoreTiming::GetTicks() - s_last_init) < SystemTimers::GetTicksPerSecond()) return; diff --git a/Source/Core/InputCommon/GCAdapter_Android.cpp b/Source/Core/InputCommon/GCAdapter_Android.cpp index 7b0c6e1545..d8628530a3 100644 --- a/Source/Core/InputCommon/GCAdapter_Android.cpp +++ b/Source/Core/InputCommon/GCAdapter_Android.cpp @@ -195,7 +195,7 @@ void Init() if (s_fd) return; - if (Core::GetState() != Core::State::Uninitialized) + if (Core::GetState() != Core::State::Uninitialized && Core::GetState() != Core::State::Starting) { if ((CoreTiming::GetTicks() - s_last_init) < SystemTimers::GetTicksPerSecond()) return; From 8e805dcbf43505aaf5b9af06f6f23159f3c083e4 Mon Sep 17 00:00:00 2001 From: Michael M Date: Mon, 4 Sep 2017 10:57:42 -0700 Subject: [PATCH 3/4] Core: SetOnStoppedCallback -> SetOnStateChangedCallback --- Source/Core/Core/Core.cpp | 17 ++++++++++++----- Source/Core/Core/Core.h | 4 ++-- Source/Core/DolphinNoGUI/MainNoGUI.cpp | 5 ++++- Source/Core/DolphinQt2/MainWindow.cpp | 5 ++++- Source/Core/DolphinWX/Frame.cpp | 5 +++-- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index d3d34e1ee4..d70d9ff712 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -98,7 +98,7 @@ static Common::Flag s_is_booting; static void* s_window_handle = nullptr; static std::string s_state_filename; static std::thread s_emu_thread; -static StoppedCallbackFunc s_on_stopped_callback; +static StateChangedCallbackFunc s_on_state_changed_callback; static std::thread s_cpu_thread; static bool s_request_refresh_info = false; @@ -455,14 +455,16 @@ static void EmuThread(std::unique_ptr boot) { const SConfig& core_parameter = SConfig::GetInstance(); s_is_booting.Set(); + if (s_on_state_changed_callback) + s_on_state_changed_callback(State::Starting); Common::ScopeGuard flag_guard{[] { s_is_booting.Clear(); s_is_started = false; s_is_stopping = false; s_wants_determinism = false; - if (s_on_stopped_callback) - s_on_stopped_callback(); + if (s_on_state_changed_callback) + s_on_state_changed_callback(State::Uninitialized); INFO_LOG(CONSOLE, "Stop\t\t---- Shutdown complete ----"); }}; @@ -685,6 +687,9 @@ void SetState(State state) PanicAlert("Invalid state"); break; } + + if (s_on_state_changed_callback) + s_on_state_changed_callback(GetState()); } State GetState() @@ -869,6 +874,8 @@ void Callback_VideoCopiedToXFB(bool video_update) { s_frame_step = false; CPU::Break(); + if (s_on_state_changed_callback) + s_on_state_changed_callback(Core::GetState()); } } @@ -962,9 +969,9 @@ void Shutdown() HostDispatchJobs(); } -void SetOnStoppedCallback(StoppedCallbackFunc callback) +void SetOnStateChangedCallback(StateChangedCallbackFunc callback) { - s_on_stopped_callback = std::move(callback); + s_on_state_changed_callback = std::move(callback); } void UpdateWantDeterminism(bool initial) diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h index a796f0addf..4ed2570081 100644 --- a/Source/Core/Core/Core.h +++ b/Source/Core/Core/Core.h @@ -85,8 +85,8 @@ void UpdateTitle(); void RunAsCPUThread(std::function function); // for calling back into UI code without introducing a dependency on it in core -using StoppedCallbackFunc = std::function; -void SetOnStoppedCallback(StoppedCallbackFunc callback); +using StateChangedCallbackFunc = std::function; +void SetOnStateChangedCallback(StateChangedCallbackFunc callback); // Run on the Host thread when the factors change. [NOT THREADSAFE] void UpdateWantDeterminism(bool initial = false); diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp index 37860057aa..ecd2d3ba88 100644 --- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp +++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp @@ -392,7 +392,10 @@ int main(int argc, char* argv[]) UICommon::SetUserDirectory(user_directory); UICommon::Init(); - Core::SetOnStoppedCallback([]() { s_running.Clear(); }); + Core::SetOnStateChangedCallback([](Core::State state) { + if (state == Core::State::Uninitialized) + s_running.Clear(); + }); platform->Init(); // Shut down cleanly on SIGINT and SIGTERM diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index f4dee4f7e0..5f52b407bb 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -121,7 +121,10 @@ void MainWindow::ShutdownControllers() void MainWindow::InitCoreCallbacks() { - Core::SetOnStoppedCallback([this] { emit EmulationStopped(); }); + Core::SetOnStateChangedCallback([=](Core::State state) { + if (state == Core::State::Uninitialized) + emit EmulationStopped(); + }); installEventFilter(this); m_render_widget->installEventFilter(this); } diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp index 7800907a37..7bc9daab15 100644 --- a/Source/Core/DolphinWX/Frame.cpp +++ b/Source/Core/DolphinWX/Frame.cpp @@ -530,8 +530,9 @@ void CFrame::InitializeCoreCallbacks() }); // Warning: this gets called from the EmuThread - Core::SetOnStoppedCallback([this] { - AddPendingEvent(wxCommandEvent{wxEVT_HOST_COMMAND, IDM_STOPPED}); + Core::SetOnStateChangedCallback([this](Core::State state) { + if (state == Core::State::Uninitialized) + AddPendingEvent(wxCommandEvent{wxEVT_HOST_COMMAND, IDM_STOPPED}); }); } From 3e1072b24dd8f60fd13b9aca3527066d478f9774 Mon Sep 17 00:00:00 2001 From: Michael M Date: Mon, 4 Sep 2017 11:12:13 -0700 Subject: [PATCH 4/4] Qt: use Settings::EmulationStateChanged --- .../DolphinQt2/Config/ControllersWindow.cpp | 4 ++ .../DolphinQt2/Config/ControllersWindow.h | 2 +- .../Config/Graphics/AdvancedWidget.cpp | 6 +- .../Config/Graphics/GeneralWidget.cpp | 6 +- .../Config/Graphics/GraphicsWindow.cpp | 3 - .../Config/Graphics/GraphicsWindow.h | 2 - .../Core/DolphinQt2/Config/SettingsWindow.cpp | 8 +-- .../Core/DolphinQt2/Config/SettingsWindow.h | 4 -- Source/Core/DolphinQt2/GameList/GameList.cpp | 22 +++--- Source/Core/DolphinQt2/GameList/GameList.h | 2 - Source/Core/DolphinQt2/MainWindow.cpp | 30 +------- Source/Core/DolphinQt2/MainWindow.h | 3 - Source/Core/DolphinQt2/MenuBar.cpp | 70 +++++++------------ Source/Core/DolphinQt2/MenuBar.h | 14 ++-- .../Core/DolphinQt2/NetPlay/NetPlayDialog.cpp | 4 +- .../Core/DolphinQt2/NetPlay/NetPlayDialog.h | 1 - Source/Core/DolphinQt2/Settings.cpp | 7 +- Source/Core/DolphinQt2/Settings.h | 6 ++ Source/Core/DolphinQt2/Settings/AudioPane.cpp | 3 + Source/Core/DolphinQt2/Settings/AudioPane.h | 3 +- Source/Core/DolphinQt2/ToolBar.cpp | 45 ++++-------- Source/Core/DolphinQt2/ToolBar.h | 12 ++-- 22 files changed, 97 insertions(+), 160 deletions(-) diff --git a/Source/Core/DolphinQt2/Config/ControllersWindow.cpp b/Source/Core/DolphinQt2/Config/ControllersWindow.cpp index 59e422ba6c..ed8e08a91f 100644 --- a/Source/Core/DolphinQt2/Config/ControllersWindow.cpp +++ b/Source/Core/DolphinQt2/Config/ControllersWindow.cpp @@ -21,6 +21,7 @@ #include #include "Core/ConfigManager.h" +#include "Core/Core.h" #include "Core/HW/SI/SI.h" #include "Core/HW/Wiimote.h" #include "Core/HW/WiimoteReal/WiimoteReal.h" @@ -238,6 +239,9 @@ void ControllersWindow::CreateMainLayout() void ControllersWindow::ConnectWidgets() { + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, + [=](Core::State state) { OnEmulationStateChanged(state != Core::State::Uninitialized); }); + connect(m_wiimote_passthrough, &QRadioButton::toggled, this, &ControllersWindow::OnWiimoteModeChanged); diff --git a/Source/Core/DolphinQt2/Config/ControllersWindow.h b/Source/Core/DolphinQt2/Config/ControllersWindow.h index e8359596a9..171e44ca3c 100644 --- a/Source/Core/DolphinQt2/Config/ControllersWindow.h +++ b/Source/Core/DolphinQt2/Config/ControllersWindow.h @@ -25,9 +25,9 @@ class ControllersWindow final : public QDialog Q_OBJECT public: explicit ControllersWindow(QWidget* parent); - void OnEmulationStateChanged(bool running); private: + void OnEmulationStateChanged(bool running); void OnWiimoteModeChanged(bool passthrough); void OnWiimoteTypeChanged(int state); void OnGCTypeChanged(int state); diff --git a/Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.cpp index 0033bbc085..6be05f7398 100644 --- a/Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.cpp +++ b/Source/Core/DolphinQt2/Config/Graphics/AdvancedWidget.cpp @@ -11,9 +11,11 @@ #include "Core/Config/GraphicsSettings.h" #include "Core/ConfigManager.h" +#include "Core/Core.h" #include "DolphinQt2/Config/Graphics/GraphicsBool.h" #include "DolphinQt2/Config/Graphics/GraphicsChoice.h" #include "DolphinQt2/Config/Graphics/GraphicsWindow.h" +#include "DolphinQt2/Settings.h" #include "VideoCommon/VideoConfig.h" AdvancedWidget::AdvancedWidget(GraphicsWindow* parent) : GraphicsWidget(parent) @@ -24,8 +26,8 @@ AdvancedWidget::AdvancedWidget(GraphicsWindow* parent) : GraphicsWidget(parent) AddDescriptions(); connect(parent, &GraphicsWindow::BackendChanged, this, &AdvancedWidget::OnBackendChanged); - connect(parent, &GraphicsWindow::EmulationStarted, [this] { OnEmulationStateChanged(true); }); - connect(parent, &GraphicsWindow::EmulationStopped, [this] { OnEmulationStateChanged(false); }); + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, + [=](Core::State state) { OnEmulationStateChanged(state != Core::State::Uninitialized); }); OnBackendChanged(); } diff --git a/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp index 3a6f81c2b2..f746b711bb 100644 --- a/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp +++ b/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp @@ -15,9 +15,11 @@ #include "Core/Config/GraphicsSettings.h" #include "Core/ConfigManager.h" +#include "Core/Core.h" #include "DolphinQt2/Config/Graphics/GraphicsBool.h" #include "DolphinQt2/Config/Graphics/GraphicsChoice.h" #include "DolphinQt2/Config/Graphics/GraphicsWindow.h" +#include "DolphinQt2/Settings.h" #include "UICommon/VideoUtils.h" #include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoConfig.h" @@ -32,8 +34,8 @@ GeneralWidget::GeneralWidget(X11Utils::XRRConfiguration* xrr_config, GraphicsWin emit BackendChanged(QString::fromStdString(SConfig::GetInstance().m_strVideoBackend)); connect(parent, &GraphicsWindow::BackendChanged, this, &GeneralWidget::OnBackendChanged); - connect(parent, &GraphicsWindow::EmulationStarted, [this] { OnEmulationStateChanged(true); }); - connect(parent, &GraphicsWindow::EmulationStopped, [this] { OnEmulationStateChanged(false); }); + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, + [=](Core::State state) { OnEmulationStateChanged(state != Core::State::Uninitialized); }); } void GeneralWidget::CreateWidgets() diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp index 7aca3d3087..55f0e03922 100644 --- a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.cpp @@ -29,9 +29,6 @@ GraphicsWindow::GraphicsWindow(X11Utils::XRRConfiguration* xrr_config, MainWindo setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); OnBackendChanged(QString::fromStdString(SConfig::GetInstance().m_strVideoBackend)); - - connect(parent, &MainWindow::EmulationStarted, this, &GraphicsWindow::EmulationStarted); - connect(parent, &MainWindow::EmulationStopped, this, &GraphicsWindow::EmulationStopped); } void GraphicsWindow::CreateMainLayout() diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h index c78d8663fd..2874a4c2f0 100644 --- a/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h +++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsWindow.h @@ -33,8 +33,6 @@ public: bool eventFilter(QObject* object, QEvent* event) override; signals: void BackendChanged(const QString& backend); - void EmulationStarted(); - void EmulationStopped(); private: void CreateMainLayout(); diff --git a/Source/Core/DolphinQt2/Config/SettingsWindow.cpp b/Source/Core/DolphinQt2/Config/SettingsWindow.cpp index 4099af0cd4..0ac1fe5cc6 100644 --- a/Source/Core/DolphinQt2/Config/SettingsWindow.cpp +++ b/Source/Core/DolphinQt2/Config/SettingsWindow.cpp @@ -40,15 +40,9 @@ SettingsWindow::SettingsWindow(QWidget* parent) : QDialog(parent) AddTab(m_tabs, tr("General"), new GeneralPane(), "config"); AddTab(m_tabs, tr("Interface"), new InterfacePane(), "browse"); - auto* audio_pane = new AudioPane; - m_audio_pane_index = AddTab(m_tabs, tr("Audio"), audio_pane, "play"); + m_audio_pane_index = AddTab(m_tabs, tr("Audio"), new AudioPane(), "play"); AddTab(m_tabs, tr("Paths"), new PathPane(), "browse"); - connect(this, &SettingsWindow::EmulationStarted, - [audio_pane] { audio_pane->OnEmulationStateChanged(true); }); - connect(this, &SettingsWindow::EmulationStopped, - [audio_pane] { audio_pane->OnEmulationStateChanged(false); }); - // Dialog box buttons QDialogButtonBox* ok_box = new QDialogButtonBox(QDialogButtonBox::Ok); connect(ok_box, &QDialogButtonBox::accepted, this, &SettingsWindow::accept); diff --git a/Source/Core/DolphinQt2/Config/SettingsWindow.h b/Source/Core/DolphinQt2/Config/SettingsWindow.h index 5733cb03da..f61b41bfe6 100644 --- a/Source/Core/DolphinQt2/Config/SettingsWindow.h +++ b/Source/Core/DolphinQt2/Config/SettingsWindow.h @@ -15,10 +15,6 @@ public: explicit SettingsWindow(QWidget* parent = nullptr); void SelectAudioPane(); -signals: - void EmulationStarted(); - void EmulationStopped(); - private: ListTabWidget* m_tabs; int m_audio_pane_index = -1; diff --git a/Source/Core/DolphinQt2/GameList/GameList.cpp b/Source/Core/DolphinQt2/GameList/GameList.cpp index 4f1d4fdb94..df4e9d161c 100644 --- a/Source/Core/DolphinQt2/GameList/GameList.cpp +++ b/Source/Core/DolphinQt2/GameList/GameList.cpp @@ -174,11 +174,8 @@ void GameList::ShowContextMenu(const QPoint&) QAction* change_disc = AddAction(menu, tr("Change &Disc"), this, &GameList::ChangeDisc); - connect(this, &GameList::EmulationStarted, change_disc, - [change_disc] { change_disc->setEnabled(true); }); - connect(this, &GameList::EmulationStopped, change_disc, - [change_disc] { change_disc->setEnabled(false); }); - + connect(&Settings::Instance(), &Settings::EmulationStateChanged, change_disc, + [change_disc] { change_disc->setEnabled(Core::IsRunning()); }); change_disc->setEnabled(Core::IsRunning()); menu->addSeparator(); @@ -202,15 +199,13 @@ void GameList::ShowContextMenu(const QPoint&) for (QAction* a : {wad_install_action, wad_uninstall_action}) { - connect(this, &GameList::EmulationStarted, a, [a] { a->setEnabled(false); }); a->setEnabled(!Core::IsRunning()); menu->addAction(a); } - connect(this, &GameList::EmulationStopped, wad_install_action, - [wad_install_action] { wad_install_action->setEnabled(true); }); - connect(this, &GameList::EmulationStopped, wad_uninstall_action, [wad_uninstall_action, game] { - wad_uninstall_action->setEnabled(game->IsInstalled()); + connect(&Settings::Instance(), &Settings::EmulationStateChanged, menu, [=](Core::State state) { + wad_install_action->setEnabled(state == Core::State::Uninitialized); + wad_uninstall_action->setEnabled(state == Core::State::Uninitialized && game->IsInstalled()); }); menu->addSeparator(); @@ -231,10 +226,9 @@ void GameList::ShowContextMenu(const QPoint&) connect(netplay_host, &QAction::triggered, [this, game] { emit NetPlayHost(game->GetUniqueID()); }); - connect(this, &GameList::EmulationStarted, netplay_host, - [netplay_host] { netplay_host->setEnabled(false); }); - connect(this, &GameList::EmulationStopped, netplay_host, - [netplay_host] { netplay_host->setEnabled(true); }); + connect(&Settings::Instance(), &Settings::EmulationStateChanged, menu, [=](Core::State state) { + netplay_host->setEnabled(state == Core::State::Uninitialized); + }); netplay_host->setEnabled(!Core::IsRunning()); menu->addAction(netplay_host); diff --git a/Source/Core/DolphinQt2/GameList/GameList.h b/Source/Core/DolphinQt2/GameList/GameList.h index 3121ef9c98..75103a42fd 100644 --- a/Source/Core/DolphinQt2/GameList/GameList.h +++ b/Source/Core/DolphinQt2/GameList/GameList.h @@ -29,8 +29,6 @@ public: signals: void GameSelected(); - void EmulationStarted(); - void EmulationStopped(); void NetPlayHost(const QString& game_id); void SelectionChanged(QSharedPointer game_file); diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index 5f52b407bb..4a6aab2f08 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -121,9 +121,9 @@ void MainWindow::ShutdownControllers() void MainWindow::InitCoreCallbacks() { - Core::SetOnStateChangedCallback([=](Core::State state) { + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [=](Core::State state) { if (state == Core::State::Uninitialized) - emit EmulationStopped(); + OnStopComplete(); }); installEventFilter(this); m_render_widget->installEventFilter(this); @@ -152,11 +152,6 @@ void MainWindow::CreateComponents() m_hotkey_window = new MappingWindow(this, 0); m_logger_widget = new LoggerWidget(this); - connect(this, &MainWindow::EmulationStarted, m_settings_window, - &SettingsWindow::EmulationStarted); - connect(this, &MainWindow::EmulationStopped, m_settings_window, - &SettingsWindow::EmulationStopped); - #if defined(HAVE_XRANDR) && HAVE_XRANDR m_graphics_window = new GraphicsWindow( new X11Utils::XRRConfiguration( @@ -233,17 +228,9 @@ void MainWindow::ConnectMenuBar() connect(m_menu_bar, &MenuBar::ShowAboutDialog, this, &MainWindow::ShowAboutDialog); - connect(this, &MainWindow::EmulationStarted, m_menu_bar, &MenuBar::EmulationStarted); - connect(this, &MainWindow::EmulationPaused, m_menu_bar, &MenuBar::EmulationPaused); - connect(this, &MainWindow::EmulationStopped, m_menu_bar, &MenuBar::EmulationStopped); connect(m_game_list, &GameList::SelectionChanged, m_menu_bar, &MenuBar::SelectionChanged); connect(this, &MainWindow::ReadOnlyModeChanged, m_menu_bar, &MenuBar::ReadOnlyModeChanged); connect(this, &MainWindow::RecordingStatusChanged, m_menu_bar, &MenuBar::RecordingStatusChanged); - - connect(this, &MainWindow::EmulationStarted, this, - [=]() { m_controllers_window->OnEmulationStateChanged(true); }); - connect(this, &MainWindow::EmulationStopped, this, - [=]() { m_controllers_window->OnEmulationStateChanged(false); }); } void MainWindow::ConnectHotkeys() @@ -284,20 +271,12 @@ void MainWindow::ConnectToolBar() connect(m_tool_bar, &ToolBar::SettingsPressed, this, &MainWindow::ShowSettingsWindow); connect(m_tool_bar, &ToolBar::ControllersPressed, this, &MainWindow::ShowControllersWindow); connect(m_tool_bar, &ToolBar::GraphicsPressed, this, &MainWindow::ShowGraphicsWindow); - - connect(this, &MainWindow::EmulationStarted, m_tool_bar, &ToolBar::EmulationStarted); - connect(this, &MainWindow::EmulationPaused, m_tool_bar, &ToolBar::EmulationPaused); - connect(this, &MainWindow::EmulationStopped, m_tool_bar, &ToolBar::EmulationStopped); - - connect(this, &MainWindow::EmulationStopped, this, &MainWindow::OnStopComplete); } void MainWindow::ConnectGameList() { connect(m_game_list, &GameList::GameSelected, this, &MainWindow::Play); connect(m_game_list, &GameList::NetPlayHost, this, &MainWindow::NetPlayHost); - connect(this, &MainWindow::EmulationStarted, m_game_list, &GameList::EmulationStarted); - connect(this, &MainWindow::EmulationStopped, m_game_list, &GameList::EmulationStopped); } void MainWindow::ConnectRenderWidget() @@ -336,7 +315,6 @@ void MainWindow::Play() if (Core::GetState() == Core::State::Paused) { Core::SetState(Core::State::Running); - emit EmulationStarted(); } else { @@ -363,7 +341,6 @@ void MainWindow::Play() void MainWindow::Pause() { Core::SetState(Core::State::Paused); - emit EmulationPaused(); } void MainWindow::OnStopComplete() @@ -454,7 +431,6 @@ void MainWindow::Reset() void MainWindow::FrameAdvance() { Core::DoFrameStep(); - EmulationPaused(); } void MainWindow::FullScreen() @@ -499,7 +475,6 @@ void MainWindow::StartGame(std::unique_ptr&& parameters) return; } ShowRenderWidget(); - emit EmulationStarted(); #ifdef Q_OS_WIN // Prevents Windows from sleeping, turning off the display, or idling @@ -676,7 +651,6 @@ void MainWindow::NetPlayInit() static_cast(&MainWindow::StartGame)); connect(m_netplay_dialog, &NetPlayDialog::Stop, this, &MainWindow::RequestStop); connect(m_netplay_dialog, &NetPlayDialog::rejected, this, &MainWindow::NetPlayQuit); - connect(this, &MainWindow::EmulationStopped, m_netplay_dialog, &NetPlayDialog::EmulationStopped); connect(m_netplay_setup_dialog, &NetPlaySetupDialog::Join, this, &MainWindow::NetPlayJoin); connect(m_netplay_setup_dialog, &NetPlaySetupDialog::Host, this, &MainWindow::NetPlayHost); } diff --git a/Source/Core/DolphinQt2/MainWindow.h b/Source/Core/DolphinQt2/MainWindow.h index 154bd7b75a..bb51904195 100644 --- a/Source/Core/DolphinQt2/MainWindow.h +++ b/Source/Core/DolphinQt2/MainWindow.h @@ -40,9 +40,6 @@ public: bool eventFilter(QObject* object, QEvent* event) override; signals: - void EmulationStarted(); - void EmulationPaused(); - void EmulationStopped(); void ReadOnlyModeChanged(bool read_only); void RecordingStatusChanged(bool recording); diff --git a/Source/Core/DolphinQt2/MenuBar.cpp b/Source/Core/DolphinQt2/MenuBar.cpp index 8e8d45e182..6fb6cc79a5 100644 --- a/Source/Core/DolphinQt2/MenuBar.cpp +++ b/Source/Core/DolphinQt2/MenuBar.cpp @@ -38,64 +38,42 @@ MenuBar::MenuBar(QWidget* parent) : QMenuBar(parent) AddViewMenu(); AddHelpMenu(); - EmulationStopped(); + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, + [=](Core::State state) { OnEmulationStateChanged(state); }); + OnEmulationStateChanged(Core::GetState()); connect(this, &MenuBar::SelectionChanged, this, &MenuBar::OnSelectionChanged); connect(this, &MenuBar::RecordingStatusChanged, this, &MenuBar::OnRecordingStatusChanged); connect(this, &MenuBar::ReadOnlyModeChanged, this, &MenuBar::OnReadOnlyModeChanged); } -void MenuBar::EmulationStarted() +void MenuBar::OnEmulationStateChanged(Core::State state) { + bool running = state != Core::State::Uninitialized; + bool playing = running && state != Core::State::Paused; + // Emulation - m_play_action->setEnabled(false); - m_play_action->setVisible(false); - m_pause_action->setEnabled(true); - m_pause_action->setVisible(true); - m_stop_action->setEnabled(true); - m_reset_action->setEnabled(true); - m_fullscreen_action->setEnabled(true); - m_frame_advance_action->setEnabled(true); - m_screenshot_action->setEnabled(true); - m_state_load_menu->setEnabled(true); - m_state_save_menu->setEnabled(true); + m_play_action->setEnabled(!playing); + m_play_action->setVisible(!playing); + m_pause_action->setEnabled(playing); + m_pause_action->setVisible(playing); + m_stop_action->setEnabled(running); + m_stop_action->setVisible(running); + m_reset_action->setEnabled(running); + m_fullscreen_action->setEnabled(running); + m_frame_advance_action->setEnabled(running); + m_screenshot_action->setEnabled(running); + m_state_load_menu->setEnabled(running); + m_state_save_menu->setEnabled(running); // Movie - m_recording_read_only->setEnabled(true); - m_recording_play->setEnabled(false); + m_recording_read_only->setEnabled(running); + if (!running) + m_recording_stop->setEnabled(false); + m_recording_play->setEnabled(!running); UpdateStateSlotMenu(); - UpdateToolsMenu(true); -} -void MenuBar::EmulationPaused() -{ - m_play_action->setEnabled(true); - m_play_action->setVisible(true); - m_pause_action->setEnabled(false); - m_pause_action->setVisible(false); -} -void MenuBar::EmulationStopped() -{ - // Emulation - m_play_action->setEnabled(true); - m_play_action->setVisible(true); - m_pause_action->setEnabled(false); - m_pause_action->setVisible(false); - m_stop_action->setEnabled(false); - m_reset_action->setEnabled(false); - m_fullscreen_action->setEnabled(false); - m_frame_advance_action->setEnabled(false); - m_screenshot_action->setEnabled(false); - m_state_load_menu->setEnabled(false); - m_state_save_menu->setEnabled(false); - - // Movie - m_recording_read_only->setEnabled(false); - m_recording_stop->setEnabled(false); - m_recording_play->setEnabled(false); - - UpdateStateSlotMenu(); - UpdateToolsMenu(false); + UpdateToolsMenu(running); } void MenuBar::AddFileMenu() diff --git a/Source/Core/DolphinQt2/MenuBar.h b/Source/Core/DolphinQt2/MenuBar.h index 760a84f917..c4a8c6a41c 100644 --- a/Source/Core/DolphinQt2/MenuBar.h +++ b/Source/Core/DolphinQt2/MenuBar.h @@ -9,13 +9,18 @@ #include #include +#include "DolphinQt2/GameList/GameFile.h" + +namespace Core +{ +enum class State; +} + namespace DiscIO { enum class Region; }; -#include "DolphinQt2/GameList/GameFile.h" - class MenuBar final : public QMenuBar { Q_OBJECT @@ -23,9 +28,6 @@ class MenuBar final : public QMenuBar public: explicit MenuBar(QWidget* parent = nullptr); - void EmulationStarted(); - void EmulationPaused(); - void EmulationStopped(); void UpdateStateSlotMenu(); void UpdateToolsMenu(bool emulation_started); @@ -88,6 +90,8 @@ signals: void ReadOnlyModeChanged(bool read_only); private: + void OnEmulationStateChanged(Core::State state); + void AddFileMenu(); void AddEmulationMenu(); diff --git a/Source/Core/DolphinQt2/NetPlay/NetPlayDialog.cpp b/Source/Core/DolphinQt2/NetPlay/NetPlayDialog.cpp index 7057d5ced2..fed75b2eb1 100644 --- a/Source/Core/DolphinQt2/NetPlay/NetPlayDialog.cpp +++ b/Source/Core/DolphinQt2/NetPlay/NetPlayDialog.cpp @@ -188,8 +188,8 @@ void NetPlayDialog::ConnectWidgets() } }); - connect(this, &NetPlayDialog::EmulationStopped, this, [this] { - if (isVisible()) + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [=](Core::State state) { + if (state == Core::State::Uninitialized && isVisible()) GameStatusChanged(false); }); } diff --git a/Source/Core/DolphinQt2/NetPlay/NetPlayDialog.h b/Source/Core/DolphinQt2/NetPlay/NetPlayDialog.h index bf10962692..593d65a3c5 100644 --- a/Source/Core/DolphinQt2/NetPlay/NetPlayDialog.h +++ b/Source/Core/DolphinQt2/NetPlay/NetPlayDialog.h @@ -54,7 +54,6 @@ public: void SetMD5Result(int pid, const std::string& result) override; void AbortMD5() override; signals: - void EmulationStopped(); void Boot(const QString& filename); void Stop(); diff --git a/Source/Core/DolphinQt2/Settings.cpp b/Source/Core/DolphinQt2/Settings.cpp index 505614eae3..fbc283c267 100644 --- a/Source/Core/DolphinQt2/Settings.cpp +++ b/Source/Core/DolphinQt2/Settings.cpp @@ -11,11 +11,16 @@ #include "Common/FileUtil.h" #include "Common/StringUtil.h" #include "Core/ConfigManager.h" +#include "Core/Core.h" #include "DolphinQt2/GameList/GameListModel.h" #include "DolphinQt2/Settings.h" #include "InputCommon/InputConfig.h" -Settings::Settings() = default; +Settings::Settings() +{ + Core::SetOnStateChangedCallback( + [this](Core::State new_state) { emit EmulationStateChanged(new_state); }); +} Settings& Settings::Instance() { diff --git a/Source/Core/DolphinQt2/Settings.h b/Source/Core/DolphinQt2/Settings.h index 54bf446153..4de0b88be6 100644 --- a/Source/Core/DolphinQt2/Settings.h +++ b/Source/Core/DolphinQt2/Settings.h @@ -12,6 +12,11 @@ #include "Core/NetPlayClient.h" #include "Core/NetPlayServer.h" +namespace Core +{ +enum class State; +} + namespace DiscIO { enum class Language; @@ -76,6 +81,7 @@ public: GameListModel* GetGameListModel() const; signals: + void EmulationStateChanged(Core::State new_state); void ThemeChanged(); void PathAdded(const QString&); void PathRemoved(const QString&); diff --git a/Source/Core/DolphinQt2/Settings/AudioPane.cpp b/Source/Core/DolphinQt2/Settings/AudioPane.cpp index ad7c9aa6ed..91bbccd558 100644 --- a/Source/Core/DolphinQt2/Settings/AudioPane.cpp +++ b/Source/Core/DolphinQt2/Settings/AudioPane.cpp @@ -18,6 +18,7 @@ #include "AudioCommon/AudioCommon.h" #include "Core/ConfigManager.h" +#include "Core/Core.h" #include "DolphinQt2/Config/SettingsWindow.h" #include "DolphinQt2/Settings.h" @@ -28,6 +29,8 @@ AudioPane::AudioPane() ConnectWidgets(); connect(&Settings::Instance(), &Settings::VolumeChanged, this, &AudioPane::OnVolumeChanged); + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, + [=](Core::State state) { OnEmulationStateChanged(state != Core::State::Uninitialized); }); } void AudioPane::CreateWidgets() diff --git a/Source/Core/DolphinQt2/Settings/AudioPane.h b/Source/Core/DolphinQt2/Settings/AudioPane.h index 68ca4c682d..84d203120c 100644 --- a/Source/Core/DolphinQt2/Settings/AudioPane.h +++ b/Source/Core/DolphinQt2/Settings/AudioPane.h @@ -21,8 +21,6 @@ class AudioPane final : public QWidget public: explicit AudioPane(); - void OnEmulationStateChanged(bool running); - private: void CreateWidgets(); void ConnectWidgets(); @@ -30,6 +28,7 @@ private: void LoadSettings(); void SaveSettings(); + void OnEmulationStateChanged(bool running); void OnBackendChanged(); void OnVolumeChanged(int volume); diff --git a/Source/Core/DolphinQt2/ToolBar.cpp b/Source/Core/DolphinQt2/ToolBar.cpp index 0ea284a272..b8e6e6760d 100644 --- a/Source/Core/DolphinQt2/ToolBar.cpp +++ b/Source/Core/DolphinQt2/ToolBar.cpp @@ -4,6 +4,7 @@ #include +#include "Core/Core.h" #include "DolphinQt2/QtUtils/ActionHelper.h" #include "DolphinQt2/Resources.h" #include "DolphinQt2/Settings.h" @@ -22,40 +23,24 @@ ToolBar::ToolBar(QWidget* parent) : QToolBar(parent) connect(&Settings::Instance(), &Settings::ThemeChanged, this, &ToolBar::UpdateIcons); UpdateIcons(); - EmulationStopped(); + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, + [this](Core::State state) { OnEmulationStateChanged(state); }); + OnEmulationStateChanged(Core::GetState()); } -void ToolBar::EmulationStarted() +void ToolBar::OnEmulationStateChanged(Core::State state) { - m_play_action->setEnabled(false); - m_play_action->setVisible(false); - m_pause_action->setEnabled(true); - m_pause_action->setVisible(true); - m_stop_action->setEnabled(true); - m_stop_action->setVisible(true); - m_fullscreen_action->setEnabled(true); - m_screenshot_action->setEnabled(true); -} + bool running = state != Core::State::Uninitialized; + m_stop_action->setEnabled(running); + m_stop_action->setVisible(running); + m_fullscreen_action->setEnabled(running); + m_screenshot_action->setEnabled(running); -void ToolBar::EmulationPaused() -{ - m_play_action->setEnabled(true); - m_play_action->setVisible(true); - m_pause_action->setEnabled(false); - m_pause_action->setVisible(false); - m_stop_action->setEnabled(true); - m_stop_action->setVisible(true); -} - -void ToolBar::EmulationStopped() -{ - m_play_action->setEnabled(true); - m_play_action->setVisible(true); - m_pause_action->setEnabled(false); - m_pause_action->setVisible(false); - m_stop_action->setEnabled(false); - m_fullscreen_action->setEnabled(false); - m_screenshot_action->setEnabled(false); + bool playing = running && state != Core::State::Paused; + m_play_action->setEnabled(!playing); + m_play_action->setVisible(!playing); + m_pause_action->setEnabled(playing); + m_pause_action->setVisible(playing); } void ToolBar::MakeActions() diff --git a/Source/Core/DolphinQt2/ToolBar.h b/Source/Core/DolphinQt2/ToolBar.h index 179c0f5729..709fdee4d3 100644 --- a/Source/Core/DolphinQt2/ToolBar.h +++ b/Source/Core/DolphinQt2/ToolBar.h @@ -8,6 +8,11 @@ #include #include +namespace Core +{ +enum class State; +} + class ToolBar final : public QToolBar { Q_OBJECT @@ -15,11 +20,6 @@ class ToolBar final : public QToolBar public: explicit ToolBar(QWidget* parent = nullptr); -public slots: - void EmulationStarted(); - void EmulationPaused(); - void EmulationStopped(); - signals: void OpenPressed(); void PlayPressed(); @@ -33,6 +33,8 @@ signals: void GraphicsPressed(); private: + void OnEmulationStateChanged(Core::State state); + void MakeActions(); void UpdateIcons();