diff --git a/cores/dynamic_dummy.c b/cores/dynamic_dummy.c index 2aba2f5fd2..d456c4ed01 100644 --- a/cores/dynamic_dummy.c +++ b/cores/dynamic_dummy.c @@ -91,12 +91,23 @@ void libretro_dummy_retro_get_system_info( info->valid_extensions = ""; /* Nothing. */ } +static retro_video_refresh_t dummy_video_cb; +static retro_audio_sample_t dummy_audio_cb; +static retro_audio_sample_batch_t dummy_audio_batch_cb; +static retro_environment_t dummy_environ_cb; +static retro_input_poll_t dummy_input_poll_cb; +static retro_input_state_t dummy_input_state_cb; + /* Doesn't really matter, but need something sane. */ void libretro_dummy_retro_get_system_av_info( struct retro_system_av_info *info) { - info->timing.fps = 60.0; - info->timing.sample_rate = 30000.0; + float refresh_rate = 0.0; + if (!dummy_environ_cb(RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE, &refresh_rate)) + refresh_rate = 60.0; + + info->timing.fps = refresh_rate; + info->timing.sample_rate = 30000.0; info->geometry.base_width = 320; info->geometry.base_height = 240; @@ -105,13 +116,6 @@ void libretro_dummy_retro_get_system_av_info( info->geometry.aspect_ratio = 4.0 / 3.0; } -static retro_video_refresh_t dummy_video_cb; -static retro_audio_sample_t dummy_audio_cb; -static retro_audio_sample_batch_t dummy_audio_batch_cb; -static retro_environment_t dummy_environ_cb; -static retro_input_poll_t dummy_input_poll_cb; -static retro_input_state_t dummy_input_state_cb; - void libretro_dummy_retro_set_environment(retro_environment_t cb) { enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; diff --git a/dynamic.c b/dynamic.c index 8b24228918..8ed31ca0a1 100644 --- a/dynamic.c +++ b/dynamic.c @@ -2051,6 +2051,20 @@ bool rarch_environment_cb(unsigned cmd, void *data) break; } + case RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE: + { + /* Try to use the polled refresh rate first. */ + float target_refresh_rate = video_driver_get_refresh_rate(); + + /* If the above function failed [possibly because it is not + * implemented], use the refresh rate set in the config instead. */ + if (target_refresh_rate == 0.0 && settings) + target_refresh_rate = settings->floats.video_refresh_rate; + + *(float *)data = target_refresh_rate; + break; + } + default: RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd); return false; diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index fadab9b7ca..1482ea4104 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -1079,10 +1079,19 @@ enum retro_mod * fastforwarding mode. */ +#define RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE (50 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* float * -- + * Float value that lets us know what target refresh rate + * is curently in use by the frontend. + * + * The core can use the returned value to set an ideal + * refresh rate/framerate. + */ + /* VFS functionality */ /* File paths: - * File paths passed as parameters when using this api shall be well formed unix-style, + * File paths passed as parameters when using this api shall be well formed UNIX-style, * using "/" (unquoted forward slash) as directory separator regardless of the platform's native separator. * Paths shall also include at least one forward slash ("game.bin" is an invalid path, use "./game.bin" instead). * Other than the directory separator, cores shall not make assumptions about path format: diff --git a/retroarch.c b/retroarch.c index ccd60681e8..bdc6921129 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2563,10 +2563,13 @@ void runloop_msg_queue_push(const char *msg, enum message_queue_icon icon, enum message_queue_category category) { runloop_ctx_msg_info_t msg_info; - #if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS) - /* People have 60FPS in mind when they use runloop_msg_queue_push */ - if (video_driver_has_widgets() && menu_widgets_msg_queue_push(msg, duration / 60 * 1000, title, icon, category, prio, flush)) + float target_hz = 0.0; + + rarch_environment_cb(RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE, &target_hz); + + if (video_driver_has_widgets() && menu_widgets_msg_queue_push(msg, + duration / target_hz * 1000, title, icon, category, prio, flush)) return; #endif @@ -2895,12 +2898,19 @@ static enum runloop_state runloop_check_state( /* Check double press if enabled */ if (trig_quit_key && settings->bools.quit_press_twice) { - retro_time_t cur_time = cpu_features_get_time_usec(); + retro_time_t cur_time; + float target_hz = 0.0; + + rarch_environment_cb(RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE, &target_hz); + + cur_time = cpu_features_get_time_usec(); trig_quit_key = trig_quit_key && (cur_time - quit_key_time < QUIT_DELAY_USEC); quit_key_time = cur_time; if (!trig_quit_key) - runloop_msg_queue_push(msg_hash_to_str(MSG_PRESS_AGAIN_TO_QUIT), 1, QUIT_DELAY_USEC * 60 / 1000000, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + runloop_msg_queue_push(msg_hash_to_str(MSG_PRESS_AGAIN_TO_QUIT), 1, + QUIT_DELAY_USEC * target_hz / 1000000, + true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); } if (time_to_exit(trig_quit_key))