1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-05 09:48:42 +00:00

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
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),

View File

@ -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;