From 596d8d9985e47004432ea24d00c189f9de7e1cd5 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 22 Aug 2011 17:35:31 +0200 Subject: [PATCH] Attempt to recover SRAM write failures gracefully ... --- file.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- file.h | 8 ++++---- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/file.c b/file.c index 394930f6fe..e645c0f772 100644 --- a/file.c +++ b/file.c @@ -322,13 +322,41 @@ static bool dump_to_file(const char *path, const void *data, size_t size) return false; else { - fwrite(data, 1, size, file); + bool ret = fwrite(data, 1, size, file) == size; fclose(file); - return true; + return ret; } } -bool save_state(const char* path) +// Attempt to save valuable RAM data somewhere ... +static void dump_to_file_desperate(const void *data, size_t size) +{ +#ifdef _WIN32 + const char *base = getenv("APPDATA"); +#else + const char *base = getenv("HOME"); +#endif + + if (!base) + goto error; + + static unsigned count = 0; + + char path[MAXPATHLEN]; + snprintf(path, sizeof(path), "%s/SSNES-recovery-%u\n", base, count++); + + if (dump_to_file(path, data, size)) + SSNES_WARN("Succeeded in recovering data to \"%s\". Phew! :D\n", path); + else + goto error; + + return; + +error: + SSNES_WARN("Failed ... Tough luck ... :(\n"); +} + +bool save_state(const char *path) { SSNES_LOG("Saving state: \"%s\".\n", path); size_t size = psnes_serialize_size(); @@ -351,7 +379,7 @@ bool save_state(const char* path) return ret; } -bool load_state(const char* path) +bool load_state(const char *path) { SSNES_LOG("Loading state: \"%s\".\n", path); void *buf = NULL; @@ -371,7 +399,7 @@ bool load_state(const char* path) return true; } -void load_ram_file(const char* path, int type) +void load_ram_file(const char *path, int type) { size_t size = psnes_get_memory_size(type); uint8_t *data = psnes_get_memory_data(type); @@ -387,13 +415,20 @@ void load_ram_file(const char* path, int type) free(buf); } -void save_ram_file(const char* path, int type) +void save_ram_file(const char *path, int type) { size_t size = psnes_get_memory_size(type); uint8_t *data = psnes_get_memory_data(type); if (data && size > 0) - dump_to_file(path, data, size); + { + if (!dump_to_file(path, data, size)) + { + SSNES_ERR("Failed to save SNES RAM!\n"); + SSNES_WARN("Attempting to recover ...\n"); + dump_to_file_desperate(data, size); + } + } } static char* load_xml_map(const char *path) diff --git a/file.h b/file.h index 6029999071..b25a4e64df 100644 --- a/file.h +++ b/file.h @@ -28,11 +28,11 @@ ssize_t read_file(const char *path, void **buf); -bool load_state(const char* path); -bool save_state(const char* path); +bool load_state(const char *path); +bool save_state(const char *path); -void load_ram_file(const char* path, int type); -void save_ram_file(const char* path, int type); +void load_ram_file(const char *path, int type); +void save_ram_file(const char *path, int type); bool init_rom_file(enum ssnes_game_type type);