diff --git a/GNUmakefile b/GNUmakefile index c3c4b8f9d..eb6a93951 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -234,6 +234,7 @@ engine_objs := \ softsurface.cpp \ mmulti_null.cpp \ mutex.cpp \ + timer.cpp \ xxhash.c \ md4.cpp \ colmatch.cpp \ diff --git a/platform/Windows/build.vcxproj b/platform/Windows/build.vcxproj index 67cafed1e..0699f7305 100644 --- a/platform/Windows/build.vcxproj +++ b/platform/Windows/build.vcxproj @@ -293,6 +293,7 @@ + true @@ -372,6 +373,7 @@ + diff --git a/platform/Windows/build.vcxproj.filters b/platform/Windows/build.vcxproj.filters index 82947b6ec..d92070762 100644 --- a/platform/Windows/build.vcxproj.filters +++ b/platform/Windows/build.vcxproj.filters @@ -191,6 +191,8 @@ GL Interface + + Source Files GL Interface @@ -394,7 +396,9 @@ Header Files - + + Header Files + GL Interface diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index 9a94fd7e9..ac56fb730 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -9,6 +9,7 @@ #include "compat.h" #include "osd.h" +#include "timer.h" #ifdef __cplusplus extern "C" { @@ -262,21 +263,6 @@ void joySetDeadZone(int32_t axis, uint16_t dead, uint16_t satur); void joyGetDeadZone(int32_t axis, uint16_t *dead, uint16_t *satur); extern int32_t inputchecked; -int32_t timerInit(int32_t); -void timerUninit(void); -void timerUpdate(void); -int32_t timerGetFreq(void); -uint64_t timerGetTicksU64(void); -uint64_t timerGetFreqU64(void); -double timerGetHiTicks(void); -void (*timerSetCallback(void (*callback)(void)))(void); - -#if defined RENDERTYPESDL && !defined LUNATIC -static FORCE_INLINE uint32_t timerGetTicks(void) { return (uint32_t)SDL_GetTicks(); } -#else -uint32_t timerGetTicks(void); -#endif - int32_t wm_msgbox(const char *name, const char *fmt, ...) ATTRIBUTE((format(printf,2,3))); int32_t wm_ynbox(const char *name, const char *fmt, ...) ATTRIBUTE((format(printf,2,3))); void wm_setapptitle(const char *name); diff --git a/source/build/include/timer.h b/source/build/include/timer.h new file mode 100644 index 000000000..d72c21f66 --- /dev/null +++ b/source/build/include/timer.h @@ -0,0 +1,18 @@ +#pragma once + +#ifndef timer_h__ +#define timer_h__ + +#include "compat.h" + +int32_t timerInit(int32_t); +void timerUninit(void); +void timerUpdate(void); +int32_t 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/mdsprite.cpp b/source/build/src/mdsprite.cpp index 8ca4aaa73..6391c2995 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -92,8 +92,6 @@ static mdmodel_t *mdload(const char *); static void mdfree(mdmodel_t *); int32_t globalnoeffect=0; -extern int32_t timerticspersec; - void freeallmodels() { int32_t i; @@ -1010,7 +1008,7 @@ void updateanimation(md2model_t *m, tspriteptr_t tspr, uint8_t lpal) fps = smooth->mdsmooth ? Blrintf((1.0f / ((float)tile2model[tile].smoothduration * (1.f / (float)UINT16_MAX))) * 66.f) : anim ? anim->fpssc : 1; - i = (mdtims - sprext->mdanimtims) * ((fps * timerticspersec) / 120); + i = (mdtims - sprext->mdanimtims) * ((fps * timerGetRate()) / 120); j = (smooth->mdsmooth || !anim) ? 65536 : ((anim->endframe + 1 - anim->startframe) << 16); @@ -1018,7 +1016,7 @@ void updateanimation(md2model_t *m, tspriteptr_t tspr, uint8_t lpal) if (i < 0) { i = 0; sprext->mdanimtims = mdtims; } //compare with j*2 instead of j to ensure i stays > j-65536 for MDANIM_ONESHOT if (anim && (i >= j+j) && (fps) && !mdpause) //Keep mdanimtims close to mdtims to avoid the use of MOD - sprext->mdanimtims += j/((fps*timerticspersec)/120); + sprext->mdanimtims += j/((fps*timerGetRate())/120); k = i; diff --git a/source/build/src/osd.cpp b/source/build/src/osd.cpp index c153a531a..fc8a7393b 100644 --- a/source/build/src/osd.cpp +++ b/source/build/src/osd.cpp @@ -320,8 +320,8 @@ static int osdfunc_fileinfo(osdcmdptr_t parm) " CRC-32: %08X (%g sec)\n" " xxHash: %08X (%g sec)\n", parm->parms[0], kfilelength(h), - crcval, (double)crctime/timerGetFreq(), - xxhash, (double)xxhtime/timerGetFreq()); + crcval, (double)crctime/timerGetRate(), + xxhash, (double)xxhtime/timerGetRate()); kclose(h); diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index ead13e21e..ace92afef 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -1169,123 +1169,6 @@ void joyGetDeadZone(int32_t axis, uint16_t *dead, uint16_t *satur) // // -static uint32_t timerfreq; -static uint32_t timerlastsample; -int32_t timerticspersec=0; -static double msperu64tick = 0; -static void(*usertimercallback)(void) = NULL; - - -// -// inittimer() -- initialize timer -// -int32_t timerInit(int32_t tickspersecond) -{ - if (timerfreq) return 0; // already installed - -// initprintf("Initializing timer\n"); - -#if defined(_WIN32) && SDL_MAJOR_VERSION == 1 - int32_t t = win_inittimer(); - if (t < 0) - return t; -#endif - - timerfreq = 1000; - timerticspersec = tickspersecond; - timerlastsample = SDL_GetTicks() * timerticspersec / timerfreq; - - usertimercallback = NULL; - - msperu64tick = 1000.0 / (double)timerGetFreqU64(); - - return 0; -} - -// -// uninittimer() -- shut down timer -// -void timerUninit(void) -{ - timerfreq=0; -#if defined(_WIN32) && SDL_MAJOR_VERSION==1 - win_timerfreq=0; -#endif - msperu64tick = 0; -} - -// -// sampletimer() -- update totalclock -// -void timerUpdate(void) -{ - if (!timerfreq) return; - - int64_t i = SDL_GetTicks(); - int32_t n = tabledivide64(i * timerticspersec, timerfreq) - timerlastsample; - - if (n <= 0) return; - - totalclock += n; - timerlastsample += n; - - if (usertimercallback) - for (; n > 0; n--) usertimercallback(); -} - -#if defined LUNATIC -// -// getticks() -- returns the sdl ticks count -// -uint32_t timerGetTicks(void) -{ - return (uint32_t)SDL_GetTicks(); -} -#endif - -// high-resolution timers for profiling - -#if SDL_MAJOR_VERSION != 1 -uint64_t timerGetTicksU64(void) -{ - return SDL_GetPerformanceCounter(); -} - -uint64_t timerGetFreqU64(void) -{ - return SDL_GetPerformanceFrequency(); -} -#endif - -// Returns the time since an unspecified starting time in milliseconds. -// (May be not monotonic for certain configurations.) -ATTRIBUTE((flatten)) -double timerGetHiTicks(void) -{ - return (double)timerGetTicksU64() * msperu64tick; -} - -// -// gettimerfreq() -- returns the number of ticks per second the timer is configured to generate -// -int32_t timerGetFreq(void) -{ - return timerticspersec; -} - - -// -// installusertimercallback() -- set up a callback function to be called when the timer is fired -// -void(*timerSetCallback(void(*callback)(void)))(void) -{ - void(*oldtimercallback)(void); - - oldtimercallback = usertimercallback; - usertimercallback = callback; - - return oldtimercallback; -} diff --git a/source/build/src/sdlayer12.cpp b/source/build/src/sdlayer12.cpp index e2db358da..bedc4d0ab 100644 --- a/source/build/src/sdlayer12.cpp +++ b/source/build/src/sdlayer12.cpp @@ -173,52 +173,6 @@ static inline char grabmouse_low(char a) #endif } -// high-resolution timers for profiling -uint64_t timerGetTicksU64(void) -{ -# if defined _WIN32 - return win_getu64ticks(); -# elif defined __APPLE__ - return mach_absolute_time(); -# elif _POSIX_TIMERS>0 && defined _POSIX_MONOTONIC_CLOCK - // This is SDL HG's SDL_GetPerformanceCounter() when clock_gettime() is - // available. - uint64_t ticks; - struct timespec now; - - clock_gettime(CLOCK_MONOTONIC, &now); - ticks = now.tv_sec; - ticks *= 1000000000; - ticks += now.tv_nsec; - return ticks; -# elif defined GEKKO - return ticks_to_nanosecs(gettime()); -# else - // Blar. This pragma is unsupported on earlier GCC versions. - // At least we'll get a warning and a reference to this line... -# pragma message "Using low-resolution (1ms) timer for getu64ticks. Profiling will work badly." - return SDL_GetTicks(); -# endif -} - -uint64_t timerGetFreqU64(void) -{ -# if defined _WIN32 - return win_timerfreq; -# elif defined __APPLE__ - static mach_timebase_info_data_t ti; - if (ti.denom == 0) - (void) mach_timebase_info(&ti); // ti.numer/ti.denom: nsec/(m_a_t() tick) - return (1000000000LL*ti.denom)/ti.numer; -# elif _POSIX_TIMERS>0 && defined _POSIX_MONOTONIC_CLOCK - return 1000000000; -# elif defined GEKKO - return TB_NSPERSEC; -# else - return 1000; -# endif -} - void videoGetModes(void) { int32_t i, maxx = 0, maxy = 0; diff --git a/source/build/src/timer.cpp b/source/build/src/timer.cpp new file mode 100644 index 000000000..67a31f664 --- /dev/null +++ b/source/build/src/timer.cpp @@ -0,0 +1,60 @@ + +#include "timer.h" + +#include "build.h" +#include "compat.h" + +#include + +using namespace std; +using namespace chrono; + +static int32_t timerlastsample; +static int32_t timerticspersec=0; +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; } + +// 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(); } + +int32_t timerInit(int32_t const tickspersecond) +{ + timerticspersec = tickspersecond; + timerlastsample = timerGetTicksU64() * timerticspersec / timerGetFreqU64(); + + usertimercallback = NULL; + + return 0; +} + +void timerUpdate(void) +{ + if (!timerticspersec) return; + + uint64_t n = (timerGetTicksU64() * timerticspersec / timerGetFreqU64()) - timerlastsample; + if (n <= 0) return; + + totalclock += n; + timerlastsample += n; + + if (usertimercallback) + for (; n > 0; n--) usertimercallback(); +} + +void(*timerSetCallback(void(*callback)(void)))(void) +{ + void(*oldtimercallback)(void); + + oldtimercallback = usertimercallback; + usertimercallback = callback; + + return oldtimercallback; +} diff --git a/source/build/src/winbits.cpp b/source/build/src/winbits.cpp index cdc1e24cd..284abafcf 100644 --- a/source/build/src/winbits.cpp +++ b/source/build/src/winbits.cpp @@ -18,8 +18,6 @@ int32_t backgroundidle = 1; -int64_t win_timerfreq = 0; - char silentvideomodeswitch = 0; static char taskswitching = 1; @@ -147,38 +145,6 @@ int32_t win_checkinstance(void) return (WaitForSingleObject(instanceflag,0) == WAIT_TIMEOUT); } -// -// high-resolution timers for profiling -// -#if defined(RENDERTYPEWIN) || SDL_MAJOR_VERSION==1 -int32_t win_inittimer(void) -{ - int64_t t; - - if (win_timerfreq) return 0; // already installed - - // OpenWatcom seems to want us to query the value into a local variable - // instead of the global 'win_timerfreq' or else it gets pissed with an - // access violation - if (!QueryPerformanceFrequency((LARGE_INTEGER *)&t)) - { - ShowErrorBox("Failed fetching timer frequency"); - return -1; - } - win_timerfreq = t; - - return 0; -} - -uint64_t win_getu64ticks(void) -{ - uint64_t i; - if (win_timerfreq == 0) return 0; - QueryPerformanceCounter((LARGE_INTEGER *)&i); - return i; -} -#endif - static void ToggleDesktopComposition(BOOL compEnable) { diff --git a/source/build/src/winlayer.cpp b/source/build/src/winlayer.cpp index a8b262510..d2763ab5a 100644 --- a/source/build/src/winlayer.cpp +++ b/source/build/src/winlayer.cpp @@ -1369,132 +1369,6 @@ static const char *GetDInputError(HRESULT code) -//------------------------------------------------------------------------------------------------- -// TIMER -//================================================================================================= - -static int32_t timerlastsample=0; -int32_t timerticspersec=0; -static double msperu64tick = 0; -static void (*usertimercallback)(void) = NULL; - -// This timer stuff is all Ken's idea. - -// -// installusertimercallback() -- set up a callback function to be called when the timer is fired -// -void (*timerSetCallback(void (*callback)(void)))(void) -{ - void (*oldtimercallback)(void); - - oldtimercallback = usertimercallback; - usertimercallback = callback; - - return oldtimercallback; -} - - -// -// inittimer() -- initialize timer -// -int32_t timerInit(int32_t tickspersecond) -{ - int64_t t; - - if (win_timerfreq) return 0; // already installed - - // initprintf("Initializing timer\n"); - - t = win_inittimer(); - if (t < 0) - return t; - - timerticspersec = tickspersecond; - QueryPerformanceCounter((LARGE_INTEGER *)&t); - timerlastsample = (int32_t)(t*timerticspersec / win_timerfreq); - - usertimercallback = NULL; - - msperu64tick = 1000.0 / (double)timerGetFreqU64(); - - return 0; -} - -// -// uninittimer() -- shut down timer -// -void timerUninit(void) -{ - if (!win_timerfreq) return; - - win_timerfreq=0; - timerticspersec = 0; - - msperu64tick = 0; -} - -// -// sampletimer() -- update totalclock -// -void timerUpdate(void) -{ - int64_t i; - int32_t n; - - if (!win_timerfreq) return; - - QueryPerformanceCounter((LARGE_INTEGER *)&i); - n = (int32_t)((i*timerticspersec / win_timerfreq) - timerlastsample); - - if (n <= 0) return; - - totalclock += n; - timerlastsample += n; - - if (usertimercallback) for (; n>0; n--) usertimercallback(); -} - - -// -// getticks() -- returns the windows ticks count -// -uint32_t timerGetTicks(void) -{ - int64_t i; - if (win_timerfreq == 0) return 0; - QueryPerformanceCounter((LARGE_INTEGER *)&i); - return (uint32_t)(i*longlong(1000)/win_timerfreq); -} - -// high-resolution timers for profiling -uint64_t timerGetTicksU64(void) -{ - return win_getu64ticks(); -} - -uint64_t timerGetFreqU64(void) -{ - return win_timerfreq; -} - -// Returns the time since an unspecified starting time in milliseconds. -ATTRIBUTE((flatten)) -double timerGetHiTicks(void) -{ - return (double)timerGetTicksU64() * msperu64tick; -} - -// -// gettimerfreq() -- returns the number of ticks per second the timer is configured to generate -// -int32_t timerGetFreq(void) -{ - return timerticspersec; -} - - - - //------------------------------------------------------------------------------------------------- // VIDEO //=================================================================================================