Small save/load state speedup, noticeable only in TAS Editor or lua bots
This commit is contained in:
parent
d659fab541
commit
e1950ba025
|
@ -247,6 +247,11 @@ public:
|
||||||
|
|
||||||
virtual void fflush() {}
|
virtual void fflush() {}
|
||||||
|
|
||||||
|
void set_len(s32 length)
|
||||||
|
{
|
||||||
|
len = length;
|
||||||
|
if(pos>length) pos=length;
|
||||||
|
}
|
||||||
void trim()
|
void trim()
|
||||||
{
|
{
|
||||||
vec->resize(len);
|
vec->resize(len);
|
||||||
|
|
|
@ -82,6 +82,11 @@ bool internalSaveLoad = false;
|
||||||
bool backupSavestates = true;
|
bool backupSavestates = true;
|
||||||
bool compressSavestates = true; //By default FCEUX compresses savestates when a movie is inactive.
|
bool compressSavestates = true; //By default FCEUX compresses savestates when a movie is inactive.
|
||||||
|
|
||||||
|
// a temp memory stream. We'll be dumping some data here and then compress
|
||||||
|
EMUFILE_MEMORY memory_savestate;
|
||||||
|
// temporary buffer for compressed data of a savestate
|
||||||
|
std::vector<uint8> compressed_buf;
|
||||||
|
|
||||||
#define SFMDATA_SIZE (64)
|
#define SFMDATA_SIZE (64)
|
||||||
static SFORMAT SFMDATA[SFMDATA_SIZE];
|
static SFORMAT SFMDATA[SFMDATA_SIZE];
|
||||||
static int SFEXINDEX;
|
static int SFEXINDEX;
|
||||||
|
@ -355,11 +360,10 @@ extern int geniestage;
|
||||||
|
|
||||||
bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||||
{
|
{
|
||||||
//a temp memory stream. we'll dump some data here and then compress
|
// reset memory_savestate
|
||||||
//TODO - support dumping directly without compressing to save a buffer copy
|
memory_savestate.set_len(0);
|
||||||
|
|
||||||
EMUFILE_MEMORY ms;
|
EMUFILE* os = &memory_savestate;
|
||||||
EMUFILE* os = &ms;
|
|
||||||
|
|
||||||
uint32 totalsize = 0;
|
uint32 totalsize = 0;
|
||||||
|
|
||||||
|
@ -404,7 +408,7 @@ bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||||
if(SPreSave) SPostSave();
|
if(SPreSave) SPostSave();
|
||||||
|
|
||||||
//save the length of the file
|
//save the length of the file
|
||||||
int len = ms.size();
|
int len = memory_savestate.size();
|
||||||
|
|
||||||
//sanity check: len and totalsize should be the same
|
//sanity check: len and totalsize should be the same
|
||||||
if(len != totalsize)
|
if(len != totalsize)
|
||||||
|
@ -414,15 +418,16 @@ bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
int error = Z_OK;
|
int error = Z_OK;
|
||||||
uint8* cbuf = (uint8*)ms.buf();
|
uint8* cbuf = (uint8*)memory_savestate.buf();
|
||||||
uLongf comprlen = -1;
|
uLongf comprlen = -1;
|
||||||
if(compressionLevel != Z_NO_COMPRESSION && compressSavestates)
|
if(compressionLevel != Z_NO_COMPRESSION && compressSavestates)
|
||||||
{
|
{
|
||||||
//worst case compression.
|
// worst case compression: zlib says "0.1% larger than sourceLen plus 12 bytes"
|
||||||
//zlib says "0.1% larger than sourceLen plus 12 bytes"
|
|
||||||
comprlen = (len>>9)+12 + len;
|
comprlen = (len>>9)+12 + len;
|
||||||
cbuf = new uint8[comprlen];
|
if (compressed_buf.size() < comprlen) compressed_buf.resize(comprlen);
|
||||||
error = compress2(cbuf,&comprlen,(uint8*)ms.buf(),len,compressionLevel);
|
cbuf = &compressed_buf[0];
|
||||||
|
// do compression
|
||||||
|
error = compress2(cbuf, &comprlen, (uint8*)memory_savestate.buf(), len, compressionLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
//dump the header
|
//dump the header
|
||||||
|
@ -435,7 +440,6 @@ bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||||
outstream->fwrite((char*)header,16);
|
outstream->fwrite((char*)header,16);
|
||||||
outstream->fwrite((char*)cbuf,comprlen==-1?totalsize:comprlen);
|
outstream->fwrite((char*)cbuf,comprlen==-1?totalsize:comprlen);
|
||||||
|
|
||||||
if(cbuf != (uint8*)ms.buf()) delete[] cbuf;
|
|
||||||
return error == Z_OK;
|
return error == Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,30 +648,31 @@ bool FCEUSS_LoadFP(EMUFILE* is, ENUM_SSLOADPARAMS params)
|
||||||
int stateversion = FCEU_de32lsb(header + 8);
|
int stateversion = FCEU_de32lsb(header + 8);
|
||||||
int comprlen = FCEU_de32lsb(header + 12);
|
int comprlen = FCEU_de32lsb(header + 12);
|
||||||
|
|
||||||
std::vector<uint8> buf(totalsize);
|
// memory_savestate is global variable which already has its vector of bytes
|
||||||
|
if ((int)(memory_savestate.get_vec())->size() < totalsize)
|
||||||
|
(memory_savestate.get_vec())->resize(totalsize);
|
||||||
|
memory_savestate.set_len(totalsize);
|
||||||
|
memory_savestate.fseek(0, SEEK_SET);
|
||||||
|
|
||||||
//not compressed:
|
|
||||||
if(comprlen != -1)
|
if(comprlen != -1)
|
||||||
{
|
{
|
||||||
//load the compressed chunk and decompress
|
// the savestate is compressed: read from is to compressed_buf, then decompress from compressed_buf to memory_savestate.vec
|
||||||
std::vector<char> cbuf(comprlen);
|
if ((int)compressed_buf.size() < comprlen) compressed_buf.resize(comprlen);
|
||||||
is->fread((char*)&cbuf[0],comprlen);
|
is->fread(&compressed_buf[0], comprlen);
|
||||||
|
|
||||||
uLongf uncomprlen = totalsize;
|
uLongf uncomprlen = totalsize;
|
||||||
int error = uncompress((uint8*)&buf[0],&uncomprlen,(uint8*)&cbuf[0],comprlen);
|
int error = uncompress(memory_savestate.buf(), &uncomprlen, &compressed_buf[0], comprlen);
|
||||||
if(error != Z_OK || uncomprlen != totalsize)
|
if(error != Z_OK || uncomprlen != totalsize)
|
||||||
return false;
|
return false; // we dont need to restore the backup here because we havent messed with the emulator state yet
|
||||||
//we dont need to restore the backup here because we havent messed with the emulator state yet
|
} else
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
is->fread((char*)&buf[0],totalsize);
|
// the savestate is not compressed: just read from is to memory_savestate.vec
|
||||||
|
is->fread(memory_savestate.buf(), totalsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
FCEUMOV_PreLoad();
|
FCEUMOV_PreLoad();
|
||||||
|
|
||||||
EMUFILE_MEMORY mstemp(&buf);
|
bool x = (ReadStateChunks(&memory_savestate, totalsize) != 0);
|
||||||
bool x = ReadStateChunks(&mstemp,totalsize)!=0;
|
|
||||||
|
|
||||||
//mbg 5/24/08 - we don't support old states, so this shouldnt matter.
|
//mbg 5/24/08 - we don't support old states, so this shouldnt matter.
|
||||||
//if(read_sfcpuc && stateversion<9500)
|
//if(read_sfcpuc && stateversion<9500)
|
||||||
|
@ -677,14 +682,13 @@ bool FCEUSS_LoadFP(EMUFILE* is, ENUM_SSLOADPARAMS params)
|
||||||
{
|
{
|
||||||
GameStateRestore(stateversion);
|
GameStateRestore(stateversion);
|
||||||
}
|
}
|
||||||
if(x)
|
if (x)
|
||||||
{
|
{
|
||||||
FCEUPPU_LoadState(stateversion);
|
FCEUPPU_LoadState(stateversion);
|
||||||
FCEUSND_LoadState(stateversion);
|
FCEUSND_LoadState(stateversion);
|
||||||
x=FCEUMOV_PostLoad();
|
x=FCEUMOV_PostLoad();
|
||||||
}
|
} else if (backup)
|
||||||
|
{
|
||||||
if(!x && backup) {
|
|
||||||
msBackupSavestate.fseek(0,SEEK_SET);
|
msBackupSavestate.fseek(0,SEEK_SET);
|
||||||
FCEUSS_LoadFP(&msBackupSavestate,SSLOADPARAM_NOBACKUP);
|
FCEUSS_LoadFP(&msBackupSavestate,SSLOADPARAM_NOBACKUP);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue