Hi Sam, hi list,
I solved the problem with SDL_GetTicks() and Windows NT/2000
described in my mail “Strange problems with SDL_GetTicks() &
Windows2000” (Message-ID: <3B3FA21E.45CF9DF0 at mediaways.net>),
completely with a patch against SDL 1.2.1!
The credits must go to Matthijs Hollemans who provided me the
code for the WIN32 functions calling QueryPerformanceFrequency()
and QueryPerformanceCounter(), which replace the timeGetTime()
function used in the current implementation of SDL 1.2.1 that
only provides a precision of 10-15 ms for the current SDL_GetTicks()
function under Windows NT/2000.
Attached is a unified diff “SDL_systimer.c.diff” against the file
SDL-1.2.1/src/timer/win32/SDL_systimer.c.
TODO: Code to handle timer wrap-arounds like for timeGetTime().
(I prefer this case handled by the application, but YMMV.)
With this patch, I get a super-precise 1 ms accuracy of SDL_GetTicks()
on my Windows 2000 installation and the game “Rocks’n’Diamonds”,
where I got an accuracy of 15 ms before, resulting in a badly delayed
scrolling (which is fixed to 50 FPS using SDL_Delay/SDL_GetTicks).
Now it scrolls like a charm!
The references from the MSDN follow. I give up all prejudice
against it – it’s great and provides lots of detailed information.
(Shame on me that I ever have to write this about M$ stuff. )
According to the MSDN information, the code with QueryPerformance*
functions should also work fine for the WindowsCE/PocketPC version
of SDL, which currently uses GetTickCount(). Someone with SDL on
WindowsCE/PocketPC available should definitely check this out!
Here are the MSDN references:-----------------------------
QueryPerformanceCounter (Windows 95/98/ME/NT/2000):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/hh/winui/timers_4z76.asp?frame=true
QueryPerformanceCounter (Windows CE):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceoem/htm/oal_f_62.asp
QueryPerformanceFrequency (Windows 95/98/ME/NT/2000):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/hh/winui/timers_6mk9.asp
QueryPerformanceFrequency (Windows CE):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdkr/htm/_wcesdk_win32_queryperformancefrequency.asp
High-Resolution Timer:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/hh/winui/timers_827m.asp
INFO: Timer Resolution in Windows NT and Windows 2000:
http://support.microsoft.com/support/kb/articles/Q115/2/32.asp
Best regards,
Holger
holger.schemel at mediaways.net
-------------- next part --------------
— SDL_systimer.c.orig Thu Apr 26 18:50:18 2001
+++ SDL_systimer.c Mon Jul 2 22:14:29 2001
@@ -39,28 +39,63 @@
#define TIME_WRAP_VALUE (~(DWORD)0)
-/* The first ticks value of the application /
+/ The first (low-resolution) ticks value of the application */
static DWORD start;
+#ifndef USE_GETTICKCOUNT
+/* Store if a high-resolution performance counter exists on the system /
+static BOOL hires_timer_available;
+/ The first high-resolution ticks value of the application /
+static LARGE_INTEGER hires_start_ticks;
+/ The number of ticks per second of the high-resolution performance counter /
+static LARGE_INTEGER hires_ticks_per_second;
+#endif
+
void SDL_StartTicks(void)
{
/ Set first ticks value */
#ifdef USE_GETTICKCOUNT
start = GetTickCount();
#else
- start = timeGetTime();
- if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE)
- {
-
hires_timer_available = TRUE;
-
QueryPerformanceCounter(&hires_start_ticks);
- }
- else
- {
-
hires_timer_available = FALSE;
-
start = timeGetTime();
- }
#endif
}
Uint32 SDL_GetTicks(void)
{
DWORD now, ticks;
+#ifndef USE_GETTICKCOUNT
- LARGE_INTEGER hires_now;
+#endif
#ifdef USE_GETTICKCOUNT
now = GetTickCount();
#else
- now = timeGetTime();
- if (hires_timer_available)
- {
-
QueryPerformanceCounter(&hires_now);
-
hires_now.QuadPart -= hires_start_ticks.QuadPart;
-
hires_now.QuadPart *= 1000;
-
hires_now.QuadPart /= hires_ticks_per_second.QuadPart;
-
return (DWORD)hires_now.QuadPart;
- }
- else
- {
-
now = timeGetTime();
- }
#endif - if ( now < start ) {
ticks = (TIME_WRAP_VALUE-start) + now;
} else {