From 6bb71834d3761ae682269955ed751f22f9225c53 Mon Sep 17 00:00:00 2001 From: dborth Date: Wed, 2 Dec 2009 22:26:44 +0000 Subject: [PATCH] changes for save states. although there's still save corruption :( --- source/ngc/vbasupport.cpp | 37 +- source/vba/System.h | 2 +- source/vba/Util.cpp | 2 +- source/vba/common/memgzio.c | 800 +++++++++++++++++------------------- source/vba/common/memgzio.h | 31 +- source/vba/gb/GB.cpp | 29 +- source/vba/gb/gb.h | 2 +- source/vba/gba/GBA.cpp | 29 +- source/vba/gba/GBA.h | 2 +- 9 files changed, 417 insertions(+), 517 deletions(-) diff --git a/source/ngc/vbasupport.cpp b/source/ngc/vbasupport.cpp index a028e3e..9fd7eb3 100644 --- a/source/ngc/vbasupport.cpp +++ b/source/ngc/vbasupport.cpp @@ -394,42 +394,7 @@ bool SaveBatteryOrState(char * filepath, int action, bool silent) } else { - bool written = emulator.emuWriteMemState((char *)savebuffer, SAVEBUFFERSIZE); - // we need to set datasize to the exact memory size written - // but emuWriteMemState doesn't return that for us - // so instead we'll find the end of the save the old fashioned way - if(written) - { - datasize = (1024*192); // we'll start at 192K - no save should be larger - char check = savebuffer[datasize]; - while(check == 0) - { - datasize -= 16384; - check = savebuffer[datasize]; - } - datasize += 16384; - check = savebuffer[datasize]; - while(check == 0) - { - datasize -= 1024; - check = savebuffer[datasize]; - } - datasize += 1024; - check = savebuffer[datasize]; - while(check == 0) - { - datasize -= 64; - check = savebuffer[datasize]; - } - datasize += 64; - check = savebuffer[datasize]; - while(check == 0) - { - datasize -= 1; - check = savebuffer[datasize]; - } - datasize += 2; // include last byte AND a null byte - } + datasize = emulator.emuWriteMemState((char *)savebuffer, SAVEBUFFERSIZE); } // write savebuffer into file diff --git a/source/vba/System.h b/source/vba/System.h index 733e3d0..1490c80 100644 --- a/source/vba/System.h +++ b/source/vba/System.h @@ -25,7 +25,7 @@ struct EmulatedSystem { // load memory state (rewind) bool (*emuReadMemState)(char *, int); // write memory state (rewind) - bool (*emuWriteMemState)(char *, int); + int (*emuWriteMemState)(char *, int); // write PNG file bool (*emuWritePNG)(const char *); // write BMP file diff --git a/source/vba/Util.cpp b/source/vba/Util.cpp index 1f1a8b6..4f3d1df 100644 --- a/source/vba/Util.cpp +++ b/source/vba/Util.cpp @@ -163,7 +163,7 @@ void utilWriteData(gzFile gzFile, variable_desc *data) gzFile utilGzOpen(const char *file, const char *mode) { - utilGzWriteFunc = (int (*)(void *,void * const, unsigned int))gzwrite; + utilGzWriteFunc = (int (ZEXPORT *)(void *,void * const, unsigned int))gzwrite; utilGzReadFunc = gzread; utilGzCloseFunc = gzclose; utilGzSeekFunc = gzseek; diff --git a/source/vba/common/memgzio.c b/source/vba/common/memgzio.c index f81874a..cb38cb8 100644 --- a/source/vba/common/memgzio.c +++ b/source/vba/common/memgzio.c @@ -9,15 +9,33 @@ * Adapted from original gzio.c from zlib library by Forgotten */ -/* @(#) $Id: memgzio.c,v 1.3 2004/01/17 23:07:32 kxu Exp $ */ +/* @(#) $Id: memgzio.c,v 1.5 2006/06/06 21:04:20 spacy51 Exp $ */ #include #include #include #include #include + #include "memgzio.h" +#ifndef local +#define local static +#endif + +#ifndef DEF_MEM_LEVEL +# define DEF_MEM_LEVEL 8 +#endif + +#ifndef OS_CODE +#define OS_CODE 3 +#endif + +#ifndef zmemcpy +#define zmemcpy memcpy +#endif + + /*struct internal_state {int dummy;};*/ /* for buggy compilers */ #ifndef Z_BUFSIZE @@ -44,18 +62,15 @@ static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define RESERVED 0xE0 /* bits 5..7: reserved */ -typedef struct _MemFile - { - char *memory; - char *next; - int available; - int error; - char mode; - } -MEMFILE; +typedef struct _MemFile { + char *memory; + char *next; + int available; + int error; + char mode; +} MEMFILE; -typedef struct mem_stream - { +typedef struct mem_stream { z_stream stream; int z_err; /* error code for last stream operation */ int z_eof; /* set if end of input file */ @@ -67,8 +82,7 @@ typedef struct mem_stream int transparent; /* 1 if input file is not a .gz file */ char mode; /* 'w' or 'r' */ long startpos; /* start of compressed data in file (header skipped) */ - } -mem_stream; +} mem_stream; local gzFile gz_open OF((char *memory, const int available, const char *mode)); @@ -95,27 +109,23 @@ local MEMFILE *memOpen(char *memory, int available, char mode) f->mode = mode; f->error = 0; - if(mode == 'w') - { - f->available = available - 8; - f->next = memory + 8; - memory[0] = 'V'; - memory[1] = 'B'; - memory[2] = 'A'; - memory[3] = ' '; - *((int *)(memory+4)) = 0; - } - else - { - if(memory[0] != 'V' || memory[1] != 'B' || memory[2] != 'A' || - memory[3] != ' ') - { - free(f); - return NULL; - } - f->available = *((int *)(memory+4)); - f->next = memory+8; + if(mode == 'w') { + f->available = available - 8; + f->next = memory + 8; + memory[0] = 'V'; + memory[1] = 'B'; + memory[2] = 'A'; + memory[3] = ' '; + *((int *)(memory+4)) = 0; + } else { + if(memory[0] != 'V' || memory[1] != 'B' || memory[2] != 'A' || + memory[3] != ' ') { + free(f); + return NULL; } + f->available = *((int *)(memory+4)); + f->next = memory+8; + } return f; } @@ -125,18 +135,16 @@ local size_t memWrite(const void *buffer, size_t size, size_t count, { size_t total = size*count; - if(file->mode != 'w') - { - file->error = 1; - return 0; - } + if(file->mode != 'w') { + file->error = 1; + return 0; + } - if(total > (size_t)file->available) - { - total = file->available; - } + if(total > (size_t)file->available) { + total = file->available; + } memcpy(file->next, buffer, total); - file->available -= total; + file->available -= (int)total; file->next += total; return total; } @@ -146,39 +154,34 @@ local size_t memRead(void *buffer, size_t size, size_t count, { size_t total = size*count; - if(file->mode != 'r') - { - file->error = 1; - return 0; - } + if(file->mode != 'r') { + file->error = 1; + return 0; + } if(file->available == 0) return -1; - if(total > (size_t)file->available) - { - total = file->available; - } + if(total > (size_t)file->available) { + total = file->available; + } memcpy(buffer, file->next, total); - file->available -= total; + file->available -= (int)total; file->next += total; return total; } local int memPutc(int c, MEMFILE *file) { - if(file->mode != 'w') - { - file->error = 1; - return -1; - } + if(file->mode != 'w') { + file->error = 1; + return -1; + } - if(file->available >= 1) - { - *file->next++ = c; - file->available--; - } - else + if(file->available >= 1) { + *file->next++ = c; + file->available--; + } else return -1; return c; @@ -186,7 +189,7 @@ local int memPutc(int c, MEMFILE *file) local long memTell(MEMFILE *f) { - return (f->next - f->memory) - 8; + return (long)(f->next - f->memory) - 8; } local int memError(MEMFILE *f) @@ -196,10 +199,9 @@ local int memError(MEMFILE *f) local int memClose(MEMFILE *f) { - if(f->mode == 'w') - { - *((int *)(f->memory+4)) = memTell(f); - } + if(f->mode == 'w') { + *((int *)(f->memory+4)) = memTell(f); + } free(f); return 0; } @@ -214,7 +216,7 @@ local int memPrintf(MEMFILE *f, const char *format, ...) len = vsprintf(buffer, format, list); va_end(list); - return memWrite(buffer, 1, len, f); + return (int)memWrite(buffer, 1, len, f); } /* =========================================================================== @@ -227,132 +229,114 @@ local int memPrintf(MEMFILE *f, const char *format, ...) zlib error is Z_MEM_ERROR). */ local gzFile gz_open (memory, available, mode) -char *memory; -const int available; -const char *mode; + char *memory; + const int available; + const char *mode; { - int err; - int level = Z_DEFAULT_COMPRESSION; /* compression level */ - int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ - char *p = (char*)mode; - mem_stream *s; - char fmode[80]; /* copy of mode, without the compression level */ - char *m = fmode; + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + mem_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; - s = (mem_stream *)ALLOC(sizeof(mem_stream)); - if (!s) return Z_NULL; + s = (mem_stream *)ALLOC(sizeof(mem_stream)); + if (!s) return Z_NULL; - s->stream.zalloc = (alloc_func)0; - s->stream.zfree = (free_func)0; - s->stream.opaque = (voidpf)0; - s->stream.next_in = s->inbuf = Z_NULL; - s->stream.next_out = s->outbuf = Z_NULL; - s->stream.avail_in = s->stream.avail_out = 0; - s->z_err = Z_OK; - s->z_eof = 0; - s->crc = crc32(0L, Z_NULL, 0); - s->msg = NULL; - s->transparent = 0; - s->file = NULL; + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->z_err = Z_OK; + s->z_eof = 0; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + s->file = NULL; - s->mode = '\0'; - do - { - if (*p == 'r') s->mode = 'r'; - if (*p == 'w' || *p == 'a') s->mode = 'w'; - if (*p >= '0' && *p <= '9') - { - level = *p - '0'; - } - else if (*p == 'f') - { - strategy = Z_FILTERED; - } - else if (*p == 'h') - { - strategy = Z_HUFFMAN_ONLY; - } - else - { - *m++ = *p; /* copy the mode */ - } - } - while (*p++ && m != fmode + sizeof(fmode)); - if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; - if (s->mode == 'w') - { + if (s->mode == 'w') { #ifdef NO_DEFLATE - err = Z_STREAM_ERROR; + err = Z_STREAM_ERROR; #else - err = deflateInit2(&(s->stream), level, - Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); - /* windowBits is passed < 0 to suppress zlib header */ + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ - s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); #endif - if (err != Z_OK || s->outbuf == Z_NULL) - { - return destroy(s), (gzFile)Z_NULL; + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; } } - else - { - s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + s->stream.avail_out = Z_BUFSIZE; - err = inflateInit2(&(s->stream), -MAX_WBITS); - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are - * present after the compressed stream. - */ - if (err != Z_OK || s->inbuf == Z_NULL) - { - return destroy(s), (gzFile)Z_NULL; - } - } - s->stream.avail_out = Z_BUFSIZE; + errno = 0; + s->file = memOpen(memory, available, s->mode); - errno = 0; - s->file = memOpen(memory, available, s->mode); - - if (s->file == NULL) - { - return destroy(s), (gzFile)Z_NULL; + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; } - if (s->mode == 'w') - { - /* Write a very simple .gz header: - */ - memPrintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], - Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); - s->startpos = 10L; - /* We use 10L instead of ftell(s->file) to because ftell causes an - * fflush on some systems. This version of the library doesn't use - * startpos anyway in write mode, so this initialization is not - * necessary. - */ - } - else - { - check_header(s); /* skip the .gz header */ - s->startpos = (memTell(s->file) - s->stream.avail_in); + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + memPrintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->startpos = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * startpos anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->startpos = (memTell(s->file) - s->stream.avail_in); } - return (gzFile)s; + return (gzFile)s; } /* =========================================================================== Opens a gzip (.gz) file for reading or writing. */ gzFile ZEXPORT memgzopen (memory, available, mode) -char *memory; -int available; -const char *mode; + char *memory; + int available; + const char *mode; { - return gz_open (memory, available, mode); + return gz_open (memory, available, mode); } /* =========================================================================== @@ -361,23 +345,21 @@ const char *mode; IN assertion: the stream s has been sucessfully opened for reading. */ local int get_byte(s) -mem_stream *s; + mem_stream *s; { - if (s->z_eof) return EOF; - if (s->stream.avail_in == 0) - { - errno = 0; - s->stream.avail_in = memRead(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) - { - s->z_eof = 1; - if (memError(s->file)) s->z_err = Z_ERRNO; - return EOF; - } - s->stream.next_in = s->inbuf; + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = (uInt)memRead(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (memError(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; } - s->stream.avail_in--; - return *(s->stream.next_in)++; + s->stream.avail_in--; + return *(s->stream.next_in)++; } /* =========================================================================== @@ -390,103 +372,90 @@ mem_stream *s; for concatenated .gz files. */ local void check_header(s) -mem_stream *s; + mem_stream *s; { - int method; /* method byte */ - int flags; /* flags byte */ - uInt len; - int c; + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; - /* Check the gzip magic header */ - for (len = 0; len < 2; len++) - { - c = get_byte(s); - if (c != gz_magic[len]) - { - if (len != 0) s->stream.avail_in++, s->stream.next_in--; - if (c != EOF) - { - s->stream.avail_in++, s->stream.next_in--; - s->transparent = 1; - } - s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; - return; - } + /* Check the gzip magic header */ + for (len = 0; len < 2; len++) { + c = get_byte(s); + if (c != gz_magic[len]) { + if (len != 0) s->stream.avail_in++, s->stream.next_in--; + if (c != EOF) { + s->stream.avail_in++, s->stream.next_in--; + s->transparent = 1; + } + s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; + return; + } } - method = get_byte(s); - flags = get_byte(s); - if (method != Z_DEFLATED || (flags & RESERVED) != 0) - { - s->z_err = Z_DATA_ERROR; - return; + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; } - /* Discard time, xflags and OS code: */ - for (len = 0; len < 6; len++) (void)get_byte(s); + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); - if ((flags & EXTRA_FIELD) != 0) - { /* skip the extra field */ - len = (uInt)get_byte(s); - len += ((uInt)get_byte(s))<<8; - /* len is garbage if EOF but the loop below will quit anyway */ - while (len-- != 0 && get_byte(s) != EOF) ; + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; } - if ((flags & ORIG_NAME) != 0) - { /* skip the original file name */ - while ((c = get_byte(s)) != 0 && c != EOF) ; + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; } - if ((flags & COMMENT) != 0) - { /* skip the .gz file comment */ - while ((c = get_byte(s)) != 0 && c != EOF) ; + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; } - if ((flags & HEAD_CRC) != 0) - { /* skip the header crc */ - for (len = 0; len < 2; len++) (void)get_byte(s); + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); } - s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; } -/* =========================================================================== -* Cleanup then free the given mem_stream. Return a zlib error code. - Try freeing in the reverse order of allocations. -*/ + /* =========================================================================== + * Cleanup then free the given mem_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ local int destroy (s) -mem_stream *s; + mem_stream *s; { - int err = Z_OK; + int err = Z_OK; - if (!s) return Z_STREAM_ERROR; + if (!s) return Z_STREAM_ERROR; - TRYFREE(s->msg); + TRYFREE(s->msg); - if (s->stream.state != NULL) - { - if (s->mode == 'w') - { + if (s->stream.state != NULL) { + if (s->mode == 'w') { #ifdef NO_DEFLATE - err = Z_STREAM_ERROR; + err = Z_STREAM_ERROR; #else - err = deflateEnd(&(s->stream)); + err = deflateEnd(&(s->stream)); #endif - } - else if (s->mode == 'r') - { - err = inflateEnd(&(s->stream)); - } + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } } - if (s->file != NULL && memClose(s->file)) - { + if (s->file != NULL && memClose(s->file)) { #ifdef ESPIPE - if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ #endif - err = Z_ERRNO; + err = Z_ERRNO; } - if (s->z_err < 0) err = s->z_err; + if (s->z_err < 0) err = s->z_err; - TRYFREE(s->inbuf); - TRYFREE(s->outbuf); - TRYFREE(s); - return err; + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s); + return err; } /* =========================================================================== @@ -494,104 +463,91 @@ mem_stream *s; gzread returns the number of bytes actually read (0 for end of file). */ int ZEXPORT memgzread (file, buf, len) -gzFile file; -voidp buf; -unsigned len; + gzFile file; + voidp buf; + unsigned len; { - mem_stream *s = (mem_stream*)file; - Bytef *start = (Bytef*)buf; /* starting point for crc computation */ - Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + mem_stream *s = (mem_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ - if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; - if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; - if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ - next_out = (Byte*)buf; - s->stream.next_out = (Bytef*)buf; - s->stream.avail_out = len; + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; - while (s->stream.avail_out != 0) - { + while (s->stream.avail_out != 0) { - if (s->transparent) - { - /* Copy first the lookahead bytes: */ - uInt n = s->stream.avail_in; - if (n > s->stream.avail_out) n = s->stream.avail_out; - if (n > 0) - { - zmemcpy(s->stream.next_out, s->stream.next_in, n); - next_out += n; - s->stream.next_out = next_out; - s->stream.next_in += n; - s->stream.avail_out -= n; - s->stream.avail_in -= n; + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= (uInt)memRead(next_out, 1, s->stream.avail_out, s->file); + } + len -= s->stream.avail_out; + s->stream.total_in += (uLong)len; + s->stream.total_out += (uLong)len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = (uInt)memRead(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (memError(s->file)) { + s->z_err = Z_ERRNO; + break; + } } - if (s->stream.avail_out > 0) - { - s->stream.avail_out -= memRead(next_out, 1, s->stream.avail_out, - s->file); - } - len -= s->stream.avail_out; - s->stream.total_in += (uLong)len; - s->stream.total_out += (uLong)len; - if (len == 0) s->z_eof = 1; - return (int)len; + s->stream.next_in = s->inbuf; } - if (s->stream.avail_in == 0 && !s->z_eof) - { + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); - errno = 0; - s->stream.avail_in = memRead(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) - { - s->z_eof = 1; - if (memError(s->file)) - { - s->z_err = Z_ERRNO; - break; - } - } - s->stream.next_in = s->inbuf; - } - s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; - if (s->z_err == Z_STREAM_END) - { - /* Check CRC and original size */ - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - start = s->stream.next_out; + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may + * be different from s->stream.total_out) in case of + * concatenated .gz files. Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + uLong total_in = s->stream.total_in; + uLong total_out = s->stream.total_out; - if (getLong(s) != s->crc) - { - s->z_err = Z_DATA_ERROR; - } - else - { - (void)getLong(s); - /* The uncompressed length returned by above getlong() may - * be different from s->stream.total_out) in case of - * concatenated .gz files. Check for such files: - */ - check_header(s); - if (s->z_err == Z_OK) - { - uLong total_in = s->stream.total_in; - uLong total_out = s->stream.total_out; - - inflateReset(&(s->stream)); - s->stream.total_in = total_in; - s->stream.total_out = total_out; - s->crc = crc32(0L, Z_NULL, 0); - } - } - } - if (s->z_err != Z_OK || s->z_eof) break; + inflateReset(&(s->stream)); + s->stream.total_in = total_in; + s->stream.total_out = total_out; + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; } - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - return (int)(len - s->stream.avail_out); + return (int)(len - s->stream.avail_out); } @@ -601,37 +557,34 @@ unsigned len; gzwrite returns the number of bytes actually written (0 in case of error). */ int ZEXPORT memgzwrite (file, buf, len) -gzFile file; -const voidp buf; -unsigned len; + gzFile file; + const voidp buf; + unsigned len; { - mem_stream *s = (mem_stream*)file; + mem_stream *s = (mem_stream*)file; - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - s->stream.next_in = (Bytef*)buf; - s->stream.avail_in = len; + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; - while (s->stream.avail_in != 0) - { + while (s->stream.avail_in != 0) { - if (s->stream.avail_out == 0) - { + if (s->stream.avail_out == 0) { - s->stream.next_out = s->outbuf; - if (memWrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) - { - s->z_err = Z_ERRNO; - break; + s->stream.next_out = s->outbuf; + if (memWrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; } - s->stream.avail_out = Z_BUFSIZE; + s->stream.avail_out = Z_BUFSIZE; } - s->z_err = deflate(&(s->stream), Z_NO_FLUSH); - if (s->z_err != Z_OK) break; + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + if (s->z_err != Z_OK) break; } - s->crc = crc32(s->crc, (const Bytef *)buf, len); + s->crc = crc32(s->crc, (const Bytef *)buf, len); - return (int)(len - s->stream.avail_in); + return (int)(len - s->stream.avail_in); } #endif /* =========================================================================== @@ -639,59 +592,55 @@ unsigned len; flush is as in the deflate() function. */ local int do_flush (file, flush) -gzFile file; -int flush; + gzFile file; + int flush; { - uInt len; - int done = 0; - mem_stream *s = (mem_stream*)file; + uInt len; + int done = 0; + mem_stream *s = (mem_stream*)file; - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - s->stream.avail_in = 0; /* should be zero already anyway */ + s->stream.avail_in = 0; /* should be zero already anyway */ - for (;;) - { - len = Z_BUFSIZE - s->stream.avail_out; + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; - if (len != 0) - { - if ((uInt)memWrite(s->outbuf, 1, len, s->file) != len) - { - s->z_err = Z_ERRNO; - return Z_ERRNO; + if (len != 0) { + if ((uInt)memWrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; } - s->stream.next_out = s->outbuf; - s->stream.avail_out = Z_BUFSIZE; + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; } - if (done) break; - s->z_err = deflate(&(s->stream), flush); + if (done) break; + s->z_err = deflate(&(s->stream), flush); - /* Ignore the second of two consecutive flushes: */ - if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; - /* deflate has finished flushing only when it hasn't used up - * all the available space in the output buffer: - */ - done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); - if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; } - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; } /* =========================================================================== Outputs a long in LSB order to the given file */ local void putLong (file, x) -MEMFILE *file; -uLong x; + MEMFILE *file; + uLong x; { - int n; - for (n = 0; n < 4; n++) - { - memPutc((int)(x & 0xff), file); - x >>= 8; + int n; + for (n = 0; n < 4; n++) { + memPutc((int)(x & 0xff), file); + x >>= 8; } } @@ -700,17 +649,17 @@ uLong x; of error. */ local uLong getLong (s) -mem_stream *s; + mem_stream *s; { - uLong x = (uLong)get_byte(s); - int c; + uLong x = (uLong)get_byte(s); + int c; - x += ((uLong)get_byte(s))<<8; - x += ((uLong)get_byte(s))<<16; - c = get_byte(s); - if (c == EOF) s->z_err = Z_DATA_ERROR; - x += ((uLong)c)<<24; - return x; + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; } /* =========================================================================== @@ -718,34 +667,33 @@ mem_stream *s; and deallocates all the (de)compression state. */ int ZEXPORT memgzclose (file) -gzFile file; + gzFile file; { - int err; - mem_stream *s = (mem_stream*)file; + int err; + mem_stream *s = (mem_stream*)file; - if (s == NULL) return Z_STREAM_ERROR; + if (s == NULL) return Z_STREAM_ERROR; - if (s->mode == 'w') - { + if (s->mode == 'w') { #ifdef NO_DEFLATE - return Z_STREAM_ERROR; + return Z_STREAM_ERROR; #else - err = do_flush (file, Z_FINISH); - if (err != Z_OK) return destroy((mem_stream*)file); + err = do_flush (file, Z_FINISH); + if (err != Z_OK) return destroy((mem_stream*)file); - putLong (s->file, s->crc); - putLong (s->file, s->stream.total_in); + putLong (s->file, s->crc); + putLong (s->file, s->stream.total_in); #endif } - return destroy((mem_stream*)file); + return destroy((mem_stream*)file); } long ZEXPORT memtell(file) -gzFile file; + gzFile file; { - mem_stream *s = (mem_stream*)file; + mem_stream *s = (mem_stream*)file; - if (s == NULL) return Z_STREAM_ERROR; + if (s == NULL) return Z_STREAM_ERROR; - return memTell(s->file); + return memTell(s->file); } diff --git a/source/vba/common/memgzio.h b/source/vba/common/memgzio.h index 69e1a7c..e1f69b0 100644 --- a/source/vba/common/memgzio.h +++ b/source/vba/common/memgzio.h @@ -1,3 +1,6 @@ +#ifndef MEMGZIO_H +#define MEMGZIO_H + /* gzio.c -- IO on .gz files * Copyright (C) 1995-2002 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h @@ -8,27 +11,13 @@ /* memgzio.c - IO on .gz files in memory * Adapted from original gzio.c from zlib library by Forgotten */ -#ifndef HAVE_ZUTIL_H -#include "../win32/include/zlib/zutil.h" -#else + #include -#endif -#ifndef local -# define local static -#endif +gzFile ZEXPORT memgzopen(char *memory, int available, const char *mode); +int ZEXPORT memgzread(gzFile file, voidp buf, unsigned len); +int ZEXPORT memgzwrite(gzFile file, const voidp buf, unsigned len); +int ZEXPORT memgzclose(gzFile file); +long ZEXPORT memtell(gzFile file); -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -#define OS_CODE 0x03 /* assume Unix */ -#define zmemcpy memcpy - -gzFile ZEXPORT memgzopen(char *memory, int, const char *); -int ZEXPORT memgzread(gzFile, voidp, unsigned); -int ZEXPORT memgzwrite(gzFile, const voidp, unsigned); -int ZEXPORT memgzclose(gzFile); -long ZEXPORT memtell(gzFile); +#endif // MEMGZIO_H diff --git a/source/vba/gb/GB.cpp b/source/vba/gb/GB.cpp index cc43c32..75a9012 100644 --- a/source/vba/gb/GB.cpp +++ b/source/vba/gb/GB.cpp @@ -3550,24 +3550,23 @@ static bool gbWriteSaveState(gzFile gzFile) return true; } -bool gbWriteMemSaveState(char *memory, int available) +int gbWriteMemSaveState(char *memory, int available) { - gzFile gzFile = utilMemGzOpen(memory, available, "w"); + int pos = 0; + gzFile gzFile = utilMemGzOpen(memory, available, "w"); - if(gzFile == NULL) { - return false; - } + if(gzFile == NULL) + return 0; - bool res = gbWriteSaveState(gzFile); - - long pos = utilGzMemTell(gzFile)+8; - - if(pos >= (available)) - res = false; - - utilGzClose(gzFile); - - return res; + if(gbWriteSaveState(gzFile)) + { + pos = utilGzMemTell(gzFile)+8; + + if(pos >= (available)) + pos = 0; + } + utilGzClose(gzFile); + return pos; } bool gbWriteSaveState(const char *name) diff --git a/source/vba/gb/gb.h b/source/vba/gb/gb.h index 58712b3..c2f68ee 100644 --- a/source/vba/gb/gb.h +++ b/source/vba/gb/gb.h @@ -30,7 +30,7 @@ bool gbWriteBatteryFile(const char *); bool gbWriteBatteryFile(const char *, bool); bool gbReadBatteryFile(const char *); bool gbWriteSaveState(const char *); -bool gbWriteMemSaveState(char *, int); +int gbWriteMemSaveState(char *, int); bool gbReadSaveState(const char *); bool gbReadMemSaveState(char *, int); void gbSgbRenderBorder(); diff --git a/source/vba/gba/GBA.cpp b/source/vba/gba/GBA.cpp index dd141db..7624518 100644 --- a/source/vba/gba/GBA.cpp +++ b/source/vba/gba/GBA.cpp @@ -634,24 +634,23 @@ bool CPUWriteState(const char *file) return res; } -bool CPUWriteMemState(char *memory, int available) +int CPUWriteMemState(char *memory, int available) { - gzFile gzFile = utilMemGzOpen(memory, available, "w"); + int pos = 0; + gzFile gzFile = utilMemGzOpen(memory, available, "w"); - if(gzFile == NULL) { - return false; - } + if(gzFile == NULL) + return 0; - bool res = CPUWriteState(gzFile); - - long pos = utilGzMemTell(gzFile)+8; - - if(pos >= (available)) - res = false; - - utilGzClose(gzFile); - - return res; + if(CPUWriteState(gzFile)) + { + pos = utilGzMemTell(gzFile)+8; + + if(pos >= (available)) + pos = 0; + } + utilGzClose(gzFile); + return pos; } static bool CPUReadState(gzFile gzFile) diff --git a/source/vba/gba/GBA.h b/source/vba/gba/GBA.h index 33dee51..c97cb60 100644 --- a/source/vba/gba/GBA.h +++ b/source/vba/gba/GBA.h @@ -90,7 +90,7 @@ extern void CPUUpdateRender(); extern void CPUUpdateRenderBuffers(bool); extern bool CPUReadMemState(char *, int); extern bool CPUReadState(const char *); -extern bool CPUWriteMemState(char *, int); +extern int CPUWriteMemState(char *, int); extern bool CPUWriteState(const char *); extern int CPULoadRom(const char *); extern void doMirroring(bool);