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)
{
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)
return false;
@ -1380,6 +1387,13 @@ bool retro_serialize(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)
return false;

14
ppu.cpp
View File

@ -1937,6 +1937,20 @@ void S9xResetPPU (void)
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)
{
S9xControlsSoftReset();

1
ppu.h
View File

@ -384,6 +384,7 @@ extern struct SPPU PPU;
extern struct InternalPPU IPPU;
void S9xResetPPU (void);
void S9xResetPPUFast (void);
void S9xSoftResetPPU (void);
void S9xSetPPU (uint8, 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 FreezeBlock (STREAM, const char *, uint8 *, 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)
@ -1469,6 +1471,8 @@ void S9xFreezeToStream (STREAM stream)
int S9xUnfreezeFromStream (STREAM stream)
{
const bool8 fast = Settings.FastSavestates;
int result = SUCCESS;
int version, len;
char buffer[PATH_MAX + 1];
@ -1535,19 +1539,31 @@ int S9xUnfreezeFromStream (STREAM stream)
if (result != SUCCESS)
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)
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)
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)
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)
break;
@ -1587,9 +1603,19 @@ int S9xUnfreezeFromStream (STREAM stream)
if (result != SUCCESS && Settings.DSP == 4)
break;
result = UnfreezeBlockCopy (stream, "CX4", &local_cx4_data, 8192);
if (result != SUCCESS && Settings.C4)
break;
if (Settings.C4)
{
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);
if (result != SUCCESS && Settings.SETA == ST_010)
@ -1599,9 +1625,19 @@ int S9xUnfreezeFromStream (STREAM stream)
if (result != SUCCESS && Settings.OBC1)
break;
result = UnfreezeBlockCopy (stream, "OBM", &local_obc1_data, 8192);
if (result != SUCCESS && Settings.OBC1)
break;
if (Settings.OBC1)
{
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);
if (result != SUCCESS && Settings.SPC7110)
@ -1664,7 +1700,15 @@ int S9xUnfreezeFromStream (STREAM stream)
uint32 old_flags = CPU.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);
@ -1675,13 +1719,17 @@ int S9xUnfreezeFromStream (STREAM stream)
struct SDMASnapshot dma_snap;
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) {
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);
}
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)
{
char buffer[20];
@ -2130,7 +2223,10 @@ static int UnfreezeBlock (STREAM stream, const char *name, uint8 *block, int siz
len = size;
}
memset(block, 0, size);
if (!Settings.FastSavestates)
{
memset(block, 0, size);
}
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;
//check name first to avoid memory allocation
int blockLength;
if (!CheckBlockName(stream, name, blockLength))
{
return 0;
}
*block = new uint8[size];
result = UnfreezeBlock(stream, name, *block, size);

View File

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