mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 04:14:00 +00:00
Disable save states based on save state support level defined in core info files (#13562)
This commit is contained in:
parent
6f7332c8fa
commit
42e03cae83
21
command.c
21
command.c
@ -1088,6 +1088,8 @@ bool command_event_save_auto_state(
|
||||
return false;
|
||||
if (current_core_type == CORE_TYPE_DUMMY)
|
||||
return false;
|
||||
if (!core_info_current_supports_savestate())
|
||||
return false;
|
||||
|
||||
if (string_is_empty(path_basename(path_get(RARCH_PATH_BASENAME))))
|
||||
return false;
|
||||
@ -1148,6 +1150,9 @@ bool command_event_load_entry_state(void)
|
||||
runloop_state_t *runloop_st = runloop_state_get_ptr();
|
||||
bool ret = false;
|
||||
|
||||
if (!core_info_current_supports_savestate())
|
||||
return false;
|
||||
|
||||
#ifdef HAVE_CHEEVOS
|
||||
if (rcheevos_hardcore_active())
|
||||
return false;
|
||||
@ -1187,6 +1192,10 @@ void command_event_load_auto_state(void)
|
||||
char savestate_name_auto[PATH_MAX_LENGTH];
|
||||
runloop_state_t *runloop_st = runloop_state_get_ptr();
|
||||
bool ret = false;
|
||||
|
||||
if (!core_info_current_supports_savestate())
|
||||
return;
|
||||
|
||||
#ifdef HAVE_CHEEVOS
|
||||
if (rcheevos_hardcore_active())
|
||||
return;
|
||||
@ -1551,16 +1560,22 @@ bool command_event_main_state(unsigned cmd)
|
||||
char msg[128];
|
||||
char state_path[16384];
|
||||
settings_t *settings = config_get_ptr();
|
||||
bool savestates_enabled = core_info_current_supports_savestate();
|
||||
bool ret = false;
|
||||
bool push_msg = true;
|
||||
|
||||
state_path[0] = msg[0] = '\0';
|
||||
|
||||
retroarch_get_current_savestate_path(state_path, sizeof(state_path));
|
||||
if (savestates_enabled)
|
||||
{
|
||||
retroarch_get_current_savestate_path(state_path,
|
||||
sizeof(state_path));
|
||||
|
||||
core_serialize_size(&info);
|
||||
core_serialize_size(&info);
|
||||
savestates_enabled = (info.size > 0);
|
||||
}
|
||||
|
||||
if (info.size)
|
||||
if (savestates_enabled)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
|
160
core_info.c
160
core_info.c
@ -48,6 +48,7 @@
|
||||
/* Core Info Cache START */
|
||||
/*************************/
|
||||
|
||||
#define CORE_INFO_CACHE_VERSION "1.1"
|
||||
#define CORE_INFO_CACHE_DEFAULT_CAPACITY 8
|
||||
|
||||
/* TODO/FIXME: Apparently rzip compression is an issue on UWP */
|
||||
@ -60,6 +61,7 @@ typedef struct
|
||||
core_info_t *items;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
char *version;
|
||||
bool refresh;
|
||||
} core_info_cache_list_t;
|
||||
|
||||
@ -103,7 +105,9 @@ static bool CCJSONObjectMemberHandler(void *context,
|
||||
{
|
||||
CCJSONContext *pCtx = (CCJSONContext *)context;
|
||||
|
||||
if ((pCtx->object_depth == 2) && (pCtx->array_depth == 1) && length)
|
||||
if ((pCtx->object_depth == 2) &&
|
||||
(pCtx->array_depth == 1) &&
|
||||
length)
|
||||
{
|
||||
pCtx->current_string_val = NULL;
|
||||
pCtx->current_string_list_val = NULL;
|
||||
@ -199,26 +203,29 @@ static bool CCJSONObjectMemberHandler(void *context,
|
||||
}
|
||||
else if (string_is_equal(pValue, "supports_no_game"))
|
||||
pCtx->current_entry_bool_val = &pCtx->core_info->supports_no_game;
|
||||
else if (string_is_equal(pValue, "savestate_support_level"))
|
||||
pCtx->current_entry_uint_val = &pCtx->core_info->savestate_support_level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((pCtx->object_depth == 3)
|
||||
&& (pCtx->array_depth == 1) && length)
|
||||
else if ((pCtx->object_depth == 3) &&
|
||||
(pCtx->array_depth == 1) &&
|
||||
length)
|
||||
{
|
||||
pCtx->current_string_val = NULL;
|
||||
pCtx->current_entry_uint_val = NULL;
|
||||
|
||||
if (pCtx->to_core_file_id)
|
||||
{
|
||||
if (string_is_equal(pValue, "str"))
|
||||
if (string_is_equal(pValue, "str"))
|
||||
pCtx->current_string_val = &pCtx->core_info->core_file_id.str;
|
||||
else if (string_is_equal(pValue, "hash"))
|
||||
pCtx->current_entry_uint_val = &pCtx->core_info->core_file_id.hash;
|
||||
}
|
||||
}
|
||||
else if ((pCtx->object_depth == 3)
|
||||
&& (pCtx->array_depth == 2)
|
||||
&& length)
|
||||
else if ((pCtx->object_depth == 3) &&
|
||||
(pCtx->array_depth == 2) &&
|
||||
length)
|
||||
{
|
||||
pCtx->current_string_val = NULL;
|
||||
pCtx->current_entry_bool_val = NULL;
|
||||
@ -227,7 +234,7 @@ static bool CCJSONObjectMemberHandler(void *context,
|
||||
{
|
||||
size_t firmware_idx = pCtx->core_info->firmware_count - 1;
|
||||
|
||||
if (string_is_equal(pValue, "path"))
|
||||
if (string_is_equal(pValue, "path"))
|
||||
pCtx->current_string_val = &pCtx->core_info->firmware[firmware_idx].path;
|
||||
else if (string_is_equal(pValue, "desc"))
|
||||
pCtx->current_string_val = &pCtx->core_info->firmware[firmware_idx].desc;
|
||||
@ -235,6 +242,15 @@ static bool CCJSONObjectMemberHandler(void *context,
|
||||
pCtx->current_entry_bool_val = &pCtx->core_info->firmware[firmware_idx].optional;
|
||||
}
|
||||
}
|
||||
else if ((pCtx->object_depth == 1) &&
|
||||
(pCtx->array_depth == 0) &&
|
||||
length)
|
||||
{
|
||||
pCtx->current_string_val = NULL;
|
||||
|
||||
if (string_is_equal(pValue, "version"))
|
||||
pCtx->current_string_val = &pCtx->core_info_cache_list->version;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -319,6 +335,11 @@ static bool CCJSONStartObjectHandler(void *context)
|
||||
pCtx->core_info = (core_info_t*)calloc(1, sizeof(core_info_t));
|
||||
if (!pCtx->core_info)
|
||||
return false;
|
||||
|
||||
/* Assume all cores have 'full' savestate support
|
||||
* by default */
|
||||
pCtx->core_info->savestate_support_level =
|
||||
CORE_INFO_SAVESTATE_DETERMINISTIC;
|
||||
}
|
||||
else if ((pCtx->object_depth == 3) && (pCtx->array_depth == 2))
|
||||
{
|
||||
@ -448,6 +469,7 @@ static void core_info_copy(core_info_t *src, core_info_t *dst)
|
||||
? strdup(src->core_file_id.str) : NULL;
|
||||
dst->core_file_id.hash = src->core_file_id.hash;
|
||||
|
||||
dst->savestate_support_level = src->savestate_support_level;
|
||||
dst->has_info = src->has_info;
|
||||
dst->supports_no_game = src->supports_no_game;
|
||||
dst->database_match_archive_member = src->database_match_archive_member;
|
||||
@ -542,6 +564,7 @@ static void core_info_transfer(core_info_t *src, core_info_t *dst)
|
||||
src->core_file_id.str = NULL;
|
||||
dst->core_file_id.hash = src->core_file_id.hash;
|
||||
|
||||
dst->savestate_support_level = src->savestate_support_level;
|
||||
dst->has_info = src->has_info;
|
||||
dst->supports_no_game = src->supports_no_game;
|
||||
dst->database_match_archive_member = src->database_match_archive_member;
|
||||
@ -565,6 +588,10 @@ static void core_info_cache_list_free(
|
||||
}
|
||||
|
||||
free(core_info_cache_list->items);
|
||||
|
||||
if (core_info_cache_list->version)
|
||||
free(core_info_cache_list->version);
|
||||
|
||||
free(core_info_cache_list);
|
||||
}
|
||||
|
||||
@ -657,6 +684,7 @@ static core_info_cache_list_t *core_info_cache_list_new(void)
|
||||
|
||||
core_info_cache_list->capacity = CORE_INFO_CACHE_DEFAULT_CAPACITY;
|
||||
core_info_cache_list->refresh = false;
|
||||
core_info_cache_list->version = NULL;
|
||||
|
||||
return core_info_cache_list;
|
||||
}
|
||||
@ -758,6 +786,21 @@ static core_info_cache_list_t *core_info_cache_read(const char *info_dir)
|
||||
free(context.core_info);
|
||||
}
|
||||
|
||||
/* If info cache file has the wrong version
|
||||
* number, discard it */
|
||||
if (string_is_empty(core_info_cache_list->version) ||
|
||||
!string_is_equal(core_info_cache_list->version,
|
||||
CORE_INFO_CACHE_VERSION))
|
||||
{
|
||||
RARCH_WARN("[Core Info] Core info cache has invalid version"
|
||||
" - forcing refresh (required v%s, found v%s)\n",
|
||||
CORE_INFO_CACHE_VERSION,
|
||||
core_info_cache_list->version);
|
||||
|
||||
core_info_cache_list_free(context.core_info_cache_list);
|
||||
core_info_cache_list = core_info_cache_list_new();
|
||||
}
|
||||
|
||||
end:
|
||||
intfstream_close(file);
|
||||
free(file);
|
||||
@ -822,7 +865,7 @@ static bool core_info_cache_write(core_info_cache_list_t *list, const char *info
|
||||
rjsonwriter_add_string(writer, "version");
|
||||
rjsonwriter_add_colon(writer);
|
||||
rjsonwriter_add_space(writer);
|
||||
rjsonwriter_add_string(writer, "1.0");
|
||||
rjsonwriter_add_string(writer, CORE_INFO_CACHE_VERSION);
|
||||
rjsonwriter_add_comma(writer);
|
||||
rjsonwriter_add_newline(writer);
|
||||
rjsonwriter_add_spaces(writer, 2);
|
||||
@ -1051,6 +1094,14 @@ static bool core_info_cache_write(core_info_cache_list_t *list, const char *info
|
||||
rjsonwriter_add_comma(writer);
|
||||
rjsonwriter_add_newline(writer);
|
||||
|
||||
rjsonwriter_add_spaces(writer, 6);
|
||||
rjsonwriter_add_string(writer, "savestate_support_level");
|
||||
rjsonwriter_add_colon(writer);
|
||||
rjsonwriter_add_space(writer);
|
||||
rjsonwriter_add_unsigned(writer, info->savestate_support_level);
|
||||
rjsonwriter_add_comma(writer);
|
||||
rjsonwriter_add_newline(writer);
|
||||
|
||||
rjsonwriter_add_spaces(writer, 6);
|
||||
rjsonwriter_add_string(writer, "has_info");
|
||||
rjsonwriter_add_colon(writer);
|
||||
@ -1703,6 +1754,40 @@ static void core_info_parse_config_file(
|
||||
&tmp_bool))
|
||||
info->is_experimental = tmp_bool;
|
||||
|
||||
|
||||
/* Savestate support level is slightly more complex,
|
||||
* since it is a value derived from two configuration
|
||||
* parameters */
|
||||
|
||||
/* > Assume all cores have 'full' savestate support
|
||||
* by default */
|
||||
info->savestate_support_level =
|
||||
CORE_INFO_SAVESTATE_DETERMINISTIC;
|
||||
|
||||
/* > Check whether savestate functionality is defined
|
||||
* in the info file */
|
||||
if (config_get_bool(conf, "savestate", &tmp_bool))
|
||||
{
|
||||
if (tmp_bool)
|
||||
{
|
||||
/* Check if savestate features are defined */
|
||||
entry = config_get_entry(conf, "savestate_features");
|
||||
|
||||
if (entry && !string_is_empty(entry->value))
|
||||
{
|
||||
if (string_is_equal(entry->value, "basic"))
|
||||
info->savestate_support_level =
|
||||
CORE_INFO_SAVESTATE_BASIC;
|
||||
else if (string_is_equal(entry->value, "serialized"))
|
||||
info->savestate_support_level =
|
||||
CORE_INFO_SAVESTATE_SERIALIZED;
|
||||
}
|
||||
}
|
||||
else
|
||||
info->savestate_support_level =
|
||||
CORE_INFO_SAVESTATE_DISABLED;
|
||||
}
|
||||
|
||||
core_info_resolve_firmware(info, conf);
|
||||
|
||||
info->has_info = true;
|
||||
@ -2097,6 +2182,7 @@ bool core_info_init_current_core(void)
|
||||
current->is_experimental = false;
|
||||
current->is_locked = false;
|
||||
current->firmware_count = 0;
|
||||
current->savestate_support_level = CORE_INFO_SAVESTATE_DETERMINISTIC;
|
||||
current->path = NULL;
|
||||
current->display_name = NULL;
|
||||
current->display_version = NULL;
|
||||
@ -2916,6 +3002,62 @@ bool core_info_hw_api_supported(core_info_t *info)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool core_info_current_supports_savestate(void)
|
||||
{
|
||||
core_info_state_t *p_coreinfo = &core_info_st;
|
||||
|
||||
/* If no core is currently loaded, assume
|
||||
* by default that all savestate functionality
|
||||
* is supported */
|
||||
if (!p_coreinfo->current)
|
||||
return true;
|
||||
|
||||
return p_coreinfo->current->savestate_support_level >=
|
||||
CORE_INFO_SAVESTATE_BASIC;
|
||||
}
|
||||
|
||||
bool core_info_current_supports_rewind(void)
|
||||
{
|
||||
core_info_state_t *p_coreinfo = &core_info_st;
|
||||
|
||||
/* If no core is currently loaded, assume
|
||||
* by default that all savestate functionality
|
||||
* is supported */
|
||||
if (!p_coreinfo->current)
|
||||
return true;
|
||||
|
||||
return p_coreinfo->current->savestate_support_level >=
|
||||
CORE_INFO_SAVESTATE_SERIALIZED;
|
||||
}
|
||||
|
||||
bool core_info_current_supports_netplay(void)
|
||||
{
|
||||
core_info_state_t *p_coreinfo = &core_info_st;
|
||||
|
||||
/* If no core is currently loaded, assume
|
||||
* by default that all savestate functionality
|
||||
* is supported */
|
||||
if (!p_coreinfo->current)
|
||||
return true;
|
||||
|
||||
return p_coreinfo->current->savestate_support_level >=
|
||||
CORE_INFO_SAVESTATE_DETERMINISTIC;
|
||||
}
|
||||
|
||||
bool core_info_current_supports_runahead(void)
|
||||
{
|
||||
core_info_state_t *p_coreinfo = &core_info_st;
|
||||
|
||||
/* If no core is currently loaded, assume
|
||||
* by default that all savestate functionality
|
||||
* is supported */
|
||||
if (!p_coreinfo->current)
|
||||
return true;
|
||||
|
||||
return p_coreinfo->current->savestate_support_level >=
|
||||
CORE_INFO_SAVESTATE_DETERMINISTIC;
|
||||
}
|
||||
|
||||
/* Sets 'locked' status of specified core
|
||||
* > Returns true if successful
|
||||
* > Like all functions that access the cached
|
||||
|
28
core_info.h
28
core_info.h
@ -25,6 +25,23 @@
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/* Defines the levels of savestate support
|
||||
* that may be offered by a core:
|
||||
* - serialized: rewind
|
||||
* - deterministic: netplay/runahead
|
||||
* Thus:
|
||||
* (level < CORE_INFO_SAVESTATE_BASIC)
|
||||
* -> no savestate support
|
||||
* (level < CORE_INFO_SAVESTATE_SERIALIZED)
|
||||
* -> no rewind/netplay/runahead
|
||||
* (level < CORE_INFO_SAVESTATE_DETERMINISTIC)
|
||||
* -> no netplay/runahead
|
||||
*/
|
||||
#define CORE_INFO_SAVESTATE_DISABLED 0
|
||||
#define CORE_INFO_SAVESTATE_BASIC 1
|
||||
#define CORE_INFO_SAVESTATE_SERIALIZED 2
|
||||
#define CORE_INFO_SAVESTATE_DETERMINISTIC 3
|
||||
|
||||
enum core_info_list_qsort_type
|
||||
{
|
||||
CORE_INFO_LIST_SORT_PATH = 0,
|
||||
@ -84,6 +101,7 @@ typedef struct
|
||||
core_info_firmware_t *firmware;
|
||||
core_file_id_t core_file_id; /* ptr alignment */
|
||||
size_t firmware_count;
|
||||
uint32_t savestate_support_level;
|
||||
bool has_info;
|
||||
bool supports_no_game;
|
||||
bool database_match_archive_member;
|
||||
@ -184,6 +202,16 @@ bool core_info_list_get_info(core_info_list_t *core_info_list,
|
||||
|
||||
bool core_info_hw_api_supported(core_info_t *info);
|
||||
|
||||
/* Convenience wrapper functions used to interpret
|
||||
* the 'savestate_support_level' parameter of
|
||||
* the currently loaded core. If no core is
|
||||
* loaded, will return 'true' (since full
|
||||
* savestate functionality is assumed by default) */
|
||||
bool core_info_current_supports_savestate(void);
|
||||
bool core_info_current_supports_rewind(void);
|
||||
bool core_info_current_supports_netplay(void);
|
||||
bool core_info_current_supports_runahead(void);
|
||||
|
||||
/* Sets 'locked' status of specified core
|
||||
* > Returns true if successful
|
||||
* > Like all functions that access the cached
|
||||
|
@ -467,6 +467,26 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_REQUIRED_HW_API,
|
||||
"Required Graphics API"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_SUPPORT_LEVEL,
|
||||
"Save State Support"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_DISABLED,
|
||||
"None"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_BASIC,
|
||||
"Basic (Save/Load)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_SERIALIZED,
|
||||
"Serialized (Save/Load, Rewind)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_DETERMINISTIC,
|
||||
"Deterministic (Save/Load, Rewind, Run-Ahead, Netplay)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE,
|
||||
"Firmware"
|
||||
|
@ -460,13 +460,14 @@ static int menu_displaylist_parse_core_info(menu_displaylist_info_t *info,
|
||||
settings_t *settings)
|
||||
{
|
||||
char tmp[PATH_MAX_LENGTH];
|
||||
unsigned i, count = 0;
|
||||
core_info_t *core_info = NULL;
|
||||
const char *core_path = NULL;
|
||||
unsigned i, count = 0;
|
||||
core_info_t *core_info = NULL;
|
||||
const char *core_path = NULL;
|
||||
const char *savestate_support = NULL;
|
||||
#if !(defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
bool kiosk_mode_enable = settings->bools.kiosk_mode_enable;
|
||||
bool kiosk_mode_enable = settings->bools.kiosk_mode_enable;
|
||||
#if defined(HAVE_NETWORKING) && defined(HAVE_ONLINE_UPDATER)
|
||||
bool menu_show_core_updater = settings->bools.menu_show_core_updater;
|
||||
bool menu_show_core_updater = settings->bools.menu_show_core_updater;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -615,6 +616,39 @@ static int menu_displaylist_parse_core_info(menu_displaylist_info_t *info,
|
||||
count++;
|
||||
}
|
||||
|
||||
switch (core_info->savestate_support_level)
|
||||
{
|
||||
case CORE_INFO_SAVESTATE_BASIC:
|
||||
savestate_support = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_BASIC);
|
||||
break;
|
||||
case CORE_INFO_SAVESTATE_SERIALIZED:
|
||||
savestate_support = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_SERIALIZED);
|
||||
break;
|
||||
case CORE_INFO_SAVESTATE_DETERMINISTIC:
|
||||
savestate_support = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_DETERMINISTIC);
|
||||
break;
|
||||
default:
|
||||
if (core_info->savestate_support_level >
|
||||
CORE_INFO_SAVESTATE_DETERMINISTIC)
|
||||
savestate_support = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_DETERMINISTIC);
|
||||
else
|
||||
savestate_support = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_DISABLED);
|
||||
break;
|
||||
}
|
||||
fill_pathname_join_concat_noext(tmp,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_SUPPORT_LEVEL),
|
||||
": ",
|
||||
savestate_support,
|
||||
sizeof(tmp));
|
||||
if (menu_entries_append_enum(info->list, tmp, "",
|
||||
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0))
|
||||
count++;
|
||||
|
||||
if (core_info->firmware_count > 0)
|
||||
{
|
||||
core_info_ctx_firmware_t firmware_info;
|
||||
@ -2872,6 +2906,7 @@ static int menu_displaylist_parse_load_content_settings(
|
||||
#endif
|
||||
bool quickmenu_show_resume_content = settings->bools.quick_menu_show_resume_content;
|
||||
bool quickmenu_show_restart_content = settings->bools.quick_menu_show_restart_content;
|
||||
bool savestates_enabled = core_info_current_supports_savestate();
|
||||
rarch_system_info_t *system = &runloop_state_get_ptr()->system;
|
||||
|
||||
if (quickmenu_show_resume_content)
|
||||
@ -2920,7 +2955,8 @@ static int menu_displaylist_parse_load_content_settings(
|
||||
}
|
||||
#endif
|
||||
|
||||
if (settings->bools.quick_menu_show_save_load_state)
|
||||
if (savestates_enabled &&
|
||||
settings->bools.quick_menu_show_save_load_state)
|
||||
{
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
|
||||
MENU_ENUM_LABEL_STATE_SLOT, PARSE_ONLY_INT, true) == 0)
|
||||
@ -2941,7 +2977,8 @@ static int menu_displaylist_parse_load_content_settings(
|
||||
count++;
|
||||
}
|
||||
|
||||
if (settings->bools.quick_menu_show_save_load_state &&
|
||||
if (savestates_enabled &&
|
||||
settings->bools.quick_menu_show_save_load_state &&
|
||||
settings->bools.quick_menu_show_undo_save_load_state)
|
||||
{
|
||||
#ifdef HAVE_CHEEVOS
|
||||
|
@ -2594,6 +2594,12 @@ enum msg_hash_enums
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE,
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_REQUIRED_HW_API,
|
||||
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_SUPPORT_LEVEL,
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_DISABLED,
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_BASIC,
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_SERIALIZED,
|
||||
MENU_ENUM_LABEL_VALUE_CORE_INFO_SAVESTATE_DETERMINISTIC,
|
||||
|
||||
/* System information */
|
||||
|
||||
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LAKKA_VERSION,
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include <time/rtime.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../core.h"
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETWORKING
|
||||
@ -52,6 +52,7 @@
|
||||
|
||||
#include "../content.h"
|
||||
#include "../core.h"
|
||||
#include "../core_info.h"
|
||||
#include "../file_path_special.h"
|
||||
#include "../configuration.h"
|
||||
#include "../msg_hash.h"
|
||||
@ -440,6 +441,13 @@ bool content_undo_load_state(void)
|
||||
settings_t *settings = config_get_ptr();
|
||||
bool block_sram_overwrite = settings->bools.block_sram_overwrite;
|
||||
|
||||
if (!core_info_current_supports_savestate())
|
||||
{
|
||||
RARCH_LOG("[State]: %s\n",
|
||||
msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES));
|
||||
return false;
|
||||
}
|
||||
|
||||
RARCH_LOG("[State]: %s \"%s\", %u %s.\n",
|
||||
msg_hash_to_str(MSG_LOADING_STATE),
|
||||
undo_load_buf.path,
|
||||
@ -886,6 +894,13 @@ error:
|
||||
**/
|
||||
bool content_undo_save_state(void)
|
||||
{
|
||||
if (!core_info_current_supports_savestate())
|
||||
{
|
||||
RARCH_LOG("[State]: %s\n",
|
||||
msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES));
|
||||
return false;
|
||||
}
|
||||
|
||||
return task_push_undo_save_state(undo_save_buf.path,
|
||||
undo_save_buf.data,
|
||||
undo_save_buf.size);
|
||||
@ -1474,6 +1489,13 @@ bool content_save_state(const char *path, bool save_to_disk, bool autosave)
|
||||
void *data = NULL;
|
||||
size_t serial_size;
|
||||
|
||||
if (!core_info_current_supports_savestate())
|
||||
{
|
||||
RARCH_LOG("[State]: %s\n",
|
||||
msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES));
|
||||
return false;
|
||||
}
|
||||
|
||||
core_serialize_size(&info);
|
||||
|
||||
if (info.size == 0)
|
||||
@ -1606,8 +1628,8 @@ void content_wait_for_save_state_task(void)
|
||||
bool content_load_state(const char *path,
|
||||
bool load_to_backup_buffer, bool autoload)
|
||||
{
|
||||
retro_task_t *task = task_init();
|
||||
save_task_state_t *state = (save_task_state_t*)calloc(1, sizeof(*state));
|
||||
retro_task_t *task = NULL;
|
||||
save_task_state_t *state = NULL;
|
||||
settings_t *settings = config_get_ptr();
|
||||
int state_slot = settings->ints.state_slot;
|
||||
#if defined(HAVE_ZLIB)
|
||||
@ -1616,6 +1638,16 @@ bool content_load_state(const char *path,
|
||||
bool compress_files = false;
|
||||
#endif
|
||||
|
||||
if (!core_info_current_supports_savestate())
|
||||
{
|
||||
RARCH_LOG("[State]: %s\n",
|
||||
msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES));
|
||||
goto error;
|
||||
}
|
||||
|
||||
task = task_init();
|
||||
state = (save_task_state_t*)calloc(1, sizeof(*state));
|
||||
|
||||
if (!task || !state)
|
||||
goto error;
|
||||
|
||||
@ -1847,6 +1879,13 @@ bool content_load_state_from_ram(void)
|
||||
bool ret = false;
|
||||
void* temp_data = NULL;
|
||||
|
||||
if (!core_info_current_supports_savestate())
|
||||
{
|
||||
RARCH_LOG("[State]: %s\n",
|
||||
msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ram_buf.state_buf.data)
|
||||
return false;
|
||||
|
||||
@ -1891,6 +1930,13 @@ bool content_save_state_to_ram(void)
|
||||
void *data = NULL;
|
||||
size_t serial_size;
|
||||
|
||||
if (!core_info_current_supports_savestate())
|
||||
{
|
||||
RARCH_LOG("[State]: %s\n",
|
||||
msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES));
|
||||
return false;
|
||||
}
|
||||
|
||||
core_serialize_size(&info);
|
||||
|
||||
if (info.size == 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user