From 8d2745fc33352c84ad32664567c922a627040994 Mon Sep 17 00:00:00 2001 From: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> Date: Sun, 3 Oct 2021 18:06:19 +0300 Subject: [PATCH] Added support for sub-millisecond frame times. --- SpaceCadetPinball/pb.cpp | 23 ++++++++++++++--------- SpaceCadetPinball/pb.h | 4 ++-- SpaceCadetPinball/winmain.cpp | 15 +++++++-------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index b484115..d27b35f 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -30,7 +30,7 @@ TPinballTable* pb::MainTable = nullptr; DatFile* pb::record_table = nullptr; int pb::time_ticks = 0, pb::demo_mode = 0, pb::cheat_mode = 0, pb::game_mode = 2, pb::mode_countdown_; -float pb::time_now, pb::time_next, pb::ball_speed_limit; +float pb::time_now = 0, pb::time_next = 0, pb::ball_speed_limit, pb::time_ticks_remainder = 0; high_score_struct pb::highscore_table[5]; bool pb::FullTiltMode = false; @@ -209,26 +209,31 @@ void pb::ballset(int x, int y) ball->Speed = maths::normalize_2d(&ball->Acceleration); } -void pb::frame(int dtMilliSec) +void pb::frame(float dtMilliSec) { if (dtMilliSec > 100) dtMilliSec = 100; - if (dtMilliSec <= 0) + if (dtMilliSec < 0) return; - float dtMicroSec = dtMilliSec * 0.001f; + float dtSec = dtMilliSec * 0.001f; if (!mode_countdown(dtMilliSec)) { - time_next = time_now + dtMicroSec; - timed_frame(time_now, dtMicroSec, true); + time_next = time_now + dtSec; + timed_frame(time_now, dtSec, true); time_now = time_next; - time_ticks += dtMilliSec; + + dtMilliSec += time_ticks_remainder; + auto dtWhole = static_cast(dtMilliSec); + time_ticks_remainder = dtMilliSec - static_cast(dtWhole); + time_ticks += dtWhole; + if (nudge::nudged_left || nudge::nudged_right || nudge::nudged_up) { - nudge::nudge_count = dtMicroSec * 4.0f + nudge::nudge_count; + nudge::nudge_count = dtSec * 4.0f + nudge::nudge_count; } else { - auto nudgeDec = nudge::nudge_count - dtMicroSec; + auto nudgeDec = nudge::nudge_count - dtSec; if (nudgeDec <= 0.0f) nudgeDec = 0.0; nudge::nudge_count = nudgeDec; diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h index 17bd97e..155deb7 100644 --- a/SpaceCadetPinball/pb.h +++ b/SpaceCadetPinball/pb.h @@ -33,7 +33,7 @@ class pb { public: static int time_ticks; - static float ball_speed_limit, time_now, time_next; + static float ball_speed_limit, time_now, time_next, time_ticks_remainder; static int cheat_mode, game_mode; static DatFile* record_table; static TPinballTable* MainTable; @@ -48,7 +48,7 @@ public: static void toggle_demo(); static void replay_level(int demoMode); static void ballset(int x, int y); - static void frame(int dtMilliSec); + static void frame(float dtMilliSec); static void timed_frame(float timeNow, float timeDelta, bool drawBalls); static void window_size(int* width, int* height); static void pause_continue(); diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index 16ac96a..87a8d1d 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -154,8 +154,8 @@ int winmain::WinMain(LPCSTR lpCmdLine) DWORD dtHistoryCounter = 300u, updateCounter = 0, frameCounter = 0; auto frameStart = Clock::now(); - double frameDuration = TargetFrameTime.count(), UpdateToFrameCounter = 0; - DurationMs sleepRemainder(0); + double UpdateToFrameCounter = 0; + DurationMs sleepRemainder(0), frameDuration(TargetFrameTime); auto prevTime = frameStart; while (true) { @@ -219,12 +219,12 @@ int winmain::WinMain(LPCSTR lpCmdLine) } if (!single_step) { - auto deltaT = static_cast(frameDuration); - frameDuration -= deltaT; - pb::frame(deltaT); + auto dt = static_cast(frameDuration.count()); + auto dtWhole = static_cast(std::round(dt)); + pb::frame(dt); if (gfr_display) { - auto deltaTPal = deltaT + 10; + auto deltaTPal = dtWhole + 10; auto fillChar = static_cast(deltaTPal); if (deltaTPal > 236) { @@ -277,8 +277,7 @@ int winmain::WinMain(LPCSTR lpCmdLine) } // Limit duration to 2 * target time - frameDuration = std::min(frameDuration + DurationMs(frameEnd - frameStart).count(), - 2 * TargetFrameTime.count()); + frameDuration = std::min(DurationMs(frameEnd - frameStart), 2 * TargetFrameTime); frameStart = frameEnd; UpdateToFrameCounter++; }