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