Mercurial > sdl-ios-xcode
diff src/timer/macos/SDL_MPWtimer.c @ 0:74212992fb08
Initial revision
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Thu, 26 Apr 2001 16:45:43 +0000 |
parents | |
children | e8157fcb3114 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/timer/macos/SDL_MPWtimer.c Thu Apr 26 16:45:43 2001 +0000 @@ -0,0 +1,152 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include <Types.h> +#include <Timer.h> +#include <OSUtils.h> +#include <Gestalt.h> +#include <Processes.h> + +#include <LowMem.h> + +#include "SDL_timer.h" +#include "SDL_timer_c.h" + +#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. + */ +#define USE_MICROSECONDS +#define WideTo64bit(w) (*(UInt64 *) &(w)) + +UInt64 start; + +void SDL_StartTicks(void) +{ +#ifdef USE_MICROSECONDS + UnsignedWide now; + + Microseconds(&now); + start = WideTo64bit(now); +#else + /* FIXME: Should we implement a wrapping algorithm, like Win32? */ +#endif +} + +Uint32 SDL_GetTicks(void) +{ +#ifdef USE_MICROSECONDS + UnsignedWide now; + + Microseconds(&now); + return (Uint32)((WideTo64bit(now)-start)/1000); +#else + return(LMGetTicks()*MS_PER_TICK); +#endif +} + +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 ); +#else + UInt32 unused; /* MJS */ + Delay(ms/MS_PER_TICK, &unused); +#endif +} + + +/* Data to handle a single periodic alarm */ +typedef struct _ExtendedTimerRec +{ + TMTask tmTask; + ProcessSerialNumber taskPSN; +} ExtendedTimerRec, *ExtendedTimerPtr; + +static ExtendedTimerRec gExtendedTimerRec; + + +int SDL_SYS_TimerInit(void) +{ + /* We don't need a setup? */ + return(0); +} + +void SDL_SYS_TimerQuit(void) +{ + /* We don't need a cleanup? */ + return; +} + +/* Our Stub routine to set up and then call the real routine. */ +pascal void TimerCallbackProc(TMTaskPtr tmTaskPtr) +{ + Uint32 ms; + + 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; + } +} + +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); + + /* Install the task record */ + InsXTime((QElemPtr)&gExtendedTimerRec.tmTask); + + /* Go! */ + PrimeTime((QElemPtr)&gExtendedTimerRec.tmTask, SDL_alarm_interval); + return(0); +} + +void SDL_SYS_StopTimer(void) +{ + RmvTime((QElemPtr)&gExtendedTimerRec.tmTask); +}