home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 10
/
Fresh_Fish_10_2352.bin
/
new
/
dev
/
obero
/
oberon-a
/
examples
/
libraries
/
graphics
/
vsprite.mod
< prev
next >
Wrap
Text File
|
1995-07-02
|
8KB
|
266 lines
(*************************************************************************
$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.