mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-09 10:54:30 +00:00
Add optional frame skipping when fast-forwarding (#13550)
This commit is contained in:
parent
fa213a724f
commit
84f558db0b
@ -1253,6 +1253,9 @@ static const bool savestate_thumbnail_enable = false;
|
||||
/* Maximum fast forward ratio. */
|
||||
#define DEFAULT_FASTFORWARD_RATIO 0.0
|
||||
|
||||
/* Skip frames when fast forwarding. */
|
||||
#define DEFAULT_FASTFORWARD_FRAMESKIP true
|
||||
|
||||
/* Enable runloop for variable refresh rate screens. Force x1 speed while handling fast forward too. */
|
||||
#define DEFAULT_VRR_RUNLOOP_ENABLE false
|
||||
|
||||
|
@ -1654,6 +1654,7 @@ static struct config_bool_setting *populate_settings_bool(
|
||||
SETTING_BOOL("ui_menubar_enable", &settings->bools.ui_menubar_enable, true, DEFAULT_UI_MENUBAR_ENABLE, false);
|
||||
SETTING_BOOL("suspend_screensaver_enable", &settings->bools.ui_suspend_screensaver_enable, true, true, false);
|
||||
SETTING_BOOL("rewind_enable", &settings->bools.rewind_enable, true, DEFAULT_REWIND_ENABLE, false);
|
||||
SETTING_BOOL("fastforward_frameskip", &settings->bools.fastforward_frameskip, true, DEFAULT_FASTFORWARD_FRAMESKIP, false);
|
||||
SETTING_BOOL("vrr_runloop_enable", &settings->bools.vrr_runloop_enable, true, DEFAULT_VRR_RUNLOOP_ENABLE, false);
|
||||
SETTING_BOOL("apply_cheats_after_toggle", &settings->bools.apply_cheats_after_toggle, true, DEFAULT_APPLY_CHEATS_AFTER_TOGGLE, false);
|
||||
SETTING_BOOL("apply_cheats_after_load", &settings->bools.apply_cheats_after_load, true, DEFAULT_APPLY_CHEATS_AFTER_LOAD, false);
|
||||
|
@ -834,6 +834,7 @@ typedef struct settings
|
||||
bool history_list_enable;
|
||||
bool playlist_entry_rename;
|
||||
bool rewind_enable;
|
||||
bool fastforward_frameskip;
|
||||
bool vrr_runloop_enable;
|
||||
bool apply_cheats_after_toggle;
|
||||
bool apply_cheats_after_load;
|
||||
|
@ -3579,6 +3579,7 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
const enum retro_pixel_format
|
||||
video_driver_pix_fmt = video_st->pix_fmt;
|
||||
bool runloop_idle = runloop_st->idle;
|
||||
bool render_frame = !runloop_st->fastforward_frameskip_frames_current;
|
||||
bool video_driver_active = video_st->active;
|
||||
#if defined(HAVE_GFX_WIDGETS)
|
||||
bool widgets_active = dispwidget_get_ptr()->active;
|
||||
@ -3617,6 +3618,11 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
|
||||
video_driver_build_info(&video_info);
|
||||
|
||||
render_frame |= video_info.menu_is_alive;
|
||||
|
||||
if (!render_frame)
|
||||
runloop_st->fastforward_frameskip_frames_current--;
|
||||
|
||||
/* Get the amount of frames per seconds. */
|
||||
if (video_st->frame_count)
|
||||
{
|
||||
@ -3772,7 +3778,7 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
pitch, runloop_idle);
|
||||
|
||||
#ifdef HAVE_VIDEO_FILTER
|
||||
if (data && video_st->state_filter)
|
||||
if (render_frame && data && video_st->state_filter)
|
||||
{
|
||||
unsigned output_width = 0;
|
||||
unsigned output_height = 0;
|
||||
@ -3834,11 +3840,7 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
msg_entry.category,
|
||||
msg_entry.prio,
|
||||
false,
|
||||
#ifdef HAVE_MENU
|
||||
menu_state_get_ptr()->alive
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
video_info.menu_is_alive
|
||||
);
|
||||
}
|
||||
/* ...otherwise, just output message via
|
||||
@ -3858,7 +3860,7 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
}
|
||||
}
|
||||
|
||||
if (video_info.statistics_show)
|
||||
if (render_frame && video_info.statistics_show)
|
||||
{
|
||||
audio_statistics_t audio_stats;
|
||||
double stddev = 0.0;
|
||||
@ -3920,13 +3922,17 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
/* TODO/FIXME - add OSD chat text here */
|
||||
}
|
||||
|
||||
if (video_st->current_video && video_st->current_video->frame)
|
||||
if (render_frame && video_st->current_video && video_st->current_video->frame)
|
||||
{
|
||||
video_st->active = video_st->current_video->frame(
|
||||
video_st->data, data, width, height,
|
||||
video_st->frame_count, (unsigned)pitch,
|
||||
video_info.menu_screensaver_active || video_info.notifications_hidden ? "" : video_driver_msg,
|
||||
&video_info);
|
||||
|
||||
runloop_st->fastforward_frameskip_frames_current = runloop_st->fastforward_frameskip_frames;
|
||||
}
|
||||
|
||||
video_st->frame_count++;
|
||||
|
||||
/* Display the status text, with a higher priority. */
|
||||
|
@ -1234,6 +1234,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_FASTFORWARD_RATIO,
|
||||
"fastforward_ratio"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP,
|
||||
"fastforward_frameskip"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_CORE,
|
||||
"file_browser_core"
|
||||
|
@ -3460,6 +3460,14 @@ MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO,
|
||||
"The maximum rate at which content will be run when using fast-forward (e.g., 5.0x for 60 fps content = 300 fps cap). If set to 0.0x, fast-forward ratio is unlimited (no FPS cap)."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_FASTFORWARD_FRAMESKIP,
|
||||
"Fast-Forward Frameskip"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_FASTFORWARD_FRAMESKIP,
|
||||
"Skip frames according to fast-forward rate. This conserves power and allows the use of 3rd party frame limiting."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO,
|
||||
"Slow-Motion Rate"
|
||||
|
@ -494,6 +494,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_gpu_record, MENU_
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_savestate_auto_index, MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_block_sram_overwrite, MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_fastforward_ratio, MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO)
|
||||
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_enabled, MENU_ENUM_SUBLABEL_RUN_AHEAD_ENABLED)
|
||||
@ -3409,6 +3410,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_FASTFORWARD_RATIO:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_fastforward_ratio);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_fastforward_frameskip);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_vrr_runloop_enable);
|
||||
break;
|
||||
|
@ -9393,6 +9393,7 @@ unsigned menu_displaylist_build_list(
|
||||
#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 },
|
||||
|
@ -13950,6 +13950,22 @@ static bool setting_append_list(
|
||||
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_SET_FRAME_LIMIT);
|
||||
menu_settings_list_current_add_range(list, list_info, 0, 10, 1.0, true, true);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.fastforward_frameskip,
|
||||
MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP,
|
||||
MENU_ENUM_LABEL_VALUE_FASTFORWARD_FRAMESKIP,
|
||||
DEFAULT_FASTFORWARD_FRAMESKIP,
|
||||
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.vrr_runloop_enable,
|
||||
|
@ -1993,6 +1993,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(OVERLAY_CENTER_Y),
|
||||
|
||||
MENU_LABEL(FASTFORWARD_RATIO),
|
||||
MENU_LABEL(FASTFORWARD_FRAMESKIP),
|
||||
MENU_LABEL(VRR_RUNLOOP_ENABLE),
|
||||
MENU_LABEL(REWIND_ENABLE),
|
||||
MENU_LABEL(CHEAT_APPLY_AFTER_TOGGLE),
|
||||
|
18
runloop.c
18
runloop.c
@ -4910,6 +4910,22 @@ static bool core_unload_game(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void runloop_apply_fastmotion_frameskip(runloop_state_t *runloop_st, settings_t *settings)
|
||||
{
|
||||
unsigned frames = 0;
|
||||
|
||||
if (runloop_st->fastmotion && settings->bools.fastforward_frameskip)
|
||||
{
|
||||
frames = (unsigned)settings->floats.fastforward_ratio;
|
||||
/* Pick refresh rate as unlimited throttle rate */
|
||||
frames = (!frames) ? (unsigned)roundf(settings->floats.video_refresh_rate) : frames;
|
||||
/* Decrease one to represent skipped frames */
|
||||
frames--;
|
||||
}
|
||||
|
||||
runloop_st->fastforward_frameskip_frames_current = runloop_st->fastforward_frameskip_frames = frames;
|
||||
}
|
||||
|
||||
static void runloop_apply_fastmotion_override(runloop_state_t *runloop_st, settings_t *settings)
|
||||
{
|
||||
video_driver_state_t *video_st = video_state_get_ptr();
|
||||
@ -4947,6 +4963,7 @@ static void runloop_apply_fastmotion_override(runloop_state_t *runloop_st, setti
|
||||
if (!runloop_st->fastmotion)
|
||||
runloop_st->fastforward_after_frames = 1;
|
||||
|
||||
runloop_apply_fastmotion_frameskip(runloop_st, settings);
|
||||
driver_set_nonblock_state();
|
||||
|
||||
/* Reset frame time counter when toggling
|
||||
@ -7063,6 +7080,7 @@ static enum runloop_state_enum runloop_check_state(
|
||||
runloop_st->fastmotion = true;
|
||||
}
|
||||
|
||||
runloop_apply_fastmotion_frameskip(runloop_st, settings);
|
||||
driver_set_nonblock_state();
|
||||
|
||||
/* Reset frame time counter when toggling
|
||||
|
@ -216,6 +216,8 @@ struct runloop
|
||||
unsigned max_frames;
|
||||
unsigned audio_latency;
|
||||
unsigned fastforward_after_frames;
|
||||
unsigned fastforward_frameskip_frames;
|
||||
unsigned fastforward_frameskip_frames_current;
|
||||
unsigned perf_ptr_libretro;
|
||||
unsigned subsystem_current_count;
|
||||
unsigned entry_state_slot;
|
||||
|
Loading…
x
Reference in New Issue
Block a user