sstate: major redesign, remove split freeze{out,in}, remove gsfreezedata

This commit is contained in:
Gauvain 'GovanifY' Roussel-Tarbouriech 2021-06-15 17:54:24 +02:00 committed by Kojin
parent e90fbfe138
commit 44026aa899
20 changed files with 97 additions and 311 deletions

View File

@ -678,7 +678,7 @@ void GSkeyEvent(GSKeyEventData* e)
}
}
int GSfreeze(int mode, GSFreezeData* data)
int GSfreeze(int mode, freezeData* data)
{
try
{
@ -949,9 +949,9 @@ void GSReplay(char* lpszCmdLine, int renderer)
file->Read(&crc, 4);
GSsetGameCRC(crc, 0);
GSFreezeData fd;
freezeData fd;
file->Read(&fd.size, 4);
fd.data = new uint8[fd.size];
fd.data = new char[fd.size];
file->Read(fd.data, fd.size);
GSfreeze(FREEZE_LOAD, &fd);
@ -1861,44 +1861,3 @@ GSRendererType GSApp::GetCurrentRendererType() const
{
return m_current_renderer_type;
}
void GSDoFreezeOut(void* dest)
{
GSFreezeData fP = {0, (u8*)dest};
if (GSfreeze(FREEZE_SIZE, &fP) != 0)
return;
if (!fP.size)
return;
Console.Indent().WriteLn("Saving GS");
if (GSfreeze(FREEZE_SAVE, &fP) != 0)
throw std::runtime_error(" * GS: Error saving state!\n");
}
void GSDoFreezeIn(pxInputStream& infp)
{
GSFreezeData fP = {0, nullptr};
if (GSfreeze(FREEZE_SIZE, &fP) != 0)
fP.size = 0;
Console.Indent().WriteLn("Loading GS");
if (!infp.IsOk() || !infp.Length())
{
// no state data to read, but GS expects some state data?
// Issue a warning to console...
if (fP.size != 0)
Console.Indent().Warning("Warning: No data for GS found. Status may be unpredictable.");
return;
}
ScopedAlloc<s8> data(fP.size);
fP.data = (u8*)data.GetPtr();
infp.Read(fP.data, fP.size);
if (GSfreeze(FREEZE_LOAD, &fP) != 0)
throw std::runtime_error(" * GS: Error loading state!\n");
}

View File

@ -1783,12 +1783,6 @@ struct GSKeyEventData
uint32 key, type;
};
struct GSFreezeData
{
int size;
uint8* data;
};
// ST_WRITE is defined in libc, avoid this
enum stateType
{
@ -1872,7 +1866,7 @@ void GSgifTransfer3(uint8* mem, uint32 size);
void GSvsync(int field);
uint32 GSmakeSnapshot(char* path);
void GSkeyEvent(GSKeyEventData* e);
int GSfreeze(int mode, GSFreezeData* data);
int GSfreeze(int mode, freezeData* data);
void GSconfigure();
int GStest();
void GSirqCallback(void (*irq)());
@ -1967,7 +1961,3 @@ struct GSErrorGlVertexArrayTooSmall : GSError
extern GSApp theApp;
extern bool gsopen_done;
void GSDoFreezeOut(void* dest);
void GSDoFreezeIn(pxInputStream& infp);

View File

@ -31,7 +31,7 @@ GSDumpBase::~GSDumpBase()
fclose(m_gs);
}
void GSDumpBase::AddHeader(uint32 crc, const GSFreezeData& fd, const GSPrivRegSet* regs)
void GSDumpBase::AddHeader(uint32 crc, const freezeData& fd, const GSPrivRegSet* regs)
{
AppendRawData(&crc, 4);
AppendRawData(&fd.size, 4);
@ -91,7 +91,7 @@ void GSDumpBase::Write(const void* data, size_t size)
// GSDump implementation
//////////////////////////////////////////////////////////////////////
GSDump::GSDump(const std::string& fn, uint32 crc, const GSFreezeData& fd, const GSPrivRegSet* regs)
GSDump::GSDump(const std::string& fn, uint32 crc, const freezeData& fd, const GSPrivRegSet* regs)
: GSDumpBase(fn + ".gs")
{
AddHeader(crc, fd, regs);
@ -111,7 +111,7 @@ void GSDump::AppendRawData(uint8 c)
// GSDumpXz implementation
//////////////////////////////////////////////////////////////////////
GSDumpXz::GSDumpXz(const std::string& fn, uint32 crc, const GSFreezeData& fd, const GSPrivRegSet* regs)
GSDumpXz::GSDumpXz(const std::string& fn, uint32 crc, const freezeData& fd, const GSPrivRegSet* regs)
: GSDumpBase(fn + ".gs.xz")
{
m_strm = LZMA_STREAM_INIT;

View File

@ -45,7 +45,7 @@ class GSDumpBase
FILE* m_gs;
protected:
void AddHeader(uint32 crc, const GSFreezeData& fd, const GSPrivRegSet* regs);
void AddHeader(uint32 crc, const freezeData& fd, const GSPrivRegSet* regs);
void Write(const void* data, size_t size);
virtual void AppendRawData(const void* data, size_t size) = 0;
@ -66,7 +66,7 @@ class GSDump final : public GSDumpBase
void AppendRawData(uint8 c) final;
public:
GSDump(const std::string& fn, uint32 crc, const GSFreezeData& fd, const GSPrivRegSet* regs);
GSDump(const std::string& fn, uint32 crc, const freezeData& fd, const GSPrivRegSet* regs);
virtual ~GSDump() = default;
};
@ -82,6 +82,6 @@ class GSDumpXz final : public GSDumpBase
void AppendRawData(uint8 c);
public:
GSDumpXz(const std::string& fn, uint32 crc, const GSFreezeData& fd, const GSPrivRegSet* regs);
GSDumpXz(const std::string& fn, uint32 crc, const freezeData& fd, const GSPrivRegSet* regs);
virtual ~GSDumpXz();
};

View File

@ -2397,20 +2397,20 @@ void GSState::Transfer(const uint8* mem, uint32 size)
}
template <class T>
static void WriteState(uint8*& dst, T* src, size_t len = sizeof(T))
static void WriteState(char*& dst, T* src, size_t len = sizeof(T))
{
memcpy(dst, src, len);
dst += len;
}
template <class T>
static void ReadState(T* dst, uint8*& src, size_t len = sizeof(T))
static void ReadState(T* dst, char*& src, size_t len = sizeof(T))
{
memcpy(dst, src, len);
src += len;
}
int GSState::Freeze(GSFreezeData* fd, bool sizeonly)
int GSState::Freeze(freezeData* fd, bool sizeonly)
{
if (sizeonly)
{
@ -2425,7 +2425,7 @@ int GSState::Freeze(GSFreezeData* fd, bool sizeonly)
Flush();
uint8* data = fd->data;
char* data = fd->data;
WriteState(data, &m_version);
WriteState(data, &m_env.PRIM);
@ -2492,7 +2492,7 @@ int GSState::Freeze(GSFreezeData* fd, bool sizeonly)
return 0;
}
int GSState::Defrost(const GSFreezeData* fd)
int GSState::Defrost(const freezeData* fd)
{
if (!fd || !fd->data || fd->size == 0)
{
@ -2504,7 +2504,7 @@ int GSState::Defrost(const GSFreezeData* fd)
return -1;
}
uint8* data = fd->data;
char* data = fd->data;
int version;

View File

@ -266,8 +266,8 @@ public:
void WriteCSR(uint32 csr) { m_regs->CSR.u32[1] = csr; }
void ReadFIFO(uint8* mem, int size);
template<int index> void Transfer(const uint8* mem, uint32 size);
int Freeze(GSFreezeData* fd, bool sizeonly);
int Defrost(const GSFreezeData* fd);
int Freeze(freezeData* fd, bool sizeonly);
int Defrost(const freezeData* fd);
void GetLastTag(uint32* tag)
{
*tag = m_path3hack;

View File

@ -446,9 +446,9 @@ void GSRenderer::VSync(int field)
{
if (!m_dump && m_shift_key)
{
GSFreezeData fd = {0, nullptr};
freezeData fd = {0, nullptr};
Freeze(&fd, true);
fd.data = new uint8[fd.size];
fd.data = new char[fd.size];
Freeze(&fd, false);
if (m_control_key)

View File

@ -497,7 +497,7 @@ void SysMtgsThread::ExecuteTaskInThread()
{
MTGS_FreezeData* data = (MTGS_FreezeData*)tag.pointer;
int mode = tag.data[0];
data->retval = GSfreeze(mode, (GSFreezeData*)data->fdata);
data->retval = GSfreeze(mode, (freezeData*)data->fdata);
}
break;

View File

@ -290,44 +290,3 @@ void PADWriteEvent(keyEvent& evt)
g_ev_fifo.push(evt);
}
#endif
void PADDoFreezeOut(void* dest)
{
freezeData fP = {0, (s8*)dest};
if (PADfreeze(FREEZE_SIZE, &fP) != 0)
return;
if (!fP.size)
return;
Console.Indent().WriteLn("Saving PAD");
if (PADfreeze(FREEZE_SAVE, &fP) != 0)
throw std::runtime_error(" * PAD: Error saving state!\n");
}
void PADDoFreezeIn(pxInputStream& infp)
{
freezeData fP = {0, nullptr};
if (PADfreeze(FREEZE_SIZE, &fP) != 0)
fP.size = 0;
Console.Indent().WriteLn("Loading PAD");
if (!infp.IsOk() || !infp.Length())
{
// no state data to read, but PAD expects some state data?
// Issue a warning to console...
if (fP.size != 0)
Console.Indent().Warning("Warning: No data for PAD found. Status may be unpredictable.");
return;
}
ScopedAlloc<s8> data(fP.size);
fP.data = data.GetPtr();
infp.Read(fP.data, fP.size);
if (PADfreeze(FREEZE_LOAD, &fP) != 0)
throw std::runtime_error(" * PAD: Error loading state!\n");
}

View File

@ -144,8 +144,6 @@ u8 PADpoll(u8 value);
keyEvent* PADkeyEvent();
void PADupdate(int pad);
void PADconfigure();
void PADDoFreezeOut(void* dest);
void PADDoFreezeIn(pxInputStream& infp);
#if defined(__unix__)
void PADWriteEvent(keyEvent& evt);

View File

@ -1663,44 +1663,3 @@ s32 PADsetSlot(u8 port, u8 slot)
// return pads[port][slot].enabled | !slot;
return 1;
}
void PADDoFreezeOut(void* dest)
{
freezeData fP = {0, (s8*)dest};
if (PADfreeze(FREEZE_SIZE, &fP) != 0)
return;
if (!fP.size)
return;
Console.Indent().WriteLn("Saving PAD");
if (PADfreeze(FREEZE_SAVE, &fP) != 0)
throw std::runtime_error(" * PAD: Error saving state!\n");
}
void PADDoFreezeIn(pxInputStream& infp)
{
freezeData fP = {0, nullptr};
if (PADfreeze(FREEZE_SIZE, &fP) != 0)
fP.size = 0;
Console.Indent().WriteLn("Loading PAD");
if (!infp.IsOk() || !infp.Length())
{
// no state data to read, but PAD expects some state data?
// Issue a warning to console...
if (fP.size != 0)
Console.Indent().Warning("Warning: No data for PAD found. Status may be unpredictable.");
return;
}
ScopedAlloc<s8> data(fP.size);
fP.data = data.GetPtr();
infp.Read(fP.data, fP.size);
if (PADfreeze(FREEZE_LOAD, &fP) != 0)
throw std::runtime_error(" * PAD: Error loading state!\n");
}

View File

@ -56,5 +56,3 @@ void PADconfigure();
s32 PADfreeze(int mode, freezeData* data);
s32 PADsetSlot(u8 port, u8 slot);
void PADsetSettingsDir(const char* dir);
void PADDoFreezeOut(void* dest);
void PADDoFreezeIn(pxInputStream& infp);

View File

@ -576,48 +576,3 @@ s32 SPU2freeze(int mode, freezeData* data)
// technically unreachable, but kills a warning:
return 0;
}
void SPU2DoFreezeOut(void* dest)
{
ScopedLock lock(mtx_SPU2Status);
freezeData fP = {0, (s8*)dest};
if (SPU2freeze(FREEZE_SIZE, &fP) != 0)
return;
if (!fP.size)
return;
Console.Indent().WriteLn("Saving SPU2");
if (SPU2freeze(FREEZE_SAVE, &fP) != 0)
throw std::runtime_error(" * SPU2: Error saving state!\n");
}
void SPU2DoFreezeIn(pxInputStream& infp)
{
ScopedLock lock(mtx_SPU2Status);
freezeData fP = {0, nullptr};
if (SPU2freeze(FREEZE_SIZE, &fP) != 0)
fP.size = 0;
Console.Indent().WriteLn("Loading SPU2");
if (!infp.IsOk() || !infp.Length())
{
// no state data to read, but SPU2 expects some state data?
// Issue a warning to console...
if (fP.size != 0)
Console.Indent().Warning("Warning: No data for SPU2 found. Status may be unpredictable.");
return;
}
ScopedAlloc<s8> data(fP.size);
fP.data = data.GetPtr();
infp.Read(fP.data, fP.size);
if (SPU2freeze(FREEZE_LOAD, &fP) != 0)
throw std::runtime_error(" * SPU2: Error loading state!\n");
}

View File

@ -37,8 +37,6 @@ void SPU2endRecording();
void SPU2async(u32 cycles);
s32 SPU2freeze(int mode, freezeData* data);
void SPU2DoFreezeIn(pxInputStream& infp);
void SPU2DoFreezeOut(void* dest);
void SPU2configure();

View File

@ -494,7 +494,6 @@ s32 USBfreeze(int mode, freezeData* data)
}
}
}
}
//TODO straight copying of structs can break cross-platform/cross-compiler save states 'cause padding 'n' stuff
else if (mode == FREEZE_SAVE)
@ -629,45 +628,3 @@ s64 get_clock()
{
return clocks;
}
void USBDoFreezeOut(void* dest)
{
freezeData fP = {0, (s8*)dest};
if (USBfreeze(FREEZE_SIZE, &fP) != 0)
return;
if (!fP.size)
return;
Console.Indent().WriteLn("Saving USB");
if (USBfreeze(FREEZE_SAVE, &fP) != 0)
throw std::runtime_error(" * USB: Error saving state!\n");
}
void USBDoFreezeIn(pxInputStream& infp)
{
freezeData fP = {(int)infp.Length(), nullptr};
//if (USBfreeze(FREEZE_SIZE, &fP) != 0)
// fP.size = 0;
Console.Indent().WriteLn("Loading USB");
if (!infp.IsOk() || !infp.Length())
{
// no state data to read, but USB expects some state data?
// Issue a warning to console...
if (fP.size != 0)
Console.Indent().Warning("Warning: No data for USB found. Status may be unpredictable.");
return;
}
ScopedAlloc<s8> data(fP.size);
fP.data = data.GetPtr();
infp.Read(fP.data, fP.size);
//if (USBfreeze(FREEZE_LOAD, &fP) != 0)
// throw std::runtime_error(" * USB: Error loading state!\n");
USBfreeze(FREEZE_LOAD, &fP);
}

