diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 422de26688..d70d9ff712 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -98,11 +98,12 @@ 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; static bool s_is_throttler_temp_disabled = false; +static bool s_frame_step = false; struct HostJob { @@ -454,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 ----"); }}; @@ -473,6 +476,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}; @@ -683,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() @@ -698,6 +705,9 @@ State GetState() return State::Running; } + if (s_is_booting.IsSet()) + return State::Starting; + return State::Uninitialized; } @@ -859,6 +869,14 @@ void Callback_VideoCopiedToXFB(bool video_update) s_drawn_frame++; Movie::FrameUpdate(); + + if (s_frame_step) + { + s_frame_step = false; + CPU::Break(); + if (s_on_state_changed_callback) + s_on_state_changed_callback(Core::GetState()); + } } void UpdateTitle() @@ -951,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) @@ -1024,4 +1042,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..4ed2570081 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); @@ -84,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); @@ -105,4 +106,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/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/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 96616fd3b2..a55b5b94b2 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -122,7 +122,10 @@ void MainWindow::ShutdownControllers() void MainWindow::InitCoreCallbacks() { - Core::SetOnStoppedCallback([this] { emit EmulationStopped(); }); + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [=](Core::State state) { + if (state == Core::State::Uninitialized) + OnStopComplete(); + }); installEventFilter(this); m_render_widget->installEventFilter(this); } @@ -151,11 +154,6 @@ void MainWindow::CreateComponents() m_log_widget = new LogWidget(this); m_log_config_widget = new LogConfigWidget(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( @@ -232,17 +230,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() @@ -283,20 +273,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() @@ -340,7 +322,6 @@ void MainWindow::Play() if (Core::GetState() == Core::State::Paused) { Core::SetState(Core::State::Running); - emit EmulationStarted(); } else { @@ -367,7 +348,6 @@ void MainWindow::Play() void MainWindow::Pause() { Core::SetState(Core::State::Paused); - emit EmulationPaused(); } void MainWindow::OnStopComplete() @@ -457,8 +437,7 @@ void MainWindow::Reset() void MainWindow::FrameAdvance() { - Movie::DoFrameStep(); - EmulationPaused(); + Core::DoFrameStep(); } void MainWindow::FullScreen() @@ -503,7 +482,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 @@ -680,7 +658,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 a30c5699d5..84a2f04de6 100644 --- a/Source/Core/DolphinQt2/MainWindow.h +++ b/Source/Core/DolphinQt2/MainWindow.h @@ -41,9 +41,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(); 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}); }); } 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 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;