diff --git a/src/duckstation-qt/qthostinterface.cpp b/src/duckstation-qt/qthostinterface.cpp index 47bc8289d..3af8be79a 100644 --- a/src/duckstation-qt/qthostinterface.cpp +++ b/src/duckstation-qt/qthostinterface.cpp @@ -964,6 +964,29 @@ void QtHostInterface::populateSaveStateMenus(const char* game_code, QMenu* load_ load_menu->clear(); save_menu->clear(); + connect(load_menu->addAction(tr("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()) + return; + + loadState(path); + }); + load_menu->addSeparator(); + + connect(save_menu->addAction(tr("From File...")), &QAction::triggered, [this]() { + if (!System::IsValid()) + return; + + const QString path( + QFileDialog::getSaveFileName(m_main_window, tr("Select Save State File"), QString(), tr("Save States (*.sav)"))); + if (path.isEmpty()) + return; + + SaveState(path.toUtf8().constData()); + }); + save_menu->addSeparator(); + if (game_code && std::strlen(game_code) > 0) { for (u32 slot = 1; slot <= PER_GAME_SAVE_STATE_SLOTS; slot++) @@ -1271,6 +1294,19 @@ void QtHostInterface::loadState(bool global, qint32 slot) renderDisplay(); } +void QtHostInterface::saveState(const QString& filename, bool block_until_done /* = false */) +{ + if (!isOnWorkerThread()) + { + QMetaObject::invokeMethod(this, "saveState", block_until_done ? Qt::BlockingQueuedConnection : Qt::QueuedConnection, + Q_ARG(const QString&, filename), Q_ARG(bool, block_until_done)); + return; + } + + if (!System::IsShutdown()) + SaveState(filename.toUtf8().data()); +} + void QtHostInterface::saveState(bool global, qint32 slot, bool block_until_done /* = false */) { if (!isOnWorkerThread()) diff --git a/src/duckstation-qt/qthostinterface.h b/src/duckstation-qt/qthostinterface.h index 844d52743..34e3fd0a0 100644 --- a/src/duckstation-qt/qthostinterface.h +++ b/src/duckstation-qt/qthostinterface.h @@ -161,6 +161,7 @@ public Q_SLOTS: void changeDiscFromPlaylist(quint32 index); void loadState(const QString& filename); void loadState(bool global, qint32 slot); + void saveState(const QString& filename, bool block_until_done = false); void saveState(bool global, qint32 slot, bool block_until_done = false); void setAudioOutputVolume(int volume, int fast_forward_volume); void setAudioOutputMuted(bool muted);