mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-06 12:45:21 +02:00
Merge pull request #22236 from hrydgard/savestate-hardcore-race
Fix savestate loads slipping past hardcore mode during boot
This commit is contained in:
+25
-15
@@ -197,16 +197,16 @@ int g_screenshotFailures;
|
||||
}
|
||||
|
||||
void Enqueue(const SaveState::Operation &op) {
|
||||
if (!NetworkAllowSaveState()) {
|
||||
// These two both refuse the operation, and both say so - dropping it silently just
|
||||
// looks like the hotkey didn't work. Callers that ask the same questions themselves
|
||||
// return before getting here, so nothing shows a message twice.
|
||||
if (NetworkWarnUserIfOnlineAndCantSavestate()) {
|
||||
return;
|
||||
}
|
||||
if (Achievements::HardcoreModeActive()) {
|
||||
if (g_Config.bAchievementsSaveStateInHardcoreMode && ((op.type == SaveState::OperationType::Save))) {
|
||||
// We allow saving in hardcore mode if this setting is on.
|
||||
} else {
|
||||
// Operation not allowed
|
||||
return;
|
||||
}
|
||||
// Hardcore mode bans loading savestates outright, and saving too unless the user opted
|
||||
// back into that.
|
||||
if (Achievements::WarnUserIfHardcoreModeActive(op.type == OperationType::Save)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(mutex);
|
||||
@@ -218,7 +218,7 @@ int g_screenshotFailures;
|
||||
}
|
||||
|
||||
void Load(const Path &filename, int slot, Callback callback) {
|
||||
if (!NetworkAllowSaveState()) {
|
||||
if (NetworkWarnUserIfOnlineAndCantSavestate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ int g_screenshotFailures;
|
||||
}
|
||||
|
||||
void Save(const Path &filename, int slot, Callback callback) {
|
||||
if (!NetworkAllowSaveState()) {
|
||||
if (NetworkWarnUserIfOnlineAndCantSavestate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ int g_screenshotFailures;
|
||||
}
|
||||
|
||||
void LoadSlot(std::string_view gamePrefix, int slot, Callback callback) {
|
||||
if (!NetworkAllowSaveState()) {
|
||||
if (NetworkWarnUserIfOnlineAndCantSavestate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ int g_screenshotFailures;
|
||||
}
|
||||
|
||||
bool UndoLoad(std::string_view gamePrefix, Callback callback) {
|
||||
if (!NetworkAllowSaveState()) {
|
||||
if (NetworkWarnUserIfOnlineAndCantSavestate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -466,7 +466,7 @@ int g_screenshotFailures;
|
||||
}
|
||||
|
||||
void SaveSlot(std::string_view gamePrefix, int slot, Callback callback) {
|
||||
if (!NetworkAllowSaveState()) {
|
||||
if (NetworkWarnUserIfOnlineAndCantSavestate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -511,7 +511,7 @@ int g_screenshotFailures;
|
||||
}
|
||||
|
||||
bool UndoSaveSlot(std::string_view gamePrefix, int slot) {
|
||||
if (!NetworkAllowSaveState()) {
|
||||
if (NetworkWarnUserIfOnlineAndCantSavestate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -544,7 +544,7 @@ int g_screenshotFailures;
|
||||
}
|
||||
|
||||
bool UndoLastSave(std::string_view gamePrefix) {
|
||||
if (!NetworkAllowSaveState()) {
|
||||
if (NetworkWarnUserIfOnlineAndCantSavestate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -810,6 +810,16 @@ int g_screenshotFailures;
|
||||
SaveStart state;
|
||||
|
||||
for (const auto &op : operations) {
|
||||
// Re-check here, and not just in Enqueue: during boot, RetroAchievements is still
|
||||
// identifying the game asynchronously, and until it's done hardcore mode doesn't
|
||||
// read as active yet. An operation queued in that window (a hotkey press, --state,
|
||||
// auto-load) passed the check in Enqueue and would otherwise be applied here, after
|
||||
// identification has finished and hardcore mode has come up.
|
||||
if (Achievements::WarnUserIfHardcoreModeActive(op.type == OperationType::Save)) {
|
||||
WARN_LOG(Log::SaveState, "Dropping queued savestate operation - hardcore mode is active");
|
||||
continue;
|
||||
}
|
||||
|
||||
CChunkFileReader::Error result;
|
||||
Status callbackResult;
|
||||
std::string callbackMessage;
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "Core/ConfigValues.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "Core/RetroAchievements.h"
|
||||
#include "Core/CoreParameter.h"
|
||||
#include "Core/HLE/sceKernel.h" // GPI/GPO
|
||||
#include "Core/MIPS/MIPSTables.h"
|
||||
@@ -187,6 +188,10 @@ void DevMenuScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
});
|
||||
|
||||
items->Add(new Choice(dev->T("Toggle Freeze")))->OnClick.Add([](UI::EventParams &e) {
|
||||
// Freezing restores a savestate every frame, so it's not allowed in hardcore mode.
|
||||
if (Achievements::WarnUserIfHardcoreModeActive(false)) {
|
||||
return;
|
||||
}
|
||||
if (PSP_CoreParameter().frozen) {
|
||||
PSP_CoreParameter().frozen = false;
|
||||
} else {
|
||||
|
||||
+8
-2
@@ -1709,8 +1709,14 @@ ScreenRenderFlags EmuScreen::RunEmulation(bool skipBufferEffects) {
|
||||
gpu->BeginHostFrame(displayLayoutConfig);
|
||||
}
|
||||
|
||||
// Freeze-frame functionality (loads a savestate on every frame).
|
||||
if (PSP_CoreParameter().freezeNext) {
|
||||
// Freeze-frame functionality (loads a savestate on every frame). It's a savestate load
|
||||
// like any other, so it's banned in hardcore mode - and checked here rather than only
|
||||
// where it's toggled, since hardcore mode can come up after the fact, once the game
|
||||
// has been identified.
|
||||
if (Achievements::HardcoreModeActive()) {
|
||||
PSP_CoreParameter().freezeNext = false;
|
||||
PSP_CoreParameter().frozen = false;
|
||||
} else if (PSP_CoreParameter().freezeNext) {
|
||||
PSP_CoreParameter().frozen = true;
|
||||
PSP_CoreParameter().freezeNext = false;
|
||||
SaveState::SaveToRam(freezeState_);
|
||||
|
||||
Reference in New Issue
Block a user