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)
|
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
14
ppu.cpp
|
@ -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
1
ppu.h
|
@ -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);
|
||||||
|
|
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 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);
|
||||||
|
|
3
snes9x.h
3
snes9x.h
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue