Deduplicate some code in task_save_ram.c/task_save_state.c

This commit is contained in:
twinaphex 2016-09-19 02:44:00 +02:00
parent cea2ac6766
commit 13d9e7c761
2 changed files with 85 additions and 129 deletions

View File

@ -291,6 +291,27 @@ void autosave_deinit(void)
} }
#endif #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: * content_load_ram_file:
* @path : path of RAM state that will be loaded from. * @path : path of RAM state that will be loaded from.
@ -303,17 +324,9 @@ bool content_load_ram_file(unsigned slot)
ssize_t rc; ssize_t rc;
ram_type_t ram; ram_type_t ram;
retro_ctx_memory_info_t mem_info; retro_ctx_memory_info_t mem_info;
global_t *global = global_get_ptr();
void *buf = NULL; void *buf = NULL;
ram.path = global->savefiles->elems[slot].data; if (!content_get_memory(&mem_info, &ram, slot))
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)
return false; return false;
if (!filestream_read_file(ram.path, &buf, &rc)) if (!filestream_read_file(ram.path, &buf, &rc))
@ -352,20 +365,10 @@ bool content_save_ram_file(unsigned slot)
{ {
ram_type_t ram; ram_type_t ram;
retro_ctx_memory_info_t mem_info; 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; 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", RARCH_LOG("%s #%u %s \"%s\".\n",
msg_hash_to_str(MSG_SAVING_RAM_TYPE), msg_hash_to_str(MSG_SAVING_RAM_TYPE),

View File

@ -60,35 +60,15 @@ struct sram_block
size_t size; size_t size;
}; };
/** static unsigned content_allocate_save_blocks(struct sram_block *blocks)
* undo_load_state:
* Revert to the state before a state was loaded.
*
* Returns: true if successful, false otherwise.
**/
bool content_undo_load_state()
{ {
unsigned i; unsigned i;
retro_ctx_serialize_info_t serial_info;
size_t temp_data_size;
void* temp_data = NULL;
unsigned num_blocks = 0; unsigned num_blocks = 0;
struct sram_block *blocks = NULL;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
global_t *global = global_get_ptr(); global_t *global = global_get_ptr();
RARCH_LOG("%s: \"%s\".\n", /* Checking of SRAM overwrite, the backing up of it and
msg_hash_to_str(MSG_LOADING_STATE), flushing. */
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... */
if (settings->block_sram_overwrite && global->savefiles if (settings->block_sram_overwrite && global->savefiles
&& global->savefiles->size) && global->savefiles->size)
{ {
@ -136,23 +116,14 @@ bool content_undo_load_state()
memcpy(blocks[i].data, ptr, blocks[i].size); 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; return num_blocks;
serial_info.size = temp_data_size; }
/* Swap the current state with the backup state. This way, we can undo static void content_flush_save_blocks(struct sram_block *blocks,
what we're undoing */ unsigned num_blocks)
content_save_state("RAM", false); {
bool ret = core_unserialize(&serial_info); unsigned i;
/* Clean up the temporary copy */
free(temp_data);
temp_data = NULL;
/* Flush back. */ /* Flush back. */
for (i = 0; i < num_blocks; i++) for (i = 0; i < num_blocks; i++)
@ -175,6 +146,54 @@ bool content_undo_load_state()
for (i = 0; i < num_blocks; i++) for (i = 0; i < num_blocks; i++)
free(blocks[i].data); free(blocks[i].data);
free(blocks); 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) if (!ret)
{ {
@ -194,7 +213,8 @@ bool content_undo_load_state()
**/ **/
bool content_undo_save_state(void) 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 */ /* Wipe the save file buffer as it's intended to be one use only */
undo_save_buf.path[0] = '\0'; 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; void *buf = NULL;
struct sram_block *blocks = NULL; struct sram_block *blocks = NULL;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
global_t *global = global_get_ptr();
bool ret = filestream_read_file(path, &buf, &size); bool ret = filestream_read_file(path, &buf, &size);
RARCH_LOG("%s: \"%s\".\n", RARCH_LOG("%s: \"%s\".\n",
@ -367,83 +386,17 @@ bool content_load_state(const char *path, bool load_to_backup_buffer)
return true; return true;
} }
if (settings->block_sram_overwrite && global->savefiles num_blocks = content_allocate_save_blocks(blocks);
&& 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);
}
}
serial_info.data_const = buf; serial_info.data_const = buf;
serial_info.size = size; serial_info.size = size;
/* Backup the current state so we can undo this load */ /* Backup the current state so we can undo this load */
content_save_state("RAM", false); content_save_state("RAM", false);
ret = core_unserialize(&serial_info); ret = core_unserialize(&serial_info);
/* Flush back. */ content_flush_save_blocks(blocks, num_blocks);
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);
if (!ret) if (!ret)
goto error; goto error;