Mercurial > sdl-ios-xcode
annotate src/timer/win32/SDL_systimer.c @ 1180:bdcb8bb4c831
From: Tyler Montbriand <tsm@accesscomm.ca>
To: sdl@libsdl.org
Date: Fri, 30 Sep 2005 02:24:50 -0600
Subject: [SDL] WinCE timers, continued
Here's a strange timer for Windows CE that doesn't ignore time across
suspends. It uses GetSystemTime to keep the time continuous, and GetTicks to
get finer-grained readings than 1 second. It detects the difference between
the GetTicks time and GetSystemTime time on power-on to keep the error within
one second max.
It's not a patch on the current win32 timer code -- took one look at that and
figured it had more than enough #ifdefs already. It's windows-ce specific.
Another thing I've noticed is that the Windows CE 4.0 and newer API has
functions warn processes about suspends. This is something SDL REALLY needs
for audio in particular, because turning it off while it's playing causes
anything that uses audio to hardlock the system on power-on. Unfortunately I
don't have 4.0 to play with. :(
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Tue, 22 Nov 2005 07:10:07 +0000 |
parents | b8d311d90021 |
children | c9b51268668f |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
517
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 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 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
89
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 #include <windows.h> | |
29 #include <mmsystem.h> | |
30 | |
31 #include "SDL_timer.h" | |
32 #include "SDL_timer_c.h" | |
33 #include "SDL_error.h" | |
34 | |
35 #ifdef _WIN32_WCE | |
1180
bdcb8bb4c831
From: Tyler Montbriand <tsm@accesscomm.ca>
Ryan C. Gordon <icculus@icculus.org>
parents:
769
diff
changeset
|
36 #error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead. |
bdcb8bb4c831
From: Tyler Montbriand <tsm@accesscomm.ca>
Ryan C. Gordon <icculus@icculus.org>
parents:
769
diff
changeset
|
37 |
bdcb8bb4c831
From: Tyler Montbriand <tsm@accesscomm.ca>
Ryan C. Gordon <icculus@icculus.org>
parents:
769
diff
changeset
|
38 /* but if you really want to use this file, use these #defines... */ |
bdcb8bb4c831
From: Tyler Montbriand <tsm@accesscomm.ca>
Ryan C. Gordon <icculus@icculus.org>
parents:
769
diff
changeset
|
39 #define USE_GETTICKCOUNT |
bdcb8bb4c831
From: Tyler Montbriand <tsm@accesscomm.ca>
Ryan C. Gordon <icculus@icculus.org>
parents:
769
diff
changeset
|
40 #define USE_SETTIMER |
0 | 41 #endif |
42 | |
43 #define TIME_WRAP_VALUE (~(DWORD)0) | |
44 | |
89
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
45 /* The first (low-resolution) ticks value of the application */ |
0 | 46 static DWORD start; |
47 | |
89
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
48 #ifndef USE_GETTICKCOUNT |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
49 /* Store if a high-resolution performance counter exists on the system */ |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
50 static BOOL hires_timer_available; |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
51 /* The first high-resolution ticks value of the application */ |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
52 static LARGE_INTEGER hires_start_ticks; |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
53 /* The number of ticks per second of the high-resolution performance counter */ |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
54 static LARGE_INTEGER hires_ticks_per_second; |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
55 #endif |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
56 |
0 | 57 void SDL_StartTicks(void) |
58 { | |
59 /* Set first ticks value */ | |
60 #ifdef USE_GETTICKCOUNT | |
61 start = GetTickCount(); | |
62 #else | |
326
72d55d02cb47
Disabled QueryPerformanceCounter(), due to problems on Win2K
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
63 #if 0 /* Apparently there are problems with QPC on Win2K */ |
89
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
64 if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
65 { |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
66 hires_timer_available = TRUE; |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
67 QueryPerformanceCounter(&hires_start_ticks); |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
68 } |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
69 else |
326
72d55d02cb47
Disabled QueryPerformanceCounter(), due to problems on Win2K
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
70 #endif |
89
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
71 { |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
72 hires_timer_available = FALSE; |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
73 timeBeginPeriod(1); /* use 1 ms timer precision */ |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
74 start = timeGetTime(); |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
75 } |
0 | 76 #endif |
77 } | |
78 | |
79 Uint32 SDL_GetTicks(void) | |
80 { | |
81 DWORD now, ticks; | |
89
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
82 #ifndef USE_GETTICKCOUNT |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
83 LARGE_INTEGER hires_now; |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
84 #endif |
0 | 85 |
86 #ifdef USE_GETTICKCOUNT | |
87 now = GetTickCount(); | |
88 #else | |
89
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
89 if (hires_timer_available) |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
90 { |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
91 QueryPerformanceCounter(&hires_now); |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
92 |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
93 hires_now.QuadPart -= hires_start_ticks.QuadPart; |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
94 hires_now.QuadPart *= 1000; |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
95 hires_now.QuadPart /= hires_ticks_per_second.QuadPart; |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
96 |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
97 return (DWORD)hires_now.QuadPart; |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
98 } |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
99 else |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
100 { |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
101 now = timeGetTime(); |
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
102 } |
0 | 103 #endif |
89
69b8fac3e1c0
Added Holger Schemel's fix for SDL_GetTicks() on W2K
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
104 |
0 | 105 if ( now < start ) { |
106 ticks = (TIME_WRAP_VALUE-start) + now; | |
107 } else { | |
108 ticks = (now - start); | |
109 } | |
110 return(ticks); | |
111 } | |
112 | |
113 void SDL_Delay(Uint32 ms) | |
114 { | |
115 Sleep(ms); | |
116 } | |
117 | |
118 #ifdef USE_SETTIMER | |
119 | |
120 static UINT WIN_timer; | |
121 | |
122 int SDL_SYS_TimerInit(void) | |
123 { | |
124 return(0); | |
125 } | |
126 | |
127 void SDL_SYS_TimerQuit(void) | |
128 { | |
129 return; | |
130 } | |
131 | |
132 /* Forward declaration because this is called by the timer callback */ | |
133 int SDL_SYS_StartTimer(void); | |
134 | |
135 static VOID CALLBACK TimerCallbackProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) | |
136 { | |
137 Uint32 ms; | |
138 | |
139 ms = SDL_alarm_callback(SDL_alarm_interval); | |
140 if ( ms != SDL_alarm_interval ) { | |
141 KillTimer(NULL, idEvent); | |
142 if ( ms ) { | |
143 SDL_alarm_interval = ROUND_RESOLUTION(ms); | |
144 SDL_SYS_StartTimer(); | |
145 } else { | |
146 SDL_alarm_interval = 0; | |
147 } | |
148 } | |
149 } | |
150 | |
151 int SDL_SYS_StartTimer(void) | |
152 { | |
153 int retval; | |
154 | |
155 WIN_timer = SetTimer(NULL, 0, SDL_alarm_interval, TimerCallbackProc); | |
156 if ( WIN_timer ) { | |
157 retval = 0; | |
158 } else { | |
159 retval = -1; | |
160 } | |
161 return retval; | |
162 } | |
163 | |
164 void SDL_SYS_StopTimer(void) | |
165 { | |
166 if ( WIN_timer ) { | |
167 KillTimer(NULL, WIN_timer); | |
168 WIN_timer = 0; | |
169 } | |
170 } | |
171 | |
172 #else /* !USE_SETTIMER */ | |
173 | |
174 /* Data to handle a single periodic alarm */ | |
175 static UINT timerID = 0; | |
176 | |
177 static void CALLBACK HandleAlarm(UINT uID, UINT uMsg, DWORD dwUser, | |
178 DWORD dw1, DWORD dw2) | |
179 { | |
180 SDL_ThreadedTimerCheck(); | |
181 } | |
182 | |
183 | |
184 int SDL_SYS_TimerInit(void) | |
185 { | |
186 MMRESULT result; | |
187 | |
188 /* Set timer resolution */ | |
189 result = timeBeginPeriod(TIMER_RESOLUTION); | |
190 if ( result != TIMERR_NOERROR ) { | |
191 SDL_SetError("Warning: Can't set %d ms timer resolution", | |
192 TIMER_RESOLUTION); | |
193 } | |
194 /* Allow 10 ms of drift so we don't chew on CPU */ | |
195 timerID = timeSetEvent(TIMER_RESOLUTION,1,HandleAlarm,0,TIME_PERIODIC); | |
196 if ( ! timerID ) { | |
197 SDL_SetError("timeSetEvent() failed"); | |
198 return(-1); | |
199 } | |
200 return(SDL_SetTimerThreaded(1)); | |
201 } | |
202 | |
203 void SDL_SYS_TimerQuit(void) | |
204 { | |
205 if ( timerID ) { | |
206 timeKillEvent(timerID); | |
207 } | |
208 timeEndPeriod(TIMER_RESOLUTION); | |
209 } | |
210 | |
211 int SDL_SYS_StartTimer(void) | |
212 { | |
213 SDL_SetError("Internal logic error: Win32 uses threaded timer"); | |
214 return(-1); | |
215 } | |
216 | |
217 void SDL_SYS_StopTimer(void) | |
218 { | |
219 return; | |
220 } | |
221 | |
222 #endif /* USE_SETTIMER */ |