improved delta calculations for capped framrates
Some checks failed
Build coop / build-linux (push) Has been cancelled
Build coop / build-steamos (push) Has been cancelled
Build coop / build-windows-opengl (push) Has been cancelled
Build coop / build-windows-directx (push) Has been cancelled
Build coop / build-macos-arm (push) Has been cancelled
Build coop / build-macos-intel (push) Has been cancelled

This commit is contained in:
Isaac0-dev 2025-07-26 13:30:24 +10:00
parent 46b1a8bbb9
commit 593eb9aafc

View file

@ -61,6 +61,8 @@
#include "gfx_dimensions.h" #include "gfx_dimensions.h"
#include "game/segment2.h" #include "game/segment2.h"
#include "engine/math_util.h"
#ifdef DISCORD_SDK #ifdef DISCORD_SDK
#include "pc/discord/discord.h" #include "pc/discord/discord.h"
#endif #endif
@ -203,18 +205,16 @@ static s32 get_num_frames_to_draw(f64 t, u32 frameLimit) {
static u32 get_refresh_rate() { static u32 get_refresh_rate() {
if (configFramerateMode == RRM_MANUAL) { return configFrameLimit; } if (configFramerateMode == RRM_MANUAL) { return configFrameLimit; }
if (configFramerateMode == RRM_UNLIMITED) { return 3000; } // Has no effect if (configFramerateMode == RRM_UNLIMITED) { return 3000; } // Has no effect
#ifdef HAVE_SDL2
static u32 refreshRate = 60; static u32 refreshRate = 60;
#ifdef HAVE_SDL2
if (!refreshRate) { if (!refreshRate) {
SDL_DisplayMode mode; SDL_DisplayMode mode;
if (SDL_GetCurrentDisplayMode(0, &mode) == 0) { if (SDL_GetCurrentDisplayMode(0, &mode) == 0) {
refreshRate = (u32) mode.refresh_rate; refreshRate = (u32) mode.refresh_rate;
} }
} }
return refreshRate;
#else
return 60;
#endif #endif
return refreshRate;
} }
void produce_interpolation_frames_and_delay(void) { void produce_interpolation_frames_and_delay(void) {
@ -229,15 +229,21 @@ void produce_interpolation_frames_and_delay(void) {
f64 curTime = clock_elapsed_f64(); f64 curTime = clock_elapsed_f64();
f64 loopStartTime = curTime; f64 loopStartTime = curTime;
f64 expectedTime = 0; f64 expectedTime = 0;
u16 frames = 0;
const f64 interpFrameTime = sFrameTime / (f64) numFramesToDraw;
// interpolate and render // interpolate and render
// make sure to draw at least one frame to prevent the game from freezing completely // make sure to draw at least one frame to prevent the game from freezing completely
// (including inputs and window events) if the game update duration is greater than 33ms // (including inputs and window events) if the game update duration is greater than 33ms
do { do {
++frames;
// when we know how many frames to draw, use a precise delta
f64 idealTime = configFramerateMode != RRM_UNLIMITED ? (sFrameTimeStart + interpFrameTime * frames) : curTime;
f32 delta = ( f32 delta = (
is30Fps ? is30Fps ?
1.0f : 1.0f :
MIN(MAX((curTime - sFrameTimeStart) / sFrameTime, 0.f), 1.f) clamp((idealTime - sFrameTimeStart) / sFrameTime, 0.f, 1.f)
); );
gRenderingDelta = delta; gRenderingDelta = delta;
@ -248,7 +254,7 @@ void produce_interpolation_frames_and_delay(void) {
gfx_end_frame_render(); gfx_end_frame_render();
// delay if our framerate is capped // delay if our framerate is capped
if (!configUncappedFramerate && !configWindow.vsync) { if (configFramerateMode != RRM_UNLIMITED && !configWindow.vsync) {
f64 now = clock_elapsed_f64(); f64 now = clock_elapsed_f64();
f64 elapsedTime = now - loopStartTime; f64 elapsedTime = now - loopStartTime;
expectedTime += (targetTime - curTime) / (f64) numFramesToDraw; expectedTime += (targetTime - curTime) / (f64) numFramesToDraw;