System: Centralize pause checks

This commit is contained in:
Stenzek 2025-07-29 17:08:23 +10:00
parent fbca692629
commit f569448ea1
No known key found for this signature in database
5 changed files with 76 additions and 21 deletions

View File

@ -141,20 +141,6 @@ static void HotkeyToggleOSD()
#ifndef __ANDROID__
static bool CanPause()
{
const u32 frames_until_pause_allowed = Achievements::GetPauseThrottleFrames();
if (frames_until_pause_allowed == 0)
return true;
const float seconds = static_cast<float>(frames_until_pause_allowed) / System::GetVideoFrameRate();
Host::AddIconOSDMessage("PauseCooldown", ICON_FA_CLOCK,
TRANSLATE_PLURAL_STR("Hotkeys", "You cannot pause until another %n second(s) have passed.",
"", static_cast<int>(std::ceil(seconds))),
std::max(seconds, Host::OSD_QUICK_DURATION));
return false;
}
#define DEFINE_NON_ANDROID_HOTKEY(name, category, display_name, handler) \
DEFINE_HOTKEY(name, category, display_name, handler)
@ -168,25 +154,25 @@ BEGIN_HOTKEY_LIST(g_common_hotkeys)
DEFINE_NON_ANDROID_HOTKEY("OpenPauseMenu", TRANSLATE_NOOP("Hotkeys", "Interface"),
TRANSLATE_NOOP("Hotkeys", "Open Pause Menu"), [](s32 pressed) {
if (!pressed && CanPause())
if (!pressed && System::CanPauseSystem(true))
FullscreenUI::OpenPauseMenu();
})
DEFINE_NON_ANDROID_HOTKEY("OpenCheatsMenu", TRANSLATE_NOOP("Hotkeys", "Interface"),
TRANSLATE_NOOP("Hotkeys", "Open Cheat Settings"), [](s32 pressed) {
if (!pressed && CanPause())
if (!pressed && System::CanPauseSystem(true))
FullscreenUI::OpenCheatsMenu();
})
DEFINE_NON_ANDROID_HOTKEY("OpenAchievements", TRANSLATE_NOOP("Hotkeys", "Interface"),
TRANSLATE_NOOP("Hotkeys", "Open Achievement List"), [](s32 pressed) {
if (!pressed && CanPause())
if (!pressed && System::CanPauseSystem(true))
FullscreenUI::OpenAchievementsWindow();
})
DEFINE_NON_ANDROID_HOTKEY("OpenLeaderboards", TRANSLATE_NOOP("Hotkeys", "Interface"),
TRANSLATE_NOOP("Hotkeys", "Open Leaderboard List"), [](s32 pressed) {
if (!pressed && CanPause())
if (!pressed && System::CanPauseSystem(true))
FullscreenUI::OpenLeaderboardsWindow();
})
@ -198,7 +184,7 @@ DEFINE_NON_ANDROID_HOTKEY("Screenshot", TRANSLATE_NOOP("Hotkeys", "Interface"),
DEFINE_NON_ANDROID_HOTKEY("TogglePause", TRANSLATE_NOOP("Hotkeys", "Interface"),
TRANSLATE_NOOP("Hotkeys", "Toggle Pause"), [](s32 pressed) {
if (!pressed && CanPause())
if (!pressed && System::CanPauseSystem(true))
System::PauseSystem(!System::IsPaused());
})
@ -235,7 +221,7 @@ DEFINE_HOTKEY("ToggleTurbo", TRANSLATE_NOOP("Hotkeys", "System"), TRANSLATE_NOOP
DEFINE_NON_ANDROID_HOTKEY("PowerOff", TRANSLATE_NOOP("Hotkeys", "System"),
TRANSLATE_NOOP("Hotkeys", "Power Off System"), [](s32 pressed) {
if (!pressed && CanPause())
if (!pressed && System::CanPauseSystem(true))
Host::RequestSystemShutdown(true, g_settings.save_state_on_exit, true);
})

View File

@ -1632,6 +1632,24 @@ void System::PauseSystem(bool paused)
}
}
bool System::CanPauseSystem(bool display_message)
{
const u32 frames_until_pause_allowed = Achievements::GetPauseThrottleFrames();
if (frames_until_pause_allowed == 0)
return true;
if (display_message)
{
const float seconds = static_cast<float>(frames_until_pause_allowed) / System::GetVideoFrameRate();
Host::AddIconOSDMessage("PauseCooldown", ICON_FA_CLOCK,
TRANSLATE_PLURAL_STR("Hotkeys", "You cannot pause until another %n second(s) have passed.",
"", static_cast<int>(std::ceil(seconds))),
std::max(seconds, Host::OSD_QUICK_DURATION));
}
return false;
}
bool System::SaveResumeState(Error* error)
{
if (s_state.running_game_serial.empty())

View File

@ -260,6 +260,9 @@ bool BootSystem(SystemBootParameters parameters, Error* error);
void PauseSystem(bool paused);
void ResetSystem();
/// Returns true if the system can be paused, i.e. not subject to achievement restrictions.
bool CanPauseSystem(bool display_message);
/// Returns the maximum size of a save state, considering the current configuration.
size_t GetMaxSaveStateSize();

View File

@ -1338,6 +1338,35 @@ void MainWindow::onFullscreenUIStartedOrStopped(bool running)
m_ui.actionStartFullscreenUI2->setText(running ? tr("Exit Big Picture") : tr("Big Picture"));
}
void MainWindow::onPauseActionToggled(bool checked)
{
if (s_system_paused == checked)
return;
if (checked && s_achievements_hardcore_mode)
{
// Need to check restrictions.
Host::RunOnCPUThread([]() {
if (System::CanPauseSystem(true))
{
g_emu_thread->setSystemPaused(true);
}
else
{
// Restore action state.
Host::RunOnUIThread([]() {
QSignalBlocker sb(g_main_window->m_ui.actionPause);
g_main_window->m_ui.actionPause->setChecked(false);
});
}
});
}
else
{
g_emu_thread->setSystemPaused(checked);
}
}
void MainWindow::onRemoveDiscActionTriggered()
{
g_emu_thread->changeDisc(QString(), false, true);
@ -2274,7 +2303,7 @@ void MainWindow::connectSignals()
connect(m_ui.actionPowerOffWithoutSaving, &QAction::triggered, this,
[this]() { requestShutdown(false, false, false, true, false, false); });
connect(m_ui.actionReset, &QAction::triggered, this, []() { g_emu_thread->resetSystem(true); });
connect(m_ui.actionPause, &QAction::toggled, this, [](bool active) { g_emu_thread->setSystemPaused(active); });
connect(m_ui.actionPause, &QAction::toggled, this, &MainWindow::onPauseActionToggled);
connect(m_ui.actionScreenshot, &QAction::triggered, g_emu_thread, &EmuThread::saveScreenshot);
connect(m_ui.actionScanForNewGames, &QAction::triggered, this, &MainWindow::onScanForNewGamesTriggered);
connect(m_ui.actionRescanAllGames, &QAction::triggered, this, [this]() { refreshGameList(true); });
@ -2821,6 +2850,24 @@ void MainWindow::requestShutdown(bool allow_confirm, bool allow_save_to_state, b
// Only confirm on UI thread because we need to display a msgbox.
if (!m_is_closing && s_system_valid && allow_confirm && Host::GetBoolSettingValue("Main", "ConfirmPowerOff", true))
{
// Hardcore mode restrictions.
if (!s_system_paused && s_achievements_hardcore_mode && allow_confirm)
{
Host::RunOnCPUThread(
[allow_confirm, allow_save_to_state, save_state, check_safety, exit_fullscreen_ui, quit_afterwards]() {
if (!System::CanPauseSystem(true))
return;
Host::RunOnUIThread(
[allow_confirm, allow_save_to_state, save_state, check_safety, exit_fullscreen_ui, quit_afterwards]() {
g_main_window->requestShutdown(allow_confirm, allow_save_to_state, save_state, check_safety,
exit_fullscreen_ui, quit_afterwards);
});
});
return;
}
SystemLock lock(pauseAndLockSystem());
QMessageBox msgbox(lock.getDialogParent());

View File

@ -184,6 +184,7 @@ private Q_SLOTS:
void onCheatsActionTriggered();
void onCheatsMenuAboutToShow();
void onStartFullscreenUITriggered();
void onPauseActionToggled(bool checked);
void onFullscreenUIStartedOrStopped(bool running);
void onRemoveDiscActionTriggered();
void onScanForNewGamesTriggered();