diff 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
line wrap: on
line diff
--- a/src/timer/amigaos/SDL_systimer.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/timer/amigaos/SDL_systimer.c	Thu May 10 20:13:29 2001 +0000
@@ -26,98 +26,221 @@
 #endif
 
 #include <stdio.h>
-#include <sys/time.h>
+#include <time.h>
 #include <signal.h>
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
+#include <exec/types.h>
+#ifdef __SASC
+#include <proto/dos.h>
+#include <clib/graphics_protos.h>
+#include <pragmas/graphics.h>
+#include <clib/exec_protos.h>
+#include <pragmas/exec.h>
+#else
+#include <inline/dos.h>
+#include <inline/exec.h>
+#include <inline/graphics.h>
+#endif
+#include "mydebug.h"
+
+extern struct DosLibrary *DOSBase;
+extern struct ExecBase *SysBase;
+static struct GfxBase *GfxBase;
 
 #include "SDL_error.h"
 #include "SDL_timer.h"
 #include "SDL_timer_c.h"
 
+#if defined(DISABLE_THREADS) || defined(FORK_HACK)
+#define USE_ITIMER
+#endif
+
 /* The first ticks value of the application */
-static struct timeval start;
+
+#ifndef __PPC__
+static clock_t start;
 
 void SDL_StartTicks(void)
 {
 	/* Set first ticks value */
-	gettimeofday(&start, NULL);
+	start=clock();
 }
 
 Uint32 SDL_GetTicks (void)
 {
-	struct timeval now;
-	Uint32 ticks;
+	clock_t ticks;
+
+	ticks=clock()-start;
+
+#ifdef __SASC
+// CLOCKS_PER_SEC == 1000 !
 
-	gettimeofday(&now, NULL);
-	ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000;
 	return(ticks);
+#else
+// CLOCKS_PER_SEC != 1000 !
+
+	return ticks*(1000/CLOCKS_PER_SEC);
+#endif
 }
 
 void SDL_Delay (Uint32 ms)
 {
-	int was_error;
-#ifndef linux	/* Non-Linux implementations need to calculate time left */
-	Uint32 then, now, elapsed;
-#endif
-	struct timeval tv;
+// Do a busy wait if time is less than 50ms
 
-	/* Set the timeout interval - Linux only needs to do this once */
-#ifdef linux
-	tv.tv_sec = ms/1000;
-	tv.tv_usec = (ms%1000)*1000;
-#else
-	then = SDL_GetTicks();
+	if(ms<50)
+	{
+		clock_t to_wait=clock();
+
+#ifndef __SASC
+		ms*=(CLOCKS_PER_SEC/1000);
 #endif
-	do {
-		errno = 0;
-#ifndef linux
-		/* Calculate the time interval left (in case of interrupt) */
-		now = SDL_GetTicks();
-		elapsed = (now-then);
-		then = now;
-		if ( elapsed >= ms ) {
-			break;
+		to_wait+=ms;
+
+		while(clock()<to_wait);
+	}
+	else
+	{
+		Delay(ms/20);
+	}
+}
+
+#else
+
+ULONG MY_CLOCKS_PER_SEC;
+
+void PPC_TimerInit(void);
+APTR MyTimer;
+
+ULONG start[2];
+
+void SDL_StartTicks(void)
+{
+	/* Set first ticks value */
+	if(!MyTimer)
+		PPC_TimerInit();
+	
+	PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,start);
+	start[1]>>=10;
+	start[1]|=((result[0]&0x3ff)<<22);
+	start[0]>>=10;
+}
+
+Uint32 SDL_GetTicks (void)
+{
+	ULONG result[2];
+	PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
+
+//	PPCAsr64p(result,10);
+// Non va, la emulo:
+	
+	result[1]>>=10;
+	result[1]|=((result[0]&0x3ff)<<22);
+
+// Non mi interessa piu' result[0]
+
+	return result[1]*1000/MY_CLOCKS_PER_SEC;
+}
+
+void SDL_Delay (Uint32 ms)
+{
+// Do a busy wait if time is less than 50ms
+
+	if(ms<50)
+	{
+		ULONG to_wait[2],actual[2];
+		PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
+		actual[1]=0;
+		to_wait[1]+=ms*1000/MY_CLOCKS_PER_SEC;
+
+		while(actual[1]<to_wait[1])
+		{
+			PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,actual);
 		}
-		ms -= elapsed;
-		tv.tv_sec = ms/1000;
-		tv.tv_usec = (ms%1000)*1000;
+	}
+	else
+	{
+		Delay(ms/50);
+	}
+}
+
+void PPC_TimerInit(void)
+{
+	struct TagItem tags[]=
+		{
+			PPCTIMERTAG_CPU,TRUE,
+			TAG_DONE,0
+		};
+
+
+	if(MyTimer=PPCCreateTimerObject(tags))
+	{
+		ULONG result[2];
+
+		PPCGetTimerObject(MyTimer,PPCTIMERTAG_TICKSPERSEC,result);
+		D(bug("Timer inizializzato, TPS: %lu - %lu\n",result[0],result[1]));
+//		PPCAsr64p(result,10);
+		result[1]>>=10;
+		result[1]|=((result[0]&0x3ff)<<22);
+		result[0]>>=10;
+
+		D(bug("Shiftato TPS: %lu - %lu\n",result[0],result[1]));
+		MY_CLOCKS_PER_SEC=result[1];
+
+		PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
+
+		D(bug("Current ticks: %lu - %lu\n",result[0],result[1]));
+		result[1]>>=10;
+		result[1]|=((result[0]&0x3ff)<<22);
+		result[0]>>=10;
+//		PPCAsr64p(result,10);
+		D(bug("Shiftato: %lu - %lu\n",result[0],result[1]));
+	}
+	else
+	{
+		D(bug("Errore nell'inizializzazione del timer!\n"));
+	}	
+}
+
 #endif
