diff --git a/command.c b/command.c index 63e5ff9d90..d6c5440ef9 100644 --- a/command.c +++ b/command.c @@ -1601,8 +1601,14 @@ static void command_event_undo_save_state(char *s, size_t len) { snprintf(s, len, "%s \"%s\".", msg_hash_to_str(MSG_FAILED_TO_UNDO_SAVE_STATE), - "from internal buffer"); + "RAM"); + + return; } + + /* TODO/FIXME - use msg_hash_to_str here and there */ + snprintf(s, len, "%s", + "Restored save state."); } /** @@ -1639,8 +1645,12 @@ static void command_event_undo_load_state(char *s, size_t len) { snprintf(s, len, "%s \"%s\".", msg_hash_to_str(MSG_FAILED_TO_UNDO_LOAD_STATE), - "from internal buffer"); + "RAM"); + return; } + /* TODO/FIXME - use msg_hash_to_str here and there */ + snprintf(s, len, "%s", + "Undid load state."); } static void command_event_main_state(unsigned cmd) diff --git a/command.h b/command.h index 205728fde4..fce1ac2392 100644 --- a/command.h +++ b/command.h @@ -49,6 +49,7 @@ enum event_command CMD_EVENT_UNLOAD_CORE, CMD_EVENT_LOAD_STATE, CMD_EVENT_UNDO_LOAD_STATE, + /* Rewrites a savestate on disk */ CMD_EVENT_UNDO_SAVE_STATE, CMD_EVENT_SAVE_STATE, CMD_EVENT_SAVE_STATE_DECREMENT, diff --git a/content.h b/content.h index 0fbda04fdc..00e2796c29 100644 --- a/content.h +++ b/content.h @@ -47,7 +47,7 @@ bool content_save_ram_file(unsigned slot); /* Load a state from disk to memory. */ bool content_load_state(const char* path); -bool content_load_state_with_backup(const char* path, bool save_to_backup_buffer); +bool content_load_state_with_backup(const char* path, bool load_to_backup_buffer); /* Save a state from memory to disk. */ bool content_save_state(const char *path); @@ -78,6 +78,9 @@ void content_deinit(void); * selected libretro core. */ bool content_init(void); +/* Resets the state and savefile backup buffers */ +bool content_reset_savestate_backups(); + RETRO_END_DECLS #endif diff --git a/tasks/task_save_state.c b/tasks/task_save_state.c index 932727c3dc..b605988834 100644 --- a/tasks/task_save_state.c +++ b/tasks/task_save_state.c @@ -64,7 +64,7 @@ struct sram_block bool content_undo_load_state() { - if (old_state_buf.data == NULL) + if (old_state_buf.data == NULL || old_state_buf.size == 0) return false; unsigned i; @@ -79,7 +79,7 @@ bool content_undo_load_state() RARCH_LOG("%s: \"%s\".\n", msg_hash_to_str(MSG_LOADING_STATE), - "from internal buffer"); + "RAM"); RARCH_LOG("%s: %u %s.\n", msg_hash_to_str(MSG_STATE_SIZE), @@ -136,11 +136,25 @@ bool content_undo_load_state() memcpy(blocks[i].data, ptr, blocks[i].size); } } + + /* We need to make a temporary copy of the buffer, to allow the swap below */ + void* temp_data = malloc(old_state_buf.size); + size_t temp_data_size = old_state_buf.size; + memcpy(temp_data, old_state_buf.data, old_state_buf.size); - serial_info.data_const = old_state_buf.data; - serial_info.size = old_state_buf.size; + serial_info.data_const = temp_data; + serial_info.size = temp_data_size; + + /* Swap the current state with the backup state. This way, we can undo + what we're undoing */ + content_save_state_with_backup("RAM", false); bool ret = core_unserialize(&serial_info); + /* Clean up the temporary copy */ + free(temp_data); + temp_data = NULL; + temp_data_size = 0; + /* Flush back. */ for (i = 0; i < num_blocks; i++) { @@ -166,16 +180,7 @@ bool content_undo_load_state() if (!ret) RARCH_ERR("%s \"%s\".\n", msg_hash_to_str(MSG_FAILED_TO_UNDO_LOAD_STATE), - "from internal buffer"); - - /* Wipe the old state buffer, it's meant to be one use only */ - old_state_buf.path[0] = '\0'; - if (old_state_buf.data) { - free(old_state_buf.data); - old_state_buf.data = NULL; - } - - old_state_buf.data = 0; + "RAM"); return ret; } @@ -196,7 +201,7 @@ bool content_undo_save_state() if (!ret) RARCH_ERR("%s \"%s\".\n", msg_hash_to_str(MSG_FAILED_TO_UNDO_SAVE_STATE), - "from internal buffer"); + "RAM"); return ret; } @@ -388,7 +393,7 @@ bool content_load_state_with_backup(const char *path, bool load_to_backup_buffer serial_info.size = size; /* Backup the current state so we can undo this load */ - content_save_state_with_backup("internal buffer", false); + content_save_state_with_backup("RAM", false); ret = core_unserialize(&serial_info); /* Flush back. */ @@ -443,12 +448,14 @@ bool content_rename_state(const char *origin, const char *dest) } /* -* Resets the state and savefile backups +* * TODO/FIXME: Figure out when and where this should be called * */ bool content_reset_savestate_backups() { + printf("Resetting undo buffers.\n"); + if (old_save_file.data) { free(old_save_file.data);