From 051cc3fe4d0170a6181e5f98dabc81438723ed50 Mon Sep 17 00:00:00 2001 From: Arzed Five Date: Wed, 8 Jun 2016 20:27:54 +0100 Subject: [PATCH] Undo Save State currently seems to be working almost as intended (missing OSD messages). Undo Load State isn't working yet. --- command.c | 98 ++++++++++++----------------------------- content.h | 3 +- tasks/task_save_state.c | 32 +++++++++++++- 3 files changed, 61 insertions(+), 72 deletions(-) diff --git a/command.c b/command.c index 4d351b30fb..3a69e11525 100644 --- a/command.c +++ b/command.c @@ -1578,27 +1578,6 @@ static void command_event_save_state(const char *path, char *s, size_t len) { settings_t *settings = config_get_ptr(); - char buf[PATH_MAX_LENGTH] = {0}; - -#if 0 - /* if a save state already exists rename it to .last before saving - * so it can be recovered */ - if (path_file_exists(path)) - { - strlcpy(buf, path, sizeof(buf)); - snprintf(buf, sizeof(buf), "%s", path); - path_remove_extension(buf); - snprintf(buf, sizeof(buf), "%s.last", buf); - - if (!content_rename_state(path, buf)) - { - snprintf(s, len, "%s \"%s\".", - msg_hash_to_str(MSG_FAILED_TO_SAVE_UNDO), - path); - return; - } - } -#endif if (!content_save_state(path)) { @@ -1616,6 +1595,16 @@ static void command_event_save_state(const char *path, settings->state_slot); } +static void command_event_undo_save_state(char *s, size_t len) +{ + if (!content_undo_save_state()) + { + snprintf(s, len, "%s \"%s\".", + msg_hash_to_str(MSG_FAILED_TO_SAVE_UNDO), + "from internal buffer"); + } +} + /** * event_load_state * @path : Path to state. @@ -1624,29 +1613,9 @@ static void command_event_save_state(const char *path, * * Loads a state with path being @path. **/ -static void command_event_load_state(const char *path, char *s, size_t len, bool undo) +static void command_event_load_state(const char *path, char *s, size_t len) { settings_t *settings = config_get_ptr(); - char buf[PATH_MAX_LENGTH] = {0}; - - /* save a state before loading (unless it's an undo operation already) - * so the state can be recovered - */ - if (!undo) - { - strlcpy(buf, path, sizeof(buf)); - snprintf(buf, sizeof(buf), "%s", path); - path_remove_extension(buf); - snprintf(buf, sizeof(buf), "%s.undo", buf); - - if (!content_save_state(buf)) - { - snprintf(s, len, "%s \"%s\".", - msg_hash_to_str(MSG_FAILED_TO_SAVE_UNDO), - path); - return; - } - } if (!content_load_state(path)) { @@ -1659,18 +1628,25 @@ static void command_event_load_state(const char *path, char *s, size_t len, bool if (settings->state_slot < 0) snprintf(s, len, "%s #-1 (auto).", msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT)); - else if (!undo) + else snprintf(s, len, "%s #%d.", msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT), settings->state_slot); - else - snprintf(s, len, "%s #-1 (undo).", msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT)); +} + +static void command_event_undo_load_state(char *s, size_t len) +{ + if (!content_undo_load_state()) + { + snprintf(s, len, "%s \"%s\".", + msg_hash_to_str(MSG_FAILED_TO_LOAD_UNDO), + "from internal buffer"); + } } static void command_event_main_state(unsigned cmd) { retro_ctx_size_info_t info; char path[PATH_MAX_LENGTH] = {0}; - char buf[PATH_MAX_LENGTH] = {0}; char msg[128] = {0}; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); @@ -1694,33 +1670,13 @@ static void command_event_main_state(unsigned cmd) command_event_save_state(path, msg, sizeof(msg)); break; case CMD_EVENT_LOAD_STATE: - command_event_load_state(path, msg, sizeof(msg), false); + command_event_load_state(path, msg, sizeof(msg)); break; case CMD_EVENT_UNDO_LOAD_STATE: - strlcpy(buf, path, sizeof(buf)); - path_remove_extension(buf); - snprintf(buf, sizeof(buf), "%s.undo", buf); - - if (path_file_exists(buf)) - command_event_load_state(buf, msg, sizeof(msg), true); - else - { - snprintf(msg, sizeof(msg), "%s.", - msg_hash_to_str(MSG_FAILED_TO_LOAD_UNDO)); - } + command_event_undo_load_state(msg, sizeof(msg)); break; case CMD_EVENT_UNDO_SAVE_STATE: - strlcpy(buf, path, sizeof(buf)); - path_remove_extension(buf); - snprintf(buf, sizeof(buf), "%s.last", buf); - - if (path_file_exists(buf)) - command_event_load_state(buf, msg, sizeof(msg), true); - else - { - snprintf(msg, sizeof(msg), "%s.", - msg_hash_to_str(MSG_FAILED_TO_LOAD_UNDO)); - } + command_event_undo_save_state(msg, sizeof(msg)); break; } } @@ -1823,6 +1779,7 @@ bool command_event(enum event_command cmd, void *data) #ifndef HAVE_DYNAMIC command_event(CMD_EVENT_QUIT, NULL); #endif + content_reset_savestate_backups(); break; case CMD_EVENT_LOAD_STATE: /* Immutable - disallow savestate load when @@ -2122,9 +2079,12 @@ bool command_event(enum event_command cmd, void *data) if (hwr) memset(hwr, 0, sizeof(*hwr)); + content_reset_savestate_backups(); + break; } case CMD_EVENT_CORE_INIT: + content_reset_savestate_backups(); if (!command_event_init_core((enum rarch_core_type*)data)) return false; break; diff --git a/content.h b/content.h index a53ec3cb3c..0fbda04fdc 100644 --- a/content.h +++ b/content.h @@ -56,9 +56,10 @@ bool content_save_state_with_backup(const char *path, bool save_to_disk); /* Copy a save state. */ bool content_rename_state(const char *origin, const char *dest); -/* Load a state backup from disk to memory. */ +/* Undoes the last load state operation that was done */ bool content_undo_load_state(); +/* Restores the last savestate file which was overwritten */ bool content_undo_save_state(); bool content_does_not_need_content(void); diff --git a/tasks/task_save_state.c b/tasks/task_save_state.c index bd3c59b0c9..67da9363ae 100644 --- a/tasks/task_save_state.c +++ b/tasks/task_save_state.c @@ -182,7 +182,7 @@ bool content_undo_load_state() bool content_undo_save_state() { - filestream_write_file(old_save_file.path, old_save_file.data, old_save_file.size); + bool ret = filestream_write_file(old_save_file.path, old_save_file.data, old_save_file.size); /* Wipe the save file buffer as it's intended to be one use only */ old_save_file.path[0] = '\0'; @@ -193,7 +193,7 @@ bool content_undo_save_state() old_save_file.data = 0; - return true; + return ret; } @@ -434,3 +434,31 @@ bool content_rename_state(const char *origin, const char *dest) RARCH_LOG ("Error %d renaming file %s", ret, origin); return false; } + +/* +* Resets the state and savefile backups +* TODO/FIXME: Figure out when and where this should be called +* +*/ +bool content_reset_savestate_backups() +{ + if (old_save_file.data) + { + free(old_save_file.data); + old_save_file.data = NULL; + } + + old_save_file.path[0] = '\0'; + old_save_file.size = 0; + + if (old_state_buf.data) + { + free(old_state_buf.data); + old_state_buf.data = NULL; + } + + old_state_buf.path[0] = '\0'; + old_state_buf.size = 0; + + return true; +}