-		was_error = select(0, NULL, NULL, NULL, &tv);
-	} while ( was_error && (errno == EINTR) );
-}
 
 #include "SDL_thread.h"
 
 /* Data to handle a single periodic alarm */
 static int timer_alive = 0;
-static SDL_Thread *timer = NULL;
+static SDL_Thread *timer_thread = NULL;
 
 static int RunTimer(void *unused)
 {
+	D(bug("SYSTimer: Entering RunTimer loop..."));
+
+	if(GfxBase==NULL)
+		GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37);
+
 	while ( timer_alive ) {
 		if ( SDL_timer_running ) {
 			SDL_ThreadedTimerCheck();
 		}
-		SDL_Delay(1);
+		if(GfxBase)
+			WaitTOF();  // Check the timer every fifth of seconds. Was SDL_Delay(1)->BusyWait!
+		else
+			Delay(1);
 	}
+	D(bug("SYSTimer: EXITING RunTimer loop..."));
 	return(0);
 }
 
 /* This is only called if the event thread is not running */
 int SDL_SYS_TimerInit(void)
 {
-#ifdef NO_AMIGADEBUG
-	fprintf(stderr,"Creo il thread per il timer (NOITMER)...\n");
-#endif
+	D(bug("Creo il thread per il timer (NOITMER)...\n"));
+
 	timer_alive = 1;
-	timer = SDL_CreateThread(RunTimer, NULL);
-	if ( timer == NULL )
+	timer_thread = SDL_CreateThread(RunTimer, NULL);
+	if ( timer_thread == NULL )
 	{
-#ifdef NO_AMIGADEBUG
-		fprintf(stderr,"Creazione del thread fallita...\n");
-#endif
+		D(bug("Creazione del thread fallita...\n"));
 
 		return(-1);
 	}
@@ -127,15 +250,15 @@
 void SDL_SYS_TimerQuit(void)
 {
 	timer_alive = 0;
-	if ( timer ) {
-		SDL_WaitThread(timer, NULL);
-		timer = NULL;
+	if ( timer_thread ) {
+		SDL_WaitThread(timer_thread, NULL);
+		timer_thread = NULL;
 	}
 }
 
 int SDL_SYS_StartTimer(void)
 {
-	SDL_SetError("Internal logic error: Linux uses threaded timer");
+	SDL_SetError("Internal logic error: AmigaOS uses threaded timer");
 	return(-1);
 }