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 {