diff --git a/tasks/task_save_ram.c b/tasks/task_save_ram.c index 3358f9818d..c9e134aeaa 100644 --- a/tasks/task_save_ram.c +++ b/tasks/task_save_ram.c @@ -291,6 +291,27 @@ void autosave_deinit(void) } #endif +static bool content_get_memory(retro_ctx_memory_info_t *mem_info, + ram_type_t *ram, unsigned slot) +{ + global_t *global = global_get_ptr(); + + if (!global) + return false; + + ram->type = global->savefiles->elems[slot].attr.i; + ram->path = global->savefiles->elems[slot].data; + + mem_info->id = ram->type; + + core_get_memory(mem_info); + + if (!mem_info->data || mem_info->size == 0) + return false; + + return true; +} + /** * content_load_ram_file: * @path : path of RAM state that will be loaded from. @@ -303,17 +324,9 @@ bool content_load_ram_file(unsigned slot) ssize_t rc; ram_type_t ram; retro_ctx_memory_info_t mem_info; - global_t *global = global_get_ptr(); void *buf = NULL; - ram.path = global->savefiles->elems[slot].data; - ram.type = global->savefiles->elems[slot].attr.i; - - mem_info.id = ram.type; - - core_get_memory(&mem_info); - - if (mem_info.size == 0 || !mem_info.data) + if (!content_get_memory(&mem_info, &ram, slot)) return false; if (!filestream_read_file(ram.path, &buf, &rc)) @@ -352,20 +365,10 @@ bool content_save_ram_file(unsigned slot) { ram_type_t ram; retro_ctx_memory_info_t mem_info; - global_t *global = global_get_ptr(); - if (!global) + if (!content_get_memory(&mem_info, &ram, slot)) return false; - ram.type = global->savefiles->elems[slot].attr.i; - ram.path = global->savefiles->elems[slot].data; - - mem_info.id = ram.type; - - core_get_memory(&mem_info); - - if (!mem_info.data || mem_info.size == 0) - return false; RARCH_LOG("%s #%u %s \"%s\".\n", msg_hash_to_str(MSG_SAVING_RAM_TYPE), diff --git a/tasks/task_save_state.c b/tasks/task_save_state.c index 04f246a6de..64c184e81d 100644 --- a/tasks/task_save_state.c +++ b/tasks/task_save_state.c @@ -60,35 +60,15 @@ struct sram_block size_t size; }; -/** - * undo_load_state: - * Revert to the state before a state was loaded. - * - * Returns: true if successful, false otherwise. - **/ -bool content_undo_load_state() +static unsigned content_allocate_save_blocks(struct sram_block *blocks) { unsigned i; - retro_ctx_serialize_info_t serial_info; - size_t temp_data_size; - void* temp_data = NULL; unsigned num_blocks = 0; - struct sram_block *blocks = NULL; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); - RARCH_LOG("%s: \"%s\".\n", - msg_hash_to_str(MSG_LOADING_STATE), - undo_load_buf.path); - - RARCH_LOG("%s: %u %s.\n", - msg_hash_to_str(MSG_STATE_SIZE), - undo_load_buf.size, - msg_hash_to_str(MSG_BYTES)); - - - /* TODO/FIXME - This checking of SRAM overwrite, the backing up of it and - its flushing could all be in their own functions... */ + /* Checking of SRAM overwrite, the backing up of it and + flushing. */ if (settings->block_sram_overwrite && global->savefiles && global->savefiles->size) { @@ -136,23 +116,14 @@ 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 */ - temp_data = malloc(undo_load_buf.size); - temp_data_size = undo_load_buf.size; - memcpy(temp_data, undo_load_buf.data, undo_load_buf.size); - serial_info.data_const = temp_data; - serial_info.size = temp_data_size; + return num_blocks; +} - /* Swap the current state with the backup state. This way, we can undo - what we're undoing */ - content_save_state("RAM", false); - bool ret = core_unserialize(&serial_info); - - /* Clean up the temporary copy */ - free(temp_data); - temp_data = NULL; +static void content_flush_save_blocks(struct sram_block *blocks, + unsigned num_blocks) +{ + unsigned i; /* Flush back. */ for (i = 0; i < num_blocks; i++) @@ -175,6 +146,54 @@ bool content_undo_load_state() for (i = 0; i < num_blocks; i++) free(blocks[i].data); free(blocks); +} + +/** + * undo_load_state: + * Revert to the state before a state was loaded. + * + * Returns: true if successful, false otherwise. + **/ +bool content_undo_load_state(void) +{ + retro_ctx_serialize_info_t serial_info; + size_t temp_data_size; + bool ret = false; + void* temp_data = NULL; + unsigned num_blocks = 0; + struct sram_block *blocks = NULL; + settings_t *settings = config_get_ptr(); + + RARCH_LOG("%s: \"%s\".\n", + msg_hash_to_str(MSG_LOADING_STATE), + undo_load_buf.path); + + RARCH_LOG("%s: %u %s.\n", + msg_hash_to_str(MSG_STATE_SIZE), + undo_load_buf.size, + msg_hash_to_str(MSG_BYTES)); + + num_blocks = content_allocate_save_blocks(blocks); + + /* We need to make a temporary copy of the buffer, to allow the swap below */ + temp_data = malloc(undo_load_buf.size); + temp_data_size = undo_load_buf.size; + memcpy(temp_data, undo_load_buf.data, undo_load_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("RAM", false); + + ret = core_unserialize(&serial_info); + + /* Clean up the temporary copy */ + free(temp_data); + temp_data = NULL; + + content_flush_save_blocks(blocks, num_blocks); if (!ret) { @@ -194,7 +213,8 @@ bool content_undo_load_state() **/ bool content_undo_save_state(void) { - bool ret = filestream_write_file(undo_save_buf.path, undo_save_buf.data, undo_save_buf.size); + bool ret = filestream_write_file(undo_save_buf.path, + undo_save_buf.data, undo_save_buf.size); /* Wipe the save file buffer as it's intended to be one use only */ undo_save_buf.path[0] = '\0'; @@ -329,7 +349,6 @@ bool content_load_state(const char *path, bool load_to_backup_buffer) void *buf = NULL; struct sram_block *blocks = NULL; settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); bool ret = filestream_read_file(path, &buf, &size); RARCH_LOG("%s: \"%s\".\n", @@ -367,83 +386,17 @@ bool content_load_state(const char *path, bool load_to_backup_buffer) return true; } - if (settings->block_sram_overwrite && global->savefiles - && global->savefiles->size) - { - RARCH_LOG("%s.\n", - msg_hash_to_str(MSG_BLOCKING_SRAM_OVERWRITE)); - blocks = (struct sram_block*) - calloc(global->savefiles->size, sizeof(*blocks)); - - if (blocks) - { - num_blocks = global->savefiles->size; - for (i = 0; i < num_blocks; i++) - blocks[i].type = global->savefiles->elems[i].attr.i; - } - } - - - for (i = 0; i < num_blocks; i++) - { - retro_ctx_memory_info_t mem_info; - - mem_info.id = blocks[i].type; - core_get_memory(&mem_info); - - blocks[i].size = mem_info.size; - } - - for (i = 0; i < num_blocks; i++) - if (blocks[i].size) - blocks[i].data = malloc(blocks[i].size); - - /* Backup current SRAM which is overwritten by unserialize. */ - for (i = 0; i < num_blocks; i++) - { - if (blocks[i].data) - { - retro_ctx_memory_info_t mem_info; - const void *ptr = NULL; - - mem_info.id = blocks[i].type; - - core_get_memory(&mem_info); - - ptr = mem_info.data; - if (ptr) - memcpy(blocks[i].data, ptr, blocks[i].size); - } - } + num_blocks = content_allocate_save_blocks(blocks); serial_info.data_const = buf; serial_info.size = size; /* Backup the current state so we can undo this load */ content_save_state("RAM", false); + ret = core_unserialize(&serial_info); - /* Flush back. */ - for (i = 0; i < num_blocks; i++) - { - if (blocks[i].data) - { - retro_ctx_memory_info_t mem_info; - void *ptr = NULL; - - mem_info.id = blocks[i].type; - - core_get_memory(&mem_info); - - ptr = mem_info.data; - if (ptr) - memcpy(ptr, blocks[i].data, blocks[i].size); - } - } - - for (i = 0; i < num_blocks; i++) - free(blocks[i].data); - free(blocks); + content_flush_save_blocks(blocks, num_blocks); if (!ret) goto error;