diff --git a/source/build/include/timer.h b/source/build/include/timer.h index d72c21f66..a2f6c781f 100644 --- a/source/build/include/timer.h +++ b/source/build/include/timer.h @@ -5,14 +5,17 @@ #include "compat.h" -int32_t timerInit(int32_t); -void timerUninit(void); +// for compatibility +#define timerUninit() + +int timerInit(int const tickspersecond); void timerUpdate(void); -int32_t timerGetRate(void); +int timerGetRate(void); uint64_t timerGetTicksU64(void); uint64_t timerGetFreqU64(void); double timerGetHiTicks(void); uint32_t timerGetTicks(void); + void (*timerSetCallback(void (*callback)(void)))(void); #endif // timer_h__ diff --git a/source/build/src/timer.cpp b/source/build/src/timer.cpp index 67a31f664..4463e91da 100644 --- a/source/build/src/timer.cpp +++ b/source/build/src/timer.cpp @@ -9,41 +9,38 @@ using namespace std; using namespace chrono; -static int32_t timerlastsample; -static int32_t timerticspersec=0; +static time_point timerlastsample; +static int timerticspersec; static void(*usertimercallback)(void) = NULL; -int32_t timerGetRate(void) { return timerticspersec; } -void timerUninit(void) { timerticspersec = 0; } - -uint32_t timerGetTicks(void) { return duration_cast(system_clock::now().time_since_epoch()).count(); } -uint64_t timerGetTicksU64(void) { return high_resolution_clock::now().time_since_epoch().count(); } -uint64_t timerGetFreqU64(void) { return high_resolution_clock::period::den; } +int timerGetRate(void) { return timerticspersec; } +uint32_t timerGetTicks(void) { return duration_cast(steady_clock::now().time_since_epoch()).count(); } +uint64_t timerGetTicksU64(void) { return steady_clock::now().time_since_epoch().count(); } +uint64_t timerGetFreqU64(void) { return steady_clock::period::den; } // Returns the time since an unspecified starting time in milliseconds. // (May be not monotonic for certain configurations.) -ATTRIBUTE((flatten)) -double timerGetHiTicks(void) { return duration(high_resolution_clock::now().time_since_epoch()).count(); } +double timerGetHiTicks(void) { return duration(steady_clock::now().time_since_epoch()).count() / 1000000.0; } -int32_t timerInit(int32_t const tickspersecond) +int timerInit(int const tickspersecond) { timerticspersec = tickspersecond; - timerlastsample = timerGetTicksU64() * timerticspersec / timerGetFreqU64(); + timerlastsample = steady_clock::now(); usertimercallback = NULL; return 0; } -void timerUpdate(void) +ATTRIBUTE((flatten)) void timerUpdate(void) { - if (!timerticspersec) return; + auto time = steady_clock::now(); + int n = (time - timerlastsample).count() * (double)timerticspersec / timerGetFreqU64(); - uint64_t n = (timerGetTicksU64() * timerticspersec / timerGetFreqU64()) - timerlastsample; if (n <= 0) return; totalclock += n; - timerlastsample += n; + timerlastsample = time; if (usertimercallback) for (; n > 0; n--) usertimercallback(); diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 1b073c731..d1b38fa06 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -6338,16 +6338,16 @@ int G_FPSLimit(void) if (!r_maxfps) return 1; - static double nextPageDelay; - static uint64_t lastFrameTicks; + static double nextPageDelay; + static double lastFrameTicks; - uint64_t const frameTicks = timerGetTicksU64(); - int64_t const elapsedTime = frameTicks - lastFrameTicks; + double const frameTicks = timerGetTicksU64(); + double const elapsedTime = frameTicks-lastFrameTicks; - if (elapsedTime >= lrint(floor(nextPageDelay))) + if (elapsedTime >= nextPageDelay) { - if (elapsedTime <= lrint(floor(nextPageDelay + g_frameDelay))) - nextPageDelay = nearbyint(nextPageDelay + g_frameDelay - (double)elapsedTime); + if (elapsedTime <= nextPageDelay+g_frameDelay) + nextPageDelay += g_frameDelay-elapsedTime; lastFrameTicks = frameTicks; diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h index 780885f32..598b66f52 100644 --- a/source/duke3d/src/game.h +++ b/source/duke3d/src/game.h @@ -350,7 +350,7 @@ extern palette_t CrosshairColors; extern palette_t DefaultCrosshairColors; extern double g_frameDelay; -static inline double calcFrameDelay(int const maxFPS) { return maxFPS > 0 ? nearbyint((double)timerGetFreqU64()/maxFPS) : 0.0; } +static inline double calcFrameDelay(int const maxFPS) { return maxFPS > 0 ? (timerGetFreqU64()/(double)maxFPS) : 0.0; } int32_t A_CheckInventorySprite(spritetype *s); int32_t A_InsertSprite(int16_t whatsect, int32_t s_x, int32_t s_y, int32_t s_z, int16_t s_pn, int8_t s_s, uint8_t s_xr,