diff --git a/src/core/achievements.cpp b/src/core/achievements.cpp index eff4390ad..090a2389d 100644 --- a/src/core/achievements.cpp +++ b/src/core/achievements.cpp @@ -2228,6 +2228,26 @@ bool Achievements::ConfirmSystemReset() return true; } +bool Achievements::ConfirmHardcoreModeDisable(const char* trigger) +{ +#ifdef ENABLE_RAINTEGRATION + if (IsUsingRAIntegration()) + return (RA_WarnDisableHardcore(trigger) != 0); +#endif + + // I really hope this doesn't deadlock :/ + const bool confirmed = Host::ConfirmMessage( + TRANSLATE("Achievements", "Confirm Hardcore Mode Disable"), + fmt::format(TRANSLATE_FS("Achievements", "{0} cannot be performed while hardcore mode is active. Do you " + "want to disable hardcore mode? {0} will be cancelled if you select No."), + trigger)); + if (!confirmed) + return false; + + DisableHardcoreMode(); + return true; +} + void Achievements::ConfirmHardcoreModeDisableAsync(const char* trigger, std::function callback) { auto real_callback = [callback = std::move(callback)](bool res) mutable { @@ -2249,7 +2269,7 @@ void Achievements::ConfirmHardcoreModeDisableAsync(const char* trigger, std::fun #endif Host::ConfirmMessageAsync( - TRANSLATE_STR("Achievements", "Confirm Hardcore Mode"), + TRANSLATE_STR("Achievements", "Confirm Hardcore Mode Disable"), fmt::format(TRANSLATE_FS("Achievements", "{0} cannot be performed while hardcore mode is active. Do you want to " "disable hardcore mode? {0} will be cancelled if you select No."), trigger), diff --git a/src/core/achievements.h b/src/core/achievements.h index 900d179be..e14928ff3 100644 --- a/src/core/achievements.h +++ b/src/core/achievements.h @@ -116,6 +116,7 @@ bool ResetHardcoreMode(bool is_booting); void DisableHardcoreMode(); /// Prompts the user to disable hardcore mode, if they agree, returns true. +bool ConfirmHardcoreModeDisable(const char* trigger); void ConfirmHardcoreModeDisableAsync(const char* trigger, std::function callback); /// Returns true if hardcore mode is active, and functionality should be restricted. diff --git a/src/core/system.cpp b/src/core/system.cpp index 5b639bb82..fb4728ab5 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1741,36 +1741,6 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error) return false; } - // Achievement hardcore checks before committing to anything. - if (!IsReplayingGPUDump()) - { - // Check for resuming with hardcore mode. - if (parameters.disable_achievements_hardcore_mode) - Achievements::DisableHardcoreMode(); - else - Achievements::ResetHardcoreMode(true); - - if ((!parameters.save_state.empty() || !exe_override.empty()) && Achievements::IsHardcoreModeActive()) - { - const bool is_exe_override_boot = parameters.save_state.empty(); - Achievements::ConfirmHardcoreModeDisableAsync( - is_exe_override_boot ? TRANSLATE("Achievements", "Overriding executable") : - TRANSLATE("Achievements", "Resuming state"), - [parameters = std::move(parameters)](bool approved) mutable { - if (approved) - { - Host::RunOnCPUThread([parameters = std::move(parameters)]() mutable { - parameters.disable_achievements_hardcore_mode = true; - BootSystem(std::move(parameters), nullptr); - }); - } - }); - - // Technically a failure, but user-initiated. Returning false here would try to display a non-existent error. - return true; - } - } - // Can't early cancel without destroying past this point. Assert(s_state.state == State::Shutdown); s_state.state = State::Starting; @@ -1800,6 +1770,49 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error) exe_override = std::move(parameters.override_exe); } + // Achievement hardcore checks before committing to anything. + if (disc) + { + // Check for resuming with hardcore mode. + if (parameters.disable_achievements_hardcore_mode) + Achievements::DisableHardcoreMode(); + else + Achievements::ResetHardcoreMode(true); + + if ((!parameters.save_state.empty() || !exe_override.empty()) && Achievements::IsHardcoreModeActive()) + { + const bool is_exe_override_boot = parameters.save_state.empty(); + bool cancelled; + if (FullscreenUI::IsInitialized()) + { + Achievements::ConfirmHardcoreModeDisableAsync(is_exe_override_boot ? + TRANSLATE("Achievements", "Overriding executable") : + TRANSLATE("Achievements", "Resuming state"), + [parameters = std::move(parameters)](bool approved) mutable { + if (approved) + { + parameters.disable_achievements_hardcore_mode = true; + BootSystem(std::move(parameters), nullptr); + } + }); + cancelled = true; + } + else + { + cancelled = !Achievements::ConfirmHardcoreModeDisable(is_exe_override_boot ? + TRANSLATE("Achievements", "Overriding executable") : + TRANSLATE("Achievements", "Resuming state")); + } + + if (cancelled) + { + // Technically a failure, but user-initiated. Returning false here would try to display a non-existent error. + DestroySystem(); + return true; + } + } + } + // Are we fast booting? Must be checked after updating game settings. if (boot_mode == BootMode::FullBoot && disc_region != DiscRegion::NonPS1 && parameters.override_fast_boot.value_or(static_cast(g_settings.bios_patch_fast_boot)))