View File

@ -48,10 +48,6 @@ void USBwrite8(u32 addr, u8 value);
void USBwrite16(u32 addr, u16 value);
void USBwrite32(u32 addr, u32 value);
void USBDoFreezeOut(void* dest);
void USBDoFreezeIn(pxInputStream& infp);
void USBsetRAM(void* mem);
extern FILE* usbLog;

View File

@ -36,10 +36,6 @@ void USBwrite8(u32 addr, u8 value) {}
void USBwrite16(u32 addr, u16 value) {}
void USBwrite32(u32 addr, u32 value) {}
void USBDoFreezeOut(void* dest) {}
void USBDoFreezeIn(pxInputStream& infp) {}
void USBsetRAM(void* mem) { ram = static_cast<u8*>(mem); }
FILE* usbLog = nullptr;

View File

@ -729,7 +729,7 @@ void Dialogs::GSDumpDialog::GSThread::ExecuteTaskInThread()
m_dump_file->Read(state_data.get(), ss);
m_dump_file->Read(&regs, 8192);
GSFreezeData fd = {(int)ss, (u8*)state_data.get()};
freezeData fd = {(int)ss, (s8*)state_data.get()};
m_root_window->m_dump_packets.clear();
while (m_dump_file->Tell() < m_dump_file->Length())

