/*
* Animated Cursor
*generic animated cursor support.
*/
// Assumes inclusion of
Boolean InitAnimatedCursors( short acurID, short interval); void ReleaseAnimatedCursors(void);
void SpinCursor(void );
typedef struct
/* The structure of an 'acur' resource */
{
short numberOfFrames; [TOKEN:12074] number of cursors to animate */
short whichFrame; [TOKEN:12074] current frame number */
CursHandle frame[]; [TOKEN:12074] Pointer to the first cursor */ } acur, *acurPtr, **acurHandle;
/* Redefine HiWord() as a macro to increase speed. */ #define HiWrd(aLong) (((aLong) >> 16) & 0xFFFF)
/* Some module-local globals */
static short gTickInterval; /* number of ticks between a frame switch */
static long gLastTick; /* tick count of last call to SpinCursor */
static acurHandle gFrameList; [TOKEN:12074] our cursor list */
/* Try to get the acur record and the cursor list for acurID, returning TRUE
if everything goes as planned. */
InitAnimatedCursors( short acurID, short interval)
{
register short i=0;
register short cursID;
if((gFrameList = (acurHandle) GetResource('acur',acurID))) { /* got it! */
while((i<(*gFrameList)-> numberOfFrames) && noErrFlag) {
/* The id of the cursor is stored in the high word of the frame handle */
cursID = ( short) HiWrd((long) (*gFrameList)-> frame[i]);
(*gFrameList)-> frame[i] = GetCursor(cursID);
if((*gFrameList)-> frame[i])
i++; /* get the next one */
else
noErrFlag=FALSE; /* foo! we couldn't find the cursor
*/
}
}
if(noErrFlag) {
/* We have the cursors, now initialize the other fields */
gTickInterval = interval;
(*gFrameList)-> whichFrame = 0;
}
return noErrFlag;
}
/* Free up the storage used by the current animated cursor and all
of its frames */
void
ReleaseAnimatedCursors()
{
short i;
for(i=0;i<(*gFrameList)-> numberOfFrames;i++)
}
/* Display the next frame in the sequence, if it's time. If not, do nothing.
This code should be pretty tight, but it might be possible to bum a few
instructions; ideally it should be as fast as possible. I doubt it will
be necessary to hand-hack it though.
I chose this implementation over using a VBL task for the following reason:
the whole point of using an animated cursor is to let the user know that
your application is chugging away doing something. With this technique if
the applications shoots off to never-never land, the cursor will probably
stop spinning. A VBL task, on the other hand, would probably just sit and
merrily go on spinning away, the user none the wiser. */
void
SpinCursor()
{
register long newTick;
/* Is it time? */
if(newTick < (gLastTick + gTickInterval))
return; /* nope */
/* Grab the frame, increment (and reset, if necessary) the count, and
display the new cursor */
SetCursor(*((*gFrameList)-> frame[(*gFrameList)-> whichFrame++])); if((*gFrameList)-> whichFrame == (*gFrameList)-> numberOfFrames)
(*gFrameList)-> whichFrame = 0;
gLastTick = newTick;
}
#define countingHand 1000 [TOKEN:12074] id of the 'acur' resource */
#define watchCursor 1002