diff options
Diffstat (limited to 'apps/plugins/sdl/src/timer/macos/SDL_MPWtimer.c')
-rw-r--r-- | apps/plugins/sdl/src/timer/macos/SDL_MPWtimer.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/timer/macos/SDL_MPWtimer.c b/apps/plugins/sdl/src/timer/macos/SDL_MPWtimer.c new file mode 100644 index 0000000000..114b6c7c0a --- /dev/null +++ b/apps/plugins/sdl/src/timer/macos/SDL_MPWtimer.c | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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_MACOS | ||
25 | |||
26 | #include <Types.h> | ||
27 | #include <Timer.h> | ||
28 | #include <OSUtils.h> | ||
29 | #include <Gestalt.h> | ||
30 | #include <Processes.h> | ||
31 | |||
32 | #include <LowMem.h> | ||
33 | |||
34 | #include "SDL_timer.h" | ||
35 | #include "../SDL_timer_c.h" | ||
36 | |||
37 | #define MS_PER_TICK (1000/60) /* MacOS tick = 1/60 second */ | ||
38 | |||
39 | /* Note: This is only a step above the original 1/60s implementation. | ||
40 | * For a good implementation, see FastTimes.[ch], by Matt Slot. | ||
41 | */ | ||
42 | #define USE_MICROSECONDS | ||
43 | #define WideTo64bit(w) (*(UInt64 *) &(w)) | ||
44 | |||
45 | UInt64 start; | ||
46 | |||
47 | void SDL_StartTicks(void) | ||
48 | { | ||
49 | #ifdef USE_MICROSECONDS | ||
50 | UnsignedWide now; | ||
51 | |||
52 | Microseconds(&now); | ||
53 | start = WideTo64bit(now); | ||
54 | #else | ||
55 | /* FIXME: Should we implement a wrapping algorithm, like Win32? */ | ||
56 | #endif | ||
57 | } | ||
58 | |||
59 | Uint32 SDL_GetTicks(void) | ||
60 | { | ||
61 | #ifdef USE_MICROSECONDS | ||
62 | UnsignedWide now; | ||
63 | |||
64 | Microseconds(&now); | ||
65 | return (Uint32)((WideTo64bit(now)-start)/1000); | ||
66 | #else | ||
67 | return(LMGetTicks()*MS_PER_TICK); | ||
68 | #endif | ||
69 | } | ||
70 | |||
71 | void SDL_Delay(Uint32 ms) | ||
72 | { | ||
73 | #ifdef USE_MICROSECONDS | ||
74 | Uint32 end_ms; | ||
75 | |||
76 | end_ms = SDL_GetTicks() + ms; | ||
77 | do { | ||
78 | /* FIXME: Yield CPU? */ ; | ||
79 | } while ( SDL_GetTicks() < end_ms ); | ||
80 | #else | ||
81 | UInt32 unused; /* MJS */ | ||
82 | Delay(ms/MS_PER_TICK, &unused); | ||
83 | #endif | ||
84 | } | ||
85 | |||
86 | |||
87 | /* Data to handle a single periodic alarm */ | ||
88 | typedef struct _ExtendedTimerRec | ||
89 | { | ||
90 | TMTask tmTask; | ||
91 | ProcessSerialNumber taskPSN; | ||
92 | } ExtendedTimerRec, *ExtendedTimerPtr; | ||
93 | |||
94 | static ExtendedTimerRec gExtendedTimerRec; | ||
95 | |||
96 | |||
97 | int SDL_SYS_TimerInit(void) | ||
98 | { | ||
99 | /* We don't need a setup? */ | ||
100 | return(0); | ||
101 | } | ||
102 | |||
103 | void SDL_SYS_TimerQuit(void) | ||
104 | { | ||
105 | /* We don't need a cleanup? */ | ||
106 | return; | ||
107 | } | ||
108 | |||
109 | /* Our Stub routine to set up and then call the real routine. */ | ||
110 | pascal void TimerCallbackProc(TMTaskPtr tmTaskPtr) | ||
111 | { | ||
112 | Uint32 ms; | ||
113 | |||
114 | WakeUpProcess(&((ExtendedTimerPtr) tmTaskPtr)->taskPSN); | ||
115 | |||
116 | ms = SDL_alarm_callback(SDL_alarm_interval); | ||
117 | if ( ms ) { | ||
118 | SDL_alarm_interval = ROUND_RESOLUTION(ms); | ||
119 | PrimeTime((QElemPtr)&gExtendedTimerRec.tmTask, | ||
120 | SDL_alarm_interval); | ||
121 | } else { | ||
122 | SDL_alarm_interval = 0; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | int SDL_SYS_StartTimer(void) | ||
127 | { | ||
128 | /* | ||
129 | * Configure the global structure that stores the timing information. | ||
130 | */ | ||
131 | gExtendedTimerRec.tmTask.qLink = NULL; | ||
132 | gExtendedTimerRec.tmTask.qType = 0; | ||
133 | gExtendedTimerRec.tmTask.tmAddr = NewTimerUPP(TimerCallbackProc); | ||
134 | gExtendedTimerRec.tmTask.tmCount = 0; | ||
135 | gExtendedTimerRec.tmTask.tmWakeUp = 0; | ||
136 | gExtendedTimerRec.tmTask.tmReserved = 0; | ||
137 | GetCurrentProcess(&gExtendedTimerRec.taskPSN); | ||
138 | |||
139 | /* Install the task record */ | ||
140 | InsXTime((QElemPtr)&gExtendedTimerRec.tmTask); | ||
141 | |||
142 | /* Go! */ | ||
143 | PrimeTime((QElemPtr)&gExtendedTimerRec.tmTask, SDL_alarm_interval); | ||
144 | return(0); | ||
145 | } | ||
146 | |||
147 | void SDL_SYS_StopTimer(void) | ||
148 | { | ||
149 | RmvTime((QElemPtr)&gExtendedTimerRec.tmTask); | ||
150 | } | ||
151 | |||
152 | #endif /* SDL_TIMER_MACOS */ | ||