(task_save.c) Miscellaneous cleanups:

* Remove unused return type of one function
* Remove some TODO/FIXME notes
* Small style nits
This commit is contained in:
LibretroAdmin 2022-09-02 23:35:48 +02:00
parent 6226d0442f
commit 2463a63c78
2 changed files with 229 additions and 293 deletions

View File

@ -100,7 +100,7 @@ void content_deinit(void);
bool content_init(void); bool content_init(void);
/* Resets the state and savefile backup buffers */ /* Resets the state and savefile backup buffers */
bool content_reset_savestate_backups(void); void content_reset_savestate_backups(void);
/* Checks if the buffers are empty */ /* Checks if the buffers are empty */
bool content_undo_load_buf_is_empty(void); bool content_undo_load_buf_is_empty(void);

View File

@ -150,7 +150,6 @@ typedef save_task_state_t load_task_data_t;
/* Holds the previous saved state /* Holds the previous saved state
* Can be restored to disk with undo_save_state(). */ * Can be restored to disk with undo_save_state(). */
/* TODO/FIXME - global state - perhaps move outside this file */
static struct save_state_buf undo_save_buf; static struct save_state_buf undo_save_buf;
/* Holds the data from before a load_state() operation /* Holds the data from before a load_state() operation
@ -162,11 +161,9 @@ static struct save_state_buf undo_load_buf;
static struct ram_save_state_buf ram_buf; static struct ram_save_state_buf ram_buf;
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
/* TODO/FIXME - global state - perhaps move outside this file */
static struct autosave_st autosave_state; static struct autosave_st autosave_state;
#endif #endif
/* TODO/FIXME - global state - perhaps move outside this file */
static bool save_state_in_background = false; static bool save_state_in_background = false;
static struct string_list *task_save_files = NULL; static struct string_list *task_save_files = NULL;
@ -248,7 +245,7 @@ static void autosave_thread(void *data)
* *
* Create and initialize autosave object. * Create and initialize autosave object.
* *
* Returns: pointer to new autosave_t object if successful, otherwise * @return Pointer to new autosave_t object if successful, otherwise
* NULL. * NULL.
**/ **/
static autosave_t *autosave_new(const char *path, static autosave_t *autosave_new(const char *path,
@ -267,9 +264,7 @@ static autosave_t *autosave_new(const char *path,
handle->retro_buffer = data; handle->retro_buffer = data;
handle->path = path; handle->path = path;
buf = malloc(size); if (!(buf = malloc(size)))
if (!buf)
{ {
free(handle); free(handle);
return NULL; return NULL;
@ -325,11 +320,9 @@ bool autosave_init(void)
if (autosave_interval < 1 || !task_save_files) if (autosave_interval < 1 || !task_save_files)
return false; return false;
list = (autosave_t**) if (!(list = (autosave_t**)
calloc(task_save_files->size, calloc(task_save_files->size,
sizeof(*autosave_state.list)); sizeof(*autosave_state.list))))
if (!list)
return false; return false;
autosave_state.list = list; autosave_state.list = list;
@ -349,13 +342,11 @@ bool autosave_init(void)
if (mem_info.size <= 0) if (mem_info.size <= 0)
continue; continue;
auto_st = autosave_new(path, if (!(auto_st = autosave_new(path,
mem_info.data, mem_info.data,
mem_info.size, mem_info.size,
autosave_interval, autosave_interval,
compress_files); compress_files)))
if (!auto_st)
{ {
RARCH_WARN("%s\n", msg_hash_to_str(MSG_AUTOSAVE_FAILED)); RARCH_WARN("%s\n", msg_hash_to_str(MSG_AUTOSAVE_FAILED));
continue; continue;
@ -437,8 +428,6 @@ bool content_undo_load_state(void)
unsigned num_blocks = 0; unsigned num_blocks = 0;
void* temp_data = NULL; void* temp_data = NULL;
struct sram_block *blocks = NULL; struct sram_block *blocks = NULL;
settings_t *settings = config_get_ptr();
bool block_sram_overwrite = settings->bools.block_sram_overwrite;
if (!core_info_current_supports_savestate()) if (!core_info_current_supports_savestate())
{ {
@ -457,15 +446,15 @@ bool content_undo_load_state(void)
* the backing up of it and * the backing up of it and
* its flushing could all be in their * its flushing could all be in their
* own functions... */ * own functions... */
if (block_sram_overwrite && task_save_files if ( config_get_ptr()->bools.block_sram_overwrite
&& task_save_files
&& task_save_files->size) && task_save_files->size)
{ {
RARCH_LOG("[SRAM]: %s.\n", RARCH_LOG("[SRAM]: %s.\n",
msg_hash_to_str(MSG_BLOCKING_SRAM_OVERWRITE)); msg_hash_to_str(MSG_BLOCKING_SRAM_OVERWRITE));
blocks = (struct sram_block*)
calloc(task_save_files->size, sizeof(*blocks));
if (blocks) if ((blocks = (struct sram_block*)
calloc(task_save_files->size, sizeof(*blocks))))
{ {
num_blocks = (unsigned)task_save_files->size; num_blocks = (unsigned)task_save_files->size;
for (i = 0; i < num_blocks; i++) for (i = 0; i < num_blocks; i++)
@ -499,8 +488,7 @@ bool content_undo_load_state(void)
core_get_memory(&mem_info); core_get_memory(&mem_info);
ptr = mem_info.data; if ((ptr = mem_info.data))
if (ptr)
memcpy(blocks[i].data, ptr, blocks[i].size); memcpy(blocks[i].data, ptr, blocks[i].size);
} }
} }
@ -532,8 +520,7 @@ bool content_undo_load_state(void)
core_get_memory(&mem_info); core_get_memory(&mem_info);
ptr = mem_info.data; if ((ptr = mem_info.data))
if (ptr)
memcpy(ptr, blocks[i].data, blocks[i].size); memcpy(ptr, blocks[i].data, blocks[i].size);
} }
} }
@ -550,9 +537,10 @@ bool content_undo_load_state(void)
RARCH_ERR("[State]: %s \"%s\".\n", RARCH_ERR("[State]: %s \"%s\".\n",
msg_hash_to_str(MSG_FAILED_TO_UNDO_LOAD_STATE), msg_hash_to_str(MSG_FAILED_TO_UNDO_LOAD_STATE),
undo_load_buf.path); undo_load_buf.path);
return false;
} }
return ret; return true;
} }
static void undo_save_state_cb(retro_task_t *task, static void undo_save_state_cb(retro_task_t *task,
@ -609,40 +597,30 @@ static void task_save_handler_finished(retro_task_t *task,
free(state); free(state);
} }
static size_t content_align_size(size_t size) /* Align to 8-byte boundary */
{ #define CONTENT_ALIGN_SIZE(size) ((((size) + 7) & ~7))
/* align to 8-byte boundary */
return ((size + 7) & ~7);
}
static bool content_get_rastate_size(rastate_size_info_t* size) static size_t content_get_rastate_size(rastate_size_info_t* size)
{ {
retro_ctx_size_info_t info; retro_ctx_size_info_t info;
core_serialize_size(&info); core_serialize_size(&info);
if (!info.size) if (!info.size)
return false; return 0;
size->coremem_size = info.size; size->coremem_size = info.size;
/* 8-byte identifier, 8-byte block header, content, 8-byte terminator */ /* 8-byte identifier, 8-byte block header, content, 8-byte terminator */
size->total_size = 8 + 8 + content_align_size(info.size) + 8; size->total_size = 8 + 8 + CONTENT_ALIGN_SIZE(info.size) + 8;
#ifdef HAVE_CHEEVOS #ifdef HAVE_CHEEVOS
size->cheevos_size = rcheevos_get_serialize_size(); /* 8-byte block header + content */
if (size->cheevos_size > 0) if ((size->cheevos_size = rcheevos_get_serialize_size()) > 0)
size->total_size += 8 + content_align_size(size->cheevos_size); /* 8-byte block header + content */ size->total_size += 8 + CONTENT_ALIGN_SIZE(size->cheevos_size);
#endif #endif
return size->total_size;
return true;
} }
size_t content_get_serialized_size(void) size_t content_get_serialized_size(void)
{ {
rastate_size_info_t size; rastate_size_info_t size;
if (!content_get_rastate_size(&size)) return content_get_rastate_size(&size);
return 0;
return size.total_size;
} }
static void content_write_block_header(unsigned char* output, const char* header, size_t size) static void content_write_block_header(unsigned char* output, const char* header, size_t size)
@ -654,7 +632,8 @@ static void content_write_block_header(unsigned char* output, const char* header
output[7] = ((size >> 24) & 0xFF); output[7] = ((size >> 24) & 0xFF);
} }
static bool content_write_serialized_state(void* buffer, rastate_size_info_t* size) static bool content_write_serialized_state(void* buffer,
rastate_size_info_t* size)
{ {
retro_ctx_serialize_info_t serial_info; retro_ctx_serialize_info_t serial_info;
unsigned char* output = (unsigned char*)buffer; unsigned char* output = (unsigned char*)buffer;
@ -674,15 +653,15 @@ static bool content_write_serialized_state(void* buffer, rastate_size_info_t* si
if (!core_serialize(&serial_info)) if (!core_serialize(&serial_info))
return false; return false;
output += content_align_size(size->coremem_size); output += CONTENT_ALIGN_SIZE(size->coremem_size);
#ifdef HAVE_CHEEVOS #ifdef HAVE_CHEEVOS
if (size->cheevos_size) if (size->cheevos_size)
{ {
content_write_block_header(output, RASTATE_CHEEVOS_BLOCK, size->cheevos_size); content_write_block_header(output,
RASTATE_CHEEVOS_BLOCK, size->cheevos_size);
if (rcheevos_get_serialized_data(output + 8)) if (rcheevos_get_serialized_data(output + 8))
output += content_align_size(size->cheevos_size) + 8; output += CONTENT_ALIGN_SIZE(size->cheevos_size) + 8;
} }
#endif #endif
@ -694,21 +673,18 @@ static bool content_write_serialized_state(void* buffer, rastate_size_info_t* si
bool content_serialize_state(void* buffer, size_t buffer_size) bool content_serialize_state(void* buffer, size_t buffer_size)
{ {
rastate_size_info_t size; rastate_size_info_t size;
if (!content_get_rastate_size(&size)) size_t len = content_get_rastate_size(&size);
if (len == 0 || len > buffer_size)
return false; return false;
if (size.total_size > buffer_size)
return false;
return content_write_serialized_state(buffer, &size); return content_write_serialized_state(buffer, &size);
} }
static void *content_get_serialized_data(size_t* serial_size) static void *content_get_serialized_data(size_t* serial_size)
{ {
size_t len;
void* data; void* data;
rastate_size_info_t size; rastate_size_info_t size;
if (!content_get_rastate_size(&size)) if ((len = content_get_rastate_size(&size)) == 0)
return NULL; return NULL;
/* Ensure buffer is initialised to zero /* Ensure buffer is initialised to zero
@ -716,8 +692,7 @@ static void *content_get_serialized_data(size_t* serial_size)
* sizes when core requests a larger buffer * sizes when core requests a larger buffer
* than it needs (and leaves the excess * than it needs (and leaves the excess
* as uninitialised garbage) */ * as uninitialised garbage) */
data = calloc(size.total_size, 1); if (!(data = calloc(len, 1)))
if (!data)
return NULL; return NULL;
if (!content_write_serialized_state(data, &size)) if (!content_write_serialized_state(data, &size))
@ -738,8 +713,8 @@ static void *content_get_serialized_data(size_t* serial_size)
**/ **/
static void task_save_handler(retro_task_t *task) static void task_save_handler(retro_task_t *task)
{ {
int written;
ssize_t remaining; ssize_t remaining;
int written = 0;
save_task_state_t *state = (save_task_state_t*)task->state; save_task_state_t *state = (save_task_state_t*)task->state;
if (!state->file) if (!state->file)
@ -766,12 +741,11 @@ static void task_save_handler(retro_task_t *task)
remaining = MIN(state->size - state->written, SAVE_STATE_CHUNK); remaining = MIN(state->size - state->written, SAVE_STATE_CHUNK);
if (state->data) if (state->data)
{
written = (int)intfstream_write(state->file, written = (int)intfstream_write(state->file,
(uint8_t*)state->data + state->written, remaining); (uint8_t*)state->data + state->written, remaining);
else
written = 0;
state->written += written; state->written += written;
}
task_set_progress(task, (state->written / (float)state->size) * 100); task_set_progress(task, (state->written / (float)state->size) * 100);
@ -779,7 +753,6 @@ static void task_save_handler(retro_task_t *task)
{ {
size_t err_size = 8192 * sizeof(char); size_t err_size = 8192 * sizeof(char);
char *err = (char*)malloc(err_size); char *err = (char*)malloc(err_size);
err[0] = '\0';
if (state->undo_save) if (state->undo_save)
{ {
@ -787,7 +760,7 @@ static void task_save_handler(retro_task_t *task)
MSG_FAILED_TO_UNDO_SAVE_STATE); MSG_FAILED_TO_UNDO_SAVE_STATE);
RARCH_ERR("[State]: %s \"%s\".\n", failed_undo_str, RARCH_ERR("[State]: %s \"%s\".\n", failed_undo_str,
undo_save_buf.path); undo_save_buf.path);
err[0] = '\0';
snprintf(err, err_size - 1, "%s \"RAM\".", failed_undo_str); snprintf(err, err_size - 1, "%s \"RAM\".", failed_undo_str);
} }
else else
@ -837,8 +810,6 @@ static void task_save_handler(retro_task_t *task)
if (!string_is_empty(msg)) if (!string_is_empty(msg))
free(msg); free(msg);
return;
} }
} }
@ -852,26 +823,27 @@ static void task_save_handler(retro_task_t *task)
**/ **/
static bool task_push_undo_save_state(const char *path, void *data, size_t size) static bool task_push_undo_save_state(const char *path, void *data, size_t size)
{ {
settings_t *settings;
retro_task_t *task = task_init(); retro_task_t *task = task_init();
save_task_state_t *state = (save_task_state_t*)calloc(1, sizeof(*state)); save_task_state_t *state = (save_task_state_t*)
settings_t *settings = config_get_ptr(); calloc(1, sizeof(*state));
#if defined(HAVE_ZLIB)
bool compress_files = settings->bools.savestate_file_compression;
#else
bool compress_files = false;
#endif
if (!task || !state) if (!task || !state)
goto error; goto error;
settings = config_get_ptr();
strlcpy(state->path, path, sizeof(state->path)); strlcpy(state->path, path, sizeof(state->path));
state->data = data; state->data = data;
state->size = size; state->size = size;
state->undo_save = true; state->undo_save = true;
state->state_slot = settings->ints.state_slot; state->state_slot = settings->ints.state_slot;
state->has_valid_framebuffer = video_driver_cached_frame_has_valid_framebuffer(); state->has_valid_framebuffer = video_driver_cached_frame_has_valid_framebuffer();
state->compress_files = compress_files; #if defined(HAVE_ZLIB)
state->compress_files = settings->bools.savestate_file_compression;
#else
state->compress_files = false;
#endif
task->type = TASK_TYPE_BLOCKING; task->type = TASK_TYPE_BLOCKING;
task->state = state; task->state = state;
task->handler = task_save_handler; task->handler = task_save_handler;
@ -901,18 +873,16 @@ error:
**/ **/
bool content_undo_save_state(void) bool content_undo_save_state(void)
{ {
if (!core_info_current_supports_savestate()) if (core_info_current_supports_savestate())
{ return task_push_undo_save_state(
undo_save_buf.path,
undo_save_buf.data,
undo_save_buf.size);
RARCH_LOG("[State]: %s\n", RARCH_LOG("[State]: %s\n",
msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES)); msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES));
return false; return false;
} }
return task_push_undo_save_state(undo_save_buf.path,
undo_save_buf.data,
undo_save_buf.size);
}
/** /**
* task_load_handler_finished: * task_load_handler_finished:
* @task : the task to finish * @task : the task to finish
@ -936,9 +906,7 @@ static void task_load_handler_finished(retro_task_t *task,
if (!task_get_error(task) && task_get_cancelled(task)) if (!task_get_error(task) && task_get_cancelled(task))
task_set_error(task, strdup("Task canceled")); task_set_error(task, strdup("Task canceled"));
task_data = (load_task_data_t*)calloc(1, sizeof(*task_data)); if (!(task_data = (load_task_data_t*)calloc(1, sizeof(*task_data))))
if (!task_data)
return; return;
memcpy(task_data, state, sizeof(*task_data)); memcpy(task_data, state, sizeof(*task_data));
@ -965,25 +933,20 @@ static void task_load_handler(retro_task_t *task)
/* Always use RZIP interface when reading state /* Always use RZIP interface when reading state
* files - this will automatically handle uncompressed * files - this will automatically handle uncompressed
* data */ * data */
state->file = intfstream_open_rzip_file(state->path, if (!(state->file = intfstream_open_rzip_file(state->path,
RETRO_VFS_FILE_ACCESS_READ); RETRO_VFS_FILE_ACCESS_READ)))
goto end;
#else #else
state->file = intfstream_open_file(state->path, if (!(state->file = intfstream_open_file(state->path,
RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_READ,
RETRO_VFS_FILE_ACCESS_HINT_NONE); RETRO_VFS_FILE_ACCESS_HINT_NONE)))
goto end;
#endif #endif
if (!state->file) if ((state->size = intfstream_get_size(state->file)) < 0)
goto end; goto end;
state->size = intfstream_get_size(state->file); if (!(state->data = malloc(state->size + 1)))
if (state->size < 0)
goto end;
state->data = malloc(state->size + 1);
if (!state->data)
goto end; goto end;
} }
@ -1033,22 +996,28 @@ static void task_load_handler(retro_task_t *task)
size_t msg_size = 8192 * sizeof(char); size_t msg_size = 8192 * sizeof(char);
char *msg = (char*)malloc(msg_size); char *msg = (char*)malloc(msg_size);
msg[0] = '\0';
if (state->autoload) if (state->autoload)
snprintf(msg, msg_size - 1, {
msg[0] = '\0';
snprintf(msg,
msg_size - 1,
msg_hash_to_str(MSG_AUTOLOADING_SAVESTATE_SUCCEEDED), msg_hash_to_str(MSG_AUTOLOADING_SAVESTATE_SUCCEEDED),
state->path); state->path);
}
else else
{ {
if (state->state_slot < 0) if (state->state_slot < 0)
strlcpy(msg, msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT_AUTO), strlcpy(msg,
msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT_AUTO),
msg_size - 1); msg_size - 1);
else else
{
msg[0] = '\0';
snprintf(msg, msg_size - 1, snprintf(msg, msg_size - 1,
msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT), msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT),
state->state_slot); state->state_slot);
} }
}
task_set_title(task, strdup(msg)); task_set_title(task, strdup(msg));
free(msg); free(msg);
@ -1066,17 +1035,19 @@ end:
static bool content_load_rastate1(unsigned char* input, size_t size) static bool content_load_rastate1(unsigned char* input, size_t size)
{ {
unsigned char *stop = input + size; unsigned char *stop = input + size;
unsigned char* marker;
bool seen_core = false; bool seen_core = false;
#ifdef HAVE_CHEEVOS #ifdef HAVE_CHEEVOS
bool seen_cheevos = false; bool seen_cheevos = false;
#endif #endif
input += 8; input += 8;
while (input < stop) while (input < stop)
{ {
size_t block_size = (input[7] << 24 | input[6] << 16 | input[5] << 8 | input[4]); size_t block_size = ( input[7] << 24
marker = input; | input[6] << 16 | input[5] << 8 | input[4]);
unsigned char *marker = input;
input += 8; input += 8;
if (memcmp(marker, RASTATE_MEM_BLOCK, 4) == 0) if (memcmp(marker, RASTATE_MEM_BLOCK, 4) == 0)
@ -1097,11 +1068,9 @@ static bool content_load_rastate1(unsigned char* input, size_t size)
} }
#endif #endif
else if (memcmp(marker, RASTATE_END_BLOCK, 4) == 0) else if (memcmp(marker, RASTATE_END_BLOCK, 4) == 0)
{
break; break;
}
input += content_align_size(block_size); input += CONTENT_ALIGN_SIZE(block_size);
} }
if (!seen_core) if (!seen_core)
@ -1115,7 +1084,8 @@ static bool content_load_rastate1(unsigned char* input, size_t size)
return true; return true;
} }
bool content_deserialize_state(const void* serialized_data, size_t serialized_size) bool content_deserialize_state(
const void* serialized_data, size_t serialized_size)
{ {
if (memcmp(serialized_data, "RASTATE", 7) != 0) if (memcmp(serialized_data, "RASTATE", 7) != 0)
{ {
@ -1136,10 +1106,9 @@ bool content_deserialize_state(const void* serialized_data, size_t serialized_si
switch (input[7]) /* version */ switch (input[7]) /* version */
{ {
case 1: case 1:
if (!content_load_rastate1(input, serialized_size)) if (content_load_rastate1(input, serialized_size))
return false;
break; break;
/* fall-through intentional */
default: default:
return false; return false;
} }
@ -1194,8 +1163,7 @@ static void content_load_state_cb(retro_task_t *task,
undo_save_buf.data = NULL; undo_save_buf.data = NULL;
} }
undo_save_buf.data = malloc(size); if (!(undo_save_buf.data = malloc(size)))
if (!undo_save_buf.data)
goto error; goto error;
memcpy(undo_save_buf.data, buf, size); memcpy(undo_save_buf.data, buf, size);
@ -1212,10 +1180,9 @@ static void content_load_state_cb(retro_task_t *task,
{ {
RARCH_LOG("[SRAM]: %s.\n", RARCH_LOG("[SRAM]: %s.\n",
msg_hash_to_str(MSG_BLOCKING_SRAM_OVERWRITE)); msg_hash_to_str(MSG_BLOCKING_SRAM_OVERWRITE));
blocks = (struct sram_block*)
calloc(task_save_files->size, sizeof(*blocks));
if (blocks) if ((blocks = (struct sram_block*)
calloc(task_save_files->size, sizeof(*blocks))))
{ {
num_blocks = (unsigned)task_save_files->size; num_blocks = (unsigned)task_save_files->size;
for (i = 0; i < num_blocks; i++) for (i = 0; i < num_blocks; i++)
@ -1249,8 +1216,7 @@ static void content_load_state_cb(retro_task_t *task,
core_get_memory(&mem_info); core_get_memory(&mem_info);
ptr = mem_info.data; if ((ptr = mem_info.data))
if (ptr)
memcpy(blocks[i].data, ptr, blocks[i].size); memcpy(blocks[i].data, ptr, blocks[i].size);
} }
} }
@ -1272,8 +1238,7 @@ static void content_load_state_cb(retro_task_t *task,
core_get_memory(&mem_info); core_get_memory(&mem_info);
ptr = mem_info.data; if ((ptr = mem_info.data))
if (ptr)
memcpy(ptr, blocks[i].data, blocks[i].size); memcpy(ptr, blocks[i].data, blocks[i].size);
} }
} }
@ -1333,16 +1298,9 @@ static void save_state_cb(retro_task_t *task,
**/ **/
static void task_push_save_state(const char *path, void *data, size_t size, bool autosave) static void task_push_save_state(const char *path, void *data, size_t size, bool autosave)
{ {
settings_t *settings = config_get_ptr();
retro_task_t *task = task_init(); retro_task_t *task = task_init();
save_task_state_t *state = (save_task_state_t*)calloc(1, sizeof(*state)); save_task_state_t *state = (save_task_state_t*)calloc(1, sizeof(*state));
settings_t *settings = config_get_ptr();
bool savestate_thumbnail_enable = settings->bools.savestate_thumbnail_enable;
int state_slot = settings->ints.state_slot;
#if defined(HAVE_ZLIB)
bool compress_files = settings->bools.savestate_file_compression;
#else
bool compress_files = false;
#endif
if (!task || !state) if (!task || !state)
goto error; goto error;
@ -1352,10 +1310,14 @@ static void task_push_save_state(const char *path, void *data, size_t size, bool
state->size = size; state->size = size;
state->autosave = autosave; state->autosave = autosave;
state->mute = autosave; /* don't show OSD messages if we are auto-saving */ state->mute = autosave; /* don't show OSD messages if we are auto-saving */
state->thumbnail_enable = savestate_thumbnail_enable; state->thumbnail_enable = settings->bools.savestate_thumbnail_enable;
state->state_slot = state_slot; state->state_slot = settings->ints.state_slot;
state->has_valid_framebuffer = video_driver_cached_frame_has_valid_framebuffer(); state->has_valid_framebuffer = video_driver_cached_frame_has_valid_framebuffer();
state->compress_files = compress_files; #if defined(HAVE_ZLIB)
state->compress_files = settings->bools.savestate_file_compression;
#else
state->compress_files = false;
#endif
task->type = TASK_TYPE_BLOCKING; task->type = TASK_TYPE_BLOCKING;
task->state = state; task->state = state;
@ -1428,21 +1390,13 @@ static void task_push_load_and_save_state(const char *path, void *data,
{ {
retro_task_t *task = NULL; retro_task_t *task = NULL;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
int state_slot = settings->ints.state_slot;
#if defined(HAVE_ZLIB)
bool compress_files = settings->bools.savestate_file_compression;
#else
bool compress_files = false;
#endif
save_task_state_t *state = (save_task_state_t*) save_task_state_t *state = (save_task_state_t*)
calloc(1, sizeof(*state)); calloc(1, sizeof(*state));
if (!state) if (!state)
return; return;
task = task_init(); if (!(task = task_init()))
if (!task)
{ {
free(state); free(state);
return; return;
@ -1458,10 +1412,14 @@ static void task_push_load_and_save_state(const char *path, void *data,
are auto-saving */ are auto-saving */
if (load_to_backup_buffer) if (load_to_backup_buffer)
state->mute = true; state->mute = true;
state->state_slot = state_slot; state->state_slot = settings->ints.state_slot;
state->has_valid_framebuffer = state->has_valid_framebuffer =
video_driver_cached_frame_has_valid_framebuffer(); video_driver_cached_frame_has_valid_framebuffer();
state->compress_files = compress_files; #if defined(HAVE_ZLIB)
state->compress_files = settings->bools.savestate_file_compression;
#else
state->compress_files = false;
#endif
task->state = state; task->state = state;
task->type = TASK_TYPE_BLOCKING; task->type = TASK_TYPE_BLOCKING;
@ -1492,9 +1450,9 @@ static void task_push_load_and_save_state(const char *path, void *data,
**/ **/
bool content_save_state(const char *path, bool save_to_disk, bool autosave) bool content_save_state(const char *path, bool save_to_disk, bool autosave)
{ {
size_t serial_size;
retro_ctx_size_info_t info; retro_ctx_size_info_t info;
void *data = NULL; void *data = NULL;
size_t serial_size;
if (!core_info_current_supports_savestate()) if (!core_info_current_supports_savestate())
{ {
@ -1511,9 +1469,7 @@ bool content_save_state(const char *path, bool save_to_disk, bool autosave)
if (!save_state_in_background) if (!save_state_in_background)
{ {
data = content_get_serialized_data(&serial_size); if (!(data = content_get_serialized_data(&serial_size)))
if (!data)
{ {
RARCH_ERR("[State]: %s \"%s\".\n", RARCH_ERR("[State]: %s \"%s\".\n",
msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO), msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO),
@ -1546,15 +1502,16 @@ bool content_save_state(const char *path, bool save_to_disk, bool autosave)
else else
{ {
if (!data) if (!data)
data = content_get_serialized_data(&serial_size); {
if (!(data = content_get_serialized_data(&serial_size)))
if (!data)
{ {
RARCH_ERR("[State]: %s \"%s\".\n", RARCH_ERR("[State]: %s \"%s\".\n",
msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO), msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO),
path); path);
return false; return false;
} }
}
/* save_to_disk is false, which means we are saving the state /* save_to_disk is false, which means we are saving the state
in undo_load_buf to allow content_undo_load_state() to restore it */ in undo_load_buf to allow content_undo_load_state() to restore it */
@ -1565,8 +1522,7 @@ bool content_save_state(const char *path, bool save_to_disk, bool autosave)
undo_load_buf.data = NULL; undo_load_buf.data = NULL;
} }
undo_load_buf.data = malloc(serial_size); if (!(undo_load_buf.data = malloc(serial_size)))
if (!undo_load_buf.data)
{ {
free(data); free(data);
return false; return false;
@ -1583,9 +1539,9 @@ bool content_save_state(const char *path, bool save_to_disk, bool autosave)
/** /**
* content_ram_state_pending: * content_ram_state_pending:
* Check a ram state write to disk. * Check a RAM state write to disk.
* *
* Returns: true if need to write, false otherwise. * @return true if need to write, false otherwise.
**/ **/
bool content_ram_state_pending(void) bool content_ram_state_pending(void)
{ {
@ -1594,13 +1550,7 @@ bool content_ram_state_pending(void)
static bool task_save_state_finder(retro_task_t *task, void *user_data) static bool task_save_state_finder(retro_task_t *task, void *user_data)
{ {
if (!task) return (task && task->handler == task_save_handler);
return false;
if (task->handler == task_save_handler)
return true;
return false;
} }
/* Returns true if a save state task is in progress */ /* Returns true if a save state task is in progress */
@ -1611,10 +1561,7 @@ static bool content_save_state_in_progress(void* data)
find_data.func = task_save_state_finder; find_data.func = task_save_state_finder;
find_data.userdata = NULL; find_data.userdata = NULL;
if (task_queue_find(&find_data)) return task_queue_find(&find_data);
return true;
return false;
} }
void content_wait_for_save_state_task(void) void content_wait_for_save_state_task(void)
@ -1625,12 +1572,10 @@ void content_wait_for_save_state_task(void)
/** /**
* content_load_state: * content_load_state:
* @path : path that state will be loaded from. * @path : path that state will be loaded from.
* @load_to_backup_buffer: If true, the state will be loaded into undo_save_buf. * @load_to_backup_buffer : If true, state will be loaded into undo_save_buf.
* Load a state from disk to memory. * Load a state from disk to memory.
* *
* Returns: true if successful, false otherwise. * @return true if successful, false otherwise.
*
*
**/ **/
bool content_load_state(const char *path, bool content_load_state(const char *path,
bool load_to_backup_buffer, bool autoload) bool load_to_backup_buffer, bool autoload)
@ -1638,12 +1583,6 @@ bool content_load_state(const char *path,
retro_task_t *task = NULL; retro_task_t *task = NULL;
save_task_state_t *state = NULL; save_task_state_t *state = NULL;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
int state_slot = settings->ints.state_slot;
#if defined(HAVE_ZLIB)
bool compress_files = settings->bools.savestate_file_compression;
#else
bool compress_files = false;
#endif
if (!core_info_current_supports_savestate()) if (!core_info_current_supports_savestate())
{ {
@ -1661,10 +1600,14 @@ bool content_load_state(const char *path,
strlcpy(state->path, path, sizeof(state->path)); strlcpy(state->path, path, sizeof(state->path));
state->load_to_backup_buffer = load_to_backup_buffer; state->load_to_backup_buffer = load_to_backup_buffer;
state->autoload = autoload; state->autoload = autoload;
state->state_slot = state_slot; state->state_slot = settings->ints.state_slot;
state->has_valid_framebuffer = state->has_valid_framebuffer =
video_driver_cached_frame_has_valid_framebuffer(); video_driver_cached_frame_has_valid_framebuffer();
state->compress_files = compress_files; #if defined(HAVE_ZLIB)
state->compress_files = settings->bools.savestate_file_compression;
#else
state->compress_files = false;
#endif
task->type = TASK_TYPE_BLOCKING; task->type = TASK_TYPE_BLOCKING;
task->state = state; task->state = state;
@ -1687,15 +1630,13 @@ error:
bool content_rename_state(const char *origin, const char *dest) bool content_rename_state(const char *origin, const char *dest)
{ {
int ret = 0;
if (filestream_exists(dest)) if (filestream_exists(dest))
filestream_delete(dest); filestream_delete(dest);
ret = filestream_rename(origin, dest); if (!filestream_rename(origin, dest))
if (!ret)
return true; return true;
RARCH_ERR("[State]: Error %d renaming file \"%s\".\n", ret, origin); RARCH_ERR("[State]: Error renaming file \"%s\".\n", origin);
return false; return false;
} }
@ -1705,7 +1646,7 @@ bool content_rename_state(const char *origin, const char *dest)
* As it is, when e.g. closing Gambatte, we get the * As it is, when e.g. closing Gambatte, we get the
* same printf message 4 times. * same printf message 4 times.
*/ */
bool content_reset_savestate_backups(void) void content_reset_savestate_backups(void)
{ {
if (undo_save_buf.data) if (undo_save_buf.data)
{ {
@ -1734,8 +1675,6 @@ bool content_reset_savestate_backups(void)
ram_buf.state_buf.path[0] = '\0'; ram_buf.state_buf.path[0] = '\0';
ram_buf.state_buf.size = 0; ram_buf.state_buf.size = 0;
ram_buf.to_write_file = false; ram_buf.to_write_file = false;
return true;
} }
bool content_undo_load_buf_is_empty(void) bool content_undo_load_buf_is_empty(void)
@ -1753,7 +1692,6 @@ static bool content_get_memory(retro_ctx_memory_info_t *mem_info,
{ {
ram->type = task_save_files->elems[slot].attr.i; ram->type = task_save_files->elems[slot].attr.i;
ram->path = task_save_files->elems[slot].data; ram->path = task_save_files->elems[slot].data;
mem_info->id = ram->type; mem_info->id = ram->type;
core_get_memory(mem_info); core_get_memory(mem_info);
@ -1785,8 +1723,8 @@ bool content_load_ram_file(unsigned slot)
* not exist. This is a common enough occurrence * not exist. This is a common enough occurrence
* that we should check before attempting to * that we should check before attempting to
* invoke the relevant read_file() function */ * invoke the relevant read_file() function */
if (string_is_empty(ram.path) || if ( string_is_empty(ram.path)
!path_is_valid(ram.path)) || !path_is_valid(ram.path))
return false; return false;
#if defined(HAVE_ZLIB) #if defined(HAVE_ZLIB)
@ -1876,9 +1814,9 @@ static bool dump_to_file_desperate(const void *data,
/** /**
* content_load_state_from_ram: * content_load_state_from_ram:
* Load a state from ram. * Load a state from RAM.
* *
* Returns: true if successful, false otherwise. * @return true if successful, false otherwise.
**/ **/
bool content_load_state_from_ram(void) bool content_load_state_from_ram(void)
{ {
@ -1920,9 +1858,10 @@ bool content_load_state_from_ram(void)
{ {
RARCH_ERR("[State]: %s.\n", RARCH_ERR("[State]: %s.\n",
msg_hash_to_str(MSG_FAILED_TO_LOAD_SRAM)); msg_hash_to_str(MSG_FAILED_TO_LOAD_SRAM));
return false;
} }
return ret; return true;
} }
/** /**
@ -1998,46 +1937,40 @@ bool content_save_state_to_ram(void)
/** /**
* content_ram_state_to_file: * content_ram_state_to_file:
* @path : path of ram state that shall be written to. * @path : path of RAM state that shall be written to.
*
* Save a RAM state from memory to disk. * Save a RAM state from memory to disk.
* *
* @return true if successful, false otherwise. * @return true if successful, false otherwise.
**/ **/
bool content_ram_state_to_file(const char *path) bool content_ram_state_to_file(const char *path)
{ {
if ( path
&& ram_buf.state_buf.data
&& ram_buf.to_write_file)
{
#if defined(HAVE_ZLIB)
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
#if defined(HAVE_ZLIB) if (settings->bools.save_file_compression)
bool compress_files = settings->bools.save_file_compression; {
#else if (rzipstream_write_file(
bool compress_files = false; path, ram_buf.state_buf.data, ram_buf.state_buf.size))
#endif goto success;
bool write_success = false; }
if (!path)
return false;
if (!ram_buf.state_buf.data)
return false;
if (!ram_buf.to_write_file)
return false;
#if defined(HAVE_ZLIB)
if (compress_files)
write_success = rzipstream_write_file(
path, ram_buf.state_buf.data, ram_buf.state_buf.size);
else else
#endif #endif
write_success = filestream_write_file(
path, ram_buf.state_buf.data, ram_buf.state_buf.size);
if (write_success)
{ {
ram_buf.to_write_file = false; if (filestream_write_file(
return true; path, ram_buf.state_buf.data, ram_buf.state_buf.size))
goto success;
}
} }
return false; return false;
success:
ram_buf.to_write_file = false;
return true;
} }
/** /**
@ -2052,7 +1985,6 @@ bool content_save_ram_file(unsigned slot, bool compress)
{ {
struct ram_type ram; struct ram_type ram;
retro_ctx_memory_info_t mem_info; retro_ctx_memory_info_t mem_info;
bool write_success;
if (!content_get_memory(&mem_info, &ram, slot)) if (!content_get_memory(&mem_info, &ram, slot))
return false; return false;
@ -2065,15 +1997,26 @@ bool content_save_ram_file(unsigned slot, bool compress)
#if defined(HAVE_ZLIB) #if defined(HAVE_ZLIB)
if (compress) if (compress)
write_success = rzipstream_write_file( {
ram.path, mem_info.data, mem_info.size); if (!rzipstream_write_file(
ram.path, mem_info.data, mem_info.size))
goto fail;
}
else else
#endif #endif
write_success = filestream_write_file(
ram.path, mem_info.data, mem_info.size);
if (!write_success)
{ {
if (!filestream_write_file(
ram.path, mem_info.data, mem_info.size))
goto fail;
}
RARCH_LOG("[SRAM]: %s \"%s\".\n",
msg_hash_to_str(MSG_SAVED_SUCCESSFULLY_TO),
ram.path);
return true;
fail:
RARCH_ERR("[SRAM]: %s.\n", RARCH_ERR("[SRAM]: %s.\n",
msg_hash_to_str(MSG_FAILED_TO_SAVE_SRAM)); msg_hash_to_str(MSG_FAILED_TO_SAVE_SRAM));
RARCH_WARN("[SRAM]: Attempting to recover ...\n"); RARCH_WARN("[SRAM]: Attempting to recover ...\n");
@ -2083,19 +2026,10 @@ bool content_save_ram_file(unsigned slot, bool compress)
* will be called. */ * will be called. */
if (!dump_to_file_desperate( if (!dump_to_file_desperate(
mem_info.data, mem_info.size, ram.type)) mem_info.data, mem_info.size, ram.type))
{
RARCH_WARN("[SRAM]: Failed ... Cannot recover save file.\n"); RARCH_WARN("[SRAM]: Failed ... Cannot recover save file.\n");
}
return false; return false;
} }
RARCH_LOG("[SRAM]: %s \"%s\".\n",
msg_hash_to_str(MSG_SAVED_SUCCESSFULLY_TO),
ram.path);
return true;
}
bool event_save_files(bool is_sram_used) bool event_save_files(bool is_sram_used)
{ {
unsigned i; unsigned i;
@ -2105,8 +2039,6 @@ bool event_save_files(bool is_sram_used)
#endif #endif
#if defined(HAVE_ZLIB) #if defined(HAVE_ZLIB)
bool compress_files = settings->bools.save_file_compression; bool compress_files = settings->bools.save_file_compression;
#else
bool compress_files = false;
#endif #endif
#ifdef HAVE_CHEATS #ifdef HAVE_CHEATS
@ -2117,7 +2049,13 @@ bool event_save_files(bool is_sram_used)
return false; return false;
for (i = 0; i < task_save_files->size; i++) for (i = 0; i < task_save_files->size; i++)
{
#if defined(HAVE_ZLIB)
content_save_ram_file(i, compress_files); content_save_ram_file(i, compress_files);
#else
content_save_ram_file(i, false);
#endif
}
return true; return true;
} }
@ -2131,7 +2069,7 @@ bool event_load_save_files(bool is_sram_load_disabled)
return false; return false;
/* Report a successful load operation if /* Report a successful load operation if
* any type of ram file is found and * any type of RAM file is found and
* processed correctly */ * processed correctly */
for (i = 0; i < task_save_files->size; i++) for (i = 0; i < task_save_files->size; i++)
success |= content_load_ram_file(i); success |= content_load_ram_file(i);
@ -2144,12 +2082,10 @@ void path_init_savefile_rtc(const char *savefile_path)
union string_list_elem_attr attr; union string_list_elem_attr attr;
char savefile_name_rtc[PATH_MAX_LENGTH]; char savefile_name_rtc[PATH_MAX_LENGTH];
savefile_name_rtc[0] = '\0';
attr.i = RETRO_MEMORY_SAVE_RAM; attr.i = RETRO_MEMORY_SAVE_RAM;
string_list_append(task_save_files, savefile_path, attr); string_list_append(task_save_files, savefile_path, attr);
/* Infer .rtc save path from save ram path. */ /* Infer .rtc save path from save RAM path. */
attr.i = RETRO_MEMORY_RTC; attr.i = RETRO_MEMORY_RTC;
fill_pathname(savefile_name_rtc, fill_pathname(savefile_name_rtc,
savefile_path, ".rtc", savefile_path, ".rtc",