Disable run-ahead and rewind based on save state support level defined in core info files (#13594)

* Disable run-ahead based on save state support level defined in core info files

* Disable rewind based on save state support level defined in core info files
This commit is contained in:
jdgleaver 2022-02-04 23:25:33 +00:00 committed by GitHub
parent 763fcd8267
commit e541dd5ab1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 158 additions and 33 deletions

View File

@ -2940,6 +2940,10 @@ MSG_HASH(
MENU_ENUM_LABEL_SLOWMOTION_RATIO,
"slowmotion_ratio"
)
MSG_HASH(
MENU_ENUM_LABEL_RUN_AHEAD_UNSUPPORTED,
"run_ahead_unsupported"
)
MSG_HASH(
MENU_ENUM_LABEL_RUN_AHEAD_ENABLED,
"run_ahead_enabled"

View File

@ -3056,6 +3056,14 @@ MSG_HASH(
/* Settings > Latency */
MSG_HASH(
MENU_ENUM_LABEL_VALUE_RUN_AHEAD_UNSUPPORTED,
"[Run-Ahead Unavailable]"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_RUN_AHEAD_UNSUPPORTED,
"Current core is incompatible with run-ahead due to lack of deterministic save state support."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_RUN_AHEAD_ENABLED,
"Run-Ahead to Reduce Latency"
@ -11862,6 +11870,10 @@ MSG_HASH(
MSG_REWINDING,
"Rewinding."
)
MSG_HASH(
MSG_REWIND_UNSUPPORTED,
"Rewind unavailable because this core lacks serialized save state support."
)
MSG_HASH(
MSG_REWIND_INIT,
"Initializing rewind buffer with size"
@ -12170,6 +12182,10 @@ MSG_HASH(
MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES,
"Run-Ahead has been disabled because this core does not support save states."
)
MSG_HASH(
MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_RUNAHEAD,
"Run-Ahead unavailable because this core lacks deterministic save state support."
)
MSG_HASH(
MSG_RUNAHEAD_FAILED_TO_SAVE_STATE,
"Failed to save state. Run-Ahead has been disabled."

View File

@ -497,6 +497,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_fastforward_ratio, MENU_
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_fastforward_frameskip, MENU_ENUM_SUBLABEL_FASTFORWARD_FRAMESKIP)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_vrr_runloop_enable, MENU_ENUM_SUBLABEL_VRR_RUNLOOP_ENABLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_slowmotion_ratio, MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_run_ahead_unsupported, MENU_ENUM_SUBLABEL_RUN_AHEAD_UNSUPPORTED)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_run_ahead_enabled, MENU_ENUM_SUBLABEL_RUN_AHEAD_ENABLED)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_run_ahead_secondary_instance, MENU_ENUM_SUBLABEL_RUN_AHEAD_SECONDARY_INSTANCE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_run_ahead_hide_warnings, MENU_ENUM_SUBLABEL_RUN_AHEAD_HIDE_WARNINGS)
@ -3392,6 +3393,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_SLOWMOTION_RATIO:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_slowmotion_ratio);
break;
case MENU_ENUM_LABEL_RUN_AHEAD_UNSUPPORTED:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_run_ahead_unsupported);
break;
case MENU_ENUM_LABEL_RUN_AHEAD_ENABLED:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_run_ahead_enabled);
break;

View File

