diff --git a/libs/util/sys.c b/libs/util/sys.c index ac6c062b1..e9e3633a3 100644 --- a/libs/util/sys.c +++ b/libs/util/sys.c @@ -289,6 +289,7 @@ Sys_DoubleTime (void) { static qboolean first = true; #ifdef _WIN32 +# if 0 static DWORD starttime; DWORD now; @@ -307,6 +308,51 @@ Sys_DoubleTime (void) return 0.0; return (now - starttime) / 1000.0; +# else + // MH's solution combining timeGetTime for stability and + // QueryPerformanceCounter for precision. + static __int64 qpcfreq = 0; + static __int64 currqpccount = 0; + static __int64 lastqpccount = 0; + static double qpcfudge = 0; + DWORD currtime = 0; + static DWORD lasttime = 0; + static DWORD starttime = 0; + + if (first) { + timeBeginPeriod (1); + starttime = lasttime = timeGetTime (); + QueryPerformanceFrequency ((LARGE_INTEGER *) &qpcfreq); + QueryPerformanceCounter ((LARGE_INTEGER *) &lastqpccount); + first = false; + return 0; + } + + // get the current time from both counters + currtime = timeGetTime (); + QueryPerformanceCounter ((LARGE_INTEGER *) &currqpccount); + + if (currtime != lasttime) { + // requery the frequency in case it changes (which it can on multicore + // machines) + QueryPerformanceFrequency ((LARGE_INTEGER *) &qpcfreq); + + // store back times and calc a fudge factor as timeGetTime can + // overshoot on a sub-millisecond scale + qpcfudge = (((double) (currqpccount - lastqpccount) + / (double) qpcfreq)) + - ((double) (currtime - lasttime) * 0.001); + lastqpccount = currqpccount; + lasttime = currtime; + } else { + qpcfudge = 0; + } + + // the final time is the base from timeGetTime plus an addition from QPC + return ((double) (currtime - starttime) * 0.001) + + ((double) (currqpccount - lastqpccount) / (double) qpcfreq) + + qpcfudge; +# endif #else struct timeval tp; struct timezone tzp;