mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 22:05:38 +00:00
System: Confirm shutdown if memory card is being written
This commit is contained in:
parent
a5613fc815
commit
3fa2bd1d3a
|
@ -272,8 +272,9 @@ static void DoStartBIOS();
|
||||||
static void DoStartDisc(std::string path);
|
static void DoStartDisc(std::string path);
|
||||||
static void DoStartDisc();
|
static void DoStartDisc();
|
||||||
static void DoToggleFastForward();
|
static void DoToggleFastForward();
|
||||||
static void DoShutdown(bool save_state);
|
static void ConfirmIfSavingMemoryCards(std::string_view action, std::function<void(bool)> callback);
|
||||||
static void DoReset();
|
static void RequestShutdown(bool save_state);
|
||||||
|
static void RequestReset();
|
||||||
static void DoChangeDiscFromFile();
|
static void DoChangeDiscFromFile();
|
||||||
static void DoChangeDisc();
|
static void DoChangeDisc();
|
||||||
static void DoRequestExit();
|
static void DoRequestExit();
|
||||||
|
@ -1026,14 +1027,44 @@ void FullscreenUI::DoStartDisc()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullscreenUI::DoShutdown(bool save_state)
|
void FullscreenUI::ConfirmIfSavingMemoryCards(std::string_view action, std::function<void(bool)> callback)
|
||||||
{
|
{
|
||||||
Host::RunOnCPUThread([save_state]() { Host::RequestSystemShutdown(false, save_state); });
|
if (!System::IsSavingMemoryCards())
|
||||||
|
{
|
||||||
|
callback(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenConfirmMessageDialog(
|
||||||
|
FSUI_ICONSTR(ICON_PF_MEMORY_CARD, "Memory Card Busy"),
|
||||||
|
fmt::format(FSUI_FSTR("WARNING: Your game is still saving to the memory card. Continuing to {0} may IRREVERSIBLY "
|
||||||
|
"DESTROY YOUR MEMORY CARD. We recommend resuming your game and waiting 5 seconds for it to "
|
||||||
|
"finish saving.\n\nDo you want to {0} anyway?"),
|
||||||
|
action),
|
||||||
|
std::move(callback),
|
||||||
|
fmt::format(
|
||||||
|
fmt::runtime(FSUI_ICONSTR(ICON_FA_EXCLAMATION_TRIANGLE, "Yes, {} now and risk memory card corruption.")), action),
|
||||||
|
FSUI_ICONSTR(ICON_FA_PLAY, "No, resume the game."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullscreenUI::DoReset()
|
void FullscreenUI::RequestShutdown(bool save_state)
|
||||||
{
|
{
|
||||||
Host::RunOnCPUThread(System::ResetSystem);
|
ConfirmIfSavingMemoryCards(FSUI_VSTR("shut down"), [save_state](bool result) {
|
||||||
|
if (result)
|
||||||
|
Host::RunOnCPUThread([save_state]() { Host::RequestSystemShutdown(false, save_state); });
|
||||||
|
else
|
||||||
|
ClosePauseMenu();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void FullscreenUI::RequestReset()
|
||||||
|
{
|
||||||
|
ConfirmIfSavingMemoryCards(FSUI_VSTR("reset"), [](bool result) {
|
||||||
|
if (result)
|
||||||
|
Host::RunOnCPUThread(System::ResetSystem);
|
||||||
|
else
|
||||||
|
ClosePauseMenu();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullscreenUI::DoToggleFastForward()
|
void FullscreenUI::DoToggleFastForward()
|
||||||
|
@ -1048,27 +1079,35 @@ void FullscreenUI::DoToggleFastForward()
|
||||||
|
|
||||||
void FullscreenUI::DoChangeDiscFromFile()
|
void FullscreenUI::DoChangeDiscFromFile()
|
||||||
{
|
{
|
||||||
auto callback = [](const std::string& path) {
|
ConfirmIfSavingMemoryCards(FSUI_VSTR("change disc"), [](bool result) {
|
||||||
if (!path.empty())
|
if (!result)
|
||||||
{
|
{
|
||||||
if (!GameList::IsScannableFilename(path))
|
ClosePauseMenu();
|
||||||
{
|
return;
|
||||||
ShowToast({},
|
|
||||||
fmt::format(FSUI_FSTR("{} is not a valid disc image."), FileSystem::GetDisplayNameFromPath(path)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Host::RunOnCPUThread([path]() { System::InsertMedia(path.c_str()); });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueResetFocus();
|
auto callback = [](const std::string& path) {
|
||||||
CloseFileSelector();
|
if (!path.empty())
|
||||||
ReturnToPreviousWindow();
|
{
|
||||||
};
|
if (!GameList::IsScannableFilename(path))
|
||||||
|
{
|
||||||
|
ShowToast({},
|
||||||
|
fmt::format(FSUI_FSTR("{} is not a valid disc image."), FileSystem::GetDisplayNameFromPath(path)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Host::RunOnCPUThread([path]() { System::InsertMedia(path.c_str()); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OpenFileSelector(FSUI_ICONSTR(ICON_FA_COMPACT_DISC, "Select Disc Image"), false, std::move(callback),
|
QueueResetFocus();
|
||||||
GetDiscImageFilters(), std::string(Path::GetDirectory(System::GetDiscPath())));
|
CloseFileSelector();
|
||||||
|
ReturnToPreviousWindow();
|
||||||
|
};
|
||||||
|
|
||||||
|
OpenFileSelector(FSUI_ICONSTR(ICON_FA_COMPACT_DISC, "Select Disc Image"), false, std::move(callback),
|
||||||
|
GetDiscImageFilters(), std::string(Path::GetDirectory(System::GetDiscPath())));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullscreenUI::DoChangeDisc()
|
void FullscreenUI::DoChangeDisc()
|
||||||
|
@ -5277,7 +5316,7 @@ void FullscreenUI::DrawPauseMenu()
|
||||||
{
|
{
|
||||||
// skip submenu when we can't save anyway
|
// skip submenu when we can't save anyway
|
||||||
if (!has_game)
|
if (!has_game)
|
||||||
DoShutdown(false);
|
RequestShutdown(false);
|
||||||
else
|
else
|
||||||
OpenPauseSubMenu(PauseSubMenu::Exit);
|
OpenPauseSubMenu(PauseSubMenu::Exit);
|
||||||
}
|
}
|
||||||
|
@ -5298,14 +5337,14 @@ void FullscreenUI::DrawPauseMenu()
|
||||||
if (ActiveButton(FSUI_ICONSTR(ICON_FA_SYNC, "Reset System"), false))
|
if (ActiveButton(FSUI_ICONSTR(ICON_FA_SYNC, "Reset System"), false))
|
||||||
{
|
{
|
||||||
ClosePauseMenu();
|
ClosePauseMenu();
|
||||||
DoReset();
|
RequestReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ActiveButton(FSUI_ICONSTR(ICON_FA_SAVE, "Exit And Save State"), false))
|
if (ActiveButton(FSUI_ICONSTR(ICON_FA_SAVE, "Exit And Save State"), false))
|
||||||
DoShutdown(true);
|
RequestShutdown(true);
|
||||||
|
|
||||||
if (ActiveButton(FSUI_ICONSTR(ICON_FA_POWER_OFF, "Exit Without Saving"), false))
|
if (ActiveButton(FSUI_ICONSTR(ICON_FA_POWER_OFF, "Exit Without Saving"), false))
|
||||||
DoShutdown(false);
|
RequestShutdown(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -270,6 +270,11 @@ bool MemoryCard::Transfer(const u8 data_in, u8* data_out)
|
||||||
return ack;
|
return ack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MemoryCard::IsOrWasRecentlyWriting() const
|
||||||
|
{
|
||||||
|
return (m_state == State::WriteData || m_save_event->IsActive());
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<MemoryCard> MemoryCard::Create()
|
std::unique_ptr<MemoryCard> MemoryCard::Create()
|
||||||
{
|
{
|
||||||
std::unique_ptr<MemoryCard> mc = std::make_unique<MemoryCard>();
|
std::unique_ptr<MemoryCard> mc = std::make_unique<MemoryCard>();
|
||||||
|
|
|
@ -35,6 +35,8 @@ public:
|
||||||
void ResetTransferState();
|
void ResetTransferState();
|
||||||
bool Transfer(const u8 data_in, u8* data_out);
|
bool Transfer(const u8 data_in, u8* data_out);
|
||||||
|
|
||||||
|
bool IsOrWasRecentlyWriting() const;
|
||||||
|
|
||||||
void Format();
|
void Format();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -3300,6 +3300,18 @@ bool System::HasMemoryCard(u32 slot)
|
||||||
return (Pad::GetMemoryCard(slot) != nullptr);
|
return (Pad::GetMemoryCard(slot) != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool System::IsSavingMemoryCards()
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
|
||||||
|
{
|
||||||
|
MemoryCard* card = Pad::GetMemoryCard(i);
|
||||||
|
if (card && card->IsOrWasRecentlyWriting())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void System::SwapMemoryCards()
|
void System::SwapMemoryCards()
|
||||||
{
|
{
|
||||||
if (!IsValid())
|
if (!IsValid())
|
||||||
|
|
|
@ -301,6 +301,7 @@ void ResetControllers();
|
||||||
void UpdateMemoryCardTypes();
|
void UpdateMemoryCardTypes();
|
||||||
void UpdatePerGameMemoryCards();
|
void UpdatePerGameMemoryCards();
|
||||||
bool HasMemoryCard(u32 slot);
|
bool HasMemoryCard(u32 slot);
|
||||||
|
bool IsSavingMemoryCards();
|
||||||
|
|
||||||
/// Swaps memory cards in slot 1/2.
|
/// Swaps memory cards in slot 1/2.
|
||||||
void SwapMemoryCards();
|
void SwapMemoryCards();
|
||||||
|
|
|
@ -110,7 +110,7 @@ void AchievementLoginDialog::processLoginResult(bool result, const QString& mess
|
||||||
tr("Hardcore mode will not be enabled until the system is reset. Do you want to reset the system now?")) ==
|
tr("Hardcore mode will not be enabled until the system is reset. Do you want to reset the system now?")) ==
|
||||||
QMessageBox::Yes)
|
QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
g_emu_thread->resetSystem();
|
g_emu_thread->resetSystem(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ void AchievementSettingsWidget::onHardcoreModeStateChanged()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_emu_thread->resetSystem();
|
g_emu_thread->resetSystem(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AchievementSettingsWidget::onAchievementsNotificationDurationSliderChanged()
|
void AchievementSettingsWidget::onAchievementsNotificationDurationSliderChanged()
|
||||||
|
|
|
@ -700,7 +700,7 @@ void MainWindow::quit()
|
||||||
// Make sure VM is gone. It really should be if we're here.
|
// Make sure VM is gone. It really should be if we're here.
|
||||||
if (s_system_valid)
|
if (s_system_valid)
|
||||||
{
|
{
|
||||||
g_emu_thread->shutdownSystem(false);
|
g_emu_thread->shutdownSystem(false, true);
|
||||||
while (s_system_valid)
|
while (s_system_valid)
|
||||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
|
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
|
||||||
}
|
}
|
||||||
|
@ -990,7 +990,7 @@ void MainWindow::populateChangeDiscSubImageMenu(QMenu* menu, QActionGroup* actio
|
||||||
QString path = QString::fromStdString(glentry->path);
|
QString path = QString::fromStdString(glentry->path);
|
||||||
action->setCheckable(true);
|
action->setCheckable(true);
|
||||||
action->setChecked(path == s_current_game_path);
|
action->setChecked(path == s_current_game_path);
|
||||||
connect(action, &QAction::triggered, [path = std::move(path)]() { g_emu_thread->changeDisc(path); });
|
connect(action, &QAction::triggered, [path = std::move(path)]() { g_emu_thread->changeDisc(path, false, true); });
|
||||||
menu->addAction(action);
|
menu->addAction(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1232,9 +1232,7 @@ void MainWindow::promptForDiscChange(const QString& path)
|
||||||
|
|
||||||
switchToEmulationView();
|
switchToEmulationView();
|
||||||
|
|
||||||
g_emu_thread->changeDisc(path);
|
g_emu_thread->changeDisc(path, reset_system, true);
|
||||||
if (reset_system)
|
|
||||||
g_emu_thread->resetSystem();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onStartDiscActionTriggered()
|
void MainWindow::onStartDiscActionTriggered()
|
||||||
|
@ -1258,7 +1256,7 @@ void MainWindow::onChangeDiscFromFileActionTriggered()
|
||||||
if (filename.isEmpty())
|
if (filename.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_emu_thread->changeDisc(filename);
|
g_emu_thread->changeDisc(filename, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onChangeDiscFromGameListActionTriggered()
|
void MainWindow::onChangeDiscFromGameListActionTriggered()
|
||||||
|
@ -1273,7 +1271,7 @@ void MainWindow::onChangeDiscFromDeviceActionTriggered()
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_emu_thread->changeDisc(QString::fromStdString(path));
|
g_emu_thread->changeDisc(QString::fromStdString(path), false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onChangeDiscMenuAboutToShow()
|
void MainWindow::onChangeDiscMenuAboutToShow()
|
||||||
|
@ -1317,7 +1315,7 @@ void MainWindow::onFullscreenUIStateChange(bool running)
|
||||||
|
|
||||||
void MainWindow::onRemoveDiscActionTriggered()
|
void MainWindow::onRemoveDiscActionTriggered()
|
||||||
{
|
{
|
||||||
g_emu_thread->changeDisc(QString());
|
g_emu_thread->changeDisc(QString(), false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onViewToolbarActionToggled(bool checked)
|
void MainWindow::onViewToolbarActionToggled(bool checked)
|
||||||
|
@ -1511,7 +1509,7 @@ void MainWindow::onGameListEntryContextMenuRequested(const QPoint& point)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
connect(menu.addAction(tr("Change Disc")), &QAction::triggered, [this, entry]() {
|
connect(menu.addAction(tr("Change Disc")), &QAction::triggered, [this, entry]() {
|
||||||
g_emu_thread->changeDisc(QString::fromStdString(entry->path));
|
g_emu_thread->changeDisc(QString::fromStdString(entry->path), false, true);
|
||||||
g_emu_thread->setSystemPaused(false);
|
g_emu_thread->setSystemPaused(false);
|
||||||
switchToEmulationView();
|
switchToEmulationView();
|
||||||
});
|
});
|
||||||
|
@ -2031,8 +2029,8 @@ void MainWindow::connectSignals()
|
||||||
[this]() { requestShutdown(true, true, g_settings.save_state_on_exit); });
|
[this]() { requestShutdown(true, true, g_settings.save_state_on_exit); });
|
||||||
connect(m_ui.actionPowerOffWithoutSaving, &QAction::triggered, this,
|
connect(m_ui.actionPowerOffWithoutSaving, &QAction::triggered, this,
|
||||||
[this]() { requestShutdown(false, false, false); });
|
[this]() { requestShutdown(false, false, false); });
|
||||||
connect(m_ui.actionReset, &QAction::triggered, g_emu_thread, &EmuThread::resetSystem);
|
connect(m_ui.actionReset, &QAction::triggered, this, []() { g_emu_thread->resetSystem(true); });
|
||||||
connect(m_ui.actionPause, &QAction::toggled, [](bool active) { g_emu_thread->setSystemPaused(active); });
|
connect(m_ui.actionPause, &QAction::toggled, this, [](bool active) { g_emu_thread->setSystemPaused(active); });
|
||||||
connect(m_ui.actionScreenshot, &QAction::triggered, g_emu_thread, &EmuThread::saveScreenshot);
|
connect(m_ui.actionScreenshot, &QAction::triggered, g_emu_thread, &EmuThread::saveScreenshot);
|
||||||
connect(m_ui.actionScanForNewGames, &QAction::triggered, this, [this]() { refreshGameList(false); });
|
connect(m_ui.actionScanForNewGames, &QAction::triggered, this, [this]() { refreshGameList(false); });
|
||||||
connect(m_ui.actionRescanAllGames, &QAction::triggered, this, [this]() { refreshGameList(true); });
|
connect(m_ui.actionRescanAllGames, &QAction::triggered, this, [this]() { refreshGameList(true); });
|
||||||
|
@ -2862,7 +2860,7 @@ bool MainWindow::requestShutdown(bool allow_confirm /* = true */, bool allow_sav
|
||||||
updateWindowState(true);
|
updateWindowState(true);
|
||||||
|
|
||||||
// Now we can actually shut down the VM.
|
// Now we can actually shut down the VM.
|
||||||
g_emu_thread->shutdownSystem(save_state);
|
g_emu_thread->shutdownSystem(save_state, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1067,23 +1067,72 @@ void EmuThread::enumerateVibrationMotors()
|
||||||
onVibrationMotorsEnumerated(qmotors);
|
onVibrationMotorsEnumerated(qmotors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::shutdownSystem(bool save_state /* = true */)
|
void EmuThread::confirmActionIfMemoryCardBusy(const QString& action, bool cancel_resume_on_accept,
|
||||||
|
std::function<void(bool)> callback) const
|
||||||
|
{
|
||||||
|
DebugAssert(isOnThread());
|
||||||
|
|
||||||
|
if (!System::IsValid() || !System::IsSavingMemoryCards())
|
||||||
|
{
|
||||||
|
callback(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtHost::RunOnUIThread([action, cancel_resume_on_accept, callback = std::move(callback)]() mutable {
|
||||||
|
auto lock = g_main_window->pauseAndLockSystem();
|
||||||
|
|
||||||
|
const bool result =
|
||||||
|
(QMessageBox::question(lock.getDialogParent(), tr("Memory Card Busy"),
|
||||||
|
tr("WARNING: Your game is still saving to the memory card. Continuing to %1 may "
|
||||||
|
"IRREVERSIBLY DESTROY YOUR MEMORY CARD. We recommend resuming your game and waiting 5 "
|
||||||
|
"seconds for it to finish saving.\n\nDo you want to %1 anyway?")
|
||||||
|
.arg(action)) != QMessageBox::No);
|
||||||
|
|
||||||
|
if (cancel_resume_on_accept)
|
||||||
|
lock.cancelResume();
|
||||||
|
|
||||||
|
Host::RunOnCPUThread([result, callback = std::move(callback)]() { callback(result); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuThread::shutdownSystem(bool save_state, bool check_memcard_busy)
|
||||||
{
|
{
|
||||||
if (!isOnThread())
|
if (!isOnThread())
|
||||||
{
|
{
|
||||||
System::CancelPendingStartup();
|
System::CancelPendingStartup();
|
||||||
QMetaObject::invokeMethod(this, "shutdownSystem", Qt::QueuedConnection, Q_ARG(bool, save_state));
|
QMetaObject::invokeMethod(this, "shutdownSystem", Qt::QueuedConnection, Q_ARG(bool, save_state),
|
||||||
|
Q_ARG(bool, check_memcard_busy));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_memcard_busy && System::IsSavingMemoryCards())
|
||||||
|
{
|
||||||
|
confirmActionIfMemoryCardBusy(tr("shut down"), true, [save_state](bool result) {
|
||||||
|
if (result)
|
||||||
|
g_emu_thread->shutdownSystem(save_state, false);
|
||||||
|
else
|
||||||
|
g_emu_thread->setSystemPaused(false);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
System::ShutdownSystem(save_state);
|
System::ShutdownSystem(save_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::resetSystem()
|
void EmuThread::resetSystem(bool check_memcard_busy)
|
||||||
{
|
{
|
||||||
if (!isOnThread())
|
if (!isOnThread())
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(this, &EmuThread::resetSystem, Qt::QueuedConnection);
|
QMetaObject::invokeMethod(this, "resetSystem", Qt::QueuedConnection, Q_ARG(bool, check_memcard_busy));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_memcard_busy && System::IsSavingMemoryCards())
|
||||||
|
{
|
||||||
|
confirmActionIfMemoryCardBusy(tr("reset"), false, [](bool result) {
|
||||||
|
if (result)
|
||||||
|
g_emu_thread->resetSystem(false);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1103,11 +1152,21 @@ void EmuThread::setSystemPaused(bool paused, bool wait_until_paused /* = false *
|
||||||
System::PauseSystem(paused);
|
System::PauseSystem(paused);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::changeDisc(const QString& new_disc_filename)
|
void EmuThread::changeDisc(const QString& new_disc_filename, bool reset_system, bool check_memcard_busy)
|
||||||
{
|
{
|
||||||
if (!isOnThread())
|
if (!isOnThread())
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(this, "changeDisc", Qt::QueuedConnection, Q_ARG(const QString&, new_disc_filename));
|
QMetaObject::invokeMethod(this, "changeDisc", Qt::QueuedConnection, Q_ARG(const QString&, new_disc_filename),
|
||||||
|
Q_ARG(bool, reset_system), Q_ARG(bool, check_memcard_busy));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_memcard_busy && System::IsSavingMemoryCards())
|
||||||
|
{
|
||||||
|
confirmActionIfMemoryCardBusy(tr("change disc"), false, [new_disc_filename, reset_system](bool result) {
|
||||||
|
if (result)
|
||||||
|
g_emu_thread->changeDisc(new_disc_filename, reset_system, false);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1118,6 +1177,9 @@ void EmuThread::changeDisc(const QString& new_disc_filename)
|
||||||
System::InsertMedia(new_disc_filename.toStdString().c_str());
|
System::InsertMedia(new_disc_filename.toStdString().c_str());
|
||||||
else
|
else
|
||||||
System::RemoveMedia();
|
System::RemoveMedia();
|
||||||
|
|
||||||
|
if (reset_system)
|
||||||
|
System::ResetSystem();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::changeDiscFromPlaylist(quint32 index)
|
void EmuThread::changeDiscFromPlaylist(quint32 index)
|
||||||
|
|
|
@ -168,10 +168,10 @@ public Q_SLOTS:
|
||||||
void stopFullscreenUI();
|
void stopFullscreenUI();
|
||||||
void bootSystem(std::shared_ptr<SystemBootParameters> params);
|
void bootSystem(std::shared_ptr<SystemBootParameters> params);
|
||||||
void resumeSystemFromMostRecentState();
|
void resumeSystemFromMostRecentState();
|
||||||
void shutdownSystem(bool save_state = true);
|
void shutdownSystem(bool save_state, bool check_memcard_busy);
|
||||||
void resetSystem();
|
void resetSystem(bool check_memcard_busy);
|
||||||
void setSystemPaused(bool paused, bool wait_until_paused = false);
|
void setSystemPaused(bool paused, bool wait_until_paused = false);
|
||||||
void changeDisc(const QString& new_disc_filename);
|
void changeDisc(const QString& new_disc_filename, bool reset_system, bool check_memcard_busy);
|
||||||
void changeDiscFromPlaylist(quint32 index);
|
void changeDiscFromPlaylist(quint32 index);
|
||||||
void loadState(const QString& filename);
|
void loadState(const QString& filename);
|
||||||
void loadState(bool global, qint32 slot);
|
void loadState(bool global, qint32 slot);
|
||||||
|
@ -218,6 +218,8 @@ private:
|
||||||
void createBackgroundControllerPollTimer();
|
void createBackgroundControllerPollTimer();
|
||||||
void destroyBackgroundControllerPollTimer();
|
void destroyBackgroundControllerPollTimer();
|
||||||
void setInitialState(std::optional<bool> override_fullscreen);
|
void setInitialState(std::optional<bool> override_fullscreen);
|
||||||
|
void confirmActionIfMemoryCardBusy(const QString& action, bool cancel_resume_on_accept,
|
||||||
|
std::function<void(bool)> callback) const;
|
||||||
|
|
||||||
QThread* m_ui_thread;
|
QThread* m_ui_thread;
|
||||||
QSemaphore m_started_semaphore;
|
QSemaphore m_started_semaphore;
|
||||||
|
|
Loading…
Reference in a new issue