libretro: add fast snapshot support

This commit is contained in:
OV2 2018-08-07 18:36:43 +02:00
parent 72686f0f76
commit d2183af371
5 changed files with 150 additions and 17 deletions

View File

@ -1372,6 +1372,13 @@ size_t retro_serialize_size()
bool retro_serialize(void *data, size_t size) bool retro_serialize(void *data, size_t size)
{ {
int result = -1;
bool okay = false;
okay = environ_cb(RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE, &result);
if (okay)
{
Settings.FastSavestates = 0 != (result & 4);
}
if (S9xFreezeGameMem((uint8_t*)data,size) == FALSE) if (S9xFreezeGameMem((uint8_t*)data,size) == FALSE)
return false; return false;
@ -1380,6 +1387,13 @@ bool retro_serialize(void *data, size_t size)
bool retro_unserialize(const void* data, size_t size) bool retro_unserialize(const void* data, size_t size)
{ {
int result = -1;
bool okay = false;
okay = environ_cb(RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE, &result);
if (okay)
{
Settings.FastSavestates = 0 != (result & 4);
}
if (S9xUnfreezeGameMem((const uint8_t*)data,size) != SUCCESS) if (S9xUnfreezeGameMem((const uint8_t*)data,size) != SUCCESS)
return false; return false;

14
ppu.cpp
View File

@ -1937,6 +1937,20 @@ void S9xResetPPU (void)
PPU.M7byte = 0; PPU.M7byte = 0;
} }
void S9xResetPPUFast (void)
{
PPU.RecomputeClipWindows = TRUE;
IPPU.ColorsChanged = TRUE;
IPPU.OBJChanged = TRUE;
memset(IPPU.TileCached[TILE_2BIT], 0, MAX_2BIT_TILES);
memset(IPPU.TileCached[TILE_4BIT], 0, MAX_4BIT_TILES);
memset(IPPU.TileCached[TILE_8BIT], 0, MAX_8BIT_TILES);
memset(IPPU.TileCached[TILE_2BIT_EVEN], 0, MAX_2BIT_TILES);
memset(IPPU.TileCached[TILE_2BIT_ODD], 0, MAX_2BIT_TILES);
memset(IPPU.TileCached[TILE_4BIT_EVEN], 0, MAX_4BIT_TILES);
memset(IPPU.TileCached[TILE_4BIT_ODD], 0, MAX_4BIT_TILES);
}
void S9xSoftResetPPU (void) void S9xSoftResetPPU (void)
{ {
S9xControlsSoftReset(); S9xControlsSoftReset();

1
ppu.h
View File

@ -384,6 +384,7 @@ extern struct SPPU PPU;
extern struct InternalPPU IPPU; extern struct InternalPPU IPPU;
void S9xResetPPU (void); void S9xResetPPU (void);
void S9xResetPPUFast (void);
void S9xSoftResetPPU (void); void S9xSoftResetPPU (void);
void S9xSetPPU (uint8, uint16); void S9xSetPPU (uint8, uint16);
uint8 S9xGetPPU (uint16); uint8 S9xGetPPU (uint16);

View File

@ -1181,6 +1181,8 @@ static int UnfreezeStructCopy (STREAM, const char *, uint8 **, FreezeData *, int
static void UnfreezeStructFromCopy (void *, FreezeData *, int, uint8 *, int); static void UnfreezeStructFromCopy (void *, FreezeData *, int, uint8 *, int);
static void FreezeBlock (STREAM, const char *, uint8 *, int); static void FreezeBlock (STREAM, const char *, uint8 *, int);
static void FreezeStruct (STREAM, const char *, void *, FreezeData *, int); static void FreezeStruct (STREAM, const char *, void *, FreezeData *, int);
static bool CheckBlockName(STREAM stream, const char *name, int &len);
static void SkipBlockWithName(STREAM stream, const char *name);
void S9xResetSaveTimer (bool8 dontsave) void S9xResetSaveTimer (bool8 dontsave)
@ -1469,6 +1471,8 @@ void S9xFreezeToStream (STREAM stream)
int S9xUnfreezeFromStream (STREAM stream) int S9xUnfreezeFromStream (STREAM stream)
{ {
const bool8 fast = Settings.FastSavestates;
int result = SUCCESS; int result = SUCCESS;
int version, len; int version, len;
char buffer[PATH_MAX + 1]; char buffer[PATH_MAX + 1];
@ -1535,19 +1539,31 @@ int S9xUnfreezeFromStream (STREAM stream)
if (result != SUCCESS) if (result != SUCCESS)
break; break;
result = UnfreezeBlockCopy (stream, "VRA", &local_vram, 0x10000); if (fast)
result = UnfreezeBlock(stream, "VRA", Memory.VRAM, 0x10000);
else
result = UnfreezeBlockCopy(stream, "VRA", &local_vram, 0x10000);
if (result != SUCCESS) if (result != SUCCESS)
break; break;
result = UnfreezeBlockCopy (stream, "RAM", &local_ram, 0x20000); if (fast)
result = UnfreezeBlock(stream, "RAM", Memory.RAM, 0x20000);
else
result = UnfreezeBlockCopy(stream, "RAM", &local_ram, 0x20000);
if (result != SUCCESS) if (result != SUCCESS)
break; break;
result = UnfreezeBlockCopy (stream, "SRA", &local_sram, 0x20000); if (fast)
result = UnfreezeBlock(stream, "SRA", Memory.SRAM, 0x20000);
else
result = UnfreezeBlockCopy (stream, "SRA", &local_sram, 0x20000);
if (result != SUCCESS) if (result != SUCCESS)
break; break;
result = UnfreezeBlockCopy (stream, "FIL", &local_fillram, 0x8000); if (fast)
result = UnfreezeBlock(stream, "FIL", Memory.FillRAM, 0x8000);
else
result = UnfreezeBlockCopy(stream, "FIL", &local_fillram, 0x8000);
if (result != SUCCESS) if (result != SUCCESS)
break; break;
@ -1587,9 +1603,19 @@ int S9xUnfreezeFromStream (STREAM stream)
if (result != SUCCESS && Settings.DSP == 4) if (result != SUCCESS && Settings.DSP == 4)
break; break;
result = UnfreezeBlockCopy (stream, "CX4", &local_cx4_data, 8192); if (Settings.C4)
if (result != SUCCESS && Settings.C4) {
break; if (fast)
result = UnfreezeBlock(stream, "CX4", Memory.C4RAM, 8192);
else
result = UnfreezeBlockCopy(stream, "CX4", &local_cx4_data, 8192);
if (result != SUCCESS)
break;
}
else
{
SkipBlockWithName(stream, "CX4");
}
result = UnfreezeStructCopy(stream, "ST0", &local_st010, SnapST010, COUNT(SnapST010), version); result = UnfreezeStructCopy(stream, "ST0", &local_st010, SnapST010, COUNT(SnapST010), version);
if (result != SUCCESS && Settings.SETA == ST_010) if (result != SUCCESS && Settings.SETA == ST_010)
@ -1599,9 +1625,19 @@ int S9xUnfreezeFromStream (STREAM stream)
if (result != SUCCESS && Settings.OBC1) if (result != SUCCESS && Settings.OBC1)
break; break;
result = UnfreezeBlockCopy (stream, "OBM", &local_obc1_data, 8192); if (Settings.OBC1)
if (result != SUCCESS && Settings.OBC1) {
break; if (fast)
result = UnfreezeBlock(stream, "OBM", Memory.OBC1RAM, 8192);
else
result = UnfreezeBlockCopy(stream, "OBM", &local_obc1_data, 8192);
if (result != SUCCESS)
break;
}
else
{
SkipBlockWithName(stream, "OBM");
}
result = UnfreezeStructCopy(stream, "S71", &local_spc7110, SnapSPC7110Snap, COUNT(SnapSPC7110Snap), version); result = UnfreezeStructCopy(stream, "S71", &local_spc7110, SnapSPC7110Snap, COUNT(SnapSPC7110Snap), version);
if (result != SUCCESS && Settings.SPC7110) if (result != SUCCESS && Settings.SPC7110)
@ -1664,7 +1700,15 @@ int S9xUnfreezeFromStream (STREAM stream)
uint32 old_flags = CPU.Flags; uint32 old_flags = CPU.Flags;
uint32 sa1_old_flags = SA1.Flags; uint32 sa1_old_flags = SA1.Flags;
S9xReset(); if (fast)
{
S9xResetPPUFast();
}
else
{
//Do not call this if you have written directly to "Memory." arrays
S9xReset();
}
UnfreezeStructFromCopy(&CPU, SnapCPU, COUNT(SnapCPU), local_cpu, version); UnfreezeStructFromCopy(&CPU, SnapCPU, COUNT(SnapCPU), local_cpu, version);
@ -1675,13 +1719,17 @@ int S9xUnfreezeFromStream (STREAM stream)
struct SDMASnapshot dma_snap; struct SDMASnapshot dma_snap;
UnfreezeStructFromCopy(&dma_snap, SnapDMA, COUNT(SnapDMA), local_dma, version); UnfreezeStructFromCopy(&dma_snap, SnapDMA, COUNT(SnapDMA), local_dma, version);
memcpy(Memory.VRAM, local_vram, 0x10000); if (local_vram)
memcpy(Memory.VRAM, local_vram, 0x10000);
memcpy(Memory.RAM, local_ram, 0x20000); if (local_ram)
memcpy(Memory.RAM, local_ram, 0x20000);
memcpy(Memory.SRAM, local_sram, 0x20000); if (local_sram)
memcpy(Memory.SRAM, local_sram, 0x20000);
memcpy(Memory.FillRAM, local_fillram, 0x8000); if (local_fillram)
memcpy(Memory.FillRAM, local_fillram, 0x8000);
if(version < SNAPSHOT_VERSION_BAPU) { if(version < SNAPSHOT_VERSION_BAPU) {
printf("Using Blargg APU snapshot loading (snapshot version %d, current is %d)\n...", version, SNAPSHOT_VERSION); printf("Using Blargg APU snapshot loading (snapshot version %d, current is %d)\n...", version, SNAPSHOT_VERSION);
@ -2092,6 +2140,51 @@ static void FreezeBlock (STREAM stream, const char *name, uint8 *block, int size
WRITE_STREAM(block, size, stream); WRITE_STREAM(block, size, stream);
} }
static bool CheckBlockName(STREAM stream, const char *name, int &len)
{
char buffer[16];
len = 0;
long rewind = FIND_STREAM(stream);
size_t l = READ_STREAM(buffer, 11, stream);
buffer[l] = 0;
REVERT_STREAM(stream, FIND_STREAM(stream) - l, 0);
if (buffer[4] == '-')
{
len = (((unsigned char)buffer[6]) << 24)
| (((unsigned char)buffer[7]) << 16)
| (((unsigned char)buffer[8]) << 8)
| (((unsigned char)buffer[9]) << 0);
}
else
len = atoi(buffer + 4);
if (l != 11 || strncmp(buffer, name, 3) != 0 || buffer[3] != ':')
{
return false;
}
if (len <= 0)
{
return false;
}
return true;
}
static void SkipBlockWithName(STREAM stream, const char *name)
{
int len;
bool matchesName = CheckBlockName(stream, name, len);
if (matchesName)
{
long rewind = FIND_STREAM(stream);
rewind += len + 11;
REVERT_STREAM(stream, rewind, 0);
}
}
static int UnfreezeBlock (STREAM stream, const char *name, uint8 *block, int size) static int UnfreezeBlock (STREAM stream, const char *name, uint8 *block, int size)
{ {
char buffer[20]; char buffer[20];
@ -2130,7 +2223,10 @@ static int UnfreezeBlock (STREAM stream, const char *name, uint8 *block, int siz
len = size; len = size;
} }
memset(block, 0, size); if (!Settings.FastSavestates)
{
memset(block, 0, size);
}
if (READ_STREAM(block, len, stream) != (unsigned int) len) if (READ_STREAM(block, len, stream) != (unsigned int) len)
{ {
@ -2157,6 +2253,13 @@ static int UnfreezeBlockCopy (STREAM stream, const char *name, uint8 **block, in
{ {
int result; int result;
//check name first to avoid memory allocation
int blockLength;
if (!CheckBlockName(stream, name, blockLength))
{
return 0;
}
*block = new uint8[size]; *block = new uint8[size];
result = UnfreezeBlock(stream, name, *block, size); result = UnfreezeBlock(stream, name, *block, size);

View File

@ -476,7 +476,8 @@ struct SSettings
bool8 TakeScreenshot; bool8 TakeScreenshot;
int8 StretchScreenshots; int8 StretchScreenshots;
bool8 SnapshotScreenshots; bool8 SnapshotScreenshots;
char InitialSnapshotFilename[PATH_MAX + 1]; char InitialSnapshotFilename[PATH_MAX + 1];
bool8 FastSavestates;
bool8 ApplyCheats; bool8 ApplyCheats;
bool8 NoPatch; bool8 NoPatch;