diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index 2d3b105b9..aec1288f2 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -90,7 +90,8 @@ f32 gRenderingDelta = 0; #define FRAMERATE 30 static const f64 sFrameTime = (1.0 / ((double)FRAMERATE)); static f64 sFrameTargetTime = 0; -static f64 sFrameTimeStart; +static f64 sFrameTimeStart = 0; +static f64 sFrameLastClock = 0; bool gGameInited = false; bool gGfxInited = false; @@ -179,17 +180,21 @@ static inline void patch_interpolations(f32 delta) { void produce_interpolation_frames_and_delay(void) { u64 frames = 0; f64 curTime = clock_elapsed_f64(); + f64 timeStart = curTime; gRenderingInterpolated = true; // sanity check target time to deal with hangs and such - if (fabs(sFrameTargetTime - curTime) > 1) { sFrameTargetTime = curTime - 0.01f; } + if (curTime >= sFrameTargetTime) { sFrameTargetTime = curTime - 0.01; } + + // Account for the actual start of the frame and the time elapsed during the game logic + f64 targetDelta = ((sFrameTargetTime - curTime + (sFrameLastClock - sFrameTimeStart)) * FRAMERATE) / (f64) configFrameLimit; // interpolate and render while ((curTime = clock_elapsed_f64()) < sFrameTargetTime) { f32 delta = ((!configUncappedFramerate && configFrameLimit == FRAMERATE) ? 1.0f - : MAX(MIN((curTime - sFrameTimeStart) / (sFrameTargetTime - sFrameTimeStart), 1.0f), 0.0f) + : MAX(MIN((curTime - timeStart) / (sFrameTargetTime - timeStart), 1.0f), 0.0f) ); gRenderingDelta = delta; @@ -203,11 +208,10 @@ void produce_interpolation_frames_and_delay(void) { if (configUncappedFramerate) { continue; } // Delay if our framerate is capped. - f64 targetDelta = 1.0 / (f64) configFrameLimit; f64 now = clock_elapsed_f64(); f64 actualDelta = now - curTime; if (actualDelta >= targetDelta) { continue; } - f64 delay = ((targetDelta - actualDelta) * 1000.0) - 1.0; + f64 delay = (targetDelta - actualDelta) * 1000.0; if (delay > 0.0f) { WAPI.delay((u32)delay); } @@ -228,6 +232,7 @@ void produce_interpolation_frames_and_delay(void) { } sFrameTimeStart = sFrameTargetTime; + sFrameLastClock = clock_elapsed_f64(); sFrameTargetTime += sFrameTime; gRenderingInterpolated = false; }