mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 04:14:00 +00:00
Add optional save (SRAM) file compression
This commit is contained in:
parent
3fa60d08de
commit
0d1fd657ab
@ -911,6 +911,10 @@ static const bool savestate_auto_load = false;
|
||||
|
||||
static const bool savestate_thumbnail_enable = false;
|
||||
|
||||
/* When creating save (srm) files, compress
|
||||
* written data */
|
||||
#define DEFAULT_SAVE_FILE_COMPRESSION false
|
||||
|
||||
/* When creating save state files, compress
|
||||
* written data */
|
||||
#define DEFAULT_SAVESTATE_FILE_COMPRESSION false
|
||||
|
@ -1614,6 +1614,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
SETTING_BOOL("savestate_auto_save", &settings->bools.savestate_auto_save, true, savestate_auto_save, false);
|
||||
SETTING_BOOL("savestate_auto_load", &settings->bools.savestate_auto_load, true, savestate_auto_load, false);
|
||||
SETTING_BOOL("savestate_thumbnail_enable", &settings->bools.savestate_thumbnail_enable, true, savestate_thumbnail_enable, false);
|
||||
SETTING_BOOL("save_file_compression", &settings->bools.save_file_compression, true, DEFAULT_SAVE_FILE_COMPRESSION, false);
|
||||
SETTING_BOOL("savestate_file_compression", &settings->bools.savestate_file_compression, true, DEFAULT_SAVESTATE_FILE_COMPRESSION, false);
|
||||
SETTING_BOOL("history_list_enable", &settings->bools.history_list_enable, true, DEFAULT_HISTORY_LIST_ENABLE, false);
|
||||
SETTING_BOOL("playlist_entry_rename", &settings->bools.playlist_entry_rename, true, DEFAULT_PLAYLIST_ENTRY_RENAME, false);
|
||||
|
@ -344,6 +344,7 @@ typedef struct settings
|
||||
bool savestate_auto_save;
|
||||
bool savestate_auto_load;
|
||||
bool savestate_thumbnail_enable;
|
||||
bool save_file_compression;
|
||||
bool savestate_file_compression;
|
||||
bool network_cmd_enable;
|
||||
bool stdin_cmd_enable;
|
||||
|
@ -43,7 +43,7 @@ typedef struct content_ctx_info
|
||||
bool content_load_ram_file(unsigned slot);
|
||||
|
||||
/* Save a RAM state from memory to disk. */
|
||||
bool content_save_ram_file(unsigned slot);
|
||||
bool content_save_ram_file(unsigned slot, bool compress);
|
||||
|
||||
/* Load a state from disk to memory. */
|
||||
bool content_load_state(const char* path, bool load_to_backup_buffer, bool autoload);
|
||||
|
@ -1200,6 +1200,8 @@ MSG_HASH(MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD,
|
||||
"savestate_auto_load")
|
||||
MSG_HASH(MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE,
|
||||
"savestate_thumbnails")
|
||||
MSG_HASH(MENU_ENUM_LABEL_SAVE_FILE_COMPRESSION,
|
||||
"save_file_compression")
|
||||
MSG_HASH(MENU_ENUM_LABEL_SAVESTATE_FILE_COMPRESSION,
|
||||
"savestate_file_compression")
|
||||
MSG_HASH(MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE,
|
||||
|
@ -2616,6 +2616,14 @@ MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE,
|
||||
"Show thumbnails of save states inside the menu."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_SAVE_FILE_COMPRESSION,
|
||||
"SaveRAM Compression"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_SAVE_FILE_COMPRESSION,
|
||||
"Write non-volatile Save RAM files in an archived format. Dramatically reduces file size at the expense of (negligibly) increased saving/loading times. Note: Only applies to cores that enable saving via the standard libretro Save RAM interface."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_SAVESTATE_FILE_COMPRESSION,
|
||||
"Savestate Compression"
|
||||
|
@ -381,6 +381,7 @@ default_sublabel_macro(action_bind_sublabel_perfcnt_enable, MENU_
|
||||
default_sublabel_macro(action_bind_sublabel_savestate_auto_save, MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE)
|
||||
default_sublabel_macro(action_bind_sublabel_savestate_auto_load, MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_LOAD)
|
||||
default_sublabel_macro(action_bind_sublabel_savestate_thumbnail_enable, MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE)
|
||||
default_sublabel_macro(action_bind_sublabel_save_file_compression, MENU_ENUM_SUBLABEL_SAVE_FILE_COMPRESSION)
|
||||
default_sublabel_macro(action_bind_sublabel_savestate_file_compression, MENU_ENUM_SUBLABEL_SAVESTATE_FILE_COMPRESSION)
|
||||
default_sublabel_macro(action_bind_sublabel_autosave_interval, MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL)
|
||||
default_sublabel_macro(action_bind_sublabel_input_remap_binds_enable, MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE)
|
||||
@ -2328,6 +2329,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_savestate_thumbnail_enable);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_SAVE_FILE_COMPRESSION:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_save_file_compression);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_SAVESTATE_FILE_COMPRESSION:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_savestate_file_compression);
|
||||
break;
|
||||
|
@ -6855,6 +6855,7 @@ unsigned menu_displaylist_build_list(
|
||||
{MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_SAVESTATE_THUMBNAIL_ENABLE, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_SAVE_FILE_COMPRESSION, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_SAVESTATE_FILE_COMPRESSION, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_SAVEFILES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_SAVESTATES_IN_CONTENT_DIR_ENABLE, PARSE_ONLY_BOOL},
|
||||
|
@ -8951,6 +8951,21 @@ static bool setting_append_list(
|
||||
SD_FLAG_NONE);
|
||||
|
||||
#if defined(HAVE_ZLIB)
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.save_file_compression,
|
||||
MENU_ENUM_LABEL_SAVE_FILE_COMPRESSION,
|
||||
MENU_ENUM_LABEL_VALUE_SAVE_FILE_COMPRESSION,
|
||||
DEFAULT_SAVE_FILE_COMPRESSION,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.savestate_file_compression,
|
||||
|
@ -1607,6 +1607,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(SAVESTATE_AUTO_SAVE),
|
||||
MENU_LABEL(SAVESTATE_AUTO_LOAD),
|
||||
MENU_LABEL(SAVESTATE_THUMBNAIL_ENABLE),
|
||||
MENU_LABEL(SAVE_FILE_COMPRESSION),
|
||||
MENU_LABEL(SAVESTATE_FILE_COMPRESSION),
|
||||
|
||||
MENU_LABEL(SUSPEND_SCREENSAVER_ENABLE),
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <lists/string_list.h>
|
||||
#include <streams/interface_stream.h>
|
||||
#include <streams/file_stream.h>
|
||||
#include <streams/rzip_stream.h>
|
||||
#include <rthreads/rthreads.h>
|
||||
#include <file/file_path.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
@ -129,6 +130,7 @@ struct autosave
|
||||
volatile bool quit;
|
||||
size_t bufsize;
|
||||
unsigned interval;
|
||||
bool compress_files;
|
||||
void *buffer;
|
||||
const void *retro_buffer;
|
||||
const char *path;
|
||||
@ -163,15 +165,22 @@ static void autosave_thread(void *data)
|
||||
|
||||
if (differ)
|
||||
{
|
||||
intfstream_t *file = NULL;
|
||||
|
||||
/* Should probably deal with this more elegantly. */
|
||||
RFILE *file = filestream_open(save->path,
|
||||
RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
if (save->compress_files)
|
||||
file = intfstream_open_rzip_file(save->path,
|
||||
RETRO_VFS_FILE_ACCESS_WRITE);
|
||||
else
|
||||
file = intfstream_open_file(save->path,
|
||||
RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
|
||||
if (file)
|
||||
{
|
||||
filestream_write(file, save->buffer, save->bufsize);
|
||||
filestream_flush(file);
|
||||
filestream_close(file);
|
||||
intfstream_write(file, save->buffer, save->bufsize);
|
||||
intfstream_flush(file);
|
||||
intfstream_close(file);
|
||||
free(file);
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,7 +215,7 @@ static void autosave_thread(void *data)
|
||||
**/
|
||||
static autosave_t *autosave_new(const char *path,
|
||||
const void *data, size_t size,
|
||||
unsigned interval)
|
||||
unsigned interval, bool compress)
|
||||
{
|
||||
void *buf = NULL;
|
||||
autosave_t *handle = (autosave_t*)malloc(sizeof(*handle));
|
||||
@ -216,6 +225,7 @@ static autosave_t *autosave_new(const char *path,
|
||||
handle->quit = false;
|
||||
handle->bufsize = size;
|
||||
handle->interval = interval;
|
||||
handle->compress_files = compress;
|
||||
handle->retro_buffer = data;
|
||||
handle->path = path;
|
||||
|
||||
@ -268,6 +278,11 @@ bool autosave_init(void)
|
||||
autosave_t **list = NULL;
|
||||
settings_t *settings = config_get_ptr();
|
||||
unsigned autosave_interval = settings->uints.autosave_interval;
|
||||
#if defined(HAVE_ZLIB)
|
||||
bool compress_files = settings->bools.save_file_compression;
|
||||
#else
|
||||
bool compress_files = false;
|
||||
#endif
|
||||
|
||||
if (autosave_interval < 1 || !task_save_files)
|
||||
return false;
|
||||
@ -299,7 +314,8 @@ bool autosave_init(void)
|
||||
auto_st = autosave_new(path,
|
||||
mem_info.data,
|
||||
mem_info.size,
|
||||
autosave_interval);
|
||||
autosave_interval,
|
||||
compress_files);
|
||||
|
||||
if (!auto_st)
|
||||
{
|
||||
@ -1471,7 +1487,22 @@ bool content_load_ram_file(unsigned slot)
|
||||
if (!content_get_memory(&mem_info, &ram, slot))
|
||||
return false;
|
||||
|
||||
/* On first run of content, SRAM file will
|
||||
* not exist. This is a common enough occurrence
|
||||
* that we should check before attempting to
|
||||
* invoke the relevant read_file() function */
|
||||
if (string_is_empty(ram.path) ||
|
||||
!path_is_valid(ram.path))
|
||||
return false;
|
||||
|
||||
#if defined(HAVE_ZLIB)
|
||||
/* Always use RZIP interface when reading SRAM
|
||||
* files - this will automatically handle uncompressed
|
||||
* data */
|
||||
if (!rzipstream_read_file(ram.path, &buf, &rc))
|
||||
#else
|
||||
if (!filestream_read_file(ram.path, &buf, &rc))
|
||||
#endif
|
||||
return false;
|
||||
|
||||
if (rc > 0)
|
||||
@ -1539,6 +1570,15 @@ static bool dump_to_file_desperate(const void *data,
|
||||
free(application_data);
|
||||
free(timebuf);
|
||||
|
||||
/* Fallback (emergency) saves are always
|
||||
* uncompressed
|
||||
* > If a regular save fails, then the host
|
||||
* system is experiencing serious technical
|
||||
* difficulties (most likely some kind of
|
||||
* hardware failure)
|
||||
* > In this case, we don't want to further
|
||||
* complicate matters by introducing zlib
|
||||
* compression overheads */
|
||||
if (!filestream_write_file(path, data, size))
|
||||
{
|
||||
free(path);
|
||||
@ -1558,10 +1598,11 @@ static bool dump_to_file_desperate(const void *data,
|
||||
* Save a RAM state from memory to disk.
|
||||
*
|
||||
*/
|
||||
bool content_save_ram_file(unsigned slot)
|
||||
bool content_save_ram_file(unsigned slot, bool compress)
|
||||
{
|
||||
struct ram_type ram;
|
||||
retro_ctx_memory_info_t mem_info;
|
||||
bool write_success;
|
||||
|
||||
if (!content_get_memory(&mem_info, &ram, slot))
|
||||
return false;
|
||||
@ -1572,8 +1613,16 @@ bool content_save_ram_file(unsigned slot)
|
||||
msg_hash_to_str(MSG_TO),
|
||||
ram.path);
|
||||
|
||||
if (!filestream_write_file(
|
||||
ram.path, mem_info.data, mem_info.size))
|
||||
#if defined(HAVE_ZLIB)
|
||||
if (compress)
|
||||
write_success = rzipstream_write_file(
|
||||
ram.path, mem_info.data, mem_info.size);
|
||||
else
|
||||
#endif
|
||||
write_success = filestream_write_file(
|
||||
ram.path, mem_info.data, mem_info.size);
|
||||
|
||||
if (!write_success)
|
||||
{
|
||||
RARCH_ERR("%s.\n",
|
||||
msg_hash_to_str(MSG_FAILED_TO_SAVE_SRAM));
|
||||
@ -1602,6 +1651,11 @@ bool event_save_files(bool is_sram_used)
|
||||
unsigned i;
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *path_cheat_database = settings->paths.path_cheat_database;
|
||||
#if defined(HAVE_ZLIB)
|
||||
bool compress_files = settings->bools.save_file_compression;
|
||||
#else
|
||||
bool compress_files = false;
|
||||
#endif
|
||||
|
||||
cheat_manager_save_game_specific_cheats(
|
||||
path_cheat_database);
|
||||
@ -1609,7 +1663,7 @@ bool event_save_files(bool is_sram_used)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < task_save_files->size; i++)
|
||||
content_save_ram_file(i);
|
||||
content_save_ram_file(i, compress_files);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user