@ -3112,7 +3112,9 @@ static int menu_displaylist_parse_load_content_settings(
#endif
#ifdef HAVE_REWIND
if (settings->bools.menu_show_rewind && !settings->bools.kiosk_mode_enable)
if (settings->bools.menu_show_rewind &&
!settings->bools.kiosk_mode_enable &&
core_info_current_supports_rewind())
{
if (menu_entries_append_enum(list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS),
@ -8485,6 +8487,10 @@ unsigned menu_displaylist_build_list(
case DISPLAYLIST_LATENCY_SETTINGS_LIST:
{
bool video_hard_sync = settings->bools.video_hard_sync;
#ifdef HAVE_RUNAHEAD
bool runahead_supported = true;
bool runahead_enabled = settings->bools.run_ahead_enabled;
#endif
menu_displaylist_build_info_selective_t build_list[] = {
{MENU_ENUM_LABEL_VIDEO_FRAME_DELAY, PARSE_ONLY_UINT, true },
{MENU_ENUM_LABEL_VIDEO_FRAME_DELAY_AUTO, PARSE_ONLY_BOOL, true },
@ -8492,7 +8498,7 @@ unsigned menu_displaylist_build_list(
{MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR, PARSE_ONLY_UINT, true },
{MENU_ENUM_LABEL_INPUT_BLOCK_TIMEOUT, PARSE_ONLY_UINT, true },
#ifdef HAVE_RUNAHEAD
{MENU_ENUM_LABEL_RUN_AHEAD_ENABLED, PARSE_ONLY_BOOL, true },
{MENU_ENUM_LABEL_RUN_AHEAD_ENABLED, PARSE_ONLY_BOOL, false },
{MENU_ENUM_LABEL_RUN_AHEAD_FRAMES, PARSE_ONLY_UINT, false },
{MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE, PARSE_ONLY_BOOL, false },
{MENU_ENUM_LABEL_RUN_AHEAD_HIDE_WARNINGS, PARSE_ONLY_BOOL, false },
@ -8506,6 +8512,7 @@ unsigned menu_displaylist_build_list(
PARSE_ONLY_UINT, false);
count++;
}
if (video_driver_test_all_flags(GFX_CTX_FLAGS_HARD_SYNC))
{
MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
@ -8521,26 +8528,32 @@ unsigned menu_displaylist_build_list(
}
}
#ifdef HAVE_RUNAHEAD
if (retroarch_ctl(RARCH_CTL_CORE_IS_RUNNING, NULL) &&
!retroarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
runahead_supported = core_info_current_supports_runahead();
if (runahead_supported)
{
bool runahead_enabled = settings->bools.run_ahead_enabled;
if (runahead_enabled)
for (i = 0; i < ARRAY_SIZE(build_list); i++)
{
for (i = 0; i < ARRAY_SIZE(build_list); i++)
switch (build_list[i].enum_idx)
{
switch (build_list[i].enum_idx)
{
case MENU_ENUM_LABEL_RUN_AHEAD_FRAMES:
case MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE:
case MENU_ENUM_LABEL_RUN_AHEAD_HIDE_WARNINGS:
case MENU_ENUM_LABEL_RUN_AHEAD_ENABLED:
build_list[i].checked = true;
break;
case MENU_ENUM_LABEL_RUN_AHEAD_FRAMES:
case MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE:
case MENU_ENUM_LABEL_RUN_AHEAD_HIDE_WARNINGS:
if (runahead_enabled)
build_list[i].checked = true;
break;
default:
break;
}
break;
default:
break;
}
}
}
#endif
for (i = 0; i < ARRAY_SIZE(build_list); i++)
{
if (!build_list[i].checked && !include_everything)
@ -8552,6 +8565,15 @@ unsigned menu_displaylist_build_list(
count++;
}
#ifdef HAVE_RUNAHEAD
if (!runahead_supported &&
menu_entries_append_enum(list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_RUN_AHEAD_UNSUPPORTED),
msg_hash_to_str(MENU_ENUM_LABEL_RUN_AHEAD_UNSUPPORTED),
MENU_ENUM_LABEL_RUN_AHEAD_UNSUPPORTED,
FILE_TYPE_NONE, 0, 0))
count++;
#endif
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_GAMEMODE_ENABLE, PARSE_ONLY_BOOL, false) == 0)
count++;
@ -9423,20 +9445,44 @@ unsigned menu_displaylist_build_list(
break;
case DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST:
{
menu_displaylist_build_info_t build_list[] = {
#ifdef HAVE_REWIND
{MENU_ENUM_LABEL_REWIND_SETTINGS, PARSE_ACTION },
bool rewind_supported = true;
#endif
{MENU_ENUM_LABEL_FRAME_TIME_COUNTER_SETTINGS, PARSE_ACTION},
{MENU_ENUM_LABEL_FASTFORWARD_RATIO, PARSE_ONLY_FLOAT},
{MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP, PARSE_ONLY_BOOL },
{MENU_ENUM_LABEL_SLOWMOTION_RATIO, PARSE_ONLY_FLOAT},
{MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE, PARSE_ONLY_BOOL },
{MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE, PARSE_ONLY_BOOL },
menu_displaylist_build_info_selective_t build_list[] = {
#ifdef HAVE_REWIND
{MENU_ENUM_LABEL_REWIND_SETTINGS, PARSE_ACTION, false},
#endif
{MENU_ENUM_LABEL_FRAME_TIME_COUNTER_SETTINGS, PARSE_ACTION, true},
{MENU_ENUM_LABEL_FASTFORWARD_RATIO, PARSE_ONLY_FLOAT, true},
{MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_SLOWMOTION_RATIO, PARSE_ONLY_FLOAT, true},
{MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE, PARSE_ONLY_BOOL , true},
};
#ifdef HAVE_REWIND
if (retroarch_ctl(RARCH_CTL_CORE_IS_RUNNING, NULL) &&
!retroarch_ctl(RARCH_CTL_IS_DUMMY_CORE, NULL))
rewind_supported = core_info_current_supports_rewind();
if (rewind_supported)
for (i = 0; i < ARRAY_SIZE(build_list); i++)
{
switch (build_list[i].enum_idx)
{
case MENU_ENUM_LABEL_REWIND_SETTINGS:
build_list[i].checked = true;
break;
default:
break;
}
}
#endif
for (i = 0; i < ARRAY_SIZE(build_list); i++)
{
if (!build_list[i].checked && !include_everything)
continue;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
build_list[i].enum_idx, build_list[i].parse_type,
false) == 0)

View File

@ -374,6 +374,7 @@ enum msg_hash_enums
MSG_DECOMPRESSION_FAILED,
MSG_DISK_EJECTED,
MSG_DISK_CLOSED,
MSG_REWIND_UNSUPPORTED,
MSG_REWIND_INIT,
MSG_REWIND_INIT_FAILED,
MSG_REWIND_INIT_FAILED_THREADED_AUDIO,
@ -488,6 +489,7 @@ enum msg_hash_enums
MSG_RUNAHEAD_ENABLED_WITH_SECOND_INSTANCE,
MSG_RUNAHEAD_DISABLED,
MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES,
MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_RUNAHEAD,
MSG_RUNAHEAD_FAILED_TO_SAVE_STATE,
MSG_RUNAHEAD_FAILED_TO_LOAD_STATE,
MSG_RUNAHEAD_FAILED_TO_CREATE_SECONDARY_INSTANCE,
@ -2050,6 +2052,7 @@ enum msg_hash_enums
MENU_LABEL(THUMBNAILS_DIRECTORY),
MENU_LABEL(SLOWMOTION_RATIO),
MENU_LABEL(RUN_AHEAD_UNSUPPORTED),
MENU_LABEL(RUN_AHEAD_ENABLED),
MENU_LABEL(RUN_AHEAD_SECONDARY_INSTANCE),
MENU_LABEL(RUN_AHEAD_HIDE_WARNINGS),

View File

@ -1623,6 +1623,14 @@ bool command_event(enum event_command cmd, void *data)
char msg[256];
msg[0] = '\0';
if (!core_info_current_supports_runahead())
{
runloop_msg_queue_push(msg_hash_to_str(MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_RUNAHEAD),
1, 100, false,
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
break;
}
settings->bools.run_ahead_enabled =
!(settings->bools.run_ahead_enabled);
@ -2007,9 +2015,11 @@ bool command_event(enum event_command cmd, void *data)
case CMD_EVENT_REWIND_DEINIT:
#ifdef HAVE_REWIND
{
bool core_type_is_dummy = runloop_st->current_core_type == CORE_TYPE_DUMMY;
if (core_type_is_dummy)
bool core_type_is_dummy = runloop_st->current_core_type == CORE_TYPE_DUMMY;
if (core_type_is_dummy)
return false;
state_manager_event_deinit(&runloop_st->rewind_st);
}
#endif
@ -2019,8 +2029,9 @@ bool command_event(enum event_command cmd, void *data)
{
bool rewind_enable = settings->bools.rewind_enable;
size_t rewind_buf_size = settings->sizes.rewind_buffer_size;
bool core_type_is_dummy = runloop_st->current_core_type == CORE_TYPE_DUMMY;
if (core_type_is_dummy)
bool core_type_is_dummy = runloop_st->current_core_type == CORE_TYPE_DUMMY;
if (core_type_is_dummy)
return false;
#ifdef HAVE_CHEEVOS
if (rcheevos_hardcore_active())

View File

@ -4727,6 +4727,26 @@ static void do_runahead(
if (!runloop_st->runahead_save_state_size_known)
{
/* Disable runahead if current core reports
* that it has an insufficient savestate
* support level */
if (!core_info_current_supports_runahead())
{
runahead_error(runloop_st);
/* If core is incompatible with runahead,
* log a warning but do not spam OSD messages.
* Runahead menu entries are hidden when using
* incompatible cores, so there is no mechanism
* for users to respond to notifications. In
* addition, auto-disabling runahead is a feature,
* not a cause for 'concern'; OSD warnings should
* be reserved for when a core reports that it is
* runahead-compatible but subsequently fails in
* execution */
RARCH_WARN("[Run-Ahead]: %s\n", msg_hash_to_str(MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_RUNAHEAD));
goto force_input_dirty;
}
if (!runahead_create(runloop_st))
{
if (!runahead_hide_warnings)
@ -7650,7 +7670,8 @@ int runloop_iterate(void)
bool run_ahead_hide_warnings = settings->bools.run_ahead_hide_warnings;
bool run_ahead_secondary_instance = settings->bools.run_ahead_secondary_instance;
/* Run Ahead Feature replaces the call to core_run in this loop */
bool want_runahead = run_ahead_enabled && run_ahead_num_frames > 0;
bool want_runahead = run_ahead_enabled &&
(run_ahead_num_frames > 0) && runloop_st->runahead_available;
#ifdef HAVE_NETWORKING
want_runahead = want_runahead && !netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL);
#endif
@ -8040,7 +8061,8 @@ bool core_set_cheat(retro_ctx_cheat_info_t *info)
run_ahead_enabled = settings->bools.run_ahead_enabled;
run_ahead_frames = settings->uints.run_ahead_frames;
run_ahead_secondary_instance = settings->bools.run_ahead_secondary_instance;
want_runahead = run_ahead_enabled && (run_ahead_frames > 0);
want_runahead = run_ahead_enabled &&
(run_ahead_frames > 0) && runloop_st->runahead_available;
#ifdef HAVE_NETWORKING
if (want_runahead)
want_runahead = !netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL);
@ -8078,7 +8100,8 @@ bool core_reset_cheat(void)
run_ahead_enabled = settings->bools.run_ahead_enabled;
run_ahead_frames = settings->uints.run_ahead_frames;
run_ahead_secondary_instance = settings->bools.run_ahead_secondary_instance;
want_runahead = run_ahead_enabled && (run_ahead_frames > 0);
want_runahead = run_ahead_enabled &&
(run_ahead_frames > 0) && runloop_st->runahead_available;
#ifdef HAVE_NETWORKING
if (want_runahead)
want_runahead = !netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL);

View File

@ -30,6 +30,7 @@
#include "state_manager.h"
#include "msg_hash.h"
#include "core.h"
#include "core_info.h"
#include "retroarch.h"
#include "verbosity.h"
#include "content.h"
@ -582,6 +583,12 @@ void state_manager_event_init(
if (!rewind_st || rewind_st->state)
return;
if (!core_info_current_supports_rewind())
{
RARCH_ERR("%s\n", msg_hash_to_str(MSG_REWIND_UNSUPPORTED));
return;
}
if (audio_driver_has_callback())
{
RARCH_ERR("%s.\n", msg_hash_to_str(MSG_REWIND_INIT_FAILED));
@ -641,10 +648,11 @@ bool state_manager_check_rewind(
unsigned rewind_granularity, bool is_paused,
char *s, size_t len, unsigned *time)
{
bool ret = false;
static bool first = true;
bool ret = false;
static bool first = true;
static bool was_pressed = false;
#ifdef HAVE_NETWORKING
bool was_reversed = false;
bool was_reversed = false;
#endif
if (!rewind_st)
@ -666,7 +674,16 @@ bool state_manager_check_rewind(
}
if (!rewind_st->state)
{
if ((pressed && !was_pressed) &&
!core_info_current_supports_rewind())
runloop_msg_queue_push(msg_hash_to_str(MSG_REWIND_UNSUPPORTED),
1, 100, false, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
was_pressed = pressed;
return false;
}
if (pressed)
{
@ -740,5 +757,6 @@ bool state_manager_check_rewind(
core_set_rewind_callbacks();
was_pressed = pressed;
return ret;
}