• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2006 Sam Lantinga
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14 
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23 
24 #ifdef SDL_TIMER_WIN32
25 
26 #define WIN32_LEAN_AND_MEAN
27 #include <windows.h>
28 #include <mmsystem.h>
29 
30 #include "SDL_timer.h"
31 #include "../SDL_timer_c.h"
32 
33 #ifdef _WIN32_WCE
34   #error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead.
35 #endif
36 
37 #define TIME_WRAP_VALUE	(~(DWORD)0)
38 
39 /* The first (low-resolution) ticks value of the application */
40 static DWORD start;
41 
42 #ifndef USE_GETTICKCOUNT
43 /* Store if a high-resolution performance counter exists on the system */
44 static BOOL hires_timer_available;
45 /* The first high-resolution ticks value of the application */
46 static LARGE_INTEGER hires_start_ticks;
47 /* The number of ticks per second of the high-resolution performance counter */
48 static LARGE_INTEGER hires_ticks_per_second;
49 #endif
50 
SDL_StartTicks(void)51 void SDL_StartTicks(void)
52 {
53 	/* Set first ticks value */
54 #ifdef USE_GETTICKCOUNT
55 	start = GetTickCount();
56 #else
57 #if 0 /* Apparently there are problems with QPC on Win2K */
58 	if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE)
59 	{
60 		hires_timer_available = TRUE;
61 		QueryPerformanceCounter(&hires_start_ticks);
62 	}
63 	else
64 #endif
65 	{
66 		hires_timer_available = FALSE;
67 		timeBeginPeriod(1);		/* use 1 ms timer precision */
68 		start = timeGetTime();
69 	}
70 #endif
71 }
72 
SDL_GetTicks(void)73 Uint32 SDL_GetTicks(void)
74 {
75 	DWORD now, ticks;
76 #ifndef USE_GETTICKCOUNT
77 	LARGE_INTEGER hires_now;
78 #endif
79 
80 #ifdef USE_GETTICKCOUNT
81 	now = GetTickCount();
82 #else
83 	if (hires_timer_available)
84 	{
85 		QueryPerformanceCounter(&hires_now);
86 
87 		hires_now.QuadPart -= hires_start_ticks.QuadPart;
88 		hires_now.QuadPart *= 1000;
89 		hires_now.QuadPart /= hires_ticks_per_second.QuadPart;
90 
91 		return (DWORD)hires_now.QuadPart;
92 	}
93 	else
94 	{
95 		now = timeGetTime();
96 	}
97 #endif
98 
99 	if ( now < start ) {
100 		ticks = (TIME_WRAP_VALUE-start) + now;
101 	} else {
102 		ticks = (now - start);
103 	}
104 	return(ticks);
105 }
106 
SDL_Delay(Uint32 ms)107 void SDL_Delay(Uint32 ms)
108 {
109 	Sleep(ms);
110 }
111 
112 /* Data to handle a single periodic alarm */
113 static UINT timerID = 0;
114 
HandleAlarm(UINT uID,UINT uMsg,DWORD_PTR dwUser,DWORD_PTR dw1,DWORD_PTR dw2)115 static void CALLBACK HandleAlarm(UINT uID,  UINT uMsg, DWORD_PTR dwUser,
116 						DWORD_PTR dw1, DWORD_PTR dw2)
117 {
118 	SDL_ThreadedTimerCheck();
119 }
120 
121 
SDL_SYS_TimerInit(void)122 int SDL_SYS_TimerInit(void)
123 {
124 	MMRESULT result;
125 
126 	/* Set timer resolution */
127 	result = timeBeginPeriod(TIMER_RESOLUTION);
128 	if ( result != TIMERR_NOERROR ) {
129 		SDL_SetError("Warning: Can't set %d ms timer resolution",
130 							TIMER_RESOLUTION);
131 	}
132 	/* Allow 10 ms of drift so we don't chew on CPU */
133 	timerID = timeSetEvent(TIMER_RESOLUTION,1,HandleAlarm,0,TIME_PERIODIC);
134 	if ( ! timerID ) {
135 		SDL_SetError("timeSetEvent() failed");
136 		return(-1);
137 	}
138 	return(SDL_SetTimerThreaded(1));
139 }
140 
SDL_SYS_TimerQuit(void)141 void SDL_SYS_TimerQuit(void)
142 {
143 	if ( timerID ) {
144 		timeKillEvent(timerID);
145 	}
146 	timeEndPeriod(TIMER_RESOLUTION);
147 }
148 
SDL_SYS_StartTimer(void)149 int SDL_SYS_StartTimer(void)
150 {
151 	SDL_SetError("Internal logic error: Win32 uses threaded timer");
152 	return(-1);
153 }
154 
SDL_SYS_StopTimer(void)155 void SDL_SYS_StopTimer(void)
156 {
157 	return;
158 }
159 
160 #endif /* SDL_TIMER_WIN32 */
161