diff --git a/atari800/src/statesav.c b/atari800/src/statesav.c index a6603fd..df1ad28 100644 --- a/atari800/src/statesav.c +++ b/atari800/src/statesav.c @@ -73,23 +73,7 @@ #define SAVE_VERSION_NUMBER 8 /* Last changed after Atari800 3.1.0 */ -#if defined(MEMCOMPR) -static gzFile *mem_open(const char *name, const char *mode); -static int mem_close(gzFile *stream); -static size_t mem_read(void *buf, size_t len, gzFile *stream); -static size_t mem_write(const void *buf, size_t len, gzFile *stream); -#define GZOPEN(X, Y) mem_open(X, Y) -#define GZCLOSE(X) mem_close(X) -#define GZREAD(X, Y, Z) mem_read(Y, Z, X) -#define GZWRITE(X, Y, Z) mem_write(Y, Z, X) -#undef GZERROR -#elif defined(HAVE_LIBZ) /* above MEMCOMPR, below HAVE_LIBZ */ -#define GZOPEN(X, Y) gzopen(X, Y) -#define GZCLOSE(X) gzclose(X) -#define GZREAD(X, Y, Z) gzread(X, Y, Z) -#define GZWRITE(X, Y, Z) gzwrite(X, (const voidp) Y, Z) -#define GZERROR(X, Y) gzerror(X, Y) -#else + #define GZOPEN(X, Y) fopen(X, Y) #define GZCLOSE(X) fclose(X) #define GZREAD(X, Y, Z) fread(Y, Z, 1, X) @@ -97,11 +81,12 @@ static size_t mem_write(const void *buf, size_t len, gzFile *stream); #undef GZERROR #define gzFile FILE * #define Z_OK 0 -#endif static gzFile StateFile = NULL; static int nFileError = Z_OK; + + static void GetGZErrorText(void) { #ifdef GZERROR @@ -330,8 +315,6 @@ void StateSav_ReadFNAME(char *filename) int StateSav_SaveAtariState(const char *filename, const char *mode, UBYTE SaveVerbose) { - UBYTE StateVersion = SAVE_VERSION_NUMBER; - if (StateFile != NULL) { GZCLOSE(StateFile); StateFile = NULL; @@ -351,6 +334,56 @@ int StateSav_SaveAtariState(const char *filename, const char *mode, UBYTE SaveVe return FALSE; } + if( StateSav_SaveAtariStateInternal(SaveVerbose) == FALSE ) + return FALSE; + + if (GZCLOSE(StateFile) != 0) { + StateFile = NULL; + return FALSE; + } + StateFile = NULL; + + if (nFileError != Z_OK) + return FALSE; + + return TRUE; +} + +int StateSav_SaveAtariStateMem(char **data ,size_t *size) +{ + nFileError = Z_OK; + + StateFile = open_memstream(data, size); + if (StateFile == NULL) { + GetGZErrorText(); + return FALSE; + } + if (GZWRITE(StateFile, "ATARI800", 8) == 0) { + GetGZErrorText(); + GZCLOSE(StateFile); + StateFile = NULL; + return FALSE; + } + + StateSav_SaveAtariStateInternal(TRUE); + + if (GZCLOSE(StateFile) != 0) { + StateFile = NULL; + return FALSE; + } + StateFile = NULL; + + if (nFileError != Z_OK) + return FALSE; + + return TRUE; +} + + +int StateSav_SaveAtariStateInternal(UBYTE SaveVerbose) +{ + UBYTE StateVersion = SAVE_VERSION_NUMBER; + StateSav_SaveUBYTE(&StateVersion, 1); StateSav_SaveUBYTE(&SaveVerbose, 1); /* The order here is important. Atari800_StateSave must be first because it saves the machine type, and @@ -400,24 +433,11 @@ int StateSav_SaveAtariState(const char *filename, const char *mode, UBYTE SaveVe DCStateSave(); #endif - if (GZCLOSE(StateFile) != 0) { - StateFile = NULL; - return FALSE; - } - StateFile = NULL; - - if (nFileError != Z_OK) - return FALSE; - return TRUE; } int StateSav_ReadAtariState(const char *filename, const char *mode) { - char header_string[8]; - UBYTE StateVersion = 0; /* The version of the save file */ - UBYTE SaveVerbose = 0; /* Verbose mode means save basic, OS if patched */ - if (StateFile != NULL) { GZCLOSE(StateFile); StateFile = NULL; @@ -431,6 +451,51 @@ int StateSav_ReadAtariState(const char *filename, const char *mode) return FALSE; } + if( StateSav_ReadAtariStateInternal() == FALSE ) + return FALSE; + + GZCLOSE(StateFile); + StateFile = NULL; + + if (nFileError != Z_OK) + return FALSE; + + return TRUE; +} + + +int StateSav_ReadAtariStateMem(const char* data, size_t size) +{ + if (StateFile != NULL) { + GZCLOSE(StateFile); + StateFile = NULL; + } + nFileError = Z_OK; + + StateFile = fmemopen((char* )data, size, "r"); + + if (StateFile == NULL) { + return FALSE; + } + + if (StateSav_ReadAtariStateInternal() == FALSE) + return FALSE; + + GZCLOSE(StateFile); + StateFile = NULL; + + if (nFileError != Z_OK) + return FALSE; + + return TRUE; +} + +int StateSav_ReadAtariStateInternal() +{ + char header_string[8]; + UBYTE StateVersion = 0; /* The version of the save file */ + UBYTE SaveVerbose = 0; /* Verbose mode means save basic, OS if patched */ + if (GZREAD(StateFile, header_string, 8) == 0) { GetGZErrorText(); GZCLOSE(StateFile); @@ -445,7 +510,7 @@ int StateSav_ReadAtariState(const char *filename, const char *mode) } if (GZREAD(StateFile, &StateVersion, 1) == 0 - || GZREAD(StateFile, &SaveVerbose, 1) == 0) { + || GZREAD(StateFile, &SaveVerbose, 1) == 0) { Log_print("Failed read from Atari state file."); GetGZErrorText(); GZCLOSE(StateFile); @@ -475,7 +540,7 @@ int StateSav_ReadAtariState(const char *filename, const char *mode) XEP80_StateRead(); #else int local_xep80_enabled; - StateSav_ReadINT(&local_xep80_enabled,1); + StateSav_ReadINT(&local_xep80_enabled, 1); if (local_xep80_enabled) { Log_print("Cannot read this state file because this version does not support XEP80."); GZCLOSE(StateFile); @@ -489,7 +554,7 @@ int StateSav_ReadAtariState(const char *filename, const char *mode) #else { int local_mio_enabled; - StateSav_ReadINT(&local_mio_enabled,1); + StateSav_ReadINT(&local_mio_enabled, 1); if (local_mio_enabled) { Log_print("Cannot read this state file because this version does not support MIO."); GZCLOSE(StateFile); @@ -503,7 +568,7 @@ int StateSav_ReadAtariState(const char *filename, const char *mode) #else { int local_bb_enabled; - StateSav_ReadINT(&local_bb_enabled,1); + StateSav_ReadINT(&local_bb_enabled, 1); if (local_bb_enabled) { Log_print("Cannot read this state file because this version does not support the Black Box."); GZCLOSE(StateFile); @@ -517,7 +582,7 @@ int StateSav_ReadAtariState(const char *filename, const char *mode) #else { int local_xld_enabled; - StateSav_ReadINT(&local_xld_enabled,1); + StateSav_ReadINT(&local_xld_enabled, 1); if (local_xld_enabled) { Log_print("Cannot read this state file because this version does not support the 1400XL/1450XLD."); GZCLOSE(StateFile); @@ -530,17 +595,9 @@ int StateSav_ReadAtariState(const char *filename, const char *mode) #ifdef DREAMCAST DCStateRead(); #endif - - GZCLOSE(StateFile); - StateFile = NULL; - - if (nFileError != Z_OK) - return FALSE; - return TRUE; } - /* hack to compress in memory before writing * - for DREAMCAST only * - 2 reasons for this: diff --git a/atari800/src/statesav.h b/atari800/src/statesav.h index 2c6b692..e01b1ba 100644 --- a/atari800/src/statesav.h +++ b/atari800/src/statesav.h @@ -6,6 +6,12 @@ int StateSav_SaveAtariState(const char *filename, const char *mode, UBYTE SaveVerbose); int StateSav_ReadAtariState(const char *filename, const char *mode); +int StateSav_SaveAtariStateMem(char **data ,size_t *size); +int StateSav_ReadAtariStateMem(const char *data , size_t size); + +int StateSav_SaveAtariStateInternal(UBYTE SaveVerbose); +int StateSav_ReadAtariStateInternal(); + void StateSav_SaveUBYTE(const UBYTE *data, int num); void StateSav_SaveUWORD(const UWORD *data, int num); void StateSav_SaveINT(const int *data, int num); diff --git a/libretro/libretro-core.c b/libretro/libretro-core.c index 2992e78..9ddad5a 100644 --- a/libretro/libretro-core.c +++ b/libretro/libretro-core.c @@ -48,6 +48,8 @@ extern void texture_uninit(void); extern void Emu_init(); extern void Emu_uninit(); extern void input_gui(void); +extern int StateSav_SaveAtariStateMem(char** data, size_t* size); +extern int StateSav_ReadAtariStateMem(const char* data, size_t size); const char *retro_save_directory; const char *retro_system_directory; @@ -736,17 +738,38 @@ bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t retro_serialize_size(void) { - return 0; + char* buf = NULL; + size_t size = 0; + bool ret = StateSav_SaveAtariStateMem(&buf, &size) == TRUE; + free(buf); + + if (!ret || size == 0) + return 0; + + return size; } bool retro_serialize(void *data_, size_t size) { - return false; + char* buf = NULL; + size_t serializeSize = 0; + bool ret = StateSav_SaveAtariStateMem(&buf, &serializeSize) == TRUE; + if (!ret || serializeSize != size) + { + free(buf); + return false; + } + + memcpy(data_, buf, size); + + free(buf); + + return true; } bool retro_unserialize(const void *data_, size_t size) { - return false; + return StateSav_ReadAtariStateMem(data_, size) == TRUE; } void *retro_get_memory_data(unsigned id)