View File

@ -402,9 +402,9 @@ namespace Implementations
{
ScopedCoreThreadPause paused_core;
std::unique_ptr<VmStateBuffer> plugstore;
GSFreezeData fP = {0, NULL};
freezeData fP = {0, NULL};
GSfreeze(FREEZE_SIZE, &fP);
u8* data = new u8[fP.size];
char* data = new char[fP.size];
fP.data = data;
if (CoreThread.HasActiveMachine())
{

View File

@ -45,6 +45,70 @@ static const wxChar* EntryFilename_StateVersion = L"PCSX2 Savestate Version.id";
static const wxChar* EntryFilename_Screenshot = L"Screenshot.jpg";
static const wxChar* EntryFilename_InternalStructures = L"PCSX2 Internal Structures.dat";
enum SysState_Component : unsigned char
{
SPU2 = 0,
PAD = 1,
USB = 2,
GS = 3,
};
typedef int (*SysState_FreezeFunction)(int, freezeData*);
static const SysState_FreezeFunction SysState_ComponentFreeze[] = {SPU2freeze, PADfreeze, USBfreeze, GSfreeze};
static const char* SysState_ComponentName[] = {"SPU2", "PAD", "USB", "GS"};
void SysState_ComponentFreezeOutRoot(void* dest, SysState_Component comp)
{
freezeData fP = {0, (char*)dest};
if (SysState_ComponentFreeze[comp](FREEZE_SIZE, &fP) != 0)
return;
if (!fP.size)
return;
Console.Indent().WriteLn("Saving %s", SysState_ComponentName[comp]);
if (SysState_ComponentFreeze[comp](FREEZE_SAVE, &fP) != 0)
throw std::runtime_error(std::string(" * ") + SysState_ComponentName[comp] + std::string(": Error saving state!\n"));
}
void SysState_ComponentFreezeIn(pxInputStream& infp, SysState_Component comp)
{
freezeData fP = {0, nullptr};
if (SysState_ComponentFreeze[comp](FREEZE_SIZE, &fP) != 0)
fP.size = 0;
Console.Indent().WriteLn("Loading %s", SysState_ComponentName[comp]);
if (!infp.IsOk() || !infp.Length())
{
// no state data to read, but component expects some state data?
// Issue a warning to console...
if (fP.size != 0)
Console.Indent().Warning("Warning: No data for %s found. Status may be unpredictable.", SysState_ComponentName[comp]);
return;
}
ScopedAlloc<s8> data(fP.size);
fP.data = data.GetPtr();
infp.Read(fP.data, fP.size);
if (SysState_ComponentFreeze[comp](FREEZE_LOAD, &fP) != 0)
throw std::runtime_error(std::string(" * ") + SysState_ComponentName[comp] + std::string(": Error loading state!\n"));
}
void SysState_ComponentFreezeOut(SaveStateBase& writer, SysState_Component comp)
{
freezeData fP = {0, NULL};
if (SysState_ComponentFreeze[comp](FREEZE_SIZE, &fP) == 0)
{
const int size = fP.size;
writer.PrepBlock(size);
SysState_ComponentFreezeOutRoot(writer.GetBlockPtr(), comp);
writer.CommitBlock(size);
}
return;
}
// --------------------------------------------------------------------------------------
// BaseSavestateEntry
@ -210,19 +274,8 @@ public:
virtual ~SavestateEntry_SPU2() = default;
wxString GetFilename() const { return L"SPU2.bin"; }
void FreezeIn(pxInputStream& reader) const { return SPU2DoFreezeIn(reader); }
void FreezeOut(SaveStateBase& writer) const
{
freezeData fP = {0, NULL};
if (SPU2freeze(FREEZE_SIZE, &fP) == 0)
{
const int size = fP.size;
writer.PrepBlock(size);
SPU2DoFreezeOut(writer.GetBlockPtr());
writer.CommitBlock(size);
}
return;
}
void FreezeIn(pxInputStream& reader) const { return SysState_ComponentFreezeIn(reader, SPU2); }
void FreezeOut(SaveStateBase& writer) const { return SysState_ComponentFreezeOut(writer, SPU2); }
bool IsRequired() const { return true; }
};
@ -232,19 +285,8 @@ public:
virtual ~SavestateEntry_USB() = default;
wxString GetFilename() const { return L"USB.bin"; }
void FreezeIn(pxInputStream& reader) const { return USBDoFreezeIn(reader); }
void FreezeOut(SaveStateBase& writer) const
{
freezeData fP = {0, NULL};
if (USBfreeze(FREEZE_SIZE, &fP) == 0)
{
const int size = fP.size;
writer.PrepBlock(size);
USBDoFreezeOut(writer.GetBlockPtr());
writer.CommitBlock(size);
}
return;
}
void FreezeIn(pxInputStream& reader) const { return SysState_ComponentFreezeIn(reader, USB); }
void FreezeOut(SaveStateBase& writer) const { return SysState_ComponentFreezeOut(writer, USB); }
bool IsRequired() const { return true; }
};
@ -254,19 +296,8 @@ public:
virtual ~SavestateEntry_PAD() = default;
wxString GetFilename() const { return L"PAD.bin"; }
void FreezeIn(pxInputStream& reader) const { return PADDoFreezeIn(reader); }
void FreezeOut(SaveStateBase& writer) const
{
freezeData fP = {0, NULL};
if (PADfreeze(FREEZE_SIZE, &fP) == 0)
{
const int size = fP.size;
writer.PrepBlock(size);
PADDoFreezeOut(writer.GetBlockPtr());
writer.CommitBlock(size);
}
return;
}
void FreezeIn(pxInputStream& reader) const { return SysState_ComponentFreezeIn(reader, PAD); }
void FreezeOut(SaveStateBase& writer) const { return SysState_ComponentFreezeOut(writer, PAD); }
bool IsRequired() const { return true; }
};
@ -276,19 +307,8 @@ public:
virtual ~SavestateEntry_GS() = default;
wxString GetFilename() const { return L"GS.bin"; }
void FreezeIn(pxInputStream& reader) const { return GSDoFreezeIn(reader); }
void FreezeOut(SaveStateBase& writer) const
{
GSFreezeData fP = {0, NULL};
if (GSfreeze(FREEZE_SIZE, &fP) == 0)
{
const int size = fP.size;
writer.PrepBlock(size);
GSDoFreezeOut(writer.GetBlockPtr());
writer.CommitBlock(size);
}
return;
}
void FreezeIn(pxInputStream& reader) const { return SysState_ComponentFreezeIn(reader, GS); }
void FreezeOut(SaveStateBase& writer) const { return SysState_ComponentFreezeOut(writer, GS); }
bool IsRequired() const { return true; }
};
@ -744,3 +764,4 @@ void StateCopy_LoadFromSlot(uint slot, bool isFromBackup)
UI_UpdateSysControls();
#endif
}