summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXTra.KrazzY <XTra.KrazzY@gmail.com>2008-08-31 09:38:41 +0000
committerXTra.KrazzY <XTra.KrazzY@gmail.com>2008-08-31 09:38:41 +0000
commit2f0eb72ba13d870d4e877ddf1b7d564c91dca812 (patch)
tree25723f00312b770f0682973d9f9084b150ef8def
parenta9c6a59307acf2d387735a025d8891cd323172be (diff)
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
-rw-r--r--Source/Core/Core/Src/State.cpp111
1 files changed, 103 insertions, 8 deletions
diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp
index 35e6ca5d44..c32f617792 100644
--- a/Source/Core/Core/Src/State.cpp
+++ b/Source/Core/Core/Src/State.cpp
@@ -37,6 +37,8 @@ static int ev_Load;
static std::string cur_filename;
+static bool const bCompressed = false;
+
enum {
version = 1
};
@@ -61,6 +63,7 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
{
static const int chunkSize = 16384;
z_stream strm;
+ unsigned char outbuf[chunkSize] = {0}, inbuf[chunkSize] = {0};
FILE *f = fopen(cur_filename.c_str(), "wb");
if(f == NULL) {
@@ -77,7 +80,47 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
ptr = buffer;
p.SetMode(PointerWrap::MODE_WRITE);
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);
delete [] buffer;
@@ -88,21 +131,73 @@ void SaveStateCallback(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");
if (!f) {
Core::DisplayMessage("State not found", 2000);
return;
}
+
Jit64::ClearCache();
- fseek(f, 0, SEEK_END);
- int sz = ftell(f);
- fseek(f, 0, SEEK_SET);
- u8 *buffer = new u8[sz];
- int x;
- if (x=fread(buffer, 1, sz, f) != sz)
- PanicAlert("wtf? %d %d", x, sz);
+
+ u8 *buffer = NULL;
+
+ int sz;
+ fread(&sz, sizeof(int), 1, f);
+
+ 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);
+
u8 *ptr = buffer;
PointerWrap p(&ptr, PointerWrap::MODE_READ);
DoState(p);