/
SDL_systimer.c
194 lines (159 loc) · 4.25 KB
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
11
12
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
14
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
20
21
Sam Lantinga
slouken@libsdl.org
*/
22
#include "SDL_config.h"
23
24
25
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
26
27
#include <mmsystem.h>
28
#include "SDL_thread.h"
29
#include "SDL_timer.h"
30
#include "../SDL_timer_c.h"
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
static Uint64 start_date;
static Uint64 start_ticks;
static Uint64 wce_ticks(void)
{
return((Uint64)GetTickCount());
}
static Uint64 wce_date(void)
{
union
{
FILETIME ftime;
Uint64 itime;
} ftime;
SYSTEMTIME stime;
GetSystemTime(&stime);
SystemTimeToFileTime(&stime,&ftime.ftime);
ftime.itime/=10000; // Convert 100ns intervals to 1ms intervals
// Remove ms portion, which can't be relied on
ftime.itime -= (ftime.itime % 1000);
return(ftime.itime);
}
static Sint32 wce_rel_ticks(void)
{
return((Sint32)(wce_ticks()-start_ticks));
}
static Sint32 wce_rel_date(void)
{
return((Sint32)(wce_date()-start_date));
}
/* Return time in ms relative to when SDL was started */
Uint32 SDL_GetTicks()
{
Sint32 offset=wce_rel_date()-wce_rel_ticks();
if((offset < -1000) || (offset > 1000))
{
// fprintf(stderr,"Time desync(%+d), resyncing\n",offset/1000);
start_ticks-=offset;
}
return((Uint32)wce_rel_ticks());
}
/* Give up approx. givem milliseconds to the OS. */
void SDL_Delay(Uint32 ms)
{
Sleep(ms);
}
/* Recard start-time of application for reference */
void SDL_StartTicks(void)
{
start_date=wce_date();
start_ticks=wce_ticks();
}
static UINT WIN_timer;
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#if ( _WIN32_WCE <= 420 )
static HANDLE timersThread = 0;
static HANDLE timersQuitEvent = 0;
DWORD TimersThreadProc(void *data)
{
while(WaitForSingleObject(timersQuitEvent, 10) == WAIT_TIMEOUT)
{
SDL_ThreadedTimerCheck();
}
return 0;
}
109
110
int SDL_SYS_TimerInit(void)
{
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// create a thread to process a threaded timers
// SetTimer does not suit the needs because
// TimerCallbackProc will be called only when WM_TIMER occured
timersQuitEvent = CreateEvent(0, TRUE, FALSE, 0);
if( !timersQuitEvent )
{
SDL_SetError("Cannot create event for timers thread");
return -1;
}
timersThread = CreateThread(NULL, 0, TimersThreadProc, 0, 0, 0);
if( !timersThread )
{
SDL_SetError("Cannot create timers thread, check amount of RAM available");
return -1;
}
SetThreadPriority(timersThread, THREAD_PRIORITY_HIGHEST);
return(SDL_SetTimerThreaded(1));
130
131
132
133
}
void SDL_SYS_TimerQuit(void)
{
134
135
136
137
138
SetEvent(timersQuitEvent);
if( WaitForSingleObject(timersThread, 2000) == WAIT_TIMEOUT )
TerminateThread(timersThread, 0);
CloseHandle(timersThread);
CloseHandle(timersQuitEvent);
139
140
141
return;
}
142
143
144
145
146
147
#else
#pragma comment(lib, "mmtimer.lib")
/* Data to handle a single periodic alarm */
static UINT timerID = 0;
148
149
150
static void CALLBACK HandleAlarm(UINT uID, UINT uMsg, DWORD dwUser,
DWORD dw1, DWORD dw2)
151
{
152
SDL_ThreadedTimerCheck();
153
154
}
155
156
int SDL_SYS_TimerInit(void)
157
{
158
MMRESULT result;
159
160
161
162
163
164
165
166
167
168
169
170
/* Set timer resolution */
result = timeBeginPeriod(TIMER_RESOLUTION);
if ( result != TIMERR_NOERROR ) {
SDL_SetError("Warning: Can't set %d ms timer resolution",
TIMER_RESOLUTION);
}
/* Allow 10 ms of drift so we don't chew on CPU */
timerID = timeSetEvent(TIMER_RESOLUTION,1,HandleAlarm,0,TIME_PERIODIC);
if ( ! timerID ) {
SDL_SetError("timeSetEvent() failed");
return(-1);
171
}
172
return(SDL_SetTimerThreaded(1));
173
174
}
175
void SDL_SYS_TimerQuit(void)
176
{
177
178
if ( timerID ) {
timeKillEvent(timerID);
179
}
180
timeEndPeriod(TIMER_RESOLUTION);
181
182
}
183
184
185
186
187
188
189
190
191
192
193
194
#endif
int SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: WinCE uses threaded timer");
return(-1);
}
void SDL_SYS_StopTimer(void)
{
return;
}