Added compression support for save states. Decompression is still buggy so compression is off by default.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@401 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
XTra.KrazzY 2008-08-31 09:38:41 +00:00
parent a9c6a59307
commit 2f0eb72ba1
1 changed files with 103 additions and 8 deletions

View File

@ -37,6 +37,8 @@ static int ev_Load;
static std::string cur_filename; static std::string cur_filename;
static bool const bCompressed = false;
enum { enum {
version = 1 version = 1
}; };
@ -61,6 +63,7 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
{ {
static const int chunkSize = 16384; static const int chunkSize = 16384;
z_stream strm; z_stream strm;
unsigned char outbuf[chunkSize] = {0}, inbuf[chunkSize] = {0};
FILE *f = fopen(cur_filename.c_str(), "wb"); FILE *f = fopen(cur_filename.c_str(), "wb");
if(f == NULL) { if(f == NULL) {
@ -77,7 +80,47 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
ptr = buffer; ptr = buffer;
p.SetMode(PointerWrap::MODE_WRITE); p.SetMode(PointerWrap::MODE_WRITE);
DoState(p); DoState(p);
fwrite(buffer, sz, 1, f);
if(bCompressed)
fwrite(&sz, sizeof(int), 1, f);
else {
int zero = 0;
fwrite(&zero, sizeof(int), 1, f);
}
if(bCompressed) {
int chunks = sz / chunkSize, leftovers = sz % chunkSize;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
deflateInit(&strm, Z_BEST_SPEED);
for(int i = 0; i < chunks; i++) {
strm.avail_in = chunkSize;
memcpy(inbuf, buffer + i * chunkSize, chunkSize);
strm.next_in = inbuf;
memcpy(outbuf, buffer + i * chunkSize, chunkSize);
strm.avail_out = chunkSize;
strm.next_out = outbuf;
deflate(&strm, Z_NO_FLUSH);
fwrite(outbuf, 1, chunkSize - strm.avail_out, f);
}
strm.avail_in = leftovers;
memcpy(inbuf, buffer + chunks * chunkSize, leftovers);
strm.next_in = inbuf;
memcpy(outbuf, buffer + chunks * chunkSize, leftovers);
strm.avail_out = leftovers;
strm.next_out = outbuf;
deflate(&strm, Z_NO_FLUSH);
fwrite(outbuf, 1, leftovers - strm.avail_out, f);
(void)deflateEnd(&strm);
} else
fwrite(buffer, sz, 1, f);
fclose(f); fclose(f);
delete [] buffer; delete [] buffer;
@ -88,21 +131,73 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
void LoadStateCallback(u64 userdata, int cyclesLate) void LoadStateCallback(u64 userdata, int cyclesLate)
{ {
static const int chunkSize = 16384;
z_stream strm;
unsigned char outbuf[chunkSize] = {0}, inbuf[chunkSize] = {0};
bool bCompressedState;
FILE *f = fopen(cur_filename.c_str(), "rb"); FILE *f = fopen(cur_filename.c_str(), "rb");
if (!f) { if (!f) {
Core::DisplayMessage("State not found", 2000); Core::DisplayMessage("State not found", 2000);
return; return;
} }
Jit64::ClearCache(); Jit64::ClearCache();
fseek(f, 0, SEEK_END);
int sz = ftell(f); u8 *buffer = NULL;
fseek(f, 0, SEEK_SET);
u8 *buffer = new u8[sz]; int sz;
int x; fread(&sz, sizeof(int), 1, f);
if (x=fread(buffer, 1, sz, f) != sz)
PanicAlert("wtf? %d %d", x, sz); bCompressedState = (sz != 0);
if(bCompressedState) {
buffer = new u8[sz];
int ret;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
int cnt = 0;
do {
strm.avail_in = uInt(fread(inbuf, 1, chunkSize, f));
if (strm.avail_in == 0)
break;
strm.next_in = inbuf;
do {
strm.avail_out = chunkSize;
strm.next_out = outbuf;
ret = inflate(&strm, Z_NO_FLUSH);
int have = chunkSize - strm.avail_out;
memcpy(buffer + cnt, outbuf, have);
cnt += have;
} while (strm.avail_out == 0);
} while (ret != Z_STREAM_END);
(void)inflateEnd(&strm);
} else {
fseek(f, 0, SEEK_END);
sz = ftell(f) - sizeof(int);
fseek(f, sizeof(int), SEEK_SET);
buffer = new u8[sz];
int x;
if (x=fread(buffer, 1, sz, f) != sz)
PanicAlert("wtf? %d %d", x, sz);
}
fclose(f); fclose(f);
u8 *ptr = buffer; u8 *ptr = buffer;
PointerWrap p(&ptr, PointerWrap::MODE_READ); PointerWrap p(&ptr, PointerWrap::MODE_READ);
DoState(p); DoState(p);