diff --git a/src/duckstation-qt/mainwindow.cpp b/src/duckstation-qt/mainwindow.cpp index c06885feb..c06305f7d 100644 --- a/src/duckstation-qt/mainwindow.cpp +++ b/src/duckstation-qt/mainwindow.cpp @@ -398,15 +398,6 @@ void MainWindow::onEmulationPaused(bool paused) updateMouseMode(paused); } -void MainWindow::onStateSaved(const QString& game_code, bool global, qint32 slot) -{ - // don't bother updating for the resume state since we're powering off anyway - if (slot < 0) - return; - - m_host_interface->populateSaveStateMenus(game_code.toStdString().c_str(), m_ui.menuLoadState, m_ui.menuSaveState); -} - void MainWindow::onSystemPerformanceCountersUpdated(float speed, float fps, float vps, float average_frame_time, float worst_frame_time, GPURenderer renderer, quint32 render_width, quint32 render_height, bool render_interlaced) @@ -425,7 +416,6 @@ void MainWindow::onSystemPerformanceCountersUpdated(float speed, float fps, floa void MainWindow::onRunningGameChanged(const QString& filename, const QString& game_code, const QString& game_title) { - m_host_interface->populateSaveStateMenus(game_code.toStdString().c_str(), m_ui.menuLoadState, m_ui.menuSaveState); if (game_title.isEmpty()) setWindowTitle(getWindowTitle()); else @@ -442,6 +432,8 @@ void MainWindow::onRunningGameChanged(const QString& filename, const QString& ga } m_ui.actionViewGameProperties->setEnabled(has_game_list_entry); + + m_running_game_code = game_code.toStdString(); } void MainWindow::onApplicationStateChanged(Qt::ApplicationState state) @@ -517,6 +509,16 @@ void MainWindow::onChangeDiscMenuAboutToHide() } } +void MainWindow::onLoadStateMenuAboutToShow() +{ + m_host_interface->populateLoadStateMenu(m_running_game_code.c_str(), m_ui.menuLoadState); +} + +void MainWindow::onSaveStateMenuAboutToShow() +{ + m_host_interface->populateSaveStateMenu(m_running_game_code.c_str(), m_ui.menuSaveState); +} + void MainWindow::onCheatsMenuAboutToShow() { m_ui.menuCheats->clear(); @@ -616,12 +618,10 @@ void MainWindow::onGameListEntrySelected(const GameListEntry* entry) if (!entry) { m_ui.statusBar->clearMessage(); - m_host_interface->populateSaveStateMenus("", m_ui.menuLoadState, m_ui.menuSaveState); return; } m_ui.statusBar->showMessage(QString::fromStdString(entry->path)); - m_host_interface->populateSaveStateMenus(entry->code.c_str(), m_ui.menuLoadState, m_ui.menuSaveState); } void MainWindow::onGameListEntryDoubleClicked(const GameListEntry* entry) @@ -1005,6 +1005,8 @@ void MainWindow::connectSignals() &MainWindow::onChangeDiscFromGameListActionTriggered); connect(m_ui.menuChangeDisc, &QMenu::aboutToShow, this, &MainWindow::onChangeDiscMenuAboutToShow); connect(m_ui.menuChangeDisc, &QMenu::aboutToHide, this, &MainWindow::onChangeDiscMenuAboutToHide); + connect(m_ui.menuLoadState, &QMenu::aboutToShow, this, &MainWindow::onLoadStateMenuAboutToShow); + connect(m_ui.menuSaveState, &QMenu::aboutToShow, this, &MainWindow::onSaveStateMenuAboutToShow); connect(m_ui.menuCheats, &QMenu::aboutToShow, this, &MainWindow::onCheatsMenuAboutToShow); connect(m_ui.actionCheats, &QAction::triggered, [this] { m_ui.menuCheats->exec(QCursor::pos()); }); connect(m_ui.actionRemoveDisc, &QAction::triggered, this, &MainWindow::onRemoveDiscActionTriggered); @@ -1098,7 +1100,6 @@ void MainWindow::connectSignals() connect(m_host_interface, &QtHostInterface::emulationStarted, this, &MainWindow::onEmulationStarted); connect(m_host_interface, &QtHostInterface::emulationStopped, this, &MainWindow::onEmulationStopped); connect(m_host_interface, &QtHostInterface::emulationPaused, this, &MainWindow::onEmulationPaused); - connect(m_host_interface, &QtHostInterface::stateSaved, this, &MainWindow::onStateSaved); connect(m_host_interface, &QtHostInterface::systemPerformanceCountersUpdated, this, &MainWindow::onSystemPerformanceCountersUpdated); connect(m_host_interface, &QtHostInterface::runningGameChanged, this, &MainWindow::onRunningGameChanged); @@ -1113,8 +1114,6 @@ void MainWindow::connectSignals() connect(m_game_list_widget, &GameListWidget::entryContextMenuRequested, this, &MainWindow::onGameListContextMenuRequested); - m_host_interface->populateSaveStateMenus(nullptr, m_ui.menuLoadState, m_ui.menuSaveState); - SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.actionDisableAllEnhancements, "Main", "DisableAllEnhancements"); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.actionDisableInterlacing, "GPU", diff --git a/src/duckstation-qt/mainwindow.h b/src/duckstation-qt/mainwindow.h index 5ade7da59..0ee78e0ff 100644 --- a/src/duckstation-qt/mainwindow.h +++ b/src/duckstation-qt/mainwindow.h @@ -69,7 +69,6 @@ private Q_SLOTS: void onEmulationStarted(); void onEmulationStopped(); void onEmulationPaused(bool paused); - void onStateSaved(const QString& game_code, bool global, qint32 slot); void onSystemPerformanceCountersUpdated(float speed, float fps, float vps, float average_frame_time, float worst_frame_time, GPURenderer renderer, quint32 render_width, quint32 render_height, bool render_interlaced); @@ -82,6 +81,8 @@ private Q_SLOTS: void onChangeDiscFromGameListActionTriggered(); void onChangeDiscMenuAboutToShow(); void onChangeDiscMenuAboutToHide(); + void onLoadStateMenuAboutToShow(); + void onSaveStateMenuAboutToShow(); void onCheatsMenuAboutToShow(); void onRemoveDiscActionTriggered(); void onViewToolbarActionToggled(bool checked); @@ -161,6 +162,8 @@ private: CheatManagerDialog* m_cheat_manager_dialog = nullptr; DebuggerWindow* m_debugger_window = nullptr; + std::string m_running_game_code; + bool m_emulation_running = false; bool m_was_paused_by_focus_loss = false; bool m_open_debugger_on_start = false; diff --git a/src/duckstation-qt/qthostinterface.cpp b/src/duckstation-qt/qthostinterface.cpp index 244f4e80b..8e2eccee7 100644 --- a/src/duckstation-qt/qthostinterface.cpp +++ b/src/duckstation-qt/qthostinterface.cpp @@ -782,11 +782,6 @@ void QtHostInterface::OnRunningGameChanged(const std::string& path, CDImage* ima } } -void QtHostInterface::OnSystemStateSaved(bool global, s32 slot) -{ - emit stateSaved(QString::fromStdString(System::GetRunningCode()), global, slot); -} - void QtHostInterface::SetDefaultSettings(SettingsInterface& si) { CommonHostInterface::SetDefaultSettings(si); @@ -961,31 +956,26 @@ static QString FormatTimestampForSaveStateMenu(u64 timestamp) return qtime.toString(QLocale::system().dateTimeFormat(QLocale::ShortFormat)); } -void QtHostInterface::populateSaveStateMenus(const char* game_code, QMenu* load_menu, QMenu* save_menu) +void QtHostInterface::populateLoadStateMenu(const char* game_code, QMenu* menu) { - auto add_slot = [this, game_code, load_menu, save_menu](const QString& title, const QString& empty_title, bool global, - s32 slot) { + auto add_slot = [this, game_code, menu](const QString& title, const QString& empty_title, bool global, s32 slot) { std::optional ssi = GetSaveStateInfo(global ? nullptr : game_code, slot); const QString menu_title = ssi.has_value() ? title.arg(slot).arg(FormatTimestampForSaveStateMenu(ssi->timestamp)) : empty_title.arg(slot); - QAction* load_action = load_menu->addAction(menu_title); + QAction* load_action = menu->addAction(menu_title); load_action->setEnabled(ssi.has_value()); if (ssi.has_value()) { const QString path(QString::fromStdString(ssi->path)); connect(load_action, &QAction::triggered, [this, path]() { loadState(path); }); } - - QAction* save_action = save_menu->addAction(menu_title); - connect(save_action, &QAction::triggered, [this, global, slot]() { saveState(global, slot); }); }; - load_menu->clear(); - save_menu->clear(); + menu->clear(); - connect(load_menu->addAction(tr("Load From File...")), &QAction::triggered, [this]() { + connect(menu->addAction(tr("Load From File...")), &QAction::triggered, [this]() { const QString path( QFileDialog::getOpenFileName(m_main_window, tr("Select Save State File"), QString(), tr("Save States (*.sav)"))); if (path.isEmpty()) @@ -993,12 +983,38 @@ void QtHostInterface::populateSaveStateMenus(const char* game_code, QMenu* load_ loadState(path); }); - QAction* load_from_state = load_menu->addAction(tr("Undo Load State")); + QAction* load_from_state = menu->addAction(tr("Undo Load State")); load_from_state->setEnabled(CanUndoLoadState()); connect(load_from_state, &QAction::triggered, this, &QtHostInterface::undoLoadState); - load_menu->addSeparator(); + menu->addSeparator(); + + if (game_code && std::strlen(game_code) > 0) + { + for (u32 slot = 1; slot <= PER_GAME_SAVE_STATE_SLOTS; slot++) + add_slot(tr("Game Save %1 (%2)"), tr("Game Save %1 (Empty)"), false, static_cast(slot)); + + menu->addSeparator(); + } + + for (u32 slot = 1; slot <= GLOBAL_SAVE_STATE_SLOTS; slot++) + add_slot(tr("Global Save %1 (%2)"), tr("Global Save %1 (Empty)"), true, static_cast(slot)); +} + +void QtHostInterface::populateSaveStateMenu(const char* game_code, QMenu* menu) +{ + auto add_slot = [this, game_code, menu](const QString& title, const QString& empty_title, bool global, s32 slot) { + std::optional ssi = GetSaveStateInfo(global ? nullptr : game_code, slot); + + const QString menu_title = + ssi.has_value() ? title.arg(slot).arg(FormatTimestampForSaveStateMenu(ssi->timestamp)) : empty_title.arg(slot); + + QAction* save_action = menu->addAction(menu_title); + connect(save_action, &QAction::triggered, [this, global, slot]() { saveState(global, slot); }); + }; + + menu->clear(); - connect(save_menu->addAction(tr("Save To File...")), &QAction::triggered, [this]() { + connect(menu->addAction(tr("Save To File...")), &QAction::triggered, [this]() { if (!System::IsValid()) return; @@ -1009,15 +1025,14 @@ void QtHostInterface::populateSaveStateMenus(const char* game_code, QMenu* load_ SaveState(path.toUtf8().constData()); }); - save_menu->addSeparator(); + menu->addSeparator(); if (game_code && std::strlen(game_code) > 0) { for (u32 slot = 1; slot <= PER_GAME_SAVE_STATE_SLOTS; slot++) add_slot(tr("Game Save %1 (%2)"), tr("Game Save %1 (Empty)"), false, static_cast(slot)); - load_menu->addSeparator(); - save_menu->addSeparator(); + menu->addSeparator(); } for (u32 slot = 1; slot <= GLOBAL_SAVE_STATE_SLOTS; slot++) diff --git a/src/duckstation-qt/qthostinterface.h b/src/duckstation-qt/qthostinterface.h index 4f375f3a8..7dd65c63b 100644 --- a/src/duckstation-qt/qthostinterface.h +++ b/src/duckstation-qt/qthostinterface.h @@ -91,7 +91,8 @@ public: void setMainWindow(MainWindow* window); HostDisplay* createHostDisplay(); - void populateSaveStateMenus(const char* game_code, QMenu* load_menu, QMenu* save_menu); + void populateLoadStateMenu(const char* game_code, QMenu* menu); + void populateSaveStateMenu(const char* game_code, QMenu* menu); /// Fills menu with save state info and handlers. void populateGameListContextMenu(const GameListEntry* entry, QWidget* parent_window, QMenu* menu); @@ -130,7 +131,6 @@ Q_SIGNALS: void emulationStarted(); void emulationStopped(); void emulationPaused(bool paused); - void stateSaved(const QString& game_code, bool global, qint32 slot); void gameListRefreshed(); QtDisplayWidget* createDisplayRequested(QThread* worker_thread, bool fullscreen, bool render_to_main); QtDisplayWidget* updateDisplayRequested(QThread* worker_thread, bool fullscreen, bool render_to_main); @@ -211,7 +211,6 @@ protected: void OnSystemPerformanceCountersUpdated() override; void OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code, const std::string& game_title) override; - void OnSystemStateSaved(bool global, s32 slot) override; void SetDefaultSettings(SettingsInterface& si) override; void ApplySettings(bool display_osd_messages) override;