mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-27 08:05:41 +00:00
Qt: Create load/save state menus on demand
This commit is contained in:
parent
4ebca591fd
commit
3e7501c5c8
|
@ -398,15 +398,6 @@ void MainWindow::onEmulationPaused(bool paused)
|
||||||
updateMouseMode(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,
|
void MainWindow::onSystemPerformanceCountersUpdated(float speed, float fps, float vps, float average_frame_time,
|
||||||
float worst_frame_time, GPURenderer renderer, quint32 render_width,
|
float worst_frame_time, GPURenderer renderer, quint32 render_width,
|
||||||
quint32 render_height, bool render_interlaced)
|
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)
|
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())
|
if (game_title.isEmpty())
|
||||||
setWindowTitle(getWindowTitle());
|
setWindowTitle(getWindowTitle());
|
||||||
else
|
else
|
||||||
|
@ -442,6 +432,8 @@ void MainWindow::onRunningGameChanged(const QString& filename, const QString& ga
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui.actionViewGameProperties->setEnabled(has_game_list_entry);
|
m_ui.actionViewGameProperties->setEnabled(has_game_list_entry);
|
||||||
|
|
||||||
|
m_running_game_code = game_code.toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onApplicationStateChanged(Qt::ApplicationState state)
|
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()
|
void MainWindow::onCheatsMenuAboutToShow()
|
||||||
{
|
{
|
||||||
m_ui.menuCheats->clear();
|
m_ui.menuCheats->clear();
|
||||||
|
@ -616,12 +618,10 @@ void MainWindow::onGameListEntrySelected(const GameListEntry* entry)
|
||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
m_ui.statusBar->clearMessage();
|
m_ui.statusBar->clearMessage();
|
||||||
m_host_interface->populateSaveStateMenus("", m_ui.menuLoadState, m_ui.menuSaveState);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui.statusBar->showMessage(QString::fromStdString(entry->path));
|
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)
|
void MainWindow::onGameListEntryDoubleClicked(const GameListEntry* entry)
|
||||||
|
@ -1005,6 +1005,8 @@ void MainWindow::connectSignals()
|
||||||
&MainWindow::onChangeDiscFromGameListActionTriggered);
|
&MainWindow::onChangeDiscFromGameListActionTriggered);
|
||||||
connect(m_ui.menuChangeDisc, &QMenu::aboutToShow, this, &MainWindow::onChangeDiscMenuAboutToShow);
|
connect(m_ui.menuChangeDisc, &QMenu::aboutToShow, this, &MainWindow::onChangeDiscMenuAboutToShow);
|
||||||
connect(m_ui.menuChangeDisc, &QMenu::aboutToHide, this, &MainWindow::onChangeDiscMenuAboutToHide);
|
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.menuCheats, &QMenu::aboutToShow, this, &MainWindow::onCheatsMenuAboutToShow);
|
||||||
connect(m_ui.actionCheats, &QAction::triggered, [this] { m_ui.menuCheats->exec(QCursor::pos()); });
|
connect(m_ui.actionCheats, &QAction::triggered, [this] { m_ui.menuCheats->exec(QCursor::pos()); });
|
||||||
connect(m_ui.actionRemoveDisc, &QAction::triggered, this, &MainWindow::onRemoveDiscActionTriggered);
|
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::emulationStarted, this, &MainWindow::onEmulationStarted);
|
||||||
connect(m_host_interface, &QtHostInterface::emulationStopped, this, &MainWindow::onEmulationStopped);
|
connect(m_host_interface, &QtHostInterface::emulationStopped, this, &MainWindow::onEmulationStopped);
|
||||||
connect(m_host_interface, &QtHostInterface::emulationPaused, this, &MainWindow::onEmulationPaused);
|
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,
|
connect(m_host_interface, &QtHostInterface::systemPerformanceCountersUpdated, this,
|
||||||
&MainWindow::onSystemPerformanceCountersUpdated);
|
&MainWindow::onSystemPerformanceCountersUpdated);
|
||||||
connect(m_host_interface, &QtHostInterface::runningGameChanged, this, &MainWindow::onRunningGameChanged);
|
connect(m_host_interface, &QtHostInterface::runningGameChanged, this, &MainWindow::onRunningGameChanged);
|
||||||
|
@ -1113,8 +1114,6 @@ void MainWindow::connectSignals()
|
||||||
connect(m_game_list_widget, &GameListWidget::entryContextMenuRequested, this,
|
connect(m_game_list_widget, &GameListWidget::entryContextMenuRequested, this,
|
||||||
&MainWindow::onGameListContextMenuRequested);
|
&MainWindow::onGameListContextMenuRequested);
|
||||||
|
|
||||||
m_host_interface->populateSaveStateMenus(nullptr, m_ui.menuLoadState, m_ui.menuSaveState);
|
|
||||||
|
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.actionDisableAllEnhancements, "Main",
|
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.actionDisableAllEnhancements, "Main",
|
||||||
"DisableAllEnhancements");
|
"DisableAllEnhancements");
|
||||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.actionDisableInterlacing, "GPU",
|
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.actionDisableInterlacing, "GPU",
|
||||||
|
|
|
@ -69,7 +69,6 @@ private Q_SLOTS:
|
||||||
void onEmulationStarted();
|
void onEmulationStarted();
|
||||||
void onEmulationStopped();
|
void onEmulationStopped();
|
||||||
void onEmulationPaused(bool paused);
|
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,
|
void onSystemPerformanceCountersUpdated(float speed, float fps, float vps, float average_frame_time,
|
||||||
float worst_frame_time, GPURenderer renderer, quint32 render_width,
|
float worst_frame_time, GPURenderer renderer, quint32 render_width,
|
||||||
quint32 render_height, bool render_interlaced);
|
quint32 render_height, bool render_interlaced);
|
||||||
|
@ -82,6 +81,8 @@ private Q_SLOTS:
|
||||||
void onChangeDiscFromGameListActionTriggered();
|
void onChangeDiscFromGameListActionTriggered();
|
||||||
void onChangeDiscMenuAboutToShow();
|
void onChangeDiscMenuAboutToShow();
|
||||||
void onChangeDiscMenuAboutToHide();
|
void onChangeDiscMenuAboutToHide();
|
||||||
|
void onLoadStateMenuAboutToShow();
|
||||||
|
void onSaveStateMenuAboutToShow();
|
||||||
void onCheatsMenuAboutToShow();
|
void onCheatsMenuAboutToShow();
|
||||||
void onRemoveDiscActionTriggered();
|
void onRemoveDiscActionTriggered();
|
||||||
void onViewToolbarActionToggled(bool checked);
|
void onViewToolbarActionToggled(bool checked);
|
||||||
|
@ -161,6 +162,8 @@ private:
|
||||||
CheatManagerDialog* m_cheat_manager_dialog = nullptr;
|
CheatManagerDialog* m_cheat_manager_dialog = nullptr;
|
||||||
DebuggerWindow* m_debugger_window = nullptr;
|
DebuggerWindow* m_debugger_window = nullptr;
|
||||||
|
|
||||||
|
std::string m_running_game_code;
|
||||||
|
|
||||||
bool m_emulation_running = false;
|
bool m_emulation_running = false;
|
||||||
bool m_was_paused_by_focus_loss = false;
|
bool m_was_paused_by_focus_loss = false;
|
||||||
bool m_open_debugger_on_start = false;
|
bool m_open_debugger_on_start = false;
|
||||||
|
|
|
@ -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)
|
void QtHostInterface::SetDefaultSettings(SettingsInterface& si)
|
||||||
{
|
{
|
||||||
CommonHostInterface::SetDefaultSettings(si);
|
CommonHostInterface::SetDefaultSettings(si);
|
||||||
|
@ -961,31 +956,26 @@ static QString FormatTimestampForSaveStateMenu(u64 timestamp)
|
||||||
return qtime.toString(QLocale::system().dateTimeFormat(QLocale::ShortFormat));
|
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,
|
auto add_slot = [this, game_code, menu](const QString& title, const QString& empty_title, bool global, s32 slot) {
|
||||||
s32 slot) {
|
|
||||||
std::optional<SaveStateInfo> ssi = GetSaveStateInfo(global ? nullptr : game_code, slot);
|
std::optional<SaveStateInfo> ssi = GetSaveStateInfo(global ? nullptr : game_code, slot);
|
||||||
|
|
||||||
const QString menu_title =
|
const QString menu_title =
|
||||||
ssi.has_value() ? title.arg(slot).arg(FormatTimestampForSaveStateMenu(ssi->timestamp)) : empty_title.arg(slot);
|
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());
|
load_action->setEnabled(ssi.has_value());
|
||||||
if (ssi.has_value())
|
if (ssi.has_value())
|
||||||
{
|
{
|
||||||
const QString path(QString::fromStdString(ssi->path));
|
const QString path(QString::fromStdString(ssi->path));
|
||||||
connect(load_action, &QAction::triggered, [this, path]() { loadState(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();
|
menu->clear();
|
||||||
save_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(
|
const QString path(
|
||||||
QFileDialog::getOpenFileName(m_main_window, tr("Select Save State File"), QString(), tr("Save States (*.sav)")));
|
QFileDialog::getOpenFileName(m_main_window, tr("Select Save State File"), QString(), tr("Save States (*.sav)")));
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
|
@ -993,12 +983,38 @@ void QtHostInterface::populateSaveStateMenus(const char* game_code, QMenu* load_
|
||||||
|
|
||||||
loadState(path);
|
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());
|
load_from_state->setEnabled(CanUndoLoadState());
|
||||||
connect(load_from_state, &QAction::triggered, this, &QtHostInterface::undoLoadState);
|
connect(load_from_state, &QAction::triggered, this, &QtHostInterface::undoLoadState);
|
||||||
load_menu->addSeparator();
|
menu->addSeparator();
|
||||||
|
|
||||||
connect(save_menu->addAction(tr("Save To File...")), &QAction::triggered, [this]() {
|
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<s32>(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<s32>(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<SaveStateInfo> 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(menu->addAction(tr("Save To File...")), &QAction::triggered, [this]() {
|
||||||
if (!System::IsValid())
|
if (!System::IsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1009,15 +1025,14 @@ void QtHostInterface::populateSaveStateMenus(const char* game_code, QMenu* load_
|
||||||
|
|
||||||
SaveState(path.toUtf8().constData());
|
SaveState(path.toUtf8().constData());
|
||||||
});
|
});
|
||||||
save_menu->addSeparator();
|
menu->addSeparator();
|
||||||
|
|
||||||
if (game_code && std::strlen(game_code) > 0)
|
if (game_code && std::strlen(game_code) > 0)
|
||||||
{
|
{
|
||||||
for (u32 slot = 1; slot <= PER_GAME_SAVE_STATE_SLOTS; slot++)
|
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<s32>(slot));
|
add_slot(tr("Game Save %1 (%2)"), tr("Game Save %1 (Empty)"), false, static_cast<s32>(slot));
|
||||||
|
|
||||||
load_menu->addSeparator();
|
menu->addSeparator();
|
||||||
save_menu->addSeparator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 slot = 1; slot <= GLOBAL_SAVE_STATE_SLOTS; slot++)
|
for (u32 slot = 1; slot <= GLOBAL_SAVE_STATE_SLOTS; slot++)
|
||||||
|
|
|
@ -91,7 +91,8 @@ public:
|
||||||
void setMainWindow(MainWindow* window);
|
void setMainWindow(MainWindow* window);
|
||||||
HostDisplay* createHostDisplay();
|
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.
|
/// Fills menu with save state info and handlers.
|
||||||
void populateGameListContextMenu(const GameListEntry* entry, QWidget* parent_window, QMenu* menu);
|
void populateGameListContextMenu(const GameListEntry* entry, QWidget* parent_window, QMenu* menu);
|
||||||
|
@ -130,7 +131,6 @@ Q_SIGNALS:
|
||||||
void emulationStarted();
|
void emulationStarted();
|
||||||
void emulationStopped();
|
void emulationStopped();
|
||||||
void emulationPaused(bool paused);
|
void emulationPaused(bool paused);
|
||||||
void stateSaved(const QString& game_code, bool global, qint32 slot);
|
|
||||||
void gameListRefreshed();
|
void gameListRefreshed();
|
||||||
QtDisplayWidget* createDisplayRequested(QThread* worker_thread, bool fullscreen, bool render_to_main);
|
QtDisplayWidget* createDisplayRequested(QThread* worker_thread, bool fullscreen, bool render_to_main);
|
||||||
QtDisplayWidget* updateDisplayRequested(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 OnSystemPerformanceCountersUpdated() override;
|
||||||
void OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code,
|
void OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code,
|
||||||
const std::string& game_title) override;
|
const std::string& game_title) override;
|
||||||
void OnSystemStateSaved(bool global, s32 slot) override;
|
|
||||||
|
|
||||||
void SetDefaultSettings(SettingsInterface& si) override;
|
void SetDefaultSettings(SettingsInterface& si) override;
|
||||||
void ApplySettings(bool display_osd_messages) override;
|
void ApplySettings(bool display_osd_messages) override;
|
||||||
|
|
Loading…
Reference in a new issue