From 08bbf6a165fa607373113ef4a6e8b13ab0395beb Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 25 Dec 2021 17:16:00 +1100 Subject: [PATCH] Fix LimitXYZ mode still undershooting by a couple FPS when moving around This was because the frame time calculation code was not accounting for how long Window_ProcessEvents took --- src/Game.c | 21 +++++++++++---------- src/Game.h | 2 ++ src/Graphics_D3D11.c | 2 +- src/Graphics_D3D9.c | 1 - src/_GLShared.h | 2 +- src/_GraphicsBase.h | 3 +-- 6 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Game.c b/src/Game.c index 6ea16a33c..3cfd48a20 100644 --- a/src/Game.c +++ b/src/Game.c @@ -38,6 +38,7 @@ #include "Animations.h" struct _GameData Game; +cc_uint64 Game_FrameStart; cc_bool Game_UseCPEBlocks; struct RayTracer Game_SelectedPos; @@ -607,25 +608,24 @@ void Game_Free(void* obj) { } #define Game_DoFrameBody() \ + render = Stopwatch_Measure();\ Window_ProcessEvents();\ if (!WindowInfo.Exists) return;\ \ - render = Stopwatch_Measure();\ - time = Stopwatch_ElapsedMicroseconds(lastRender, render) / (1000.0 * 1000.0);\ + delta = Stopwatch_ElapsedMicroseconds(Game_FrameStart, render) / (1000.0 * 1000.0);\ \ - if (time > 1.0) time = 1.0; /* avoid large delta with suspended process */ \ - if (time > 0.0) { lastRender = Stopwatch_Measure(); Game_RenderFrame(time); } + if (delta > 1.0) delta = 1.0; /* avoid large delta with suspended process */ \ + if (delta > 0.0) { Game_FrameStart = render; Game_RenderFrame(delta); } #ifdef CC_BUILD_WEB -static cc_uint64 lastRender; void Game_DoFrame(void) { cc_uint64 render; - double time; + double delta; Game_DoFrameBody() } static void Game_RunLoop(void) { - lastRender = Stopwatch_Measure(); + Game_FrameStart = Stopwatch_Measure(); /* Window_Web.c sets Game_DoFrame as the main loop callback function */ /* (i.e. web browser is in charge of calling Game_DoFrame, not us) */ } @@ -643,9 +643,10 @@ cc_bool Game_ShouldClose(void) { } #else static void Game_RunLoop(void) { - cc_uint64 lastRender, render; - double time; - lastRender = Stopwatch_Measure(); + cc_uint64 render; + double delta; + + Game_FrameStart = Stopwatch_Measure(); for (;;) { Game_DoFrameBody() } } #endif diff --git a/src/Game.h b/src/Game.h index d9b2ad7d9..43d77af09 100644 --- a/src/Game.h +++ b/src/Game.h @@ -16,6 +16,8 @@ CC_VAR extern struct _GameData { int ChunkUpdates; } Game; +/* Stopwatch measurement of when current frame started */ +extern cc_uint64 Game_FrameStart; extern struct RayTracer Game_SelectedPos; extern cc_bool Game_UseCPEBlocks; diff --git a/src/Graphics_D3D11.c b/src/Graphics_D3D11.c index 2a4dc394c..458b51bbe 100644 --- a/src/Graphics_D3D11.c +++ b/src/Graphics_D3D11.c @@ -1017,7 +1017,7 @@ void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) { gfx_minFrameMs = minFrameMs; gfx_vsync = vsync; } -void Gfx_BeginFrame(void) { frameStart = Stopwatch_Measure(); } +void Gfx_BeginFrame(void) { } void Gfx_Clear(void) { OM_Clear(); } void Gfx_EndFrame(void) { diff --git a/src/Graphics_D3D9.c b/src/Graphics_D3D9.c index cc6aba8d9..8f16f3669 100644 --- a/src/Graphics_D3D9.c +++ b/src/Graphics_D3D9.c @@ -801,7 +801,6 @@ void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) { void Gfx_BeginFrame(void) { IDirect3DDevice9_BeginScene(device); - frameStart = Stopwatch_Measure(); } void Gfx_Clear(void) { diff --git a/src/_GLShared.h b/src/_GLShared.h index 18b80234f..7aebccdcb 100644 --- a/src/_GLShared.h +++ b/src/_GLShared.h @@ -268,7 +268,7 @@ void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) { if (Gfx.Created) GL_UpdateVsync(); } -void Gfx_BeginFrame(void) { frameStart = Stopwatch_Measure(); } +void Gfx_BeginFrame(void) { } void Gfx_Clear(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void Gfx_EndFrame(void) { diff --git a/src/_GraphicsBase.h b/src/_GraphicsBase.h index dba073b60..749d0f141 100644 --- a/src/_GraphicsBase.h +++ b/src/_GraphicsBase.h @@ -22,7 +22,6 @@ static cc_bool customMipmapsLevels; static cc_bool gfx_vsync, gfx_fogEnabled; static float gfx_minFrameMs; -static cc_uint64 frameStart; cc_bool Gfx_GetFog(void) { return gfx_fogEnabled; } /* Initialises/Restores render state */ @@ -78,7 +77,7 @@ static float gfx_targetTime, gfx_actualTime; /* then sleeps if actual frame time is too fast */ static void LimitFPS(void) { cc_uint64 frameEnd = Stopwatch_Measure(); - gfx_actualTime += Stopwatch_ElapsedMicroseconds(frameStart, frameEnd) / 1000.0f; + gfx_actualTime += Stopwatch_ElapsedMicroseconds(Game_FrameStart, frameEnd) / 1000.0f; gfx_targetTime += gfx_minFrameMs; /* going faster than FPS limit - sleep to slow down */