src/timer/macos/SDL_MPWtimer.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. WideTo64bit
  2. SDL_StartTicks
  3. SDL_GetTicks
  4. SDL_Delay
  5. SDL_SYS_TimerInit
  6. SDL_SYS_TimerQuit
  7. TimerCallbackProc
  8. SDL_SYS_StartTimer
  9. SDL_SYS_StopTimer

   1 /*
   2         SDL - Simple DirectMedia Layer
   3         Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
   4 
   5         This library is free software; you can redistribute it and/or
   6         modify it under the terms of the GNU Library General Public
   7         License as published by the Free Software Foundation; either
   8         version 2 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         Library General Public License for more details.
  14 
  15         You should have received a copy of the GNU Library General Public
  16         License along with this library; if not, write to the Free
  17         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18 
  19         Sam Lantinga
  20         slouken@devolution.com
  21 */
  22 
  23 #ifdef SAVE_RCSID
  24 static char rcsid =
  25  "@(#) $Id: SDL_MPWtimer.c,v 1.1.2.4 2001/02/10 07:20:05 hercules Exp $";
  26 #endif
  27 
  28 #include <Types.h>
  29 #include <Timer.h>
  30 #include <OSUtils.h>
  31 #include <Gestalt.h>
  32 #include <Processes.h>
  33 
  34 #include <LowMem.h>
  35 
  36 #include "SDL_timer.h"
  37 #include "SDL_timer_c.h"
  38 
  39 #define MS_PER_TICK     (1000/60)               /* MacOS tick = 1/60 second */
  40 
  41 /* Note: This is only a step above the original 1/60s implementation.
  42  *       For a good implementation, see FastTimes.[ch], by Matt Slot.
  43  */
  44 #define USE_MICROSECONDS
  45 #define WideTo64bit(w)  (*(UInt64 *) &(w))
     /* [<][>][^][v][top][bottom][index][help] */
  46 
  47 UInt64 start;
  48 
  49 void SDL_StartTicks(void)
     /* [<][>][^][v][top][bottom][index][help] */
  50 {
  51 #ifdef USE_MICROSECONDS
  52         UnsignedWide now;
  53         
  54         Microseconds(&now);
  55         start = WideTo64bit(now);
  56 #else
  57         /* FIXME: Should we implement a wrapping algorithm, like Win32? */
  58 #endif
  59 }
  60 
  61 Uint32 SDL_GetTicks(void)
     /* [<][>][^][v][top][bottom][index][help] */
  62 {
  63 #ifdef USE_MICROSECONDS
  64         UnsignedWide now;
  65         
  66         Microseconds(&now);
  67         return (Uint32)((WideTo64bit(now)-start)/1000);
  68 #else
  69         return(LMGetTicks()*MS_PER_TICK);
  70 #endif
  71 }
  72 
  73 void SDL_Delay(Uint32 ms)
     /* [<][>][^][v][top][bottom][index][help] */
  74 {
  75 #ifdef USE_MICROSECONDS
  76         Uint32 end_ms;
  77         
  78         end_ms = SDL_GetTicks() + ms;
  79         do {
  80                 /* FIXME: Yield CPU? */ ;
  81         } while ( SDL_GetTicks() < end_ms );
  82 #else
  83         UInt32          unused; /* MJS */
  84         Delay(ms/MS_PER_TICK, &unused);
  85 #endif
  86 }
  87 
  88 
  89 /* Data to handle a single periodic alarm */
  90 typedef struct _ExtendedTimerRec
  91 {
  92         TMTask               tmTask;
  93         ProcessSerialNumber  taskPSN;
  94 } ExtendedTimerRec, *ExtendedTimerPtr;
  95 
  96 static ExtendedTimerRec gExtendedTimerRec;
  97 
  98 
  99 int SDL_SYS_TimerInit(void)
     /* [<][>][^][v][top][bottom][index][help] */
 100 {
 101         /* We don't need a setup? */
 102         return(0);
 103 }
 104 
 105 void SDL_SYS_TimerQuit(void)
     /* [<][>][^][v][top][bottom][index][help] */
 106 {
 107         /* We don't need a cleanup? */
 108         return;
 109 }
 110 
 111 /* Our Stub routine to set up and then call the real routine. */
 112 pascal void TimerCallbackProc(TMTaskPtr tmTaskPtr)
     /* [<][>][^][v][top][bottom][index][help] */
 113 {
 114         Uint32 ms;
 115 
 116         WakeUpProcess(&((ExtendedTimerPtr) tmTaskPtr)->taskPSN);
 117 
 118         ms = SDL_alarm_callback(SDL_alarm_interval);
 119         if ( ms ) {
 120                 SDL_alarm_interval = ROUND_RESOLUTION(ms);
 121                 PrimeTime((QElemPtr)&gExtendedTimerRec.tmTask,
 122                           SDL_alarm_interval);
 123         } else {
 124                 SDL_alarm_interval = 0;
 125         }
 126 }
 127 
 128 int SDL_SYS_StartTimer(void)
     /* [<][>][^][v][top][bottom][index][help] */
 129 {
 130         /*
 131          * Configure the global structure that stores the timing information.
 132          */
 133         gExtendedTimerRec.tmTask.qLink = NULL;
 134         gExtendedTimerRec.tmTask.qType = 0;
 135         gExtendedTimerRec.tmTask.tmAddr = NewTimerUPP(TimerCallbackProc);
 136         gExtendedTimerRec.tmTask.tmCount = 0;
 137         gExtendedTimerRec.tmTask.tmWakeUp = 0;
 138         gExtendedTimerRec.tmTask.tmReserved = 0;
 139         GetCurrentProcess(&gExtendedTimerRec.taskPSN);
 140 
 141         /* Install the task record */
 142         InsXTime((QElemPtr)&gExtendedTimerRec.tmTask);
 143 
 144         /* Go! */
 145         PrimeTime((QElemPtr)&gExtendedTimerRec.tmTask, SDL_alarm_interval);
 146         return(0);
 147 }
 148 
 149 void SDL_SYS_StopTimer(void)
     /* [<][>][^][v][top][bottom][index][help] */
 150 {
 151         RmvTime((QElemPtr)&gExtendedTimerRec.tmTask);
 152 }

/* [<][>][^][v][top][bottom][index][help] */