mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 13:14:04 +00:00
Deduplicate some code in task_save_ram.c/task_save_state.c
This commit is contained in:
parent
cea2ac6766
commit
13d9e7c761
@ -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),
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user