Mercurial > sdl-ios-xcode
comparison src/timer/amigaos/SDL_systimer.c @ 21:75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Thu, 10 May 2001 20:13:29 +0000 |
parents | 74212992fb08 |
children | e8157fcb3114 |
comparison
equal
deleted
inserted
replaced
20:3dc008dc229d | 21:75a95f82bc1f |
---|---|
24 static char rcsid = | 24 static char rcsid = |
25 "@(#) $Id$"; | 25 "@(#) $Id$"; |
26 #endif | 26 #endif |
27 | 27 |
28 #include <stdio.h> | 28 #include <stdio.h> |
29 #include <sys/time.h> | 29 #include <time.h> |
30 #include <signal.h> | 30 #include <signal.h> |
31 #include <unistd.h> | 31 #include <unistd.h> |
32 #include <string.h> | 32 #include <string.h> |
33 #include <errno.h> | 33 #include <errno.h> |
34 #include <exec/types.h> | |
35 #ifdef __SASC | |
36 #include <proto/dos.h> | |
37 #include <clib/graphics_protos.h> | |
38 #include <pragmas/graphics.h> | |
39 #include <clib/exec_protos.h> | |
40 #include <pragmas/exec.h> | |
41 #else | |
42 #include <inline/dos.h> | |
43 #include <inline/exec.h> | |
44 #include <inline/graphics.h> | |
45 #endif | |
46 #include "mydebug.h" | |
47 | |
48 extern struct DosLibrary *DOSBase; | |
49 extern struct ExecBase *SysBase; | |
50 static struct GfxBase *GfxBase; | |
34 | 51 |
35 #include "SDL_error.h" | 52 #include "SDL_error.h" |
36 #include "SDL_timer.h" | 53 #include "SDL_timer.h" |
37 #include "SDL_timer_c.h" | 54 #include "SDL_timer_c.h" |
38 | 55 |
56 #if defined(DISABLE_THREADS) || defined(FORK_HACK) | |
57 #define USE_ITIMER | |
58 #endif | |
59 | |
39 /* The first ticks value of the application */ | 60 /* The first ticks value of the application */ |
40 static struct timeval start; | 61 |
62 #ifndef __PPC__ | |
63 static clock_t start; | |
41 | 64 |
42 void SDL_StartTicks(void) | 65 void SDL_StartTicks(void) |
43 { | 66 { |
44 /* Set first ticks value */ | 67 /* Set first ticks value */ |
45 gettimeofday(&start, NULL); | 68 start=clock(); |
46 } | 69 } |
47 | 70 |
48 Uint32 SDL_GetTicks (void) | 71 Uint32 SDL_GetTicks (void) |
49 { | 72 { |
50 struct timeval now; | 73 clock_t ticks; |
51 Uint32 ticks; | 74 |
52 | 75 ticks=clock()-start; |
53 gettimeofday(&now, NULL); | 76 |
54 ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; | 77 #ifdef __SASC |
78 // CLOCKS_PER_SEC == 1000 ! | |
79 | |
55 return(ticks); | 80 return(ticks); |
81 #else | |
82 // CLOCKS_PER_SEC != 1000 ! | |
83 | |
84 return ticks*(1000/CLOCKS_PER_SEC); | |
85 #endif | |
56 } | 86 } |
57 | 87 |
58 void SDL_Delay (Uint32 ms) | 88 void SDL_Delay (Uint32 ms) |
59 { | 89 { |
60 int was_error; | 90 // Do a busy wait if time is less than 50ms |
61 #ifndef linux /* Non-Linux implementations need to calculate time left */ | 91 |
62 Uint32 then, now, elapsed; | 92 if(ms<50) |
63 #endif | 93 { |
64 struct timeval tv; | 94 clock_t to_wait=clock(); |
65 | 95 |
66 /* Set the timeout interval - Linux only needs to do this once */ | 96 #ifndef __SASC |
67 #ifdef linux | 97 ms*=(CLOCKS_PER_SEC/1000); |
68 tv.tv_sec = ms/1000; | 98 #endif |
69 tv.tv_usec = (ms%1000)*1000; | 99 to_wait+=ms; |
100 | |
101 while(clock()<to_wait); | |
102 } | |
103 else | |
104 { | |
105 Delay(ms/20); | |
106 } | |
107 } | |
108 | |
70 #else | 109 #else |
71 then = SDL_GetTicks(); | 110 |
72 #endif | 111 ULONG MY_CLOCKS_PER_SEC; |
73 do { | 112 |
74 errno = 0; | 113 void PPC_TimerInit(void); |
75 #ifndef linux | 114 APTR MyTimer; |
76 /* Calculate the time interval left (in case of interrupt) */ | 115 |
77 now = SDL_GetTicks(); | 116 ULONG start[2]; |
78 elapsed = (now-then); | 117 |
79 then = now; | 118 void SDL_StartTicks(void) |
80 if ( elapsed >= ms ) { | 119 { |
81 break; | 120 /* Set first ticks value */ |
121 if(!MyTimer) | |
122 PPC_TimerInit(); | |
123 | |
124 PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,start); | |
125 start[1]>>=10; | |
126 start[1]|=((result[0]&0x3ff)<<22); | |
127 start[0]>>=10; | |
128 } | |
129 | |
130 Uint32 SDL_GetTicks (void) | |
131 { | |
132 ULONG result[2]; | |
133 PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result); | |
134 | |
135 // PPCAsr64p(result,10); | |
136 // Non va, la emulo: | |
137 | |
138 result[1]>>=10; | |
139 result[1]|=((result[0]&0x3ff)<<22); | |
140 | |
141 // Non mi interessa piu' result[0] | |
142 | |
143 return result[1]*1000/MY_CLOCKS_PER_SEC; | |
144 } | |
145 | |
146 void SDL_Delay (Uint32 ms) | |
147 { | |
148 // Do a busy wait if time is less than 50ms | |
149 | |
150 if(ms<50) | |
151 { | |
152 ULONG to_wait[2],actual[2]; | |
153 PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result); | |
154 actual[1]=0; | |
155 to_wait[1]+=ms*1000/MY_CLOCKS_PER_SEC; | |
156 | |
157 while(actual[1]<to_wait[1]) | |
158 { | |
159 PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,actual); | |
82 } | 160 } |
83 ms -= elapsed; | 161 } |
84 tv.tv_sec = ms/1000; | 162 else |
85 tv.tv_usec = (ms%1000)*1000; | 163 { |
86 #endif | 164 Delay(ms/50); |
87 was_error = select(0, NULL, NULL, NULL, &tv); | 165 } |
88 } while ( was_error && (errno == EINTR) ); | 166 } |
89 } | 167 |
168 void PPC_TimerInit(void) | |
169 { | |
170 struct TagItem tags[]= | |
171 { | |
172 PPCTIMERTAG_CPU,TRUE, | |
173 TAG_DONE,0 | |
174 }; | |
175 | |
176 | |
177 if(MyTimer=PPCCreateTimerObject(tags)) | |
178 { | |
179 ULONG result[2]; | |
180 | |
181 PPCGetTimerObject(MyTimer,PPCTIMERTAG_TICKSPERSEC,result); | |
182 D(bug("Timer inizializzato, TPS: %lu - %lu\n",result[0],result[1])); | |
183 // PPCAsr64p(result,10); | |
184 result[1]>>=10; | |
185 result[1]|=((result[0]&0x3ff)<<22); | |
186 result[0]>>=10; | |
187 | |
188 D(bug("Shiftato TPS: %lu - %lu\n",result[0],result[1])); | |
189 MY_CLOCKS_PER_SEC=result[1]; | |
190 | |
191 PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result); | |
192 | |
193 D(bug("Current ticks: %lu - %lu\n",result[0],result[1])); | |
194 result[1]>>=10; | |
195 result[1]|=((result[0]&0x3ff)<<22); | |
196 result[0]>>=10; | |
197 // PPCAsr64p(result,10); | |
198 D(bug("Shiftato: %lu - %lu\n",result[0],result[1])); | |
199 } | |
200 else | |
201 { | |
202 D(bug("Errore nell'inizializzazione del timer!\n")); | |
203 } | |
204 } | |
205 | |
206 #endif | |
90 | 207 |
91 #include "SDL_thread.h" | 208 #include "SDL_thread.h" |
92 | 209 |
93 /* Data to handle a single periodic alarm */ | 210 /* Data to handle a single periodic alarm */ |
94 static int timer_alive = 0; | 211 static int timer_alive = 0; |
95 static SDL_Thread *timer = NULL; | 212 static SDL_Thread *timer_thread = NULL; |
96 | 213 |
97 static int RunTimer(void *unused) | 214 static int RunTimer(void *unused) |
98 { | 215 { |
216 D(bug("SYSTimer: Entering RunTimer loop...")); | |
217 | |
218 if(GfxBase==NULL) | |
219 GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37); | |
220 | |
99 while ( timer_alive ) { | 221 while ( timer_alive ) { |
100 if ( SDL_timer_running ) { | 222 if ( SDL_timer_running ) { |
101 SDL_ThreadedTimerCheck(); | 223 SDL_ThreadedTimerCheck(); |
102 } | 224 } |
103 SDL_Delay(1); | 225 if(GfxBase) |
104 } | 226 WaitTOF(); // Check the timer every fifth of seconds. Was SDL_Delay(1)->BusyWait! |
227 else | |
228 Delay(1); | |
229 } | |
230 D(bug("SYSTimer: EXITING RunTimer loop...")); | |
105 return(0); | 231 return(0); |
106 } | 232 } |
107 | 233 |
108 /* This is only called if the event thread is not running */ | 234 /* This is only called if the event thread is not running */ |
109 int SDL_SYS_TimerInit(void) | 235 int SDL_SYS_TimerInit(void) |
110 { | 236 { |
111 #ifdef NO_AMIGADEBUG | 237 D(bug("Creo il thread per il timer (NOITMER)...\n")); |
112 fprintf(stderr,"Creo il thread per il timer (NOITMER)...\n"); | 238 |
113 #endif | |
114 timer_alive = 1; | 239 timer_alive = 1; |
115 timer = SDL_CreateThread(RunTimer, NULL); | 240 timer_thread = SDL_CreateThread(RunTimer, NULL); |
116 if ( timer == NULL ) | 241 if ( timer_thread == NULL ) |
117 { | 242 { |
118 #ifdef NO_AMIGADEBUG | 243 D(bug("Creazione del thread fallita...\n")); |
119 fprintf(stderr,"Creazione del thread fallita...\n"); | |
120 #endif | |
121 | 244 |
122 return(-1); | 245 return(-1); |
123 } | 246 } |
124 return(SDL_SetTimerThreaded(1)); | 247 return(SDL_SetTimerThreaded(1)); |
125 } | 248 } |
126 | 249 |
127 void SDL_SYS_TimerQuit(void) | 250 void SDL_SYS_TimerQuit(void) |
128 { | 251 { |
129 timer_alive = 0; | 252 timer_alive = 0; |
130 if ( timer ) { | 253 if ( timer_thread ) { |
131 SDL_WaitThread(timer, NULL); | 254 SDL_WaitThread(timer_thread, NULL); |
132 timer = NULL; | 255 timer_thread = NULL; |
133 } | 256 } |
134 } | 257 } |
135 | 258 |
136 int SDL_SYS_StartTimer(void) | 259 int SDL_SYS_StartTimer(void) |
137 { | 260 { |
138 SDL_SetError("Internal logic error: Linux uses threaded timer"); | 261 SDL_SetError("Internal logic error: AmigaOS uses threaded timer"); |
139 return(-1); | 262 return(-1); |
140 } | 263 } |
141 | 264 |
142 void SDL_SYS_StopTimer(void) | 265 void SDL_SYS_StopTimer(void) |
143 { | 266 { |