From d98a56759758c246e69027bc024021e921b2d875 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 May 2021 14:36:54 +0200 Subject: [PATCH] - halt the game timer when setting up a cutscene and when starting movie playback. These are both lengthy operations that can take several 100s of milliseconds, so when starting a streaming video they can throw off the timing quite significantly. With this the intermissiondelay counter could be removed as it was only there to flush the accumulated time before starting video playback. --- source/common/cutscenes/movieplayer.cpp | 2 ++ source/common/cutscenes/screenjob.cpp | 4 +--- source/common/cutscenes/screenjob.h | 2 -- source/common/engine/gamestate.h | 1 - source/common/utility/i_time.cpp | 9 ++++++++- source/common/utility/i_time.h | 3 +++ source/core/mainloop.cpp | 7 +------ source/core/screenjob.cpp | 4 ++-- 8 files changed, 17 insertions(+), 15 deletions(-) diff --git a/source/common/cutscenes/movieplayer.cpp b/source/common/cutscenes/movieplayer.cpp index e2e2ec24c..8ea3967c5 100644 --- a/source/common/cutscenes/movieplayer.cpp +++ b/source/common/cutscenes/movieplayer.cpp @@ -797,7 +797,9 @@ DEFINE_ACTION_FUNCTION(_MoviePlayer, Create) DEFINE_ACTION_FUNCTION(_MoviePlayer, Start) { PARAM_SELF_STRUCT_PROLOGUE(MoviePlayer); + I_FreezeTime(true); self->Start(); + I_FreezeTime(false); return 0; } diff --git a/source/common/cutscenes/screenjob.cpp b/source/common/cutscenes/screenjob.cpp index e53bd84f0..9175a6f62 100644 --- a/source/common/cutscenes/screenjob.cpp +++ b/source/common/cutscenes/screenjob.cpp @@ -59,7 +59,6 @@ PClass* runnerclass; PType* runnerclasstype; CompletionFunc completion; static int ticks; -int intermissiondelay; //============================================================================= // @@ -287,6 +286,7 @@ bool ScreenJobValidate() VMValue parm[] = { runner }; VMReturn ret(&res); VMCall(func, parm, 1, &ret, 1); + I_ResetFrameTime(); return res; } } @@ -315,8 +315,6 @@ bool StartCutscene(CutsceneDef& cs, int flags, const CompletionFunc& completion_ runner = nullptr; return false; } - if (flags & SJ_DELAY) intermissiondelay = 10; // need to wait a bit at the start to let the timer catch up. - else intermissiondelay = 0; if (sysCallbacks.StartCutscene) sysCallbacks.StartCutscene(flags & SJ_BLOCKUI); } catch (...) diff --git a/source/common/cutscenes/screenjob.h b/source/common/cutscenes/screenjob.h index eaf6a10a9..92cb766e8 100644 --- a/source/common/cutscenes/screenjob.h +++ b/source/common/cutscenes/screenjob.h @@ -17,7 +17,6 @@ void Job_Init(); enum { SJ_BLOCKUI = 1, - SJ_DELAY = 2, }; struct CutsceneDef @@ -51,7 +50,6 @@ DObject* CreateRunner(bool clearbefore = true); void AddGenericVideo(DObject* runner, const FString& fn, int soundid, int fps); -extern int intermissiondelay; extern DObject* runner; extern PClass* runnerclass; extern PType* runnerclasstype; diff --git a/source/common/engine/gamestate.h b/source/common/engine/gamestate.h index edea03a69..5f674a33b 100644 --- a/source/common/engine/gamestate.h +++ b/source/common/engine/gamestate.h @@ -26,4 +26,3 @@ enum gamestate_t : int extern gamestate_t gamestate; -extern int intermissiondelay; diff --git a/source/common/utility/i_time.cpp b/source/common/utility/i_time.cpp index 61f7baecb..0a7179660 100644 --- a/source/common/utility/i_time.cpp +++ b/source/common/utility/i_time.cpp @@ -195,9 +195,16 @@ void I_FreezeTime(bool frozen) else { assert(FreezeTime != 0); - FirstFrameStartTime += GetClockTimeNS() - FreezeTime; + if (FirstFrameStartTime != 0) FirstFrameStartTime += GetClockTimeNS() - FreezeTime; FreezeTime = 0; I_SetFrameTime(); } } +void I_ResetFrameTime() +{ + // Reset the starting point of the current frame to now. For use after lengthy operations that should not result in tic accumulation. + auto ft = CurrentFrameStartTime; + I_SetFrameTime(); + FirstFrameStartTime += (CurrentFrameStartTime - ft); +} diff --git a/source/common/utility/i_time.h b/source/common/utility/i_time.h index 4c63515ac..8b4eff05c 100644 --- a/source/common/utility/i_time.h +++ b/source/common/utility/i_time.h @@ -38,3 +38,6 @@ uint64_t I_msTimeFS(); // Nanosecond-accurate time uint64_t I_nsTime(); + +// Reset the timer after a lengthy operation +void I_ResetFrameTime(); diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 24e1c65fd..3db1e65fe 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -372,11 +372,6 @@ static void GameTicker() break; case GS_CUTSCENE: case GS_INTRO: - if (intermissiondelay > 0) - { - intermissiondelay--; - break; - } if (ScreenJobTick()) { // synchronize termination with the playsim. @@ -421,7 +416,7 @@ void Display() case GS_INTRO: case GS_CUTSCENE: // screen jobs are not bound by the game ticker so they need to be ticked in the display loop. - if (intermissiondelay <= 0) ScreenJobDraw(); + ScreenJobDraw(); break; case GS_LEVEL: diff --git a/source/core/screenjob.cpp b/source/core/screenjob.cpp index d90e29f29..dff5b473d 100644 --- a/source/core/screenjob.cpp +++ b/source/core/screenjob.cpp @@ -72,7 +72,7 @@ void Local_Job_Init() // //============================================================================= -void CallCreateMapFunction(const char* qname, DObject* runner, MapRecord* map) +static void CallCreateMapFunction(const char* qname, DObject* runner, MapRecord* map) { auto func = LookupFunction(qname); if (func->Proto->ArgumentTypes.Size() == 1) return CallCreateFunction(qname, runner); // accept functions without map parameter as well here. @@ -143,7 +143,7 @@ void PlayLogos(gameaction_t complete_ga, gameaction_t def_ga, bool stopmusic) } else { - if (!StartCutscene(globalCutscenes.Intro, SJ_BLOCKUI|SJ_DELAY, [=](bool) { + if (!StartCutscene(globalCutscenes.Intro, SJ_BLOCKUI, [=](bool) { gameaction = complete_ga; })) gameaction = def_ga; }