mirror of https://github.com/snes9xgit/snes9x.git
libretro: add fast snapshot support
This commit is contained in:
parent
72686f0f76
commit
d2183af371
|
@ -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
14
ppu.cpp
|
@ -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
1
ppu.h
|
@ -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);
|
||||
|
|
135
snapshot.cpp
135
snapshot.cpp
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue