From c49f0e5c6e574601f05538c9f3eef1ae7f8f2ddc Mon Sep 17 00:00:00 2001 From: Irastris Date: Sat, 23 May 2026 09:18:29 -0400 Subject: [PATCH] Use std::chrono for THP playback pacing (#1757) * Use std::chrono for THP playback pacing * Redundant include --- include/d/actor/d_a_movie_player.h | 2 ++ src/d/actor/d_a_movie_player.cpp | 30 +++++++++++++++++++++--------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/d/actor/d_a_movie_player.h b/include/d/actor/d_a_movie_player.h index 0e666ae470..c382e0d1f7 100644 --- a/include/d/actor/d_a_movie_player.h +++ b/include/d/actor/d_a_movie_player.h @@ -5,6 +5,7 @@ #include #else #include +#include #endif #include "f_op/f_op_actor.h" #include "d/d_drawlist.h" @@ -125,6 +126,7 @@ struct daMP_THPPlayer { /* 0x0D4 */ s32 curCount; #if TARGET_PC /* 0x0D8 */ std::atomic videoDecodeCount; + std::chrono::steady_clock::time_point thpPlaybackClock; #else /* 0x0D8 */ s32 videoDecodeCount; #endif diff --git a/src/d/actor/d_a_movie_player.cpp b/src/d/actor/d_a_movie_player.cpp index 1f8bdeecd7..fcd1fb6dff 100644 --- a/src/d/actor/d_a_movie_player.cpp +++ b/src/d/actor/d_a_movie_player.cpp @@ -26,15 +26,16 @@ #include "f_op/f_op_overlap_mng.h" +#include "JSystem/JAudio2/JASCriticalSection.h" + +#if TARGET_PC #include "dusk/gx_helper.h" #include "dusk/os.h" #include "dusk/layout.hpp" - -#include "JSystem/JAudio2/JASCriticalSection.h" - #if MOVIE_SUPPORT #include "turbojpeg.h" #endif +#endif inline s32 daMP_NEXT_READ_SIZE(daMP_THPReadBuffer* readBuf) { return *(BE(s32)*)readBuf->ptr; @@ -3912,13 +3913,20 @@ static BOOL daMP_ProperTimingForGettingNextFrame() { return TRUE; } } else { - s32 frameRate = daMP_ActivePlayer.header.frameRate * 100.0f; #if TARGET_PC - // DUSK HACK: We only fire retrace callbacks *half* as often as the game expects, - // because we only run them once per frame, and normally there should be two scans - // per game frame. - frameRate *= 2; -#endif + const f32 fps = daMP_ActivePlayer.header.frameRate; + if (fps > 0.0f) { + const f32 elapsed = std::chrono::duration( + std::chrono::steady_clock::now() - daMP_ActivePlayer.thpPlaybackClock).count(); + const s32 desired = static_cast(elapsed * fps); + if (desired != daMP_ActivePlayer.prevCount) { + daMP_ActivePlayer.prevCount = desired; + daMP_ActivePlayer.curCount = desired; + return TRUE; + } + } +#else + s32 frameRate = daMP_ActivePlayer.header.frameRate * 100.0f; if (VIGetTvFormat() == VI_PAL) { daMP_ActivePlayer.curCount = daMP_ActivePlayer.retaceCount * frameRate / 5000; } else { @@ -3929,6 +3937,7 @@ static BOOL daMP_ProperTimingForGettingNextFrame() { daMP_ActivePlayer.prevCount = daMP_ActivePlayer.curCount; return TRUE; } +#endif } return FALSE; @@ -4133,6 +4142,9 @@ static BOOL daMP_THPPlayerPlay() { daMP_ActivePlayer.prevCount = 0; daMP_ActivePlayer.curCount = 0; daMP_ActivePlayer.retaceCount = -1; +#if TARGET_PC + daMP_ActivePlayer.thpPlaybackClock = std::chrono::steady_clock::now(); +#endif return TRUE; }