SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.

This commit is contained in:
Sam Lantinga
2006-07-10 21:04:37 +00:00
parent 8f3655506a
commit 6bc598ea61
686 changed files with 117556 additions and 98661 deletions

View File

@@ -38,3 +38,4 @@ extern int SDL_SYS_StartTimer(void);
/* Stop a previously started timer */
extern void SDL_SYS_StopTimer(void);
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -38,12 +38,13 @@ SDL_TimerCallback SDL_alarm_callback;
/* Data used for a thread-based timer */
static int SDL_timer_threaded = 0;
struct _SDL_TimerID {
Uint32 interval;
SDL_NewTimerCallback cb;
void *param;
Uint32 last_alarm;
struct _SDL_TimerID *next;
struct _SDL_TimerID
{
Uint32 interval;
SDL_NewTimerCallback cb;
void *param;
Uint32 last_alarm;
struct _SDL_TimerID *next;
};
static SDL_TimerID SDL_timers = NULL;
@@ -53,233 +54,247 @@ static volatile SDL_bool list_changed = SDL_FALSE;
/* Set whether or not the timer should use a thread.
This should not be called while the timer subsystem is running.
*/
int SDL_SetTimerThreaded(int value)
int
SDL_SetTimerThreaded(int value)
{
int retval;
int retval;
if ( SDL_timer_started ) {
SDL_SetError("Timer already initialized");
retval = -1;
} else {
retval = 0;
SDL_timer_threaded = value;
}
return retval;
if (SDL_timer_started) {
SDL_SetError("Timer already initialized");
retval = -1;
} else {
retval = 0;
SDL_timer_threaded = value;
}
return retval;
}
int SDL_TimerInit(void)
int
SDL_TimerInit(void)
{
int retval;
int retval;
retval = 0;
if ( SDL_timer_started ) {
SDL_TimerQuit();
}
if ( ! SDL_timer_threaded ) {
retval = SDL_SYS_TimerInit();
}
if ( SDL_timer_threaded ) {
SDL_timer_mutex = SDL_CreateMutex();
}
if ( retval == 0 ) {
SDL_timer_started = 1;
}
return(retval);
retval = 0;
if (SDL_timer_started) {
SDL_TimerQuit();
}
if (!SDL_timer_threaded) {
retval = SDL_SYS_TimerInit();
}
if (SDL_timer_threaded) {
SDL_timer_mutex = SDL_CreateMutex();
}
if (retval == 0) {
SDL_timer_started = 1;
}
return (retval);
}
void SDL_TimerQuit(void)
void
SDL_TimerQuit(void)
{
SDL_SetTimer(0, NULL);
if ( SDL_timer_threaded < 2 ) {
SDL_SYS_TimerQuit();
}
if ( SDL_timer_threaded ) {
SDL_DestroyMutex(SDL_timer_mutex);
SDL_timer_mutex = NULL;
}
SDL_timer_started = 0;
SDL_timer_threaded = 0;
SDL_SetTimer(0, NULL);
if (SDL_timer_threaded < 2) {
SDL_SYS_TimerQuit();
}
if (SDL_timer_threaded) {
SDL_DestroyMutex(SDL_timer_mutex);
SDL_timer_mutex = NULL;
}
SDL_timer_started = 0;
SDL_timer_threaded = 0;
}
void SDL_ThreadedTimerCheck(void)
void
SDL_ThreadedTimerCheck(void)
{
Uint32 now, ms;
SDL_TimerID t, prev, next;
SDL_bool removed;
Uint32 now, ms;
SDL_TimerID t, prev, next;
SDL_bool removed;
SDL_mutexP(SDL_timer_mutex);
list_changed = SDL_FALSE;
now = SDL_GetTicks();
for ( prev = NULL, t = SDL_timers; t; t = next ) {
removed = SDL_FALSE;
ms = t->interval - SDL_TIMESLICE;
next = t->next;
if ( (int)(now - t->last_alarm) > (int)ms ) {
struct _SDL_TimerID timer;
SDL_mutexP(SDL_timer_mutex);
list_changed = SDL_FALSE;
now = SDL_GetTicks();
for (prev = NULL, t = SDL_timers; t; t = next) {
removed = SDL_FALSE;
ms = t->interval - SDL_TIMESLICE;
next = t->next;
if ((int) (now - t->last_alarm) > (int) ms) {
struct _SDL_TimerID timer;
if ( (now - t->last_alarm) < t->interval ) {
t->last_alarm += t->interval;
} else {
t->last_alarm = now;
}
if ((now - t->last_alarm) < t->interval) {
t->last_alarm += t->interval;
} else {
t->last_alarm = now;
}
#ifdef DEBUG_TIMERS
printf("Executing timer %p (thread = %d)\n",
t, SDL_ThreadID());
printf("Executing timer %p (thread = %d)\n", t, SDL_ThreadID());
#endif
timer = *t;
SDL_mutexV(SDL_timer_mutex);
ms = timer.cb(timer.interval, timer.param);
SDL_mutexP(SDL_timer_mutex);
if ( list_changed ) {
/* Abort, list of timers modified */
/* FIXME: what if ms was changed? */
break;
}
if ( ms != t->interval ) {
if ( ms ) {
t->interval = ROUND_RESOLUTION(ms);
} else {
/* Remove timer from the list */
timer = *t;
SDL_mutexV(SDL_timer_mutex);
ms = timer.cb(timer.interval, timer.param);
SDL_mutexP(SDL_timer_mutex);
if (list_changed) {
/* Abort, list of timers modified */
/* FIXME: what if ms was changed? */
break;
}
if (ms != t->interval) {
if (ms) {
t->interval = ROUND_RESOLUTION(ms);
} else {
/* Remove timer from the list */
#ifdef DEBUG_TIMERS
printf("SDL: Removing timer %p\n", t);
printf("SDL: Removing timer %p\n", t);
#endif
if ( prev ) {
prev->next = next;
} else {
SDL_timers = next;
}
SDL_free(t);
--SDL_timer_running;
removed = SDL_TRUE;
}
}
}
/* Don't update prev if the timer has disappeared */
if ( ! removed ) {
prev = t;
}
}
SDL_mutexV(SDL_timer_mutex);
if (prev) {
prev->next = next;
} else {
SDL_timers = next;
}
SDL_free(t);
--SDL_timer_running;
removed = SDL_TRUE;
}
}
}
/* Don't update prev if the timer has disappeared */
if (!removed) {
prev = t;
}
}
SDL_mutexV(SDL_timer_mutex);
}
static SDL_TimerID SDL_AddTimerInternal(Uint32 interval, SDL_NewTimerCallback callback, void *param)
static SDL_TimerID
SDL_AddTimerInternal(Uint32 interval, SDL_NewTimerCallback callback,
void *param)
{
SDL_TimerID t;
t = (SDL_TimerID) SDL_malloc(sizeof(struct _SDL_TimerID));
if ( t ) {
t->interval = ROUND_RESOLUTION(interval);
t->cb = callback;
t->param = param;
t->last_alarm = SDL_GetTicks();
t->next = SDL_timers;
SDL_timers = t;
++SDL_timer_running;
list_changed = SDL_TRUE;
}
SDL_TimerID t;
t = (SDL_TimerID) SDL_malloc(sizeof(struct _SDL_TimerID));
if (t) {
t->interval = ROUND_RESOLUTION(interval);
t->cb = callback;
t->param = param;
t->last_alarm = SDL_GetTicks();
t->next = SDL_timers;
SDL_timers = t;
++SDL_timer_running;
list_changed = SDL_TRUE;
}
#ifdef DEBUG_TIMERS
printf("SDL_AddTimer(%d) = %08x num_timers = %d\n", interval, (Uint32)t, SDL_timer_running);
printf("SDL_AddTimer(%d) = %08x num_timers = %d\n", interval, (Uint32) t,
SDL_timer_running);
#endif
return t;
return t;
}
SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param)
SDL_TimerID
SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param)
{
SDL_TimerID t;
if ( ! SDL_timer_mutex ) {
if ( SDL_timer_started ) {
SDL_SetError("This platform doesn't support multiple timers");
} else {
SDL_SetError("You must call SDL_Init(SDL_INIT_TIMER) first");
}
return NULL;
}
if ( ! SDL_timer_threaded ) {
SDL_SetError("Multiple timers require threaded events!");
return NULL;
}
SDL_mutexP(SDL_timer_mutex);
t = SDL_AddTimerInternal(interval, callback, param);
SDL_mutexV(SDL_timer_mutex);
return t;
SDL_TimerID t;
if (!SDL_timer_mutex) {
if (SDL_timer_started) {
SDL_SetError("This platform doesn't support multiple timers");
} else {
SDL_SetError("You must call SDL_Init(SDL_INIT_TIMER) first");
}
return NULL;
}
if (!SDL_timer_threaded) {
SDL_SetError("Multiple timers require threaded events!");
return NULL;
}
SDL_mutexP(SDL_timer_mutex);
t = SDL_AddTimerInternal(interval, callback, param);
SDL_mutexV(SDL_timer_mutex);
return t;
}
SDL_bool SDL_RemoveTimer(SDL_TimerID id)
SDL_bool
SDL_RemoveTimer(SDL_TimerID id)
{
SDL_TimerID t, prev = NULL;
SDL_bool removed;
SDL_TimerID t, prev = NULL;
SDL_bool removed;
removed = SDL_FALSE;
SDL_mutexP(SDL_timer_mutex);
/* Look for id in the linked list of timers */
for (t = SDL_timers; t; prev=t, t = t->next ) {
if ( t == id ) {
if(prev) {
prev->next = t->next;
} else {
SDL_timers = t->next;
}
SDL_free(t);
--SDL_timer_running;
removed = SDL_TRUE;
list_changed = SDL_TRUE;
break;
}
}
removed = SDL_FALSE;
SDL_mutexP(SDL_timer_mutex);
/* Look for id in the linked list of timers */
for (t = SDL_timers; t; prev = t, t = t->next) {
if (t == id) {
if (prev) {
prev->next = t->next;
} else {
SDL_timers = t->next;
}
SDL_free(t);
--SDL_timer_running;
removed = SDL_TRUE;
list_changed = SDL_TRUE;
break;
}
}
#ifdef DEBUG_TIMERS
printf("SDL_RemoveTimer(%08x) = %d num_timers = %d thread = %d\n", (Uint32)id, removed, SDL_timer_running, SDL_ThreadID());
printf("SDL_RemoveTimer(%08x) = %d num_timers = %d thread = %d\n",
(Uint32) id, removed, SDL_timer_running, SDL_ThreadID());
#endif
SDL_mutexV(SDL_timer_mutex);
return removed;
SDL_mutexV(SDL_timer_mutex);
return removed;
}
/* Old style callback functions are wrapped through this */
static Uint32 SDLCALL callback_wrapper(Uint32 ms, void *param)
static Uint32 SDLCALL
callback_wrapper(Uint32 ms, void *param)
{
SDL_TimerCallback func = (SDL_TimerCallback) param;
return (*func)(ms);
SDL_TimerCallback func = (SDL_TimerCallback) param;
return (*func) (ms);
}
int SDL_SetTimer(Uint32 ms, SDL_TimerCallback callback)
int
SDL_SetTimer(Uint32 ms, SDL_TimerCallback callback)
{
int retval;
int retval;
#ifdef DEBUG_TIMERS
printf("SDL_SetTimer(%d)\n", ms);
printf("SDL_SetTimer(%d)\n", ms);
#endif
retval = 0;
retval = 0;
if ( SDL_timer_threaded ) {
SDL_mutexP(SDL_timer_mutex);
}
if ( SDL_timer_running ) { /* Stop any currently running timer */
if ( SDL_timer_threaded ) {
while ( SDL_timers ) {
SDL_TimerID freeme = SDL_timers;
SDL_timers = SDL_timers->next;
SDL_free(freeme);
}
SDL_timer_running = 0;
list_changed = SDL_TRUE;
} else {
SDL_SYS_StopTimer();
SDL_timer_running = 0;
}
}
if ( ms ) {
if ( SDL_timer_threaded ) {
if ( SDL_AddTimerInternal(ms, callback_wrapper, (void *)callback) == NULL ) {
retval = -1;
}
} else {
SDL_timer_running = 1;
SDL_alarm_interval = ms;
SDL_alarm_callback = callback;
retval = SDL_SYS_StartTimer();
}
}
if ( SDL_timer_threaded ) {
SDL_mutexV(SDL_timer_mutex);
}
if (SDL_timer_threaded) {
SDL_mutexP(SDL_timer_mutex);
}
if (SDL_timer_running) { /* Stop any currently running timer */
if (SDL_timer_threaded) {
while (SDL_timers) {
SDL_TimerID freeme = SDL_timers;
SDL_timers = SDL_timers->next;
SDL_free(freeme);
}
SDL_timer_running = 0;
list_changed = SDL_TRUE;
} else {
SDL_SYS_StopTimer();
SDL_timer_running = 0;
}
}
if (ms) {
if (SDL_timer_threaded) {
if (SDL_AddTimerInternal
(ms, callback_wrapper, (void *) callback) == NULL) {
retval = -1;
}
} else {
SDL_timer_running = 1;
SDL_alarm_interval = ms;
SDL_alarm_callback = callback;
retval = SDL_SYS_StartTimer();
}
}
if (SDL_timer_threaded) {
SDL_mutexV(SDL_timer_mutex);
}
return retval;
return retval;
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -44,3 +44,4 @@ extern void SDL_TimerQuit(void);
/* This function is called from the SDL event thread if it is available */
extern void SDL_ThreadedTimerCheck(void);
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -59,48 +59,48 @@ static struct GfxBase *GfxBase;
#if !defined(__PPC__) || defined(STORMC4_WOS) || defined(MORPHOS)
static clock_t start;
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
/* Set first ticks value */
start=clock();
/* Set first ticks value */
start = clock();
}
Uint32 SDL_GetTicks (void)
Uint32
SDL_GetTicks(void)
{
clock_t ticks;
clock_t ticks;
ticks=clock()-start;
ticks = clock() - start;
#ifdef __SASC
// CLOCKS_PER_SEC == 1000 !
return(ticks);
return (ticks);
#else
// CLOCKS_PER_SEC != 1000 !
return ticks*(1000/CLOCKS_PER_SEC);
return ticks * (1000 / CLOCKS_PER_SEC);
#endif
}
void SDL_Delay (Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
// Do a busy wait if time is less than 50ms
if(ms<50)
{
clock_t to_wait=clock();
if (ms < 50) {
clock_t to_wait = clock();
#ifndef __SASC
ms*=(CLOCKS_PER_SEC/1000);
ms *= (CLOCKS_PER_SEC / 1000);
#endif
to_wait+=ms;
to_wait += ms;
while(clock()<to_wait);
}
else
{
Delay(ms/20);
}
while (clock() < to_wait);
} else {
Delay(ms / 20);
}
}
#else
@@ -112,92 +112,88 @@ APTR MyTimer;
ULONG start[2];
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
/* Set first ticks value */
if(!MyTimer)
PPC_TimerInit();
/* 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;
PPCGetTimerObject(MyTimer, PPCTIMERTAG_CURRENTTICKS, start);
start[1] >>= 10;
start[1] |= ((result[0] & 0x3ff) << 22);
start[0] >>= 10;
}
Uint32 SDL_GetTicks (void)
Uint32
SDL_GetTicks(void)
{
ULONG result[2];
PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
ULONG result[2];
PPCGetTimerObject(MyTimer, PPCTIMERTAG_CURRENTTICKS, result);
// PPCAsr64p(result,10);
// PPCAsr64p(result,10);
// Non va, la emulo:
result[1]>>=10;
result[1]|=((result[0]&0x3ff)<<22);
result[1] >>= 10;
result[1] |= ((result[0] & 0x3ff) << 22);
// Non mi interessa piu' result[0]
return result[1]*1000/MY_CLOCKS_PER_SEC;
return result[1] * 1000 / MY_CLOCKS_PER_SEC;
}
void SDL_Delay (Uint32 ms)
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;
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);
}
}
else
{
Delay(ms/50);
}
while (actual[1] < to_wait[1]) {
PPCGetTimerObject(MyTimer, PPCTIMERTAG_CURRENTTICKS, actual);
}
} else {
Delay(ms / 50);
}
}
void PPC_TimerInit(void)
void
PPC_TimerInit(void)
{
struct TagItem tags[]=
{
PPCTIMERTAG_CPU,TRUE,
TAG_DONE,0
};
struct TagItem tags[] = {
PPCTIMERTAG_CPU, TRUE,
TAG_DONE, 0
};
if(MyTimer=PPCCreateTimerObject(tags))
{
ULONG result[2];
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;
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];
D(bug("Shiftato TPS: %lu - %lu\n", result[0], result[1]));
MY_CLOCKS_PER_SEC = result[1];
PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
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"));
}
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
@@ -208,60 +204,65 @@ void PPC_TimerInit(void)
static int timer_alive = 0;
static SDL_Thread *timer_thread = NULL;
static int RunTimer(void *unused)
static int
RunTimer(void *unused)
{
D(bug("SYSTimer: Entering RunTimer loop..."));
D(bug("SYSTimer: Entering RunTimer loop..."));
if(GfxBase==NULL)
GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37);
if (GfxBase == NULL)
GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 37);
while ( timer_alive ) {
if ( SDL_timer_running ) {
SDL_ThreadedTimerCheck();
}
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);
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
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)
int
SDL_SYS_TimerInit(void)
{
D(bug("Creating thread for the timer (NOITIMER)...\n"));
D(bug("Creating thread for the timer (NOITIMER)...\n"));
timer_alive = 1;
timer_thread = SDL_CreateThread(RunTimer, NULL);
if ( timer_thread == NULL )
{
D(bug("Creazione del thread fallita...\n"));
timer_alive = 1;
timer_thread = SDL_CreateThread(RunTimer, NULL);
if (timer_thread == NULL) {
D(bug("Creazione del thread fallita...\n"));
return(-1);
}
return(SDL_SetTimerThreaded(1));
return (-1);
}
return (SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if ( timer_thread ) {
SDL_WaitThread(timer_thread, NULL);
timer_thread = NULL;
}
timer_alive = 0;
if (timer_thread) {
SDL_WaitThread(timer_thread, NULL);
timer_thread = NULL;
}
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: AmigaOS uses threaded timer");
return(-1);
SDL_SetError("Internal logic error: AmigaOS uses threaded timer");
return (-1);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
return;
return;
}
#endif /* SDL_TIMER_AMIGA */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -31,65 +31,74 @@
static bigtime_t start;
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
/* Set first ticks value */
start = system_time();
/* Set first ticks value */
start = system_time();
}
Uint32 SDL_GetTicks(void)
Uint32
SDL_GetTicks(void)
{
return((system_time()-start)/1000);
return ((system_time() - start) / 1000);
}
void SDL_Delay(Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
snooze(ms*1000);
snooze(ms * 1000);
}
/* Data to handle a single periodic alarm */
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int RunTimer(void *unused)
static int
RunTimer(void *unused)
{
while ( timer_alive ) {
if ( SDL_timer_running ) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(10);
}
return(0);
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(10);
}
return (0);
}
/* This is only called if the event thread is not running */
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if ( timer == NULL )
return(-1);
return(SDL_SetTimerThreaded(1));
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if (timer == NULL)
return (-1);
return (SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if ( timer ) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
timer_alive = 0;
if (timer) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: BeOS uses threaded timer");
return(-1);
SDL_SetError("Internal logic error: BeOS uses threaded timer");
return (-1);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
return;
return;
}
#endif /* SDL_TIMER_BEOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -36,65 +36,74 @@ static unsigned start;
ms = jif * 1000/HZ
*/
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
/* Set first ticks value */
start = jiffies;
/* Set first ticks value */
start = jiffies;
}
Uint32 SDL_GetTicks(void)
Uint32
SDL_GetTicks(void)
{
return((jiffies-start)*1000/HZ);
return ((jiffies - start) * 1000 / HZ);
}
void SDL_Delay(Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
thd_sleep(ms);
thd_sleep(ms);
}
/* Data to handle a single periodic alarm */
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int RunTimer(void *unused)
static int
RunTimer(void *unused)
{
while ( timer_alive ) {
if ( SDL_timer_running ) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(10);
}
return(0);
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(10);
}
return (0);
}
/* This is only called if the event thread is not running */
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if ( timer == NULL )
return(-1);
return(SDL_SetTimerThreaded(1));
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if (timer == NULL)
return (-1);
return (SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if ( timer ) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
timer_alive = 0;
if (timer) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: DC uses threaded timer");
return(-1);
SDL_SetError("Internal logic error: DC uses threaded timer");
return (-1);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
return;
return;
}
#endif /* SDL_TIMER_DC */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -26,19 +26,22 @@
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
}
Uint32 SDL_GetTicks (void)
Uint32
SDL_GetTicks(void)
{
SDL_Unsupported();
return 0;
SDL_Unsupported();
return 0;
}
void SDL_Delay (Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
SDL_Unsupported();
SDL_Unsupported();
}
#include "SDL_thread.h"
@@ -47,45 +50,51 @@ void SDL_Delay (Uint32 ms)
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int RunTimer(void *unused)
static int
RunTimer(void *unused)
{
while ( timer_alive ) {
if ( SDL_timer_running ) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return(0);
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return (0);
}
/* This is only called if the event thread is not running */
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if ( timer == NULL )
return(-1);
return(SDL_SetTimerThreaded(1));
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if (timer == NULL)
return (-1);
return (SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if ( timer ) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
timer_alive = 0;
if (timer) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: threaded timer in use");
return(-1);
SDL_SetError("Internal logic error: threaded timer in use");
return (-1);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
return;
return;
}
#endif /* SDL_TIMER_DUMMY || SDL_TIMERS_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -20,7 +20,7 @@
#include "FastTimes.h"
#ifdef TARGET_CPU_PPC
#undef GENERATINGPOWERPC /* stop whining */
#undef GENERATINGPOWERPC /* stop whining */
#define GENERATINGPOWERPC TARGET_CPU_PPC
#endif
@@ -82,271 +82,267 @@ static asm UnsignedWide PollRTC(void);
static asm UnsignedWide PollTBR(void);
static Ptr FindFunctionInSharedLib(StringPtr libName, StringPtr funcName);
static Boolean gInited = false;
static Boolean gNative = false;
static Boolean gUseRTC = false;
static Boolean gUseTBR = false;
static double gScaleUSec = 1.0 / 1000.0; /* 1 / ( nsec / usec) */
static double gScaleMSec = 1.0 / 1000000.0; /* 1 / ( nsec / msec) */
static Boolean gInited = false;
static Boolean gNative = false;
static Boolean gUseRTC = false;
static Boolean gUseTBR = false;
static double gScaleUSec = 1.0 / 1000.0; /* 1 / ( nsec / usec) */
static double gScaleMSec = 1.0 / 1000000.0; /* 1 / ( nsec / msec) */
/* Functions loaded from DriverServicesLib */
typedef AbsoluteTime (*UpTimeProcPtr)(void);
typedef Nanoseconds (*A2NSProcPtr)(AbsoluteTime);
static UpTimeProcPtr gUpTime = NULL;
static A2NSProcPtr gA2NS = NULL;
typedef AbsoluteTime(*UpTimeProcPtr) (void);
typedef Nanoseconds(*A2NSProcPtr) (AbsoluteTime);
static UpTimeProcPtr gUpTime = NULL;
static A2NSProcPtr gA2NS = NULL;
#endif /* GENERATINGPOWERPC */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
void FastInitialize() {
SInt32 result;
void
FastInitialize()
{
SInt32 result;
if (!gInited) {
if (!gInited) {
#if GENERATINGPOWERPC
/* Initialize the feature flags */
gNative = gUseRTC = gUseTBR = false;
/* Initialize the feature flags */
gNative = gUseRTC = gUseTBR = false;
/* We use CFM to find and load needed symbols from shared libraries, so
the application doesn't have to weak-link them, for convenience. */
gUpTime = (UpTimeProcPtr) FindFunctionInSharedLib(
"\pDriverServicesLib", "\pUpTime");
if (gUpTime) gA2NS = (A2NSProcPtr) FindFunctionInSharedLib(
"\pDriverServicesLib", "\pAbsoluteToNanoseconds");
if (!gA2NS) gUpTime = nil; /* Pedantic but necessary */
/* We use CFM to find and load needed symbols from shared libraries, so
the application doesn't have to weak-link them, for convenience. */
gUpTime =
(UpTimeProcPtr) FindFunctionInSharedLib("\pDriverServicesLib",
"\pUpTime");
if (gUpTime)
gA2NS = (A2NSProcPtr)
FindFunctionInSharedLib("\pDriverServicesLib",
"\pAbsoluteToNanoseconds");
if (!gA2NS)
gUpTime = nil; /* Pedantic but necessary */
if (gUpTime) {
/* If we loaded UpTime(), then we need to know if the system has
a native implementation of the Time Manager. If so, then it's
pointless to calculate a scale factor against the missing VIA */
if (gUpTime) {
/* If we loaded UpTime(), then we need to know if the system has
a native implementation of the Time Manager. If so, then it's
pointless to calculate a scale factor against the missing VIA */
/* gestaltNativeTimeMgr = 4 in some future version of the headers */
if (!Gestalt(gestaltTimeMgrVersion, &result) &&
(result > gestaltExtendedTimeMgr))
gNative = true;
}
else {
/* If no DriverServicesLib, use Gestalt() to get the processor type.
Only NuBus PowerMacs with old System Software won't have DSL, so
we know it should either be a 601 or 603. */
/* gestaltNativeTimeMgr = 4 in some future version of the headers */
if (!Gestalt(gestaltTimeMgrVersion, &result) &&
(result > gestaltExtendedTimeMgr))
gNative = true;
} else {
/* If no DriverServicesLib, use Gestalt() to get the processor type.
Only NuBus PowerMacs with old System Software won't have DSL, so
we know it should either be a 601 or 603. */
/* Use the processor gestalt to determine which register to use */
if (!Gestalt(gestaltNativeCPUtype, &result)) {
if (result == gestaltCPU601) gUseRTC = true;
else if (result > gestaltCPU601) gUseTBR = true;
}
}
/* Use the processor gestalt to determine which register to use */
if (!Gestalt(gestaltNativeCPUtype, &result)) {
if (result == gestaltCPU601)
gUseRTC = true;
else if (result > gestaltCPU601)
gUseTBR = true;
}
}
/* Now calculate a scale factor to keep us accurate. */
if ((gUpTime && !gNative) || gUseRTC || gUseTBR) {
UInt64 tick, usec1, usec2;
UnsignedWide wide;
/* Now calculate a scale factor to keep us accurate. */
if ((gUpTime && !gNative) || gUseRTC || gUseTBR) {
UInt64 tick, usec1, usec2;
UnsignedWide wide;
/* Wait for the beginning of the very next tick */
for(tick = MyLMGetTicks() + 1; tick > MyLMGetTicks(); );
/* Poll the selected timer and prepare it (since we have time) */
wide = (gUpTime) ? (*gA2NS)((*gUpTime)()) :
((gUseRTC) ? PollRTC() : PollTBR());
usec1 = (gUseRTC) ? RTCToNano(wide) : WideTo64bit(wide);
/* Wait for the exact 60th tick to roll over */
while(tick + 60 > MyLMGetTicks());
/* Wait for the beginning of the very next tick */
for (tick = MyLMGetTicks() + 1; tick > MyLMGetTicks(););
/* Poll the selected timer again and prepare it */
wide = (gUpTime) ? (*gA2NS)((*gUpTime)()) :
((gUseRTC) ? PollRTC() : PollTBR());
usec2 = (gUseRTC) ? RTCToNano(wide) : WideTo64bit(wide);
/* Calculate a scale value that will give microseconds per second.
Remember, there are actually 60.15 ticks in a second, not 60. */
gScaleUSec = (60.0 * 1000000.0) / ((usec2 - usec1) * 60.15);
gScaleMSec = gScaleUSec / 1000.0;
}
/* Poll the selected timer and prepare it (since we have time) */
wide = (gUpTime) ? (*gA2NS) ((*gUpTime) ()) :
((gUseRTC) ? PollRTC() : PollTBR());
usec1 = (gUseRTC) ? RTCToNano(wide) : WideTo64bit(wide);
/* Wait for the exact 60th tick to roll over */
while (tick + 60 > MyLMGetTicks());
/* Poll the selected timer again and prepare it */
wide = (gUpTime) ? (*gA2NS) ((*gUpTime) ()) :
((gUseRTC) ? PollRTC() : PollTBR());
usec2 = (gUseRTC) ? RTCToNano(wide) : WideTo64bit(wide);
/* Calculate a scale value that will give microseconds per second.
Remember, there are actually 60.15 ticks in a second, not 60. */
gScaleUSec = (60.0 * 1000000.0) / ((usec2 - usec1) * 60.15);
gScaleMSec = gScaleUSec / 1000.0;
}
#endif /* GENERATINGPOWERPC */
/* We've initialized our globals */
gInited = true;
}
}
/* We've initialized our globals */
gInited = true;
}
}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
UInt64 FastMicroseconds() {
UnsignedWide wide;
UInt64 usec;
#if GENERATINGPOWERPC
/* Initialize globals the first time we are called */
if (!gInited) FastInitialize();
if (gNative) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS)((*gUpTime)());
usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5;
}
else if (gUpTime) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS)((*gUpTime)());
usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5;
}
else if (gUseTBR) {
/* On a recent PowerPC, we poll the TBR directly */
wide = PollTBR();
usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5;
}
else if (gUseRTC) {
/* On a 601, we can poll the RTC instead */
wide = PollRTC();
usec = (double) RTCToNano(wide) * gScaleUSec + 0.5;
}
else
#endif /* GENERATINGPOWERPC */
{
/* If all else fails, suffer the mixed mode overhead */
Microseconds(&wide);
usec = WideTo64bit(wide);
}
return(usec);
}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
UInt64 FastMilliseconds() {
UnsignedWide wide;
UInt64 msec;
#if GENERATINGPOWERPC
/* Initialize globals the first time we are called */
if (!gInited) FastInitialize();
if (gNative) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS)((*gUpTime)());
msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5;
}
else if (gUpTime) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS)((*gUpTime)());
msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5;
}
else if (gUseTBR) {
/* On a recent PowerPC, we poll the TBR directly */
wide = PollTBR();
msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5;
}
else if (gUseRTC) {
/* On a 601, we can poll the RTC instead */
wide = PollRTC();
msec = (double) RTCToNano(wide) * gScaleMSec + 0.5;
}
else
#endif /* GENERATINGPOWERPC */
{
/* If all else fails, suffer the mixed mode overhead */
Microseconds(&wide);
msec = ((double) WideTo64bit(wide) + 500.0) / 1000.0;
}
return(msec);
}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
StringPtr FastMethod() {
StringPtr method = "\p<Unknown>";
UInt64
FastMicroseconds()
{
UnsignedWide wide;
UInt64 usec;
#if GENERATINGPOWERPC
/* Initialize globals the first time we are called */
if (!gInited) FastInitialize();
if (gNative) {
/* The Time Manager and UpTime() are entirely native on this machine */
method = "\pNative UpTime()";
}
else if (gUpTime) {
/* Use DriverServices if it's available -- it's fast and compatible */
method = "\pUpTime()";
}
else if (gUseTBR) {
/* On a recent PowerPC, we poll the TBR directly */
method = "\pPowerPC TBR";
}
else if (gUseRTC) {
/* On a 601, we can poll the RTC instead */
method = "\pPowerPC RTC";
}
else
#endif /* GENERATINGPOWERPC */
{
/* If all else fails, suffer the mixed mode overhead */
method = "\pMicroseconds()";
}
/* Initialize globals the first time we are called */
if (!gInited)
FastInitialize();
return(method);
}
if (gNative) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS) ((*gUpTime) ());
usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5;
} else if (gUpTime) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS) ((*gUpTime) ());
usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5;
} else if (gUseTBR) {
/* On a recent PowerPC, we poll the TBR directly */
wide = PollTBR();
usec = (double) WideTo64bit(wide) * gScaleUSec + 0.5;
} else if (gUseRTC) {
/* On a 601, we can poll the RTC instead */
wide = PollRTC();
usec = (double) RTCToNano(wide) * gScaleUSec + 0.5;
} else
#endif /* GENERATINGPOWERPC */
{
/* If all else fails, suffer the mixed mode overhead */
Microseconds(&wide);
usec = WideTo64bit(wide);
}
return (usec);
}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
UInt64
FastMilliseconds()
{
UnsignedWide wide;
UInt64 msec;
#if GENERATINGPOWERPC
/* Initialize globals the first time we are called */
if (!gInited)
FastInitialize();
if (gNative) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS) ((*gUpTime) ());
msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5;
} else if (gUpTime) {
/* Use DriverServices if it's available -- it's fast and compatible */
wide = (*gA2NS) ((*gUpTime) ());
msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5;
} else if (gUseTBR) {
/* On a recent PowerPC, we poll the TBR directly */
wide = PollTBR();
msec = (double) WideTo64bit(wide) * gScaleMSec + 0.5;
} else if (gUseRTC) {
/* On a 601, we can poll the RTC instead */
wide = PollRTC();
msec = (double) RTCToNano(wide) * gScaleMSec + 0.5;
} else
#endif /* GENERATINGPOWERPC */
{
/* If all else fails, suffer the mixed mode overhead */
Microseconds(&wide);
msec = ((double) WideTo64bit(wide) + 500.0) / 1000.0;
}
return (msec);
}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
StringPtr
FastMethod()
{
StringPtr method = "\p<Unknown>";
#if GENERATINGPOWERPC
/* Initialize globals the first time we are called */
if (!gInited)
FastInitialize();
if (gNative) {
/* The Time Manager and UpTime() are entirely native on this machine */
method = "\pNative UpTime()";
} else if (gUpTime) {
/* Use DriverServices if it's available -- it's fast and compatible */
method = "\pUpTime()";
} else if (gUseTBR) {
/* On a recent PowerPC, we poll the TBR directly */
method = "\pPowerPC TBR";
} else if (gUseRTC) {
/* On a 601, we can poll the RTC instead */
method = "\pPowerPC RTC";
} else
#endif /* GENERATINGPOWERPC */
{
/* If all else fails, suffer the mixed mode overhead */
method = "\pMicroseconds()";
}
return (method);
}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
#pragma mark -
#if GENERATINGPOWERPC
asm static UnsignedWide PollRTC_() {
entry PollRTC /* Avoid CodeWarrior glue */
machine 601
@AGAIN:
mfrtcu r4 /* RTCU = SPR 4 */
mfrtcl r5 /* RTCL = SPR 5 */
mfrtcu r6
cmpw r4,r6
bne @AGAIN
stw r4,0(r3)
stw r5,4(r3)
blr
}
asm static UnsignedWide
PollRTC_()
{
entry PollRTC /* Avoid CodeWarrior glue */
machine 601 @ AGAIN:mfrtcu r4 /* RTCU = SPR 4 */
mfrtcl r5 /* RTCL = SPR 5 */
mfrtcu r6 cmpw r4, r6 bne @ AGAIN stw r4, 0(r3) stw r5, 4(r3) blr}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
asm static UnsignedWide PollTBR_() {
entry PollTBR /* Avoid CodeWarrior glue */
machine 604
@AGAIN:
mftbu r4 /* TBRU = SPR 268 */
mftb r5 /* TBRL = SPR 269 */
mftbu r6
cmpw r4,r6
bne @AGAIN
stw r4,0(r3)
stw r5,4(r3)
blr
}
asm static UnsignedWide
PollTBR_()
{
entry PollTBR /* Avoid CodeWarrior glue */
machine 604 @ AGAIN:mftbu r4 /* TBRU = SPR 268 */
mftb r5 /* TBRL = SPR 269 */
mftbu r6 cmpw r4, r6 bne @ AGAIN stw r4, 0(r3) stw r5, 4(r3) blr}
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
static Ptr FindFunctionInSharedLib(StringPtr libName, StringPtr funcName) {
OSErr error = noErr;
Str255 errorStr;
Ptr func = NULL;
Ptr entry = NULL;
CFragSymbolClass symClass;
CFragConnectionID connID;
/* Find CFM containers for the current archecture -- CFM-PPC or CFM-68K */
if (/* error = */ GetSharedLibrary(libName, kCompiledCFragArch,
kLoadCFrag, &connID, &entry, errorStr)) return(NULL);
if (/* error = */ FindSymbol(connID, funcName, &func, &symClass))
return(NULL);
return(func);
}
static Ptr
FindFunctionInSharedLib(StringPtr libName, StringPtr funcName)
{
OSErr error = noErr;
Str255 errorStr;
Ptr func = NULL;
Ptr entry = NULL;
CFragSymbolClass symClass;
CFragConnectionID connID;
/* Find CFM containers for the current archecture -- CFM-PPC or CFM-68K */
if ( /* error = */ GetSharedLibrary(libName, kCompiledCFragArch,
kLoadCFrag, &connID, &entry,
errorStr))
return (NULL);
if ( /* error = */ FindSymbol(connID, funcName, &func, &symClass))
return (NULL);
return (func);
}
#endif /* GENERATINGPOWERPC */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -16,12 +16,13 @@
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
extern void FastInitialize(void);
extern UInt64 FastMicroseconds(void);
extern UInt64 FastMilliseconds(void);
extern StringPtr FastMethod(void);
extern void FastInitialize(void);
extern UInt64 FastMicroseconds(void);
extern UInt64 FastMilliseconds(void);
extern StringPtr FastMethod(void);
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
/* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
#endif /* __FAST_TIMES_HEADER__ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -34,7 +34,7 @@
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
#define MS_PER_TICK (1000/60) /* MacOS tick = 1/60 second */
#define MS_PER_TICK (1000/60) /* MacOS tick = 1/60 second */
/* Note: This is only a step above the original 1/60s implementation.
* For a good implementation, see FastTimes.[ch], by Matt Slot.
@@ -44,42 +44,46 @@
UInt64 start;
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
#ifdef USE_MICROSECONDS
UnsignedWide now;
Microseconds(&now);
start = WideTo64bit(now);
UnsignedWide now;
Microseconds(&now);
start = WideTo64bit(now);
#else
/* FIXME: Should we implement a wrapping algorithm, like Win32? */
/* FIXME: Should we implement a wrapping algorithm, like Win32? */
#endif
}
Uint32 SDL_GetTicks(void)
Uint32
SDL_GetTicks(void)
{
#ifdef USE_MICROSECONDS
UnsignedWide now;
Microseconds(&now);
return (Uint32)((WideTo64bit(now)-start)/1000);
UnsignedWide now;
Microseconds(&now);
return (Uint32) ((WideTo64bit(now) - start) / 1000);
#else
return(LMGetTicks()*MS_PER_TICK);
return (LMGetTicks() * MS_PER_TICK);
#endif
}
void SDL_Delay(Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
#ifdef USE_MICROSECONDS
Uint32 end_ms;
end_ms = SDL_GetTicks() + ms;
do {
/* FIXME: Yield CPU? */ ;
} while ( SDL_GetTicks() < end_ms );
Uint32 end_ms;
end_ms = SDL_GetTicks() + ms;
do {
/* FIXME: Yield CPU? */ ;
}
while (SDL_GetTicks() < end_ms);
#else
UInt32 unused; /* MJS */
Delay(ms/MS_PER_TICK, &unused);
UInt32 unused; /* MJS */
Delay(ms / MS_PER_TICK, &unused);
#endif
}
@@ -87,66 +91,71 @@ void SDL_Delay(Uint32 ms)
/* Data to handle a single periodic alarm */
typedef struct _ExtendedTimerRec
{
TMTask tmTask;
ProcessSerialNumber taskPSN;
TMTask tmTask;
ProcessSerialNumber taskPSN;
} ExtendedTimerRec, *ExtendedTimerPtr;
static ExtendedTimerRec gExtendedTimerRec;
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
/* We don't need a setup? */
return(0);
/* We don't need a setup? */
return (0);
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
/* We don't need a cleanup? */
return;
/* We don't need a cleanup? */
return;
}
/* Our Stub routine to set up and then call the real routine. */
pascal void TimerCallbackProc(TMTaskPtr tmTaskPtr)
pascal void
TimerCallbackProc(TMTaskPtr tmTaskPtr)
{
Uint32 ms;
Uint32 ms;
WakeUpProcess(&((ExtendedTimerPtr) tmTaskPtr)->taskPSN);
WakeUpProcess(&((ExtendedTimerPtr) tmTaskPtr)->taskPSN);
ms = SDL_alarm_callback(SDL_alarm_interval);
if ( ms ) {
SDL_alarm_interval = ROUND_RESOLUTION(ms);
PrimeTime((QElemPtr)&gExtendedTimerRec.tmTask,
SDL_alarm_interval);
} else {
SDL_alarm_interval = 0;
}
ms = SDL_alarm_callback(SDL_alarm_interval);
if (ms) {
SDL_alarm_interval = ROUND_RESOLUTION(ms);
PrimeTime((QElemPtr) & gExtendedTimerRec.tmTask, SDL_alarm_interval);
} else {
SDL_alarm_interval = 0;
}
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
/*
* Configure the global structure that stores the timing information.
*/
gExtendedTimerRec.tmTask.qLink = NULL;
gExtendedTimerRec.tmTask.qType = 0;
gExtendedTimerRec.tmTask.tmAddr = NewTimerUPP(TimerCallbackProc);
gExtendedTimerRec.tmTask.tmCount = 0;
gExtendedTimerRec.tmTask.tmWakeUp = 0;
gExtendedTimerRec.tmTask.tmReserved = 0;
GetCurrentProcess(&gExtendedTimerRec.taskPSN);
/*
* Configure the global structure that stores the timing information.
*/
gExtendedTimerRec.tmTask.qLink = NULL;
gExtendedTimerRec.tmTask.qType = 0;
gExtendedTimerRec.tmTask.tmAddr = NewTimerUPP(TimerCallbackProc);
gExtendedTimerRec.tmTask.tmCount = 0;
gExtendedTimerRec.tmTask.tmWakeUp = 0;
gExtendedTimerRec.tmTask.tmReserved = 0;
GetCurrentProcess(&gExtendedTimerRec.taskPSN);
/* Install the task record */
InsXTime((QElemPtr)&gExtendedTimerRec.tmTask);
/* Install the task record */
InsXTime((QElemPtr) & gExtendedTimerRec.tmTask);
/* Go! */
PrimeTime((QElemPtr)&gExtendedTimerRec.tmTask, SDL_alarm_interval);
return(0);
/* Go! */
PrimeTime((QElemPtr) & gExtendedTimerRec.tmTask, SDL_alarm_interval);
return (0);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
RmvTime((QElemPtr)&gExtendedTimerRec.tmTask);
RmvTime((QElemPtr) & gExtendedTimerRec.tmTask);
}
#endif /* SDL_TIMER_MACOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -40,46 +40,50 @@
#define NewTimerProc NewTimerUPP
#endif
#define MS_PER_TICK (1000.0/60.0) /* MacOS tick = 1/60 second */
#define MS_PER_TICK (1000.0/60.0) /* MacOS tick = 1/60 second */
#define kTwoPower32 (4294967296.0) /* 2^32 */
#define kTwoPower32 (4294967296.0) /* 2^32 */
static double start_tick;
static int is_fast_inited = 0;
static int is_fast_inited = 0;
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
if ( ! is_fast_inited ) // important to check or FastTime may hang machine!
SDL_SYS_TimerInit();
if (!is_fast_inited) // important to check or FastTime may hang machine!
SDL_SYS_TimerInit();
start_tick = FastMicroseconds();
start_tick = FastMicroseconds();
}
Uint32 SDL_GetTicks(void)
Uint32
SDL_GetTicks(void)
{
if ( ! is_fast_inited )
SDL_SYS_TimerInit();
return FastMilliseconds();
if (!is_fast_inited)
SDL_SYS_TimerInit();
return FastMilliseconds();
}
void SDL_Delay(Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
Uint32 stop, now;
Uint32 stop, now;
stop = SDL_GetTicks() + ms;
do {
#if TARGET_API_MAC_CARBON
MPYield();
#else
SystemTask();
#endif
stop = SDL_GetTicks() + ms;
do {
#if TARGET_API_MAC_CARBON
MPYield();
#else
SystemTask();
#endif
now = SDL_GetTicks();
now = SDL_GetTicks();
} while ( stop > now );
}
while (stop > now);
}
/*
@@ -115,72 +119,77 @@ void SDL_Delay(Uint32 ms)
}
}*/
/* Data to handle a single periodic alarm */
typedef struct _ExtendedTimerRec
{
TMTask tmTask;
ProcessSerialNumber taskPSN;
TMTask tmTask;
ProcessSerialNumber taskPSN;
} ExtendedTimerRec, *ExtendedTimerPtr;
static ExtendedTimerRec gExtendedTimerRec;
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
FastInitialize ();
is_fast_inited = 1;
return(0);
FastInitialize();
is_fast_inited = 1;
return (0);
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
/* We don't need a cleanup? */
return;
/* We don't need a cleanup? */
return;
}
/* Our Stub routine to set up and then call the real routine. */
pascal void TimerCallbackProc(TMTaskPtr tmTaskPtr)
pascal void
TimerCallbackProc(TMTaskPtr tmTaskPtr)
{
Uint32 ms;
Uint32 ms;
WakeUpProcess(&((ExtendedTimerPtr) tmTaskPtr)->taskPSN);
WakeUpProcess(&((ExtendedTimerPtr) tmTaskPtr)->taskPSN);
ms = SDL_alarm_callback(SDL_alarm_interval);
if ( ms ) {
SDL_alarm_interval = ROUND_RESOLUTION(ms);
PrimeTime((QElemPtr)&gExtendedTimerRec.tmTask,
SDL_alarm_interval);
} else {
SDL_alarm_interval = 0;
}
ms = SDL_alarm_callback(SDL_alarm_interval);
if (ms) {
SDL_alarm_interval = ROUND_RESOLUTION(ms);
PrimeTime((QElemPtr) & gExtendedTimerRec.tmTask, SDL_alarm_interval);
} else {
SDL_alarm_interval = 0;
}
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
/*
* Configure the global structure that stores the timing information.
*/
gExtendedTimerRec.tmTask.qLink = NULL;
gExtendedTimerRec.tmTask.qType = 0;
gExtendedTimerRec.tmTask.tmAddr = NewTimerProc(TimerCallbackProc);
gExtendedTimerRec.tmTask.tmCount = 0;
gExtendedTimerRec.tmTask.tmWakeUp = 0;
gExtendedTimerRec.tmTask.tmReserved = 0;
GetCurrentProcess(&gExtendedTimerRec.taskPSN);
/*
* Configure the global structure that stores the timing information.
*/
gExtendedTimerRec.tmTask.qLink = NULL;
gExtendedTimerRec.tmTask.qType = 0;
gExtendedTimerRec.tmTask.tmAddr = NewTimerProc(TimerCallbackProc);
gExtendedTimerRec.tmTask.tmCount = 0;
gExtendedTimerRec.tmTask.tmWakeUp = 0;
gExtendedTimerRec.tmTask.tmReserved = 0;
GetCurrentProcess(&gExtendedTimerRec.taskPSN);
/* Install the task record */
InsXTime((QElemPtr)&gExtendedTimerRec.tmTask);
/* Install the task record */
InsXTime((QElemPtr) & gExtendedTimerRec.tmTask);
/* Go! */
PrimeTime((QElemPtr)&gExtendedTimerRec.tmTask, SDL_alarm_interval);
return(0);
/* Go! */
PrimeTime((QElemPtr) & gExtendedTimerRec.tmTask, SDL_alarm_interval);
return (0);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
RmvTime((QElemPtr)&gExtendedTimerRec.tmTask);
RmvTime((QElemPtr) & gExtendedTimerRec.tmTask);
}
#endif /* SDL_TIMER_MACOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -51,107 +51,116 @@
/* The first ticks value of the application */
static Uint32 start;
static SDL_bool supervisor;
static int mint_present; /* can we use Syield() ? */
static int mint_present; /* can we use Syield() ? */
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
void *oldpile;
unsigned long dummy;
void *oldpile;
unsigned long dummy;
/* Set first ticks value */
oldpile=(void *)Super(0);
start=*((volatile long *)_hz_200);
Super(oldpile);
/* Set first ticks value */
oldpile = (void *) Super(0);
start = *((volatile long *) _hz_200);
Super(oldpile);
start *= 5; /* One _hz_200 tic is 5ms */
start *= 5; /* One _hz_200 tic is 5ms */
mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);
mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);
}
Uint32 SDL_GetTicks (void)
Uint32
SDL_GetTicks(void)
{
Uint32 now;
void *oldpile=NULL;
Uint32 now;
void *oldpile = NULL;
/* Check if we are in supervisor mode
(this is the case when called from SDL_ThreadedTimerCheck,
which is called from RunTimer, running in the vbl vector)
*/
if (!supervisor) {
oldpile=(void *)Super(0);
}
/* Check if we are in supervisor mode
(this is the case when called from SDL_ThreadedTimerCheck,
which is called from RunTimer, running in the vbl vector)
*/
if (!supervisor) {
oldpile = (void *) Super(0);
}
now=*((volatile long *)_hz_200);
now = *((volatile long *) _hz_200);
if (!supervisor) {
Super(oldpile);
}
if (!supervisor) {
Super(oldpile);
}
return((now*5)-start);
return ((now * 5) - start);
}
void SDL_Delay (Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
Uint32 now;
Uint32 now;
now = SDL_GetTicks();
while ((SDL_GetTicks()-now)<ms){
if (mint_present) {
Syield();
}
}
now = SDL_GetTicks();
while ((SDL_GetTicks() - now) < ms) {
if (mint_present) {
Syield();
}
}
}
/* Data to handle a single periodic alarm */
static SDL_bool timer_installed=SDL_FALSE;
static SDL_bool timer_installed = SDL_FALSE;
static void RunTimer(void)
static void
RunTimer(void)
{
supervisor=SDL_TRUE;
SDL_ThreadedTimerCheck();
supervisor=SDL_FALSE;
supervisor = SDL_TRUE;
SDL_ThreadedTimerCheck();
supervisor = SDL_FALSE;
}
/* This is only called if the event thread is not running */
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
void *oldpile;
void *oldpile;
supervisor=SDL_FALSE;
supervisor = SDL_FALSE;
/* Install RunTimer in vbl vector */
oldpile=(void *)Super(0);
timer_installed = !SDL_AtariVblInstall(RunTimer);
Super(oldpile);
/* Install RunTimer in vbl vector */
oldpile = (void *) Super(0);
timer_installed = !SDL_AtariVblInstall(RunTimer);
Super(oldpile);
if (!timer_installed) {
return(-1);
}
return(SDL_SetTimerThreaded(0));
if (!timer_installed) {
return (-1);
}
return (SDL_SetTimerThreaded(0));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
void *oldpile;
void *oldpile;
if (timer_installed) {
/* Uninstall RunTimer vbl vector */
oldpile=(void *)Super(0);
SDL_AtariVblUninstall(RunTimer);
Super(oldpile);
timer_installed = SDL_FALSE;
}
if (timer_installed) {
/* Uninstall RunTimer vbl vector */
oldpile = (void *) Super(0);
SDL_AtariVblUninstall(RunTimer);
Super(oldpile);
timer_installed = SDL_FALSE;
}
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: MiNT uses vbl timer");
return(-1);
SDL_SetError("Internal logic error: MiNT uses vbl timer");
return (-1);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
return;
return;
}
#endif /* SDL_TIMER_MINT */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -31,3 +31,4 @@
/* Functions prototypes */
extern int SDL_AtariVblInstall(void *newvector);
extern void SDL_AtariVblUninstall(void *newvector);
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -44,184 +44,186 @@ static long long hires_start_ticks;
/* The number of ticks per second of the high-resolution performance counter */
static ULONG hires_ticks_per_second;
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
DosTmrQueryFreq(&hires_ticks_per_second);
DosTmrQueryTime((PQWORD)&hires_start_ticks);
DosTmrQueryFreq(&hires_ticks_per_second);
DosTmrQueryTime((PQWORD) & hires_start_ticks);
}
DECLSPEC Uint32 SDLCALL SDL_GetTicks(void)
DECLSPEC Uint32 SDLCALL
SDL_GetTicks(void)
{
long long hires_now;
ULONG ticks = ticks;
long long hires_now;
ULONG ticks = ticks;
DosTmrQueryTime((PQWORD)&hires_now);
DosTmrQueryTime((PQWORD) & hires_now);
/*
hires_now -= hires_start_ticks;
hires_now *= 1000;
hires_now /= hires_ticks_per_second;
*/
/* inline asm to avoid runtime inclusion */
_asm {
push edx
push eax
mov eax, dword ptr hires_now
mov edx, dword ptr hires_now+4
sub eax, dword ptr hires_start_ticks
sbb edx, dword ptr hires_start_ticks+4
mov ebx,1000
mov ecx,edx
mul ebx
push eax
push edx
mov eax,ecx
mul ebx
pop eax
add edx,eax
pop eax
mov ebx, dword ptr hires_ticks_per_second
div ebx
mov dword ptr ticks, eax
pop edx
pop eax
}
/* inline asm to avoid runtime inclusion */
_asm {
push edx
push eax
mov eax, dword ptr hires_now
mov edx, dword ptr hires_now + 4
sub eax, dword ptr hires_start_ticks
sbb edx, dword ptr hires_start_ticks + 4
mov ebx, 1000
mov ecx, edx
mul ebx
push eax
push edx
mov eax, ecx
mul ebx
pop eax
add edx, eax
pop eax
mov ebx, dword ptr hires_ticks_per_second
div ebx mov dword ptr ticks, eax pop edx pop eax}
return ticks;
return ticks;
}
/* High resolution sleep, originally made by Ilya Zakharevich */
DECLSPEC void SDLCALL SDL_Delay(Uint32 ms)
DECLSPEC void SDLCALL
SDL_Delay(Uint32 ms)
{
/* This is similar to DosSleep(), but has 8ms granularity in time-critical
threads even on Warp3. */
HEV hevEvent1 = 0; /* Event semaphore handle */
HTIMER htimerEvent1 = 0; /* Timer handle */
APIRET rc = NO_ERROR; /* Return code */
int ret = 1;
ULONG priority = 0, nesting; /* Shut down the warnings */
PPIB pib;
PTIB tib;
char *e = NULL;
APIRET badrc;
int switch_priority = 50;
/* This is similar to DosSleep(), but has 8ms granularity in time-critical
threads even on Warp3. */
HEV hevEvent1 = 0; /* Event semaphore handle */
HTIMER htimerEvent1 = 0; /* Timer handle */
APIRET rc = NO_ERROR; /* Return code */
int ret = 1;
ULONG priority = 0, nesting; /* Shut down the warnings */
PPIB pib;
PTIB tib;
char *e = NULL;
APIRET badrc;
int switch_priority = 50;
DosCreateEventSem(NULL, /* Unnamed */
&hevEvent1, /* Handle of semaphore returned */
DC_SEM_SHARED, /* Shared needed for DosAsyncTimer */
FALSE); /* Semaphore is in RESET state */
DosCreateEventSem(NULL, /* Unnamed */
&hevEvent1, /* Handle of semaphore returned */
DC_SEM_SHARED, /* Shared needed for DosAsyncTimer */
FALSE); /* Semaphore is in RESET state */
if (ms >= switch_priority)
switch_priority = 0;
if (switch_priority)
{
if (DosGetInfoBlocks(&tib, &pib)!=NO_ERROR)
switch_priority = 0;
else
{
/* In Warp3, to switch scheduling to 8ms step, one needs to do
DosAsyncTimer() in time-critical thread. On laters versions,
more and more cases of wait-for-something are covered.
It turns out that on Warp3fp42 it is the priority at the time
of DosAsyncTimer() which matters. Let's hope that this works
with later versions too... XXXX
*/
priority = (tib->tib_ptib2->tib2_ulpri);
if ((priority & 0xFF00) == 0x0300) /* already time-critical */
if (ms >= switch_priority)
switch_priority = 0;
/* Make us time-critical. Just modifying TIB is not enough... */
/* tib->tib_ptib2->tib2_ulpri = 0x0300;*/
/* We do not want to run at high priority if a signal causes us
to longjmp() out of this section... */
if (DosEnterMustComplete(&nesting))
switch_priority = 0;
else
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
if (switch_priority) {
if (DosGetInfoBlocks(&tib, &pib) != NO_ERROR)
switch_priority = 0;
else {
/* In Warp3, to switch scheduling to 8ms step, one needs to do
DosAsyncTimer() in time-critical thread. On laters versions,
more and more cases of wait-for-something are covered.
It turns out that on Warp3fp42 it is the priority at the time
of DosAsyncTimer() which matters. Let's hope that this works
with later versions too... XXXX
*/
priority = (tib->tib_ptib2->tib2_ulpri);
if ((priority & 0xFF00) == 0x0300) /* already time-critical */
switch_priority = 0;
/* Make us time-critical. Just modifying TIB is not enough... */
/* tib->tib_ptib2->tib2_ulpri = 0x0300; */
/* We do not want to run at high priority if a signal causes us
to longjmp() out of this section... */
if (DosEnterMustComplete(&nesting))
switch_priority = 0;
else
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
}
}
}
if ((badrc = DosAsyncTimer(ms,
(HSEM) hevEvent1, /* Semaphore to post */
&htimerEvent1))) /* Timer handler (returned) */
e = "DosAsyncTimer";
if ((badrc = DosAsyncTimer(ms, (HSEM) hevEvent1, /* Semaphore to post */
&htimerEvent1))) /* Timer handler (returned) */
e = "DosAsyncTimer";
if (switch_priority && tib->tib_ptib2->tib2_ulpri == 0x0300)
{
/* Nobody switched priority while we slept... Ignore errors... */
/* tib->tib_ptib2->tib2_ulpri = priority; */ /* Get back... */
if (!(rc = DosSetPriority(PRTYS_THREAD, (priority>>8) & 0xFF, 0, 0)))
rc = DosSetPriority(PRTYS_THREAD, 0, priority & 0xFF, 0);
}
if (switch_priority)
rc = DosExitMustComplete(&nesting); /* Ignore errors */
if (switch_priority && tib->tib_ptib2->tib2_ulpri == 0x0300) {
/* Nobody switched priority while we slept... Ignore errors... */
/* tib->tib_ptib2->tib2_ulpri = priority; *//* Get back... */
if (!
(rc = DosSetPriority(PRTYS_THREAD, (priority >> 8) & 0xFF, 0, 0)))
rc = DosSetPriority(PRTYS_THREAD, 0, priority & 0xFF, 0);
}
if (switch_priority)
rc = DosExitMustComplete(&nesting); /* Ignore errors */
/* The actual blocking call is made with "normal" priority. This way we
should not bother with DosSleep(0) etc. to compensate for us interrupting
higher-priority threads. The goal is to prohibit the system spending too
much time halt()ing, not to run us "no matter what". */
if (!e) /* Wait for AsyncTimer event */
badrc = DosWaitEventSem(hevEvent1, SEM_INDEFINITE_WAIT);
/* The actual blocking call is made with "normal" priority. This way we
should not bother with DosSleep(0) etc. to compensate for us interrupting
higher-priority threads. The goal is to prohibit the system spending too
much time halt()ing, not to run us "no matter what". */
if (!e) /* Wait for AsyncTimer event */
badrc = DosWaitEventSem(hevEvent1, SEM_INDEFINITE_WAIT);
if (e) ; /* Do nothing */
else if (badrc == ERROR_INTERRUPT)
ret = 0;
else if (badrc)
e = "DosWaitEventSem";
if ((rc = DosCloseEventSem(hevEvent1)) && !e) { /* Get rid of semaphore */
e = "DosCloseEventSem";
badrc = rc;
}
if (e)
{
SDL_SetError("[SDL_Delay] : Had error in %s(), rc is 0x%x\n", e, badrc);
}
if (e); /* Do nothing */
else if (badrc == ERROR_INTERRUPT)
ret = 0;
else if (badrc)
e = "DosWaitEventSem";
if ((rc = DosCloseEventSem(hevEvent1)) && !e) { /* Get rid of semaphore */
e = "DosCloseEventSem";
badrc = rc;
}
if (e) {
SDL_SetError("[SDL_Delay] : Had error in %s(), rc is 0x%x\n", e,
badrc);
}
}
/* Data to handle a single periodic alarm */
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int SDLCALL RunTimer(void *unused)
static int
RunTimer(void *unused)
{
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
while ( timer_alive ) {
if ( SDL_timer_running ) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(10);
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
return(0);
SDL_Delay(10);
}
return (0);
}
/* This is only called if the event thread is not running */
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if ( timer == NULL )
return(-1);
return(SDL_SetTimerThreaded(1));
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if (timer == NULL)
return (-1);
return (SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if ( timer ) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
timer_alive = 0;
if (timer) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: OS/2 uses threaded timer");
return(-1);
SDL_SetError("Internal logic error: OS/2 uses threaded timer");
return (-1);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
return;
return;
}
#endif /* SDL_TIMER_OS2 */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -52,129 +52,139 @@ extern void RISCOS_BackgroundTasks(void);
/* The first ticks value of the application */
clock_t start;
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
/* Set first ticks value */
start = clock();
/* Set first ticks value */
start = clock();
}
Uint32 SDL_GetTicks (void)
Uint32
SDL_GetTicks(void)
{
clock_t ticks;
clock_t ticks;
ticks=clock()-start;
ticks = clock() - start;
#if CLOCKS_PER_SEC == 1000
return(ticks);
return (ticks);
#elif CLOCKS_PER_SEC == 100
return (ticks * 10);
return (ticks * 10);
#else
return ticks*(1000/CLOCKS_PER_SEC);
return ticks * (1000 / CLOCKS_PER_SEC);
#endif
}
void SDL_Delay (Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
Uint32 now,then,elapsed;
Uint32 now, then, elapsed;
#if !SDL_THREADS_DISABLED
int is_event_thread;
if (riscos_using_threads)
{
is_event_thread = 0;
if (SDL_EventThreadID())
{
if (SDL_EventThreadID() == SDL_ThreadID()) is_event_thread = 1;
} else if (SDL_ThreadID() == riscos_main_thread) is_event_thread = 1;
} else is_event_thread = 1;
if (riscos_using_threads) {
is_event_thread = 0;
if (SDL_EventThreadID()) {
if (SDL_EventThreadID() == SDL_ThreadID())
is_event_thread = 1;
} else if (SDL_ThreadID() == riscos_main_thread)
is_event_thread = 1;
} else
is_event_thread = 1;
#endif
/*TODO: Next version of Unixlib may allow us to use usleep here */
/* for non event threads */
/*TODO: Next version of Unixlib may allow us to use usleep here */
/* for non event threads */
/* Set the timeout interval - Linux only needs to do this once */
then = SDL_GetTicks();
/* Set the timeout interval - Linux only needs to do this once */
then = SDL_GetTicks();
do {
/* Do background tasks required while sleeping as we are not multithreaded */
do {
/* Do background tasks required while sleeping as we are not multithreaded */
#if SDL_THREADS_DISABLED
RISCOS_BackgroundTasks();
RISCOS_BackgroundTasks();
#else
/* For threaded build only run background tasks in event thread */
if (is_event_thread) RISCOS_BackgroundTasks();
/* For threaded build only run background tasks in event thread */
if (is_event_thread)
RISCOS_BackgroundTasks();
#endif
/* Calculate the time interval left (in case of interrupt) */
now = SDL_GetTicks();
elapsed = (now-then);
then = now;
if ( elapsed >= ms ) {
break;
}
ms -= elapsed;
/* Calculate the time interval left (in case of interrupt) */
now = SDL_GetTicks();
elapsed = (now - then);
then = now;
if (elapsed >= ms) {
break;
}
ms -= elapsed;
#if !SDL_THREADS_DISABLED
/* Need to yield to let other threads have a go */
if (riscos_using_threads) pthread_yield();
/* Need to yield to let other threads have a go */
if (riscos_using_threads)
pthread_yield();
#endif
} while ( 1 );
}
while (1);
}
#if SDL_THREADS_DISABLED
/* Non-threaded version of timer */
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
return(0);
return (0);
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
SDL_SetTimer(0, NULL);
SDL_SetTimer(0, NULL);
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
timerStart = SDL_GetTicks();
timerStart = SDL_GetTicks();
return(0);
return (0);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
/* Don't need to do anything as we use SDL_timer_running
to detect if we need to check the timer */
/* Don't need to do anything as we use SDL_timer_running
to detect if we need to check the timer */
}
void RISCOS_CheckTimer()
void
RISCOS_CheckTimer()
{
if (SDL_timer_running && SDL_GetTicks() - timerStart >= SDL_alarm_interval)
{
Uint32 ms;
if (SDL_timer_running
&& SDL_GetTicks() - timerStart >= SDL_alarm_interval) {
Uint32 ms;
ms = SDL_alarm_callback(SDL_alarm_interval);
if ( ms != SDL_alarm_interval )
{
if ( ms )
{
SDL_alarm_interval = ROUND_RESOLUTION(ms);
} else
{
SDL_alarm_interval = 0;
SDL_timer_running = 0;
}
}
if (SDL_alarm_interval) timerStart = SDL_GetTicks();
}
ms = SDL_alarm_callback(SDL_alarm_interval);
if (ms != SDL_alarm_interval) {
if (ms) {
SDL_alarm_interval = ROUND_RESOLUTION(ms);
} else {
SDL_alarm_interval = 0;
SDL_timer_running = 0;
}
}
if (SDL_alarm_interval)
timerStart = SDL_GetTicks();
}
}
#else
@@ -187,47 +197,53 @@ void RISCOS_CheckTimer()
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int RunTimer(void *unused)
static int
RunTimer(void *unused)
{
while ( timer_alive ) {
if ( SDL_timer_running ) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return(0);
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return (0);
}
/* This is only called if the event thread is not running */
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if ( timer == NULL )
return(-1);
return(SDL_SetTimerThreaded(1));
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if (timer == NULL)
return (-1);
return (SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if ( timer ) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
timer_alive = 0;
if (timer) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: RISC OS uses threaded timer");
return(-1);
SDL_SetError("Internal logic error: RISC OS uses threaded timer");
return (-1);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
return;
return;
}
#endif /* SDL_THREADS_DISABLED */
#endif /* SDL_TIMER_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -58,132 +58,145 @@ static struct timeval start;
#endif /* HAVE_CLOCK_GETTIME */
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
/* Set first ticks value */
/* Set first ticks value */
#if HAVE_CLOCK_GETTIME
clock_gettime(CLOCK_MONOTONIC,&start);
clock_gettime(CLOCK_MONOTONIC, &start);
#else
gettimeofday(&start, NULL);
gettimeofday(&start, NULL);
#endif
}
Uint32 SDL_GetTicks (void)
Uint32
SDL_GetTicks(void)
{
#if HAVE_CLOCK_GETTIME
Uint32 ticks;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC,&now);
ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_nsec-start.tv_nsec)/1000000;
return(ticks);
Uint32 ticks;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec -
start.tv_nsec) / 1000000;
return (ticks);
#else
Uint32 ticks;
struct timeval now;
gettimeofday(&now, NULL);
ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000;
return(ticks);
Uint32 ticks;
struct timeval now;
gettimeofday(&now, NULL);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec -
start.tv_usec) / 1000;
return (ticks);
#endif
}
void SDL_Delay (Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
#if SDL_THREAD_PTH
pth_time_t tv;
tv.tv_sec = ms/1000;
tv.tv_usec = (ms%1000)*1000;
pth_nap(tv);
pth_time_t tv;
tv.tv_sec = ms / 1000;
tv.tv_usec = (ms % 1000) * 1000;
pth_nap(tv);
#else
int was_error;
int was_error;
#if HAVE_NANOSLEEP
struct timespec elapsed, tv;
struct timespec elapsed, tv;
#else
struct timeval tv;
Uint32 then, now, elapsed;
struct timeval tv;
Uint32 then, now, elapsed;
#endif
/* Set the timeout interval */
/* Set the timeout interval */
#if HAVE_NANOSLEEP
elapsed.tv_sec = ms/1000;
elapsed.tv_nsec = (ms%1000)*1000000;
elapsed.tv_sec = ms / 1000;
elapsed.tv_nsec = (ms % 1000) * 1000000;
#else
then = SDL_GetTicks();
then = SDL_GetTicks();
#endif
do {
errno = 0;
do {
errno = 0;
#if HAVE_NANOSLEEP
tv.tv_sec = elapsed.tv_sec;
tv.tv_nsec = elapsed.tv_nsec;
was_error = nanosleep(&tv, &elapsed);
tv.tv_sec = elapsed.tv_sec;
tv.tv_nsec = elapsed.tv_nsec;
was_error = nanosleep(&tv, &elapsed);
#else
/* Calculate the time interval left (in case of interrupt) */
now = SDL_GetTicks();
elapsed = (now-then);
then = now;
if ( elapsed >= ms ) {
break;
}
ms -= elapsed;
tv.tv_sec = ms/1000;
tv.tv_usec = (ms%1000)*1000;
/* Calculate the time interval left (in case of interrupt) */
now = SDL_GetTicks();
elapsed = (now - then);
then = now;
if (elapsed >= ms) {
break;
}
ms -= elapsed;
tv.tv_sec = ms / 1000;
tv.tv_usec = (ms % 1000) * 1000;
was_error = select(0, NULL, NULL, NULL, &tv);
was_error = select(0, NULL, NULL, NULL, &tv);
#endif /* HAVE_NANOSLEEP */
} while ( was_error && (errno == EINTR) );
}
while (was_error && (errno == EINTR));
#endif /* SDL_THREAD_PTH */
}
#ifdef USE_ITIMER
static void HandleAlarm(int sig)
static void
HandleAlarm(int sig)
{
Uint32 ms;
Uint32 ms;
if ( SDL_alarm_callback ) {
ms = (*SDL_alarm_callback)(SDL_alarm_interval);
if ( ms != SDL_alarm_interval ) {
SDL_SetTimer(ms, SDL_alarm_callback);
}
}
if (SDL_alarm_callback) {
ms = (*SDL_alarm_callback) (SDL_alarm_interval);
if (ms != SDL_alarm_interval) {
SDL_SetTimer(ms, SDL_alarm_callback);
}
}
}
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
struct sigaction action;
struct sigaction action;
/* Set the alarm handler (Linux specific) */
SDL_memset(&action, 0, sizeof(action));
action.sa_handler = HandleAlarm;
action.sa_flags = SA_RESTART;
sigemptyset(&action.sa_mask);
sigaction(SIGALRM, &action, NULL);
return(0);
/* Set the alarm handler (Linux specific) */
SDL_memset(&action, 0, sizeof(action));
action.sa_handler = HandleAlarm;
action.sa_flags = SA_RESTART;
sigemptyset(&action.sa_mask);
sigaction(SIGALRM, &action, NULL);
return (0);
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
SDL_SetTimer(0, NULL);
SDL_SetTimer(0, NULL);
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
struct itimerval timer;
struct itimerval timer;
timer.it_value.tv_sec = (SDL_alarm_interval/1000);
timer.it_value.tv_usec = (SDL_alarm_interval%1000)*1000;
timer.it_interval.tv_sec = (SDL_alarm_interval/1000);
timer.it_interval.tv_usec = (SDL_alarm_interval%1000)*1000;
setitimer(ITIMER_REAL, &timer, NULL);
return(0);
timer.it_value.tv_sec = (SDL_alarm_interval / 1000);
timer.it_value.tv_usec = (SDL_alarm_interval % 1000) * 1000;
timer.it_interval.tv_sec = (SDL_alarm_interval / 1000);
timer.it_interval.tv_usec = (SDL_alarm_interval % 1000) * 1000;
setitimer(ITIMER_REAL, &timer, NULL);
return (0);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
struct itimerval timer;
struct itimerval timer;
SDL_memset(&timer, 0, (sizeof timer));
setitimer(ITIMER_REAL, &timer, NULL);
SDL_memset(&timer, 0, (sizeof timer));
setitimer(ITIMER_REAL, &timer, NULL);
}
#else /* USE_ITIMER */
@@ -194,47 +207,53 @@ void SDL_SYS_StopTimer(void)
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int RunTimer(void *unused)
static int
RunTimer(void *unused)
{
while ( timer_alive ) {
if ( SDL_timer_running ) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return(0);
while (timer_alive) {
if (SDL_timer_running) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return (0);
}
/* This is only called if the event thread is not running */
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if ( timer == NULL )
return(-1);
return(SDL_SetTimerThreaded(1));
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if (timer == NULL)
return (-1);
return (SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if ( timer ) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
timer_alive = 0;
if (timer) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: Linux uses threaded timer");
return(-1);
SDL_SetError("Internal logic error: Linux uses threaded timer");
return (-1);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
return;
return;
}
#endif /* USE_ITIMER */
#endif /* SDL_TIMER_UNIX */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -31,7 +31,7 @@
#include "../SDL_timer_c.h"
#ifdef _WIN32_WCE
#error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead.
#error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead.
#endif
#define TIME_WRAP_VALUE (~(DWORD)0)
@@ -48,113 +48,118 @@ static LARGE_INTEGER hires_start_ticks;
static LARGE_INTEGER hires_ticks_per_second;
#endif
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
/* Set first ticks value */
/* Set first ticks value */
#ifdef USE_GETTICKCOUNT
start = GetTickCount();
start = GetTickCount();
#else
#if 0 /* Apparently there are problems with QPC on Win2K */
if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE)
{
hires_timer_available = TRUE;
QueryPerformanceCounter(&hires_start_ticks);
}
else
#if 0 /* Apparently there are problems with QPC on Win2K */
if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) {
hires_timer_available = TRUE;
QueryPerformanceCounter(&hires_start_ticks);
} else
#endif
{
hires_timer_available = FALSE;
timeBeginPeriod(1); /* use 1 ms timer precision */
start = timeGetTime();
}
{
hires_timer_available = FALSE;
timeBeginPeriod(1); /* use 1 ms timer precision */
start = timeGetTime();
}
#endif
}
Uint32 SDL_GetTicks(void)
Uint32
SDL_GetTicks(void)
{
DWORD now, ticks;
DWORD now, ticks;
#ifndef USE_GETTICKCOUNT
LARGE_INTEGER hires_now;
LARGE_INTEGER hires_now;
#endif
#ifdef USE_GETTICKCOUNT
now = GetTickCount();
now = GetTickCount();
#else
if (hires_timer_available)
{
QueryPerformanceCounter(&hires_now);
if (hires_timer_available) {
QueryPerformanceCounter(&hires_now);
hires_now.QuadPart -= hires_start_ticks.QuadPart;
hires_now.QuadPart *= 1000;
hires_now.QuadPart /= hires_ticks_per_second.QuadPart;
hires_now.QuadPart -= hires_start_ticks.QuadPart;
hires_now.QuadPart *= 1000;
hires_now.QuadPart /= hires_ticks_per_second.QuadPart;
return (DWORD)hires_now.QuadPart;
}
else
{
now = timeGetTime();
}
return (DWORD) hires_now.QuadPart;
} else {
now = timeGetTime();
}
#endif
if ( now < start ) {
ticks = (TIME_WRAP_VALUE-start) + now;
} else {
ticks = (now - start);
}
return(ticks);
if (now < start) {
ticks = (TIME_WRAP_VALUE - start) + now;
} else {
ticks = (now - start);
}
return (ticks);
}
void SDL_Delay(Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
Sleep(ms);
Sleep(ms);
}
/* Data to handle a single periodic alarm */
static UINT timerID = 0;
static void CALLBACK HandleAlarm(UINT uID, UINT uMsg, DWORD_PTR dwUser,
DWORD_PTR dw1, DWORD_PTR dw2)
static void CALLBACK
HandleAlarm(UINT uID, UINT uMsg, DWORD_PTR dwUser,
DWORD_PTR dw1, DWORD_PTR dw2)
{
SDL_ThreadedTimerCheck();
SDL_ThreadedTimerCheck();
}
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
MMRESULT result;
MMRESULT result;
/* Set timer resolution */
result = timeBeginPeriod(TIMER_RESOLUTION);
if ( result != TIMERR_NOERROR ) {
SDL_SetError("Warning: Can't set %d ms timer resolution",
TIMER_RESOLUTION);
}
/* Allow 10 ms of drift so we don't chew on CPU */
timerID = timeSetEvent(TIMER_RESOLUTION,1,HandleAlarm,0,TIME_PERIODIC);
if ( ! timerID ) {
SDL_SetError("timeSetEvent() failed");
return(-1);
}
return(SDL_SetTimerThreaded(1));
/* Set timer resolution */
result = timeBeginPeriod(TIMER_RESOLUTION);
if (result != TIMERR_NOERROR) {
SDL_SetError("Warning: Can't set %d ms timer resolution",
TIMER_RESOLUTION);
}
/* Allow 10 ms of drift so we don't chew on CPU */
timerID =
timeSetEvent(TIMER_RESOLUTION, 1, HandleAlarm, 0, TIME_PERIODIC);
if (!timerID) {
SDL_SetError("timeSetEvent() failed");
return (-1);
}
return (SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
if ( timerID ) {
timeKillEvent(timerID);
}
timeEndPeriod(TIMER_RESOLUTION);
if (timerID) {
timeKillEvent(timerID);
}
timeEndPeriod(TIMER_RESOLUTION);
}
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: Win32 uses threaded timer");
return(-1);
SDL_SetError("Internal logic error: Win32 uses threaded timer");
return (-1);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
return;
return;
}
#endif /* SDL_TIMER_WIN32 */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -34,62 +34,68 @@
static Uint64 start_date;
static Uint64 start_ticks;
static Uint64 wce_ticks(void)
static Uint64
wce_ticks(void)
{
return((Uint64)GetTickCount());
return ((Uint64) GetTickCount());
}
static Uint64 wce_date(void)
static Uint64
wce_date(void)
{
union
{
FILETIME ftime;
Uint64 itime;
} ftime;
SYSTEMTIME stime;
union
{
FILETIME ftime;
Uint64 itime;
} ftime;
SYSTEMTIME stime;
GetSystemTime(&stime);
SystemTimeToFileTime(&stime,&ftime.ftime);
ftime.itime/=10000; // Convert 100ns intervals to 1ms intervals
// Remove ms portion, which can't be relied on
ftime.itime -= (ftime.itime % 1000);
return(ftime.itime);
GetSystemTime(&stime);
SystemTimeToFileTime(&stime, &ftime.ftime);
ftime.itime /= 10000; // Convert 100ns intervals to 1ms intervals
// Remove ms portion, which can't be relied on
ftime.itime -= (ftime.itime % 1000);
return (ftime.itime);
}
static Sint32 wce_rel_ticks(void)
static Sint32
wce_rel_ticks(void)
{
return((Sint32)(wce_ticks()-start_ticks));
return ((Sint32) (wce_ticks() - start_ticks));
}
static Sint32 wce_rel_date(void)
static Sint32
wce_rel_date(void)
{
return((Sint32)(wce_date()-start_date));
return ((Sint32) (wce_date() - start_date));
}
/* Return time in ms relative to when SDL was started */
Uint32 SDL_GetTicks()
Uint32
SDL_GetTicks()
{
Sint32 offset=wce_rel_date()-wce_rel_ticks();
if((offset < -1000) || (offset > 1000))
{
Sint32 offset = wce_rel_date() - wce_rel_ticks();
if ((offset < -1000) || (offset > 1000)) {
// fprintf(stderr,"Time desync(%+d), resyncing\n",offset/1000);
start_ticks-=offset;
}
start_ticks -= offset;
}
return((Uint32)wce_rel_ticks());
return ((Uint32) wce_rel_ticks());
}
/* Give up approx. givem milliseconds to the OS. */
void SDL_Delay(Uint32 ms)
void
SDL_Delay(Uint32 ms)
{
Sleep(ms);
Sleep(ms);
}
/* Recard start-time of application for reference */
void SDL_StartTicks(void)
void
SDL_StartTicks(void)
{
start_date=wce_date();
start_ticks=wce_ticks();
start_date = wce_date();
start_ticks = wce_ticks();
}
static UINT WIN_timer;
@@ -99,46 +105,47 @@ static UINT WIN_timer;
static HANDLE timersThread = 0;
static HANDLE timersQuitEvent = 0;
DWORD TimersThreadProc(void *data)
DWORD
TimersThreadProc(void *data)
{
while(WaitForSingleObject(timersQuitEvent, 10) == WAIT_TIMEOUT)
{
SDL_ThreadedTimerCheck();
}
return 0;
while (WaitForSingleObject(timersQuitEvent, 10) == WAIT_TIMEOUT) {
SDL_ThreadedTimerCheck();
}
return 0;
}
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
// create a thread to process a threaded timers
// SetTimer does not suit the needs because
// TimerCallbackProc will be called only when WM_TIMER occured
// create a thread to process a threaded timers
// SetTimer does not suit the needs because
// TimerCallbackProc will be called only when WM_TIMER occured
timersQuitEvent = CreateEvent(0, TRUE, FALSE, 0);
if( !timersQuitEvent )
{
SDL_SetError("Cannot create event for timers thread");
return -1;
}
timersThread = CreateThread(NULL, 0, TimersThreadProc, 0, 0, 0);
if( !timersThread )
{
SDL_SetError("Cannot create timers thread, check amount of RAM available");
return -1;
}
SetThreadPriority(timersThread, THREAD_PRIORITY_HIGHEST);
timersQuitEvent = CreateEvent(0, TRUE, FALSE, 0);
if (!timersQuitEvent) {
SDL_SetError("Cannot create event for timers thread");
return -1;
}
timersThread = CreateThread(NULL, 0, TimersThreadProc, 0, 0, 0);
if (!timersThread) {
SDL_SetError
("Cannot create timers thread, check amount of RAM available");
return -1;
}
SetThreadPriority(timersThread, THREAD_PRIORITY_HIGHEST);
return(SDL_SetTimerThreaded(1));
return (SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
SetEvent(timersQuitEvent);
if( WaitForSingleObject(timersThread, 2000) == WAIT_TIMEOUT )
TerminateThread(timersThread, 0);
CloseHandle(timersThread);
CloseHandle(timersQuitEvent);
return;
SetEvent(timersQuitEvent);
if (WaitForSingleObject(timersThread, 2000) == WAIT_TIMEOUT)
TerminateThread(timersThread, 0);
CloseHandle(timersThread);
CloseHandle(timersQuitEvent);
return;
}
#else
@@ -148,51 +155,57 @@ void SDL_SYS_TimerQuit(void)
/* Data to handle a single periodic alarm */
static UINT timerID = 0;
static void CALLBACK HandleAlarm(UINT uID, UINT uMsg, DWORD dwUser,
DWORD dw1, DWORD dw2)
static void CALLBACK
HandleAlarm(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
SDL_ThreadedTimerCheck();
SDL_ThreadedTimerCheck();
}
int SDL_SYS_TimerInit(void)
int
SDL_SYS_TimerInit(void)
{
MMRESULT result;
MMRESULT result;
/* Set timer resolution */
result = timeBeginPeriod(TIMER_RESOLUTION);
if ( result != TIMERR_NOERROR ) {
SDL_SetError("Warning: Can't set %d ms timer resolution",
TIMER_RESOLUTION);
}
/* Allow 10 ms of drift so we don't chew on CPU */
timerID = timeSetEvent(TIMER_RESOLUTION,1,HandleAlarm,0,TIME_PERIODIC);
if ( ! timerID ) {
SDL_SetError("timeSetEvent() failed");
return(-1);
}
return(SDL_SetTimerThreaded(1));
/* Set timer resolution */
result = timeBeginPeriod(TIMER_RESOLUTION);
if (result != TIMERR_NOERROR) {
SDL_SetError("Warning: Can't set %d ms timer resolution",
TIMER_RESOLUTION);
}
/* Allow 10 ms of drift so we don't chew on CPU */
timerID =
timeSetEvent(TIMER_RESOLUTION, 1, HandleAlarm, 0, TIME_PERIODIC);
if (!timerID) {
SDL_SetError("timeSetEvent() failed");
return (-1);
}
return (SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
void
SDL_SYS_TimerQuit(void)
{
if ( timerID ) {
timeKillEvent(timerID);
}
timeEndPeriod(TIMER_RESOLUTION);
if (timerID) {
timeKillEvent(timerID);
}
timeEndPeriod(TIMER_RESOLUTION);
}
#endif
int SDL_SYS_StartTimer(void)
int
SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: WinCE uses threaded timer");
return(-1);
SDL_SetError("Internal logic error: WinCE uses threaded timer");
return (-1);
}
void SDL_SYS_StopTimer(void)
void
SDL_SYS_StopTimer(void)
{
return;
return;
}
#endif /* SDL_TIMER_WINCE */
/* vi: set ts=4 sw=4 expandtab: */