[comp.sys.mac.programmer] Animated Cursor VBL

borcelf@jacobs.cs.orst.edu (Fernando Borcel) (02/21/90)

I like the idea of an animated cursor, such as a beach ball or the hourglass
in the old RedRyder term program.  I also noticed most programs do the change
of cursor synchroneously (i.e. change it every time it goes around a loop).
 
I wrote these procedures to make it work as a VBL task.  Everything works great,
except that the A5 register seems to get a bit corrupted, screwing up some
handles later in the program.  I'm making sure all my handles are locked,
but I don't have IM vIII, so I'm not sure whether SetCursor moves memory
and is not supposed to be called from inside of a VBL task.  In any case,
here are the three routines I wrote, if you have any idea what might be
wrong (if anything), please lemme know!
 
---------------------------
unit CursorStuff;
 
interface
  procedure BeginBeachBall;
  procedure EndBeachBall;
 
implementation
  const
    NumOfFrames = 6;
 
  var
    ballframe: integer;
    Ball: array[1..NumOfFrames] of cursHandle;
    BallVBLTask: VBLTask;
    Error: integer;
 
{$D-}
  procedure BeachBall;
  {Change cursor every 10/60ths}
  begin
    SetUpA5;
      if (BallFrame >= 1) and (BallFrame <= 6) then
      {Make sure BallFrame isn't corrupted}
        begin
          SetCursor(Ball[BallFrame]^^);
          if BallFrame = NumOfFrames then
            BallFrame := 1
          else
            BallFrame := BallFrame + 1;
 
          BallVBLTask.vblCount := 10;
        end;
    RestoreA5;
  end;
{$D+}
 
  procedure BeginBeachBall;
  {Get curs resources, lock the handles, and install the}
  {VBL task}
 
    var
      i: integer;
    begin
      BallFrame := 1;
      for i := 1 to NumOfFrames do	{curs resources are 200..205}
        begin
          Ball[i] := GetCursor(199 + i);
          HLock(Handle(Ball[i]));
        end;
      with BallVBLTask do
        begin
          qType := ord(vType);
           vblCount := 10;  {Set the VBL counter to 10/60th}
            vblPhase := 0;
            vblAddr := @BeachBall;
          end;
        error := VInstall(@BallVBLTask);
 
        if error <> noErr then
          SysBeep(1);
  end;
 
  procedure EndBeachBall;
  {Remove the VBL task and dispose curs handles}
  var
    i: integer;
	
  begin
    if error = noErr then
      begin
        error := VRemove(@BallVBLTask);
        for i := 1 to NumOfFrames do
          ReleaseResource(Handle(Ball[i]));
        end;
    end;
 
 
end.
 
---------------------------------'
 
Fernando Borcel
Internet:	borcelf@jacobs.cs.ORST.EDU
FidoNet:	Nando @ 1:152/208