From 6a82db13d553139f185f460a4254feacc7924bf4 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 14 Jul 2013 13:43:01 +0200 Subject: [PATCH] Fixups for frame time callback. --- audio/thread_wrapper.c | 1 + dynamic.c | 4 +++- general.h | 6 +++--- libretro.h | 5 +++-- retroarch.c | 16 ++++++++-------- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/audio/thread_wrapper.c b/audio/thread_wrapper.c index f3f173b7b9..b7d5fa2a8f 100644 --- a/audio/thread_wrapper.c +++ b/audio/thread_wrapper.c @@ -81,6 +81,7 @@ static void audio_thread_free(void *data) { audio_thread_t *thr = (audio_thread_t*)data; slock_lock(thr->lock); + thr->stopped = false; thr->alive = false; scond_signal(thr->cond); slock_unlock(thr->lock); diff --git a/dynamic.c b/dynamic.c index 7e50ab976e..d49ac9d862 100644 --- a/dynamic.c +++ b/dynamic.c @@ -737,12 +737,14 @@ static bool environment_cb(unsigned cmd, void *data) #endif case RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK: + { RARCH_LOG("Environ SET_FRAME_TIME_CALLBACK.\n"); if (g_extern.netplay_enable) // retro_run() will be called in very strange and mysterious ways, have to disable it. return false; const struct retro_frame_time_callback *info = (const struct retro_frame_time_callback*)data; - g_extern.system.frame_time_callback = info->callback; + g_extern.system.frame_time = *info; break; + } default: RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd); diff --git a/general.h b/general.h index 55dab63154..976cd0bd28 100644 --- a/general.h +++ b/general.h @@ -388,12 +388,12 @@ struct global retro_keyboard_event_t key_event; retro_audio_callback_t audio_callback; - retro_usec_t frame_time_last; - retro_frame_time_callback_t frame_time_callback; - struct retro_disk_control_callback disk_control; struct retro_hw_render_callback hw_render_callback; + struct retro_frame_time_callback frame_time; + retro_usec_t frame_time_last; + core_option_manager_t *core_options; } system; diff --git a/libretro.h b/libretro.h index f2d7d1568b..0af84e6548 100755 --- a/libretro.h +++ b/libretro.h @@ -508,7 +508,7 @@ enum retro_mod // const struct retro_frame_time_callback * -- // Lets the core know how much time has passed since last invocation of retro_run(). // The frontend can tamper with the timing to fake fast-forward, slow-motion, frame stepping, etc. - // In this case the delta time will use the FPS value reported in get_av_info(). + // In this case the delta time will use the reference value in frame_time_callback.. // Notifies libretro that audio data should be written. @@ -521,12 +521,13 @@ struct retro_audio_callback // Notifies a libretro core of time spent since last invocation of retro_run() in microseconds. // It will be called right before retro_run() every frame. // The frontend can tamper with timing to support cases like fast-forward, slow-motion and framestepping. -// In those scenarios the FPS value in av_info will be used to fake the frame time. +// In those scenarios the reference frame time value will be used. typedef int64_t retro_usec_t; typedef void (*retro_frame_time_callback_t)(retro_usec_t usec); struct retro_frame_time_callback { retro_frame_time_callback_t callback; + retro_usec_t reference; // Represents the time of one frame. It is computed as 1000000 / fps, but the implementation will resolve the rounding to ensure that framestepping, etc is exact. }; // Pass this to retro_video_refresh_t if rendering to hardware. diff --git a/retroarch.c b/retroarch.c index 5e28a3033d..51c7a45806 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2975,6 +2975,7 @@ static inline bool check_enter_rgui(void) { g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU); old_rmenu_toggle = true; + g_extern.system.frame_time_last = 0; return true; } else @@ -2986,22 +2987,21 @@ static inline bool check_enter_rgui(void) static inline void update_frame_time(void) { - if (!g_extern.system.frame_time_callback) + if (!g_extern.system.frame_time.callback) return; rarch_time_t time = rarch_get_time_usec(); rarch_time_t delta = 0; + + bool is_locked_fps = g_extern.is_paused || driver.nonblock_state || g_extern.recording; - if (!g_extern.system.frame_time_last || g_extern.is_paused || driver.nonblock_state || g_extern.recording) - { - rarch_time_t reference_delta = (rarch_time_t)roundf(1000000LL / g_extern.system.av_info.timing.fps); - delta = reference_delta; - } + if (!g_extern.system.frame_time_last || is_locked_fps) + delta = g_extern.system.frame_time.reference; else delta = time - g_extern.system.frame_time_last; - g_extern.system.frame_time_last = time; - g_extern.system.frame_time_callback(delta); + g_extern.system.frame_time_last = is_locked_fps ? 0 : time; + g_extern.system.frame_time.callback(delta); } bool rarch_main_iterate(void)