From c95e695a3867319ef9cc4b09786a92621f1c91d5 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 19 Oct 2020 22:42:49 -0700 Subject: [PATCH] Io: Track initial free space for compat flag. This seems to be necessary for Assassin's Creed. See #12761. --- Core/Compatibility.cpp | 1 + Core/Compatibility.h | 1 + Core/HLE/sceIo.cpp | 3 +-- Core/HW/MemoryStick.cpp | 17 +++++++++++++++-- assets/compat.ini | 6 ++++++ 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index c607c0a07608..a965f1b06264 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -72,6 +72,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "ForceSoftwareRenderer", &flags_.ForceSoftwareRenderer); CheckSetting(iniFile, gameID, "DarkStalkersPresentHack", &flags_.DarkStalkersPresentHack); CheckSetting(iniFile, gameID, "ReportSmallMemstick", &flags_.ReportSmallMemstick); + CheckSetting(iniFile, gameID, "MemstickFixedFree", &flags_.MemstickFixedFree); CheckSetting(iniFile, gameID, "DateLimited", &flags_.DateLimited); } diff --git a/Core/Compatibility.h b/Core/Compatibility.h index 626d4f816c28..1d5dfa6372a7 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -70,6 +70,7 @@ struct CompatFlags { bool ForceSoftwareRenderer; bool DarkStalkersPresentHack; bool ReportSmallMemstick; + bool MemstickFixedFree; bool DateLimited; }; diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index a12ba039f928..43e0700b98ca 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -621,8 +621,6 @@ static void __IoVblank() { } void __IoInit() { - MemoryStick_Init(); - asyncNotifyEvent = CoreTiming::RegisterEvent("IoAsyncNotify", __IoAsyncNotify); syncNotifyEvent = CoreTiming::RegisterEvent("IoSyncNotify", __IoSyncNotify); @@ -663,6 +661,7 @@ void __IoInit() { __KernelRegisterWaitTypeFuncs(WAITTYPE_ASYNCIO, __IoAsyncBeginCallback, __IoAsyncEndCallback); + MemoryStick_Init(); lastMemStickState = MemoryStick_State(); lastMemStickFatState = MemoryStick_FatState(); __DisplayListenVblank(__IoVblank); diff --git a/Core/HW/MemoryStick.cpp b/Core/HW/MemoryStick.cpp index b944f1c4f698..444334a3e3d8 100644 --- a/Core/HW/MemoryStick.cpp +++ b/Core/HW/MemoryStick.cpp @@ -29,12 +29,13 @@ static MemStickState memStickState; static MemStickFatState memStickFatState; static bool memStickNeedsAssign = false; static u64 memStickInsertedAt = 0; +static uint64_t memstickInitialFree = 0; const u64 normalMemstickSize = 9ULL * 1024 * 1024 * 1024; const u64 smallMemstickSize = 1ULL * 1024 * 1024 * 1024; void MemoryStick_DoState(PointerWrap &p) { - auto s = p.Section("MemoryStick", 1, 4); + auto s = p.Section("MemoryStick", 1, 5); if (!s) return; @@ -47,6 +48,9 @@ void MemoryStick_DoState(PointerWrap &p) { u64 memStickSize = normalMemstickSize; Do(p, memStickSize); } + if (s >= 5) { + Do(p, memstickInitialFree); + } if (s >= 3) { Do(p, memStickNeedsAssign); @@ -72,18 +76,26 @@ u64 MemoryStick_SectorSize() { } u64 MemoryStick_FreeSpace() { + const CompatFlags &flags = PSP_CoreParameter().compat.flags(); u64 realFreeSpace = pspFileSystem.FreeSpace("ms0:/"); // Cap the memory stick size to avoid math errors when old games get sizes that were // not planned for back then (even though 2GB cards were available.) // We have a compat setting to make it even smaller for Harry Potter : Goblet of Fire, see #13266. - const u64 memStickSize = PSP_CoreParameter().compat.flags().ReportSmallMemstick ? smallMemstickSize : (u64)g_Config.iMemStickSizeGB * 1024 * 1024 * 1024; + const u64 memStickSize = flags.ReportSmallMemstick ? smallMemstickSize : (u64)g_Config.iMemStickSizeGB * 1024 * 1024 * 1024; // Assume the memory stick is only used to store savedata. u64 usedSpace = pspFileSystem.getDirSize("ms0:/PSP/SAVEDATA/"); u64 simulatedFreeSpace = 0; if (usedSpace < memStickSize) { simulatedFreeSpace = memStickSize - usedSpace; } + if (flags.MemstickFixedFree) { + // Assassin's Creed: Bloodlines fails to save if free space changes incorrectly during game. + realFreeSpace = 0; + if (usedSpace <= memstickInitialFree) { + realFreeSpace = memstickInitialFree - usedSpace; + } + } return std::min(simulatedFreeSpace, realFreeSpace); } @@ -119,4 +131,5 @@ void MemoryStick_Init() { } memStickNeedsAssign = false; + memstickInitialFree = pspFileSystem.FreeSpace("ms0:/") + pspFileSystem.getDirSize("ms0:/PSP/SAVEDATA/"); } diff --git a/assets/compat.ini b/assets/compat.ini index 13b91e253acd..1bda7f4fac54 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -784,6 +784,12 @@ ULJM05225 = true CPCS01043 = true ULUS10062 = true +[MemstickFixedFree] +ULJM05571 = true +ULES01367 = true +NPEH00029 = true +ULUS10455 = true + [DateLimited] # Car Jack Streets - issue #12698 NPUZ00043 = true