Added support for sub-millisecond frame times.

This commit is contained in:
Muzychenko Andrey 2021-10-03 18:06:19 +03:00
parent 5e03978cd7
commit 8d2745fc33
3 changed files with 23 additions and 19 deletions

View File

@ -30,7 +30,7 @@
TPinballTable* pb::MainTable = nullptr; TPinballTable* pb::MainTable = nullptr;
DatFile* pb::record_table = 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_; 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]; high_score_struct pb::highscore_table[5];
bool pb::FullTiltMode = false; bool pb::FullTiltMode = false;
@ -209,26 +209,31 @@ void pb::ballset(int x, int y)
ball->Speed = maths::normalize_2d(&ball->Acceleration); ball->Speed = maths::normalize_2d(&ball->Acceleration);
} }
void pb::frame(int dtMilliSec) void pb::frame(float dtMilliSec)
{ {
if (dtMilliSec > 100) if (dtMilliSec > 100)
dtMilliSec = 100; dtMilliSec = 100;
if (dtMilliSec <= 0) if (dtMilliSec < 0)
return; return;
float dtMicroSec = dtMilliSec * 0.001f; float dtSec = dtMilliSec * 0.001f;
if (!mode_countdown(dtMilliSec)) if (!mode_countdown(dtMilliSec))
{ {
time_next = time_now + dtMicroSec; time_next = time_now + dtSec;
timed_frame(time_now, dtMicroSec, true); timed_frame(time_now, dtSec, true);
time_now = time_next; time_now = time_next;
time_ticks += dtMilliSec;
dtMilliSec += time_ticks_remainder;
auto dtWhole = static_cast<int>(dtMilliSec);
time_ticks_remainder = dtMilliSec - static_cast<float>(dtWhole);
time_ticks += dtWhole;
if (nudge::nudged_left || nudge::nudged_right || nudge::nudged_up) 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 else
{ {
auto nudgeDec = nudge::nudge_count - dtMicroSec; auto nudgeDec = nudge::nudge_count - dtSec;
if (nudgeDec <= 0.0f) if (nudgeDec <= 0.0f)
nudgeDec = 0.0; nudgeDec = 0.0;
nudge::nudge_count = nudgeDec; nudge::nudge_count = nudgeDec;

View File

@ -33,7 +33,7 @@ class pb
{ {
public: public:
static int time_ticks; 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 int cheat_mode, game_mode;
static DatFile* record_table; static DatFile* record_table;
static TPinballTable* MainTable; static TPinballTable* MainTable;
@ -48,7 +48,7 @@ public:
static void toggle_demo(); static void toggle_demo();
static void replay_level(int demoMode); static void replay_level(int demoMode);
static void ballset(int x, int y); 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 timed_frame(float timeNow, float timeDelta, bool drawBalls);
static void window_size(int* width, int* height); static void window_size(int* width, int* height);
static void pause_continue(); static void pause_continue();

View File

@ -154,8 +154,8 @@ int winmain::WinMain(LPCSTR lpCmdLine)
DWORD dtHistoryCounter = 300u, updateCounter = 0, frameCounter = 0; DWORD dtHistoryCounter = 300u, updateCounter = 0, frameCounter = 0;
auto frameStart = Clock::now(); auto frameStart = Clock::now();
double frameDuration = TargetFrameTime.count(), UpdateToFrameCounter = 0; double UpdateToFrameCounter = 0;
DurationMs sleepRemainder(0); DurationMs sleepRemainder(0), frameDuration(TargetFrameTime);
auto prevTime = frameStart; auto prevTime = frameStart;
while (true) while (true)
{ {
@ -219,12 +219,12 @@ int winmain::WinMain(LPCSTR lpCmdLine)
} }
if (!single_step) if (!single_step)
{ {
auto deltaT = static_cast<int>(frameDuration); auto dt = static_cast<float>(frameDuration.count());
frameDuration -= deltaT; auto dtWhole = static_cast<int>(std::round(dt));
pb::frame(deltaT); pb::frame(dt);
if (gfr_display) if (gfr_display)
{ {
auto deltaTPal = deltaT + 10; auto deltaTPal = dtWhole + 10;
auto fillChar = static_cast<uint8_t>(deltaTPal); auto fillChar = static_cast<uint8_t>(deltaTPal);
if (deltaTPal > 236) if (deltaTPal > 236)
{ {
@ -277,8 +277,7 @@ int winmain::WinMain(LPCSTR lpCmdLine)
} }
// Limit duration to 2 * target time // Limit duration to 2 * target time
frameDuration = std::min(frameDuration + DurationMs(frameEnd - frameStart).count(), frameDuration = std::min<DurationMs>(DurationMs(frameEnd - frameStart), 2 * TargetFrameTime);
2 * TargetFrameTime.count());
frameStart = frameEnd; frameStart = frameEnd;
UpdateToFrameCounter++; UpdateToFrameCounter++;
} }