home *** CD-ROM | disk | FTP | other *** search
- (*************************************************************************
-
- $RCSfile: VSprite.mod $
- Description: Port of vsprite.c
-
- Created by: fjc (Frank Copeland)
- $Revision: 1.2 $
- $Author: fjc $
- $Date: 1995/07/02 16:59:37 $
-
- Copyright © 1995, Frank Copeland.
- This example program is part of Oberon-A.
- See Oberon-A.doc for conditions of use and distribution.
-
- Log entries are at the end of the file.
-
- *************************************************************************)
-
- <* STANDARD- *>
-
- MODULE VSprite;
-
- IMPORT
- SYS := SYSTEM, Kernel, Errors, e := Exec, i := Intuition,
- gfx := Graphics, d := Dos, at := AnimTools, s := Sets;
-
- (*------------------------------------*)
-
- CONST
- VersionTag = "$VER: VSprite 1.2 (2.6.95)\r\n";
- VersionStr = "VSprite 1.2 (2.6.95)";
- CopyrightStr = "Copyright © 1995 Frank Copeland";
-
- (*------------------------------------*)
-
- VAR
-
- returnCode : LONGINT;
-
- CONST
-
- gelSize = 4;
-
- (* VSprite data - there are two sets that are alternated between. *)
- (* note that this data is always displayed as low resolution *)
-
- CONST
-
- vspriteDataStr1 =
- "\x7F\xFE\x80\xFF"
- "\x7C\x3E\x80\x3F"
- "\x7C\x3E\x80\x3F"
- "\x7F\xFE\x80\xFF"
- "\x00\x00\x00\x00";
-
- vspriteDataStr2 =
- "\x7F\xFE\xFF\x01"
- "\x7C\x3E\xFC\x01"
- "\x7C\x3E\xFC\x01"
- "\x7F\xFE\xFF\x01"
- "\x00\x00\x00\x00";
-
- TYPE
-
- VSpriteDataArray = ARRAY 10 OF INTEGER;
- VSpriteDataPtr = POINTER [2] TO VSpriteDataArray;
-
- VAR
-
- vspriteData1, vspriteData2 : VSpriteDataPtr;
- mySpriteColors, mySpriteAltColors : ARRAY 3 OF INTEGER;
- myNewVSprite : at.NewVSprite;
- myNewWindow : i.NewWindow;
-
- myVSprite : gfx.VSpritePtr;
- myGInfo : gfx.GelsInfoPtr;
- win : i.WindowPtr;
- myRPort : gfx.RastPort;
-
-
- (* ---------------------------------- *)
-
- (* Basic VSprite display subroutine *)
-
- PROCEDURE DrawGList ( win : i.WindowPtr; myRPort : gfx.RastPortPtr );
- BEGIN (* DrawGList *)
- gfx.SortGList (myRPort);
- gfx.DrawGList (myRPort, i.ViewPortAddress (win));
- i.RethinkDisplay ()
- END DrawGList;
-
-
- PROCEDURE* Cleanup (VAR rc : LONGINT);
-
- BEGIN (* Cleanup *)
- IF myVSprite # NIL THEN
- gfx.RemVSprite (myVSprite);
- at.FreeVSprite (myVSprite);
- myVSprite := NIL
- END;
- IF myGInfo # NIL THEN
- DrawGList (win, SYS.ADR (myRPort));
- at.CleanupGelSys (myGInfo, SYS.ADR (myRPort))
- END;
- IF win # NIL THEN
- i.CloseWindow (win);
- win := NIL
- END;
- IF returnCode <= d.fail THEN
- rc := returnCode
- END
- END Cleanup;
-
- (*------------------------------------*)
- PROCEDURE Init ();
-
- BEGIN (* Init *)
- Kernel.SetCleanup (Cleanup);
-
- Kernel.Allocate (vspriteData1, SIZE (VSpriteDataArray), {e.chip});
- ASSERT (vspriteData1 # NIL);
- SYS.MOVE
- (SYS.ADR (vspriteDataStr1), vspriteData1, SIZE (VSpriteDataArray));
- Kernel.Allocate (vspriteData2, SIZE (VSpriteDataArray), {e.chip});
- ASSERT (vspriteData2 # NIL);
- SYS.MOVE
- (SYS.ADR (vspriteDataStr2), vspriteData2, SIZE (VSpriteDataArray));
-
- mySpriteColors [0] := 00000H; mySpriteAltColors [0] := 0000FH;
- mySpriteColors [1] := 000F0H; mySpriteAltColors [1] := 00F00H;
- mySpriteColors [2] := 00F00H; mySpriteAltColors [2] := 00FF0H;
-
- (* information for the new VSprite *)
- myNewVSprite.image := vspriteData1;
- myNewVSprite.colorSet := SYS.ADR (mySpriteColors);
- myNewVSprite.wordWidth := 1;
- myNewVSprite.lineHeight := gelSize;
- myNewVSprite.imageDepth := 2;
- myNewVSprite.x := 160; myNewVSprite.y := 100;
- myNewVSprite.flags := {gfx.vSprite};
- myNewVSprite.hitMask := {gfx.borderHit};
-
- myNewWindow.leftEdge := 80; myNewWindow.topEdge := 20;
- myNewWindow.width := 400; myNewWindow.height := 150;
- myNewWindow.detailPen := -1; myNewWindow.blockPen := -1;
- myNewWindow.idcmpFlags := {i.closeWindow, i.intuiTicks};
- myNewWindow.flags :=
- {i.activate, i.windowClose, i.windowDepth, i.rmbTrap, i.windowDrag};
- myNewWindow.title := SYS.ADR (VersionStr);
- myNewWindow.type := {i.wbenchScreen};
- END Init;
-
-
- (* Collision routine for vsprite hitting border. Note that when the *)
- (* collision is VSprite to VSprite (or Bob to Bob, Bob to AnimOb, etc), *)
- (* then the paramters are both pointers to a VSprite. *)
-
- PROCEDURE* BorderCheck ( borderflags : s.SET32; hitVSprite : gfx.VSpritePtr );
-
- <*$ < StackChk- DeallocPars- SaveRegs+ *>
- BEGIN (* BorderCheck *)
- Kernel.GetDataSegment;
- IF 3 IN borderflags THEN
- hitVSprite.sprColors := SYS.ADR (mySpriteAltColors);
- hitVSprite.vUserExt := -80;
- END;
- IF 2 IN borderflags THEN
- hitVSprite.sprColors := SYS.ADR (mySpriteColors);
- hitVSprite.vUserExt := 40;
- END;
- END BorderCheck;
- <*$ > *>
-
-
- (* Process window and dynamically change vsprite. Get messages. Go away *)
- (* on i.closeWindow. Update and redisplay vsprite on i.IntuiTicks. Wait *)
- (* for more messages. *)
-
- PROCEDURE ProcessWindow
- ( win : i.WindowPtr;
- myRPort : gfx.RastPortPtr;
- myVSprite : gfx.VSpritePtr );
-
- VAR msg : i.IntuiMessagePtr; sigs : s.SET32;
-
- BEGIN (* ProcessWindow *)
- LOOP
- sigs := e.Wait ({win.userPort.sigBit});
- LOOP
- msg := SYS.VAL (i.IntuiMessagePtr, e.GetMsg (win.userPort));
- IF msg = NIL THEN EXIT END;
- (* Only i.closeWindow and i.intuiTicks are active *)
- IF msg.class = {i.closeWindow} THEN
- e.ReplyMsg (msg);
- RETURN
- END;
- (* Must be an i.intuiTicks: change x and y values on the fly. Note
- ** offset by window left and top edge--sprite relative to the
- ** screen, not window. Divide the mouseY in half to adjust for lores
- ** movement increments on a hires screen.
- *)
- myVSprite.x := win.leftEdge + msg.mouseX + myVSprite.vUserExt;
- myVSprite.y := win.topEdge + (msg.mouseY DIV 2) + 1;
- e.ReplyMsg (msg)
- END; (* LOOP *)
- (* Got a message, change image data on the fly *)
- IF myVSprite.imageData = vspriteData1 THEN
- myVSprite.imageData := vspriteData2
- ELSE
- myVSprite.imageData := vspriteData1
- END;
- gfx.SortGList (myRPort);
- gfx.DoCollision (myRPort);
- DrawGList (win, myRPort)
- END; (* LOOP *)
- END ProcessWindow;
-
-
- (* Working with the VSprite. Setup the GEL system and get a new *)
- (* VSprite (MakeVSprite()). Add VSprite to the system and display. *)
- (* Use the vsprite. When done, remove VSprite and update the display *)
- (* without the VSprite. Cleanup everything. *)
-
- PROCEDURE DoVSprite ( win : i.WindowPtr; myRPort : gfx.RastPortPtr );
-
- BEGIN (* DoVSprite *)
- myGInfo := at.SetupGelSys (myRPort, -4);
- IF myGInfo = NIL THEN
- returnCode := d.warn
- ELSE
- myVSprite := at.MakeVSprite (myNewVSprite);
- IF myVSprite = NIL THEN
- returnCode := d.warn
- ELSE
- myVSprite.vUserExt := 40;
- gfx.AddVSprite (myVSprite, myRPort);
- DrawGList (win, myRPort);
- gfx.SetCollision
- ( gfx.borderHit, SYS.VAL (e.PROC, BorderCheck), myRPort.gelsInfo );
- ProcessWindow (win, myRPort, myVSprite);
- END;
- END;
- END DoVSprite;
-
-
- (* Example VSprite program. First open up the libraries and a window. *)
-
- PROCEDURE Main ();
-
- BEGIN (* Main *)
- returnCode := d.ok;
- ASSERT (gfx.base.libNode.version > 36, d.fail);
- ASSERT (i.base.libNode.version > 36, d.fail);
- win := i.OpenWindow (myNewWindow);
- ASSERT (win # NIL, d.warn);
- gfx.InitRastPort (myRPort);
- myRPort := win.wScreen.rastPort; (* Copy the structure *)
- DoVSprite (win, SYS.ADR (myRPort))
- END Main;
-
- BEGIN (* VSprite *)
- Errors.Init;
- Init ();
- Main ();
- END VSprite.
-