Savestates: Use folders for organizing savestates per game.

This commit is contained in:
Christian Kenny 2021-09-08 18:26:56 -04:00 committed by refractionpcsx2
parent 161240045f
commit ae7b84a85f
12 changed files with 78 additions and 19 deletions

View File

@ -715,7 +715,7 @@ void __fastcall eeloadHook()
}
}
if (!g_GameStarted && (disctype == 2 || disctype == 1) && fromUTF8(elfname) == discelf)
if (!g_GameStarted && ((disctype == 2 && elfname == discelf.ToStdString()) || disctype == 1))
g_GameLoading = true;
}

View File

@ -73,16 +73,56 @@ static void PostLoadPrep()
// --------------------------------------------------------------------------------------
// SaveStateBase (implementations)
// --------------------------------------------------------------------------------------
wxString SaveStateBase::GetFilename( int slot )
wxString SaveStateBase::GetSavestateFolder( int slot, bool isSavingOrLoading )
{
wxString serialName( DiscSerial );
if (serialName.IsEmpty()) serialName = L"BIOS";
wxString CRCvalue = wxString::Format(wxT("%08X"), ElfCRC);
wxString serialName(DiscSerial);
return (EmuFolders::Savestates +
pxsFmt( L"%s (%08X).%02d.p2s", WX_STR(serialName), ElfCRC, slot )).GetFullPath();
if (g_GameStarted || g_GameLoading)
{
if (DiscSerial.IsEmpty())
{
std::string ElfString = LastELF.ToStdString();
std::string ElfString_delimiter = "/";
//return (g_Conf->Folders.Savestates +
// pxsFmt( L"%08X.%03d", ElfCRC, slot )).GetFullPath();
#ifndef _UNIX_
std::replace(ElfString.begin(), ElfString.end(), '\\', '/');
#endif
size_t pos = 0;
while ((pos = ElfString.find(ElfString_delimiter)) != std::string::npos)
{
// Running homebrew/standalone ELF, return only the ELF name.
ElfString.erase(0, pos + ElfString_delimiter.length());
}
wxString ElfString_toWxString(ElfString.c_str(), wxConvUTF8);
serialName = ElfString_toWxString;
}
else
{
// Running a normal retail game
// Folder format is "SLXX-XXXX - (00000000)"
serialName = DiscSerial;
}
}
else
{
// Still inside the BIOS/not running a game (why would anyone want to do this?)
wxString biosString = (pxsFmt(L"BIOS (%s v%u.%u)", WX_STR(biosZone), (BiosVersion >> 8), BiosVersion & 0xff));
serialName = biosString;
CRCvalue = L"None";
}
wxFileName dirname = wxFileName::DirName(g_Conf->FullpathToSaveState(serialName, CRCvalue));
if (isSavingOrLoading)
{
if (!wxDirExists(g_Conf->FullpathToSaveState(serialName, CRCvalue)))
{
wxMkdir(g_Conf->FullpathToSaveState(serialName, CRCvalue));
}
}
return (dirname.GetPath() + "/" +
pxsFmt( L"%s (%s).%02d.p2s", WX_STR(serialName), WX_STR(CRCvalue), slot ));
}
SaveStateBase::SaveStateBase( SafeArray<u8>& memblock )

View File

@ -31,7 +31,7 @@ enum class FreezeAction
// the lower 16 bit value. IF the change is breaking of all compatibility with old
// states, increment the upper 16 bit value, and clear the lower 16 bits to 0.
static const u32 g_SaveVersion = (0x9A28 << 16) | 0x0000;
static const u32 g_SaveVersion = (0x9A29 << 16) | 0x0000;
// the freezing data between submodules and core
// an interesting thing to note is that this dates back from before plugin
@ -74,7 +74,7 @@ public:
SaveStateBase( VmStateBuffer* memblock );
virtual ~SaveStateBase() { }
static wxString GetFilename( int slot );
static wxString GetSavestateFolder( int slot, bool isSavingOrLoading = false );
// Gets the version of savestate that this object is acting on.
// The version refers to the low 16 bits only (high 16 bits classifies Pcsx2 build types)
@ -349,3 +349,4 @@ namespace Exception
};
}; // namespace Exception
extern wxString GetSavestateFolder( int slot );

View File

@ -485,6 +485,12 @@ void AppConfig::FolderOptions::Set(FoldersEnum_t folderidx, const wxString& src,
}
}
wxString AppConfig::FullpathToSaveState(wxString serialName, wxString CRCvalue) const
{
wxString Sstate_append = serialName + " - " + "(" + CRCvalue + ")";
return Path::Combine(Folders.Savestates, Sstate_append);
}
bool IsPortable()
{
return InstallationMode == InstallMode_Portable;

View File

@ -294,7 +294,7 @@ public:
public:
AppConfig();
wxString FullpathToSaveState(wxString serialName, wxString CRCvalue) const;
void LoadSave(IniInterface& ini, SettingsWrapper& wrap);
void LoadSaveRootItems(IniInterface& ini);

View File

@ -460,6 +460,11 @@ static void _ApplySettings(const Pcsx2Config& src, Pcsx2Config& fixup)
gameCompat = L" [Status = " + compatToStringWX(game.compat) + L"]";
gameMemCardFilter = fromUTF8(game.memcardFiltersAsString());
}
else
{
// Set correct title for loading standalone/homebrew ELFs
GameInfo::gameName = LastELF.AfterLast('\\');
}
if (fixup.EnablePatches)
{

View File

@ -116,7 +116,7 @@ void States_DefrostCurrentSlotBackup()
void States_updateLoadBackupMenuItem()
{
wxString file = SaveStateBase::GetFilename(StatesC) + ".backup";
wxString file(SaveStateBase::GetSavestateFolder(StatesC) + ".backup");
sMainFrame.EnableMenuItem(MenuId_State_LoadBackup, wxFileExists(file));
sMainFrame.SetMenuItemLabel(MenuId_State_LoadBackup, wxsFormat(L"%s %d", _("Backup"), StatesC));

View File

@ -68,14 +68,14 @@ public:
bool isUsed()
{
return wxFileExists(SaveStateBase::GetFilename(slot_num));
return wxFileExists(SaveStateBase::GetSavestateFolder(slot_num, false));
}
wxDateTime GetTimestamp()
{
if (!isUsed()) return wxInvalidDateTime;
return wxDateTime(wxFileModificationTime(SaveStateBase::GetFilename(slot_num)));
return wxDateTime(wxFileModificationTime(SaveStateBase::GetSavestateFolder(slot_num, false)));
}
void UpdateCache()

View File

@ -33,6 +33,11 @@
#include "Patch.h"
// Required for savestate folder creation
#include "CDVD/CDVD.h"
#include "ps2/BiosTools.h"
#include "Elfheader.h"
// --------------------------------------------------------------------------------------
// SysExecEvent_DownloadState
// --------------------------------------------------------------------------------------
@ -176,12 +181,12 @@ void StateCopy_LoadFromFile(const wxString& file)
// the one in the memory save. :)
void StateCopy_SaveToSlot(uint num)
{
const wxString file(SaveStateBase::GetFilename(num));
const wxString file(SaveStateBase::GetSavestateFolder(num, true));
// Backup old Savestate if one exists.
if (wxFileExists(file) && EmuConfig.BackupSavestate)
{
const wxString copy(SaveStateBase::GetFilename(num) + pxsFmt(L".backup"));
const wxString copy(SaveStateBase::GetSavestateFolder(num, true) + pxsFmt(L".backup"));
Console.Indent().WriteLn(Color_StrongGreen, L"Backing up existing state in slot %d.", num);
wxRenameFile(file, copy);
@ -198,7 +203,7 @@ void StateCopy_SaveToSlot(uint num)
void StateCopy_LoadFromSlot(uint slot, bool isFromBackup)
{
wxString file(SaveStateBase::GetFilename(slot) + wxString(isFromBackup ? L".backup" : L""));
wxString file(SaveStateBase::GetSavestateFolder(slot, true) + wxString(isFromBackup ? L".backup" : L""));
if (!wxFileExists(file))
{

View File

@ -56,7 +56,8 @@ static void _SaveLoadStuff(bool enabled)
for (Saveslot &slot : saveslot_cache)
{
// We need to reload the file information if the crc or serial # changed.
if ((slot.crc != ElfCRC)|| (slot.serialName != DiscSerial))
// Invalidate slot cache when using full boot (g_GameLoading) otherwise it won't see the new folder path
if ((g_GameLoading || slot.crc != ElfCRC) || (slot.serialName != DiscSerial))
{
slot.invalid_cache = true;
crcChanged = true;

View File

@ -46,6 +46,7 @@ static_assert( sizeof(romdir) == DIRENTRY_SIZE, "romdir struct not packed to 16
u32 BiosVersion;
u32 BiosChecksum;
u32 BiosRegion;
wxString biosZone;
bool NoOSD;
bool AllowParams1;
bool AllowParams2;
@ -272,7 +273,6 @@ void LoadBIOS()
BiosChecksum = 0;
wxString biosZone;
wxFFile fp( Bios , "rb");
fp.Read( eeMem->ROM, std::min<s64>( Ps2MemSize::Rom, filesize ) );

View File

@ -48,5 +48,6 @@ extern bool AllowParams1;
extern bool AllowParams2;
extern u32 BiosChecksum;
extern wxString BiosDescription;
extern wxString biosZone;
extern void LoadBIOS();
extern bool IsBIOS(const wxString& filename, wxString& description);