(*----------------------------------------------------------------------------*)
(*                  W H E R E   D R A G O N ' S    R O A M                    *)
(* -------------------------------------------------------------------------- *)
(*									      *)
(*  HeroMaskBM	   :							      *)
(*  HeroBM    	   : WDR.Hero.raw					      *)
(*  LandBM   	   : WDR.Land.raw 					      *)
(*  CreatureBM     : WDR.Creatures.raw					      *)
(*  CreatureMaskBM : 							      *)
(*  ItemBM	   : Items.pic						      *)
(*  ItemMaskBM     :							      *)
(*  DarkSide  	   : RastPort with 2nd BitMap for Double Buffered display     *)
(*  sp		   : Screen pointer                                           *)
(*  World.Land     : Number of the block of land                              *)
(*  World.Creature : Number of the specific creature w/ characteristics       *)
(*  World.Items    : Number of the specific item w/ characteristics           *)
(*  									      *)
(*--------------------------------+-------------------------------------------*)
(*                                |                                           *)
(*   [ My answer to Leo Swabb ]   | #   #       ###         ###               *)
(*                                | #   #       #  #        #  #              *)
(*               .__   o   _/     | # # #       #  #        ###               *)
(*                |    |\_/       | ## ## here  ### ragons  #  # oam          *)
(*                |====|          | was orginally started out on an Apple //e *)
(*       -=  ### /|   /|---       | in Assembly  Language  by  me  in 1983. I *)
(*          ####/ |  / |   \      | rewrote it on the Amiga in 1988 using The *)
(*     --= ####/##| / | \   |     | Director  (a slideshow  pseudo-language). *)
(*         ###O---@/  |  o  |     | It was rewriten in                        *)
(*   ---== #######    |     |     | Modula-2 Jan 1989.    Rui Pereira         *)
(*          #####      \   /      |                       369 Enfield Avenue  *)
(* ----===   ###        ---       |                       Vanier, Ontario     *)
(*                                | Last revision:        Canada, K1L 7L2     *)
(*          T R I A T H L O N     |  89 07 22             (613) 749-1378      *)
(*                                |                                           *)
(*--------------------------------+-------------------------------------------*)

                               MODULE WDR;


FROM Views     		IMPORT 	LoadRGB4, Lace, ViewModesSet;
FROM InOut		IMPORT  WriteCard, WriteHex, WriteString, WriteLn;
FROM SYSTEM 		IMPORT 	LONG, BYTE, ADR, ADDRESS, TSIZE, WORD, SHORT;
FROM RandomNumbers 	IMPORT 	Random, Seed;
FROM AmigaDOS 		IMPORT 	FileHandle, Close, Open, ModeOldFile, Seek,
			       	Read, Write, ModeNewFile;
FROM Intuition		IMPORT 	CloseScreen, DisplayBeep, ShowTitle, NewScreen,
				ScreenPtr, NewWindow, WindowPtr, WindowToFront,
				WindowFlags, IDCMPFlags, Window, SelectUp,
				IDCMPFlagsSet, WindowFlagsSet, SelectDown,
				OpenWindow, ReportMouse, CloseWindow, MenuUp,
				OpenScreen, ScreenFlagsSet, MenuDown,
				ScreenFlags, ScreenToFront, CurrentTime,
				IntuiMessagePtr, BeginRefresh,MakeScreen,
				RethinkDisplay, MoveScreen, OpenWorkBench;
FROM InputEvents	IMPORT	IEQualifierSet;
FROM Blit		IMPORT  MinTermFlagsSet, OwnBlitter, DisownBlitter, 
				BltBitMap, BltBitMapRastPort,
				BltClear, BltClearFlagsSet,  
				BltMaskBitMapRastPort;
FROM LongInOut		IMPORT	WriteLongHex;
FROM Graphics		IMPORT	BitMapPtr, InitBitMap, BitMap,PlanePtr;
FROM Rasters		IMPORT  InitRastPort, RastPort, AllocRaster,
				FreeRaster, SetRast,RastPortFlags, RastPortPtr,
				RastPortFlagsSet, DrawModeSet;
FROM Storage		IMPORT  ALLOCATE, DEALLOCATE;
FROM Ports		IMPORT  GetMsg, ReplyMsg;
FROM Text		IMPORT	Text;
FROM Drawing		IMPORT	SetAPen, SetDrMd, RectFill;


CONST	ESC = 33C;

	empty=3;
	Sword=4;
	Axe=5;
	Mace=6;
	Shield=7;
	Torch=8;
	OpenChest=2;
	ClosedChest=1;
	EmptyChest=3;
	nada=6;
	
	north=0;
	east=1;
	south=2;
	west=3;
	
TYPE 
	CONDITIONS   = (OK, dead, poisoned, sick, old, mad, defending,
			 attacking, hungry, thirsty, tired);
	SetOfPoison  = (none, Poisoned, Explode, MakeOld, MakeSick);
	Iniqualities = (equal, less, greater);

	CREATURES    = RECORD
			type		: CARDINAL;
			Occupation	: BYTE;
			Direction	: BYTE;
			Friendliness	: BYTE;
			x,y		: CARDINAL;
			Endurance	: INTEGER;
			Strengh		: BYTE;
			Condition	: CONDITIONS;
			Gold		: CARDINAL;
			LeftHand,
			RightHand	: CARDINAL;
	               END;

	ITEMS 	     = RECORD
			type	: CARDINAL;
			x,y	: CARDINAL;
			Strengh	: BYTE;
			Poison	: SetOfPoison;
			Weight	: CARDINAL;
		       END;

	aShot	     = RECORD
			x,	y,
			xInc,	yInc,
			xMax,	yMax,
			xFrom,	yFrom,
			Width,	Height	: CARDINAL;
			bm		: BitMapPtr;
		       END;

	ColorMap     = ARRAY [0..31] OF CARDINAL;

	MyWorld	= RECORD
			name	: ARRAY [0..31] OF CHAR;
			mx,my	: CARDINAL;
			Xoff,Yoff: CARDINAL;
			Land	: POINTER TO ARRAY [0..0] OF BYTE;
			Creature: POINTER TO ARRAY [0..0] OF BYTE;
			Items	: POINTER TO ARRAY [0..0] OF BYTE;
		  END;

VAR
	LastX, LastY, NextX, NextY,
	gold,
	mx, my, (* Maximum Coordinates *)
	wait,
	aNum,   (* General purpose *)
	ypos, 
	xpos,
	lhnum, 
	NumOfCreatures, 
	NumOfItems,
	rhnum,
	x,y,
	code,
	HeroX,
	HeroY		: CARDINAL;
	class		: IDCMPFlagsSet;
	MsgPtr		: IntuiMessagePtr;
	IEQualifier	: IEQualifierSet;
	key		: CHAR;
	byte,
	temp		: BYTE;
	xDir, 
	yDir 		: ARRAY [north..west] OF INTEGER;
	Creature 	: ARRAY [0..63] OF CREATURES;
	Item 		: ARRAY [0..63] OF ITEMS;
	dir,
	idir		: CARDINAL;
	Flag,
	fatalerror,
	trace		: BOOLEAN;
	LeftHand,
	RightHand 	: CARDINAL;
	anItem 		: CARDINAL;
	File 		: FileHandle;
	CreatureBM,
	LandBM,	
	HeroBM,
	HeroMaskBM,
	ItemBM,
	ItemMaskBM,
	CreatureMaskBM	: BitMap;
	World		: MyWorld;
	DarkSide	: RastPortPtr;
	LandStoreRP	: RastPort;
	sp		: ScreenPtr;
	sperror,
	wperror		: BOOLEAN;
	wp		: WindowPtr;
  	Color		: ColorMap;
	WB		: ScreenPtr;


PROCEDURE Hour ():CARDINAL;

VAR a,b:LONGCARD;

BEGIN
	CurrentTime (ADR(a),ADR(b));
	RETURN (SHORT(a)DIV 300) MOD 24;
END Hour;


PROCEDURE Minute():CARDINAL;

VAR a,b:LONGCARD;

BEGIN
	CurrentTime (ADR(a),ADR(b));
	RETURN (SHORT(a) DIV 5) MOD 60;
END Minute;


PROCEDURE Error (a:ARRAY OF CHAR);

BEGIN
	WriteString ('** Error ');
	WriteString (a);
	WriteLn;
END Error;


PROCEDURE MakeDarker (VAR col:CARDINAL;Dark:BOOLEAN);

VAR colmap : ARRAY [1..3] OF CARDINAL;
	i : CARDINAL;

BEGIN
	colmap[1]:=(col DIV 0100H MOD 010H);
	colmap[2]:=(col DIV 010H MOD 010H);
	colmap[3]:=(col MOD 010H);
	FOR i:=1 TO 3 DO
		IF Dark THEN
			IF colmap[i]>0 THEN
				DEC (colmap[i]);
			END;
		ELSE
			IF colmap[i]<15 THEN
				INC (colmap[i]);
			END;
		END;
	END;
	col:=colmap[1]*0100H+colmap[2]*010H+colmap[3];
END MakeDarker;


PROCEDURE FadeOut;

VAR i,ii: CARDINAL;

BEGIN
	FOR i:=0 TO 15 DO
		FOR ii:=0 TO 31 DO
			MakeDarker (Color[ii],TRUE);
		END;
		LoadRGB4 (sp^.ViewPort,ADR(Color),32);
		FOR ii:=0 TO 20000 DO
		END;
	END;
	IF trace THEN
		WriteString ('FadeOut');
		WriteLn;
	END;
END FadeOut;


PROCEDURE InitWindow (VAR w : NewWindow; sp : ScreenPtr;x,y:CARDINAL);

BEGIN
    WITH w DO
      LeftEdge := 0; TopEdge := 0; Width :=x; Height :=y;
      DetailPen := BYTE (0);
      BlockPen := BYTE (0);
      Title := ADR('WDR');
      Flags := WindowFlagsSet { Activate, Borderless, RMBTrap, BackDrop};
      IDCMPFlags := IDCMPFlagsSet {ReqClear, MouseButtons,VanillaKey};
      Type := ScreenFlagsSet { SF0, SF1, SF2, SF3};
      CheckMark := NIL;
      FirstGadget := NIL;
      Screen := sp;
      BitMap := NIL;
      MinWidth := x; MinHeight := y;
      MaxWidth := x; MaxHeight := y;
    END
END InitWindow;


PROCEDURE InitScreen (VAR s : NewScreen;x,y:CARDINAL);

BEGIN
    WITH s DO
      LeftEdge := 0; TopEdge :=0; 
      Width := x; Height := y;
      Depth := 5;
      DetailPen := BYTE (0); BlockPen := BYTE (1);
      ViewModes := ViewModesSet { Lace } ;
      Type := ScreenFlagsSet {SF0,SF1,SF2,SF3};
      Font := NIL;
      DefaultTitle := NIL;
      Gadgets := NIL;
      CustomBitMap := NIL
  END;
END InitScreen;


PROCEDURE SetColorsToIntro(s:ScreenPtr);

BEGIN
	Color[0]:=0;
	Color[1]:=0FFFH;
	Color[2]:=0DDDH;
	Color[3]:=0AAAH;
	Color[4]:=0888H;
	Color[5]:=0554H;
	Color[6]:=0333H;
	Color[7]:=0E00H;
	Color[8]:=0E40H;
	Color[9]:=0F71H;
	Color[10]:=0FD1H;
	Color[11]:=0F0H;
	Color[12]:=0C0H;
	Color[13]:=0A0H;
	Color[14]:=070H;
	Color[15]:=0520H;
	Color[16]:=0730H;
	Color[17]:=0A50H;
	Color[18]:=0D7H;
	Color[19]:=0CDH;
	Color[20]:=09EH;
	Color[21]:=06EH;
	Color[22]:=03EH;
	Color[23]:=02AH;
	Color[24]:=065FH;
	Color[25]:=043BH;
	Color[26]:=0328H;
	Color[27]:=0F85H;
	Color[28]:=0444H;
	Color[29]:=0300H;
	Color[30]:=0;
	Color[31]:=0FA1H;
	LoadRGB4 (s^.ViewPort,ADR(Color),32);
END SetColorsToIntro;


PROCEDURE SetColorsToNorm(s:ScreenPtr);

BEGIN
	Color[0]:=0;
	Color[1]:=0FC0H;
	Color[2]:=060H;
	Color[3]:=080H;
	Color[4]:=0A0H;
	Color[5]:=0C0H;
	Color[6]:=0C60H;
	Color[7]:=0C50H;
	Color[8]:=0C40H;
	Color[9]:=07FH;
	Color[10]:=05FH;
	Color[11]:=04EH;
	Color[12]:=02EH;
	Color[13]:=0EH;
	Color[14]:=0FA7H;
	Color[15]:=0FF0H;
	Color[16]:=0620H;
	Color[17]:=0820H;
	Color[18]:=0930H;
	Color[19]:=0B40H;
	Color[20]:=0333H;
	Color[21]:=0444H;
	Color[22]:=0555H;
	Color[23]:=0666H;
	Color[24]:=0777H;
	Color[25]:=0888H;
	Color[26]:=0999H;
	Color[27]:=0AAAH;
	Color[28]:=0CCCH;
	Color[29]:=0DDDH;
	Color[30]:=0FFFH;
	Color[31]:=0;
	LoadRGB4 (s^.ViewPort,ADR(Color),32);
END SetColorsToNorm;


PROCEDURE SetColorsToBlack;

VAR i : CARDINAL;

BEGIN
	FOR i:=0 TO 31 DO
		Color[i]:=0;
	END;
	LoadRGB4 (sp^.ViewPort,ADR(Color),32);
END SetColorsToBlack;


PROCEDURE SetUpBuffer(x,y:CARDINAL);

VAR   	   i : CARDINAL;
    MyScreen : NewScreen;
    MyWindow : NewWindow;

BEGIN
	InitScreen (MyScreen,x,y);
	sp:=OpenScreen(MyScreen);
	IF sp=NIL THEN
		Error("Couldn't open screen");
		sperror:=TRUE;
		fatalerror:=TRUE;
	ELSE
		sperror:=FALSE;
	END;
	SetColorsToBlack;
	InitWindow (MyWindow,sp,x,y);
	wp:=OpenWindow (MyWindow);
	IF wp=NIL THEN
		wperror:=TRUE;
		fatalerror:=TRUE;
		Error ("Couldn't open window");
	ELSE
		wperror:=FALSE;
	END;
END SetUpBuffer;


PROCEDURE InitVariables ;

BEGIN
     HeroX := 5;
     HeroY := 4;
     fatalerror:=FALSE;
     xpos:=5;ypos:=4;
     RightHand:=nada;
     LeftHand:=empty;
     lhnum:=0;
     rhnum:=0;
     dir:=south;
     IF trace THEN
	WriteString ('InitVariables.');
	WriteLn;
     END;
END InitVariables;


PROCEDURE TurnAround(adir:CARDINAL):CARDINAL;

BEGIN
	RETURN (adir+2) MOD 4;
END TurnAround;


PROCEDURE Blit (source:BitMap;fromx,fromy,tox,toy,sizex,sizey:CARDINAL);
BEGIN
	BltBitMapRastPort (source, fromx, fromy, DarkSide^, tox, toy,
			sizex, sizey, MinTermFlagsSet {7,6});
END Blit;



PROCEDURE CreatureNum (x,y:CARDINAL):CARDINAL;

VAR Ptr : ADDRESS;

BEGIN
	RETURN CARDINAL(World.Creature^[x+mx*y]);
END CreatureNum;


PROCEDURE ItemNum (x,y:CARDINAL):CARDINAL;

BEGIN
	RETURN CARDINAL(World.Items^[x+mx*y]);
END ItemNum;


PROCEDURE PutItemNum (x,y,a:CARDINAL);

BEGIN
	World.Items^[x+mx*y]:=BYTE(a);
END PutItemNum;

	
PROCEDURE FlipScrn;

VAR temp:PlanePtr;
     i:CARDINAL;

BEGIN
	FOR i:=0 TO 4 DO
		temp:=sp^.BitMap.Planes[i];
		sp^.BitMap.Planes[i]:=DarkSide^.BitMap^.Planes[i];
		DarkSide^.BitMap^.Planes[i]:=temp;
	END;
	MakeScreen(sp^);
	RethinkDisplay;
END FlipScrn;


PROCEDURE PutCreatureNum (x,y,a:CARDINAL);

VAR Ptr:ADDRESS;

BEGIN
	World.Creature^[x+mx*y]:=BYTE(a+1);
END PutCreatureNum;


PROCEDURE Land (x,y:CARDINAL):CARDINAL;

BEGIN
	RETURN CARDINAL(World.Land^[x+mx*y]);
END Land;


PROCEDURE BlitMask (scr:BitMap;fromx,fromy,tox,toy,sx,sy:CARDINAL;mask:ADDRESS);

BEGIN
	BltMaskBitMapRastPort (scr,fromx,fromy,DarkSide^,tox,toy,sx,sy,
		MinTermFlagsSet{7,6,5},mask);
END BlitMask;

	
PROCEDURE DrawBlock(aRP:RastPort;ax,ay,x,y:CARDINAL);

VAR a:CARDINAL;
 
BEGIN
	x:=x*36;
	y:=y*54;
	IF (ax<0) OR (ay<0) OR (ax>mx-1) OR (ay>my-1) THEN
		BltBitMapRastPort (LandBM,180,108,aRP,x,y,36,54,
			MinTermFlagsSet{7,6});
	ELSE
      		BltBitMapRastPort (LandBM,(Land(ax,ay) MOD 16) * 36,
		  ((Land(ax,ay) DIV 16) MOD 4) * 54,aRP, x, y, 36, 54,
		  MinTermFlagsSet{7,6});
		a:=ItemNum(ax,ay);
    		IF a > 0 THEN
		  IF Item[a-1].type<9 THEN
   			BltMaskBitMapRastPort (ItemBM,
			  (Item[a-1].type-1)*36,0,
			  aRP,x,y,36,54,
			  MinTermFlagsSet{7,6,5},ItemMaskBM.Planes[0]);
		  END;
    		END;
		a:=CreatureNum(ax,ay);
    		IF a > 0 THEN
    	       		BltMaskBitMapRastPort (CreatureBM,
			  Creature[a-1].type*36,
			  CARDINAL(Creature[a-1].Direction)*54,aRP,x,y,36,54,
			  MinTermFlagsSet{7,6,5},CreatureMaskBM.Planes[0]);
    		END;
	END;
END DrawBlock;


PROCEDURE Exit ;

VAR i,a:CARDINAL;

BEGIN
	Blit (sp^.BitMap,0,0,0,0,368,432);
	DrawBlock (DarkSide^,xpos,ypos,HeroX,HeroY);
	BlitMask (HeroBM,216,0,HeroX*36,HeroY*54,36,54,HeroMaskBM.Planes[0]);
	FlipScrn;
	FOR i:=0 TO 63000 DO
		a:=i;
		a:=a*i;
		a:=i*i*a;
	END;
	IF wp # NIL THEN
		CloseWindow (wp^);
	END;
	IF  sp # NIL THEN
		CloseScreen (sp^);
	END;
	FOR i:=0 TO 4 DO
		IF HeroBM.Planes[i] # NIL THEN
			FreeRaster (HeroBM.Planes[i],320,216);
		END;
		IF DarkSide^.BitMap^.Planes[i] # NIL THEN
			FreeRaster (DarkSide^.BitMap^.Planes[i],368,432);
		END;
		IF LandBM.Planes[i] # NIL THEN
			FreeRaster (LandBM.Planes[i],576,216);
		END;
		IF CreatureBM.Planes[i] # NIL THEN
			FreeRaster (CreatureBM.Planes[i],504,216);
		END;
		IF LandStoreRP.BitMap^.Planes[i] # NIL THEN
			FreeRaster (LandStoreRP.BitMap^.Planes[i],396,54);
		END;
		IF ItemBM.Planes[i] # NIL THEN
			FreeRaster (ItemBM.Planes[i],368,54);
		END;
	END;
	IF ItemMaskBM.Planes[0] # NIL THEN
		FreeRaster (ItemMaskBM.Planes[0],368,54);
	END;
	DEALLOCATE(LandStoreRP.BitMap,TSIZE(BitMap));
	IF CreatureMaskBM.Planes[0] # NIL THEN
		FreeRaster(CreatureMaskBM.Planes[0],504,216);
	END;
	IF HeroMaskBM.Planes[0] # NIL THEN
		FreeRaster (HeroMaskBM.Planes[0],36,54);
	END;
	IF DarkSide^.BitMap # NIL THEN
		DEALLOCATE (DarkSide^.BitMap,TSIZE(BitMap));
	END;
	IF DarkSide # NIL THEN
		DEALLOCATE (DarkSide,TSIZE(RastPort));
	END;
	IF World.Land # NIL THEN
		DEALLOCATE (World.Land,LONG(mx)*LONG(my));
	END;
	IF World.Creature # NIL THEN
		DEALLOCATE (World.Creature,LONG(mx)*LONG(my));
	END;
	IF World.Items # NIL THEN
		DEALLOCATE (World.Items,LONG(mx)*LONG(my));
	END;
	HALT;
END Exit;


PROCEDURE DrawHero(adir:CARDINAL); 

BEGIN
	CASE adir OF
		north :
 			BltMaskBitMapRastPort ( HeroBM,
						(LeftHand-3)*36,adir*54,
						DarkSide^,
						HeroX*36,HeroY*54,
						18,54,
						MinTermFlagsSet{7,6,5},
						HeroMaskBM.Planes[0]);
 			BltMaskBitMapRastPort ( HeroBM,
						(RightHand-2)*36+18,adir*54,
						DarkSide^,
						HeroX*36+18,HeroY*54,
						18,54,
						MinTermFlagsSet{7,6,5},
						HeroMaskBM.Planes[0]);
|		east  :
 			BltMaskBitMapRastPort ( HeroBM,
						(LeftHand-3)*36,adir*54,
						DarkSide^,
						HeroX*36,HeroY*54,
						36,27,
						MinTermFlagsSet{7,6,5},
						HeroMaskBM.Planes[0]);
			BltMaskBitMapRastPort ( HeroBM,
						(RightHand-2)*36,adir*54+27,
						DarkSide^,
						HeroX*36,HeroY*54+27,
						36,27,
						MinTermFlagsSet{7,6,5},
						HeroMaskBM.Planes[0]);
|		south :
			BltMaskBitMapRastPort ( HeroBM,
						(LeftHand-3)*36+18,adir*54,
						DarkSide^,
						HeroX*36+18,HeroY*54,
						18,54,
						MinTermFlagsSet{7,6,5},
						HeroMaskBM.Planes[0]);
			BltMaskBitMapRastPort ( HeroBM,
						(RightHand-2)*36,adir*54,
						DarkSide^,
						HeroX*36,HeroY*54,
						18,54,
						MinTermFlagsSet{7,6,5},
						HeroMaskBM.Planes[0]);
|		west  :
			BltMaskBitMapRastPort ( HeroBM,
						(LeftHand-3)*36,adir*54+27,
						DarkSide^,
						HeroX*36,HeroY*54+27,
						36,27,
						MinTermFlagsSet{7,6,5},
						HeroMaskBM.Planes[0]);
			BltMaskBitMapRastPort ( HeroBM,
						(RightHand-2)*36,adir*54,
						DarkSide^,
						HeroX*36,HeroY*54,
						36,27,
						MinTermFlagsSet{7,6,5},
						HeroMaskBM.Planes[0]);
	END;
END DrawHero;


PROCEDURE MoveScrn(xd,yd:CARDINAL;idir:CARDINAL);

VAR max,i,ii,from,to: CARDINAL; 
    flag:BOOLEAN;
    item:CARDINAL;
BEGIN
     flag:=FALSE;
(*     OwnBlitter;*)
     IF idir=TurnAround(dir) THEN
         dir:=idir;
	 flag:=TRUE;
     END;
     IF dir=idir THEN
	IF flag THEN
		idir:=TurnAround(idir);
	ELSE
		idir:=dir;
	END;
	IF ItemNum(xd,yd) # 0 THEN
		item:=Item[ItemNum(xd,yd)-1].type;
	ELSE
		item:=9;
	END;
        IF ( Land(xd,yd) < 32)  AND (CreatureNum(xd,yd)=0) THEN
	   from:=0;
	   IF dir MOD 2 = 0 THEN
		max:=9;
	   ELSE
		max:=7;
	   END;
           FOR i:=0 TO max DO
	        CASE dir OF
	 	  south : DrawBlock(LandStoreRP,xpos-HeroX+i,ypos+HeroY,i,0);
|		  west  : DrawBlock(LandStoreRP,xpos-HeroX-1,ypos-HeroY+i,i,0);
|		  north : DrawBlock(LandStoreRP,xpos-HeroX+i,ypos-HeroY-1,i,0);
|		  east  : DrawBlock(LandStoreRP,xpos+HeroX,ypos-HeroY+i,i,0);
                END;
	   END;
	   DrawBlock (LandStoreRP,xpos,ypos,10,0);
	   FOR ii:=0 TO 3 DO
		IF dir MOD 2 =0 THEN
			IF ii MOD 2 =0 THEN
				to:=13;
			ELSE
				to:=14;
			END;
		ELSE
			to:=9;
		END;
           	CASE dir OF
		   north : Blit (sp^.BitMap,0,0,0,to,360,432-to);
			   Blit (LandStoreRP.BitMap^,360,0,HeroX*36,
			   HeroY*54+to,36,54);	|
		   south : Blit (sp^.BitMap,0,to,0,0,360,432-to);
			   Blit (LandStoreRP.BitMap^,360,0,HeroX*36,
			   HeroY*54-to,36,54);	|
		   east  : Blit (sp^.BitMap,9,0,0,0,360-to,432);
			   Blit (LandStoreRP.BitMap^,360,0,HeroX*36-to,
			   HeroY*54,36,54);	|
		   west  : Blit (sp^.BitMap,0,0,9,0,360-to,432);
			   Blit (LandStoreRP.BitMap^,360,0,HeroX*36+to,
			   HeroY*54,36,54);
	   	END;
		FOR i:=0 TO max DO
		   CASE dir OF
			south: Blit (LandStoreRP.BitMap^,i*36,from,
				i*36,432-to,36,to);

|			north: Blit (LandStoreRP.BitMap^,i*36,54-to-from,
				i*36,0,36,to);

|			west:  Blit (LandStoreRP.BitMap^,i*36+36-to-from,0,
				0,i*54,to,54);

|			east:  Blit (LandStoreRP.BitMap^,i*36+from,0,
				360-to,i*54,to,54);

		   END;
		END;
		BltBitMapRastPort (DarkSide^.BitMap^,HeroX*36,HeroY*54,
			LandStoreRP,360,0,36,54,MinTermFlagsSet{7,6});
		CASE idir OF
			north: 	CASE ii OF
					0 : BlitMask(HeroBM,224,64,
						HeroX*36+20,HeroY*54+25,7,12,
						HeroMaskBM.Planes[0]);
					    BlitMask(HeroBM,224,64,
						HeroX*36+9,HeroY*54+42,7,12,
						HeroMaskBM.Planes[0]);
	|				2 : BlitMask(HeroBM,224,64,
						HeroX*36+9,HeroY*54+25,7,12,
						HeroMaskBM.Planes[0]);
					    BlitMask(HeroBM,224,64,
						HeroX*36+20,HeroY*54+42,7,12,
						HeroMaskBM.Planes[0]);
				END;
|			south:  CASE ii OF
					0 : BlitMask(HeroBM,224,64,
						HeroX*36+9,HeroY*54+12,7,12,
						HeroMaskBM.Planes[0]);
					    BlitMask(HeroBM,224,64,
						HeroX*36+20,HeroY*54,7,12,
						HeroMaskBM.Planes[0]);
	|				2 : BlitMask(HeroBM,224,64,
						HeroX*36+20,HeroY*54+12,7,12,
						HeroMaskBM.Planes[0]);
					    BlitMask(HeroBM,224,64,
						HeroX*36+9,HeroY*54,7,12,
						HeroMaskBM.Planes[0]);
				END;
|			east :  CASE ii OF
					0 : BlitMask(HeroBM,224,64,
						HeroX*36+10,HeroY*54+29,7,12,
						HeroMaskBM.Planes[0]);
					    BlitMask(HeroBM,224,64,
						HeroX*36,HeroY*54+8,7,12,
						HeroMaskBM.Planes[0]);
	|				2 : BlitMask(HeroBM,224,64,
						HeroX*36+10,HeroY*54+8,7,12,
						HeroMaskBM.Planes[0]);
					    BlitMask(HeroBM,224,64,
						HeroX*36,HeroY*54+29,7,12,
						HeroMaskBM.Planes[0]);
				END;
|			west :  CASE ii OF
					0 : BlitMask(HeroBM,224,64,
						HeroX*36+19,HeroY*54+8,7,12,
						HeroMaskBM.Planes[0]);
					    BlitMask(HeroBM,224,64,
						HeroX*36+29,HeroY*54+29,7,12,
						HeroMaskBM.Planes[0]);
	|				2 : BlitMask(HeroBM,224,64,
						HeroX*36+29,HeroY*54+8,7,12,
						HeroMaskBM.Planes[0]);
					    BlitMask(HeroBM,224,64,
						HeroX*36+19,HeroY*54+29,7,12,
						HeroMaskBM.Planes[0]);
				END;
		END;
		DrawHero(idir);
		FlipScrn;
		from:=from+to
            END; 
            dir:=idir;
       	    xpos:=xd;
	    ypos:=yd;
	END;
     ELSE
        dir :=idir;
	Blit (sp^.BitMap,0,0,0,0,368,432);
        DrawBlock(DarkSide^,xpos,ypos,HeroX,HeroY);
	DrawHero(dir);
	FlipScrn;
     END;
   (*  DisownBlitter;*)
END MoveScrn;


PROCEDURE openNEW (a:ARRAY OF CHAR);

BEGIN
	File:=Open (ADR(a),ModeNewFile);
	IF File=NIL THEN
		WriteString ("Couldn't open ");
		WriteString (a);
		WriteLn;
		fatalerror:=TRUE;
	END;
END openNEW;


PROCEDURE openOLD (a:ARRAY OF CHAR);

BEGIN
	File:=Open (ADR(a),ModeOldFile);
	IF File=NIL THEN
		WriteString ("** ERROR -Couldn't open ");
		WriteString (a);
		WriteLn;
		fatalerror:=TRUE;
	END;
END openOLD;


PROCEDURE load (a:ARRAY OF CHAR;x,y:CARDINAL);

VAR i : CARDINAL;

BEGIN
	SetUpBuffer(x,y);
	openOLD (a);
	FOR i:=0 TO 4 DO
		IF trace THEN
			WriteString ('load ');
			WriteCard (x,1);
			WriteString(' x ');
			WriteCard (y,1);
			WriteString (' => ');
			WriteString (a);
			WriteLn;
		END;
		IF Read (File,sp^.RastPort.BitMap^.Planes[i],LONG(x DIV 8) * LONG(y)) # LONG(x DIV 8)*LONG(y) THEN
			Error ('Reading picture');
			fatalerror:=TRUE;
		END;
	END;
(*	IF Read (File,ADR(Color),64D)=-1D THEN
		Error ('Reading colors');
	END;*)
	Close(File);
	SetColorsToIntro(sp);
END load;


PROCEDURE loadBM (VAR bm:BitMap;a:ARRAY OF CHAR;x,y,d,off:CARDINAL); 

VAR i : CARDINAL;
   add: ADDRESS;
BEGIN
	InitBitMap (bm,d,x,y);
	IF off # 0 THEN
		ALLOCATE(add,LONG(off));
	END;
	openOLD (a);
        IF trace THEN
		WriteString ('InitBitMap ');
		WriteCard (x,1);
		WriteString (' x ');
		WriteCard (y,1);
		WriteString (' => ');
		WriteString (a);
		WriteLn;
	END;
	FOR i:=0 TO d-1 DO
	  bm.Planes[i]:=AllocRaster(x,y);
	  IF bm.Planes[i] # NIL THEN
	  	IF Read (File,bm.Planes[i],LONG(x DIV 8)* LONG(y)) # LONG(x DIV 8)*LONG(y) THEN
			Error ('Reading BitMap');
			fatalerror:=TRUE;
	  	END;
		IF (off # 0) AND (i<d-1) THEN
			IF Read(File,add,LONG(off)) # LONG(off) THEN
				Error ('seeking BitMap');
			END;
		END;	
	  ELSE
		fatalerror:=TRUE;
		Error ('Not enough memory for BitMap');
	  END;
	END;
	Close (File);
	DEALLOCATE(add,LONG(off));
END loadBM;


PROCEDURE ReadCard (VAR b:CARDINAL);

BEGIN
	IF Read (File,ADR(b),2D)=-1D THEN
		Error ('Reading a cardinal');
	END;
END ReadCard;


PROCEDURE GetWorld;

VAR x,y,i,ii,plane : CARDINAL;

BEGIN
	openOLD ("WDR:World.data");
	ReadCard (xpos);
	ReadCard (ypos);
	INC(ypos);
	ReadCard (mx);
	ReadCard (my);
	ALLOCATE (World.Land,LONG(mx)*LONG(my));
	ALLOCATE (World.Creature,LONG(mx)*LONG(my));
	ALLOCATE (World.Items,LONG(mx)*LONG(my));
	IF World.Land # NIL THEN
		IF Read (File,World.Land,LONG(mx)*LONG(my)) # LONG(mx*my) THEN
			Error('Unable to read World');
			fatalerror:=TRUE;
		END;
	END;

	FOR i:=0 TO mx*my-1 DO
		World.Items^[i]:=BYTE(0);
		World.Creature^[i]:=BYTE(0);
	END;
			
	NumOfCreatures:=0;
	NumOfItems:=0;
	Close (File);
	FOR i:= 0 TO 63 DO
		IF CARDINAL(Random(10))<5 THEN
			IF World.Items # NIL THEN
				Item[NumOfItems].type :=CARDINAL(Random(7))+1;
				REPEAT
					x:=Random(64);
					y:=Random(64);
				UNTIL Land(x,y)<32;
				Item[NumOfItems].x:=x;
				Item[NumOfItems].y:=y;
				Item[NumOfItems].Strengh:=BYTE(60);
				Item[NumOfItems].Weight:=4000;
				PutItemNum(x,y,NumOfItems+1);
				INC(NumOfItems);
			END;
		ELSE
			IF World.Creature # NIL THEN
				Creature[NumOfCreatures].type:=CARDINAL(Random(11));
				Creature[NumOfCreatures].Direction:=
					BYTE(Random(4));
				Creature[NumOfCreatures].Endurance:=50;
				Creature[NumOfCreatures].Strengh:=BYTE(40);
				Creature[NumOfCreatures].Condition:=OK;
				REPEAT
					x:=Random(64);
					y:=Random(64);
				UNTIL Land(x,y)<32;
				Creature[NumOfCreatures].x:=x;
				Creature[NumOfCreatures].y:=y;
				PutCreatureNum(x,y,NumOfCreatures);
				INC(NumOfCreatures);
			END;
		END;
	END;

(*
   read (NumOfCreatures,1);
   FOR i:=0 TO CARDINAL(NumOfCreatures)-1 DO
	WITH Creature[i] DO
		read (type,1);
		read (Occupation,1);
		read (Direction,1);
		read (Friendliness,1);
		ReadCard (x);
		ReadCard (y);
		read (Endurance,1);
		read (Strengh,1);
	END;
   END;
   read (NumOfItems,1);
   FOR i:=0 TO CARDINAL(NumOfItems)-1 DO
	WITH Item[i] DO
		read (type,1);
		ReadCard (x);
		ReadCard (y);
		read (Strengh,1);
		read (byte,1);
		Poison:=VAL(SetOfPoison,byte);
		read (Weight,1);
	END;
   END;
   Close ( File);   *)
   (* directions *)
   yDir[north]:=-1;
   yDir[south]:=1;
   yDir[east]:=0;
   yDir[west]:=0;
   xDir[north]:=0;
   xDir[south]:=0;
   xDir[east]:=1;
   xDir[west]:=-1;

   (* put creatures on world *)
 (*  FOR i:=0 TO CARDINAL(NumOfCreatures)-1 DO
      	CreatureNum[Creature[i].x,Creature[i].y]:=BYTE(i+1);
   END;
   FOR i:=0 TO CARDINAL(NumOfItems)-1 DO
	ItemNum[Item[i].x,Item[i].y]:=BYTE(i+1);
   END;
 *)  IF trace THEN
	WriteString ('GetWorld');
	WriteLn;
   END;
END GetWorld;


PROCEDURE WriteBin(a:WORD);
VAR b: ARRAY[0..15] OF CHAR;
    i,c: CARDINAL;
BEGIN
	c:=CARDINAL(a);
	FOR i:=7 TO 0 BY -1 DO
		IF ODD(c) THEN
			b[i]:='1';
		ELSE
			b[i]:='0';
		END;
		c:=c DIV 2;
	END;
	WriteString(b);
END WriteBin;


PROCEDURE Mask (VAR a:BitMap;b:BitMap;x,y:CARDINAL);

VAR     i,d : CARDINAL;
  aPtr,bPtr : POINTER TO WORD;

BEGIN
	InitBitMap(a,1,x,y);
	a.Planes[0]:=AllocRaster(x,y);
	BltClear(a.Planes[0],LONG(x DIV 8)*LONG(y),BltClearFlagsSet{0});
	aPtr:=a.Planes[0];
	FOR i:=0 TO (x DIV 8)*y BY 2 DO
		FOR d:=0 TO 4 DO
			bPtr:=ADDRESS(LONG(b.Planes[d])+LONG(i));
			aPtr^:=BITSET(aPtr^)+BITSET(bPtr^);
		END;
		aPtr:=ADDRESS(LONG(aPtr)+2D);
	END;
END Mask;


PROCEDURE Init;

VAR i:CARDINAL;
   MyScreen:NewScreen;

BEGIN
   InitVariables;
   InitRastPort(LandStoreRP);
   ALLOCATE (LandStoreRP.BitMap,TSIZE(BitMap));
   InitBitMap(LandStoreRP.BitMap^,5,396,54);
   FOR i:=0 TO 4 DO
   	LandStoreRP.BitMap^.Planes[i]:=AllocRaster(396,54);
   END;
   ALLOCATE (DarkSide,TSIZE(RastPort));
   InitRastPort (DarkSide^);
   ALLOCATE (DarkSide^.BitMap,TSIZE(BitMap));
   InitBitMap (DarkSide^.BitMap^,5,368,432);
   FOR i:=0 TO 4 DO
	DarkSide^.BitMap^.Planes[i]:=AllocRaster(368,432);
   END;
   load ("WDR:WDR.Intro.raw",368,432);
   INCL(sp^.RastPort.Flags,DBuffer);
   IF NOT fatalerror THEN
     SetColorsToIntro(sp);
     loadBM (HeroBM ,"WDR:WDR.Hero.raw",320,216,5,0);
     IF NOT fatalerror THEN
        Mask (HeroMaskBM,HeroBM,320,216);
	IF NOT fatalerror THEN
	  loadBM (LandBM,"WDR:WDR.Land.raw",576,216,5,0);
	  IF NOT fatalerror THEN
	    loadBM(ItemBM,'WDR:Items.raw',368,54,5,6716);
	    Mask (ItemMaskBM,ItemBM,368,54);
	    IF NOT fatalerror THEN
	      loadBM(CreatureBM,'WDR:WDR.Creatures.raw',504,216,5,0);
	      Mask (CreatureMaskBM,CreatureBM,504,216);
	      IF NOT fatalerror THEN
		GetWorld;
 		IF NOT fatalerror THEN
		    WB:=OpenWorkBench();
		    FOR i:=5 TO 8 DO
			Color[i-5]:=WB^.ViewPort.ColorMap^.ColorTable^[i-5];
			Color[i]:=0;
		    END;
		    LoadRGB4(WB^.ViewPort,ADR(Color[5]),4);
		    FOR aNum:=0 TO 107 DO
			MoveScreen(sp^,0,4);
		    END;
		    SetColorsToBlack;
		END;
	      END;
	    END;
	  END;
        END;
     END;
   END;
END Init;


PROCEDURE read (VAR b:BYTE;c:CARDINAL);

BEGIN
	IF Read (File,ADR(b),LONG(c)) = -1D THEN
		Error ('Reading a byte');	
	END;
END read;


PROCEDURE ReadNum (VAR b:CARDINAL);

VAR error : BOOLEAN;

BEGIN
	error:=FALSE;
	key:='0';
	b:=0;
	WHILE NOT ((CARDINAL(key) = 10) OR error) DO
		b:=b*10;
		b:=b+CARDINAL(key)-48;
		IF Read (File,ADR(key),1D) # 1D THEN
			Error ('Reading a number');
			error:=TRUE;
		END;
		IF trace THEN
			WriteString ('ReadNum(byte) ');
			WriteCard (CARDINAL(key),1);
			WriteLn;
		END;
	END;
	IF trace THEN
		WriteString ('ReadNum ');
		WriteCard (b,1);
		WriteLn;
	END;
END ReadNum;


PROCEDURE write (a:CARDINAL);

BEGIN
	IF Write (File,ADR(a),2D)= -1D THEN
		Error ('Writing a cardinal');
	END;
END write;


PROCEDURE SaveWorld;

BEGIN
	openNEW ("WDR:World.data");
	write (xpos);
	write (ypos);
	write (mx);
	write (my);
	IF Write (File,World.Land,LONG(mx)*LONG(my))=-1D THEN
		Error ('Saving world');
	END;
	Close(File);
END SaveWorld;


PROCEDURE DrawScreen;

VAR xh,yh :CARDINAL;

BEGIN
   FOR xh:=0 TO 9 DO
      FOR yh:=0 TO 7 DO
         DrawBlock (DarkSide^,xpos+xh-HeroX,ypos+yh-HeroY,xh,yh);
      END;
   END;
   IF trace THEN
	WriteString ('DrawScreen');WriteLn;
   END;
END DrawScreen;


PROCEDURE Say (a:ARRAY OF CHAR);

BEGIN
	WriteString (a);WriteLn;
END Say;


PROCEDURE DrawBox (string:ADDRESS;x,y,col,row,ID:CARDINAL);

BEGIN
	Blit (HeroBM,262,7,x,y,5,5);
	Blit (HeroBM,267,7,x+5+(col+2)*8,y,5,5);
	Blit (HeroBM,262,11,x,y+(row+2)*8+5,5,5);
	Blit (HeroBM,267,11,x+5+(col+2)*8,y+5+(row+2)*8,5,5);
	FOR aNum:=0 TO col+1 DO
		Blit (HeroBM,252,21,x+5+aNum*8,y,8,5);
		Blit (HeroBM,252,25,x+5+aNum*8,y+5+(row+2)*8,8,5);
	END;
	FOR aNum:=0 TO row+1 DO
		Blit (HeroBM,279,30,x,aNum*8+5+y,5,8);
		Blit (HeroBM,283,30,x+5+(col+2)*8,aNum*8+5+y,5,8);
	END;

	aNum:=CARDINAL(DarkSide^.FgPen);
	SetAPen(DarkSide^,26);
	RectFill (DarkSide^,x+5,y+5,x+4+(col+2)*8,y+4+(row+2)*8);
	SetAPen(DarkSide^,aNum);
	FOR aNum:=0 TO row-1 DO 
		DarkSide^.cpx:=x+13;
		DarkSide^.cpy:=y+19+aNum*8;	
		Text(DarkSide^,string,col);
		string:=LONG(string)+LONG(col);
	END;
END DrawBox;


PROCEDURE len (a:ARRAY OF CHAR):CARDINAL;

VAR l:CARDINAL;
   string:POINTER TO ARRAY [0..79] OF CHAR;
BEGIN
	string:=ADR(a);
	l:=0;
	WHILE string^[l] # 0C DO
		INC(l);
	END;
	RETURN l;
END len;


PROCEDURE Print (string:ARRAY OF CHAR;x,y:CARDINAL);

BEGIN
	DarkSide^.cpx:=x;
	DarkSide^.cpy:=y;
	Text(DarkSide^,ADR(string),len(string));
END Print;


PROCEDURE PrintNum (a,x,y:CARDINAL);

VAR i:CARDINAL;
    b:ARRAY [0..3] OF CHAR;
BEGIN
	b:='  0';
	i:=2;
	WHILE (i>=0) AND (a#0) DO
		b[i]:=CHR((a MOD 10)+48);
		a:=a DIV 10;
		DEC(i);
	END;
	Print (b,x,y);
END PrintNum;


PROCEDURE InFront(what:CARDINAL):CARDINAL;
BEGIN
	CASE what OF
		0 : RETURN (ItemNum(INTEGER(xpos)+xDir[dir],INTEGER(ypos)+yDir[dir]));
|		1 : RETURN (CreatureNum(INTEGER(xpos)+xDir[dir],INTEGER(ypos)+yDir[dir]));
|		2 : RETURN (Land(INTEGER(xpos)+xDir[dir],INTEGER(ypos)+yDir[dir]));
	END;
END InFront;


PROCEDURE Attack(x,y,d:CARDINAL);
BEGIN
	IF InFront(1)>0 THEN
		DEC(Creature[InFront(1)-1].Endurance,17);
		IF Creature[InFront(1)-1].Endurance<0 THEN
			World.Creature^[Creature[InFront(1)-1].x+mx*
				Creature[InFront(1)-1].y]:=BYTE(0);
			Blit (sp^.BitMap,0,0,0,0,368,432);
			DrawBlock (DarkSide^,x,y,INTEGER(HeroX)+xDir[d],
				INTEGER(HeroY)+yDir[d]);
			BlitMask (HeroBM,216,0,(INTEGER(HeroX)+xDir[d])*36,
				(INTEGER(HeroY)+yDir[d])*54,36,54,HeroMaskBM.Planes[0]);
			FlipScrn;
		END;
	END;
END Attack;


PROCEDURE ProcessMouseButtons;

VAR b:POINTER TO BYTE;
NotDone:BOOLEAN;
BEGIN
	IF (code=SelectDown) OR (code=MenuDown) THEN
		IF (x<10) AND (y<10) THEN
			Exit;
		END;
		x:=x DIV 36;
		y:=y DIV 54;
		IF (x<=4) AND (y=4) THEN (*west*)
			IF (code=MenuDown) AND (InFront(1)>0) THEN
				Attack (xpos-1,ypos,west);	
			ELSE
				MoveScrn (xpos-1,ypos,west);
			END;
		ELSIF (x=5) AND (y<=3) THEN (*north*)
			IF (code=MenuDown) AND (InFront(1)>0) THEN
				Attack (xpos,ypos-1,north);	
			ELSE
				MoveScrn (xpos,ypos-1,north);
			END;
		ELSIF (x=5) AND (y>=5) THEN (*south*)
			IF (code=MenuDown) AND (InFront(1)>0) THEN
				Attack (xpos,ypos+1,south);	
			ELSE
				MoveScrn(xpos,ypos+1,south);
			END;
		ELSIF (x>=6) AND (y=4) THEN  (*east*)
			IF (code=MenuDown) AND (InFront(1)>0) THEN
				Attack (xpos+1,ypos,east);	
			ELSE
				MoveScrn(xpos+1,ypos,east);
			END;
		ELSIF (x=5) AND (y=4) THEN (*get*)
		   IF code=SelectDown THEN
	          	IF ItemNum(xpos,ypos)=0 THEN
             			IF InFront(0)>0 THEN
                			anItem:=Item[InFront(0)-1].type;
 	        			IF (anItem=OpenChest) OR
					  (anItem=ClosedChest) THEN
						Blit(sp^.BitMap,0,0,0,0,368,432);
                   				IF anItem=OpenChest THEN
						 gold:=gold+CARDINAL(Random (100));
						 WriteString('gold= ');
						 WriteCard(gold,1);
						 WriteLn;
						 Item[InFront(0)-1].type:=EmptyChest;
						ELSE
						 IF INTEGER(Random(3))=0 THEN
						  Item[InFront(0)-1].type:=OpenChest;
						 ELSE
						  Item[InFront(0)-1].type:=EmptyChest;
						 END;
						END;
						Blit(sp^.BitMap,0,0,0,0,368,432);
						DrawBlock (DarkSide^,INTEGER(xpos)+xDir[dir],INTEGER(ypos)+yDir[dir],
							INTEGER(HeroX)+xDir[dir],
				        		INTEGER(HeroY)+yDir[dir]);
					  	FlipScrn;
					END;
             			END;
          		ELSE
          		  IF Item[ItemNum(xpos,ypos)-1].type >3 THEN
             			anItem:=Item[ItemNum(xpos,ypos)-1].type;
             			CASE anItem OF
				Sword : LeftHand:=Sword;
           				aNum:=ItemNum(xpos,ypos);
                        		PutItemNum(xpos,ypos,lhnum);
                        		lhnum:=aNum;
|               		Axe   : LeftHand:=Axe;
           				aNum:=ItemNum(xpos,ypos);
                        		PutItemNum(xpos,ypos,lhnum);
                        		lhnum:=aNum;
|               		Mace  : LeftHand:=Mace;
                        		aNum:=ItemNum(xpos,ypos);
					PutItemNum(xpos,ypos,lhnum);
                        		lhnum:=aNum;
|               		Shield: RightHand:=Shield;
                        		aNum:=ItemNum(xpos,ypos);
		 			PutItemNum(xpos,ypos,rhnum);
                        		rhnum:=aNum;
|               		Torch : RightHand:=Torch;
                        		aNum:=ItemNum(xpos,ypos);
					PutItemNum(xpos,ypos,rhnum);
                        		rhnum:=aNum;
|				ELSE
				END;
				Blit (sp^.BitMap,0,0,0,0,368,432);
		        	DrawBlock (DarkSide^,xpos,ypos,HeroX,HeroY);
             			DrawHero(dir);
				FlipScrn;
			  END;
			END;
		   ELSE
			SetRast(DarkSide^,0);
(*			FOR aNum:=0 TO 79 DO
				BltBitMapRastPort(LandBM,0,0(*432,54*),DarkSide^,
				(aNum MOD 10)*36,(aNum DIV 10)*54,36,54,
				MinTermFlagsSet{7,6}); 
			END;
*)			BlitMask(ItemBM,288,0,140,20,80,54,ItemMaskBM.Planes[0]);
			SetAPen(DarkSide^,1);
			SetDrMd(DarkSide^,DrawModeSet{});
			DrawBox(ADR('Continue Game'),116,340,13,1,1);
			DrawBox(ADR('New Game'),151,108,4,2,1);
			DrawBox(ADR('LoadGame'),151,168,4,2,1);
			DrawBox(ADR('SaveGame'),151,228,4,2,1);
			DrawBox(ADR('Quit'),151,288,4,1,1);
			Print ('Endurance: 99',218,171);
			Print ('Strength : 99',218,180);
			Print ('Condition: Ok',218,189);
			Print ('Gold     :',218,198);
			PrintNum (gold,298,198);
			Print ('Xposition:',218,207);
			PrintNum (xpos,298,207);
			Print ('Yposition:',218,216);
			PrintNum(ypos,298,216);
			Print ('Time  : ',218,224);
			IF Hour()<10 THEN
				PrintNum (Hour(),282,224);
			ELSE
				PrintNum (Hour(),274,224);
			END;
			IF Minute()<10 THEN
				Print('0',306,224);
				PrintNum(Minute(),298,224);
			ELSE
				PrintNum (Minute(),298,224);
			END;
			Print (':',298,224);
			IF InFront(1)>0 THEN
				Print ('Creature:',218,232);
				Print (' Type:',218,240);
				PrintNum(Creature[InFront(1)-1].type,290,240);
				Print (' End.:',218,248);
		PrintNum(CARDINAL(Creature[InFront(1)-1].Endurance),290,248);
			END;
			WriteString('(x,y) = ');
			WriteCard(xpos,1);
			WriteString(', ');
			WriteCard(ypos,1);WriteLn;
			Blit (HeroBM,252,7,31,155,5,7);
			Blit (HeroBM,257,7,144,155,5,7);
			Blit (HeroBM,252,14,31,324,5,7);
			Blit (HeroBM,257,14,144,324,5,7);
			
			Blit (HeroBM,252,7,211,155,5,7);
			Blit (HeroBM,257,7,324,155,5,7);
			Blit (HeroBM,252,14,211,324,5,7);
			Blit (HeroBM,257,14,324,324,5,7);
			FOR aNum:=0 TO 2 DO
				Blit (HeroBM,252,0,36+aNum*36,155,36,7);
				Blit (HeroBM,252,0,36+aNum*36,324,36,7);
				Blit (HeroBM,247,54,31,162+aNum*54,5,54);
				Blit (HeroBM,247,54,144,162+aNum*54,5,54);

				Blit (HeroBM,252,0,216+aNum*36,155,36,7);
				Blit (HeroBM,252,0,216+aNum*36,324,36,7);
				Blit (HeroBM,247,54,211,162+aNum*54,5,54);
				Blit (HeroBM,247,54,324,162+aNum*54,5,54);
			END;
			Blit (sp^.BitMap,144,162,36,162,108,162);
			FlipScrn;
			NotDone:=TRUE;
			WHILE NotDone DO
			  IF Hour()<10 THEN
				PrintNum (Hour(),282,224);
			  ELSE
				PrintNum (Hour(),274,224);
			  END;
			  IF Minute()<10 THEN
				Print('0',306,224);
				PrintNum(Minute(),298,224);
			  ELSE
				PrintNum (Minute(),298,224);
			  END;
			  Print (':',298,224);
			  MsgPtr:=GetMsg(wp^.UserPort^);
			  IF MsgPtr # NIL THEN
				class:=MsgPtr^.Class;
				code:=MsgPtr^.Code;
				ReplyMsg(MsgPtr);
				IF (MouseButtons IN class) AND (code=SelectDown) THEN
					NotDone:=FALSE;
				END;
			  END;
			END;
			DrawScreen;
			DrawHero(dir);
			FlipScrn;
		   END;
		END;
	END;
END ProcessMouseButtons;


PROCEDURE info(a:ARRAY OF CHAR;b:ADDRESS;c:CARDINAL);

BEGIN
	WriteLongHex(LONG(b),10);
	WriteString (' - ');
	WriteLongHex(LONG(b)+LONG(c)-1D,1);
	WriteString(' => ');
	WriteString (a);
	WriteLn;
END info;


BEGIN (* main *)
 trace:=TRUE;
 Init;
 IF NOT fatalerror THEN
   DrawScreen;
   DrawHero(dir);
   FlipScrn;
   SetColorsToNorm(sp);
FOR aNum:=0 TO 107 DO
	MoveScreen(sp^,0,-4);
END;
LoadRGB4(WB^.ViewPort,ADR(Color[0]),4);
FOR aNum:=0 TO 4 DO
	info('LandStoreRP',LandStoreRP.BitMap^.Planes[aNum],2673);
END;
FOR aNum:=0 TO 4 DO
	info('sp^.BitMap.Planes[x]',sp^.BitMap.Planes[aNum],19872);
END;
FOR aNum:=0 TO 4 DO
	info('DarkSide^.BitMap^',DarkSide^.BitMap^.Planes[aNum],19872);
END;
FOR aNum:=0 TO 4 DO
	info('HeroBM',HeroBM.Planes[aNum],8640);
END;
info('HeroMaskBM',HeroMaskBM.Planes[0],8640);
FOR aNum:=0 TO 4 DO
	info('LandBM',LandBM.Planes[aNum],15552);
END;
FOR aNum:=0 TO 4 DO
	info('CreatureBM',CreatureBM.Planes[aNum],15552);
END;
info('CreatureMaskBM',CreatureMaskBM.Planes[0],15552);

(*
info('World.Land',World.Land,mx*my);
info('World.Creatures',World.Creature,mx*my);
info('World.Items',World.Items,mx*my);
info('DarkSideRP',DarkSide,TSIZE(RastPort));
info('DarkSide.BitMap',DarkSide^.BitMap,TSIZE(BitMap));
*)
LOOP
	MsgPtr :=GetMsg(wp^.UserPort^);
	WHILE MsgPtr # NIL DO
		class:=MsgPtr^.Class;
		code:=MsgPtr^.Code;
		x:=MsgPtr^.MouseX;
		y:=MsgPtr^.MouseY;
		IEQualifier:=MsgPtr^.Qualifier;
		ReplyMsg(MsgPtr);
		IF MouseButtons IN class THEN
			ProcessMouseButtons;
		ELSIF VanillaKey IN class THEN
			key:=CHR(code);
			CASE CAP(key) OF
				'Q' : Exit;|
				'8' : (*north*)
					MoveScrn (xpos,ypos-1,north);|
				'2' : (*south*)
					MoveScrn (xpos,ypos+1,south);|
				'4' : (*west*)
					MoveScrn (xpos-1,ypos,west);|
				'6' : (*east*)
					MoveScrn (xpos+1,ypos,east);|
				ELSE
			END;
		END;
		MsgPtr:=GetMsg(wp^.UserPort^);
	END;
  END;
END;
Exit;
(*
   LOOP
	GetInput (mode);
	CASE mode OF
		Give :
 		        Say ("HERE. HAVE SOME MONEY.");
          		IF InFront(1)>0 THEN
                		Say ("GEE THANK U!?");
          		END;
	END;
 	wait:= 8;
   	IF wait=0 THEN
      		REPEAT
			aNum:=Random(CARDINAL(NumOfCreatures));
      		UNTIL NOT(Creature[aNum].Condition = dead);
      		IF CARDINAL(Random(10)) > 6 THEN
        		idir:=BYTE(Random(4));
      		ELSE
         		idir:=Creature[aNum].dir;
      		END;
      		NextX:=Creature[aNum].x-1+xDir[idir];
      		NextY:=Creature[aNum].y-1+yDir[idir]; 
      		IF (Land(NextX,NextY)<32)
	 	   AND (CreatureNum(NextX,NextY)=0) THEN
         		LastX:=Creature[aNum].x;
         		LastY:=Creature[aNum].y;
         		Creature[aNum].x:=NextX;
         		Creature[aNum].y:=NextY;
	 		PutCreatureNum(LastX,LastY,0);
	 		PutCreatureNum(NextX,NextY,aNum);
	 		Creature[aNum].dir:=idir;
         		Flag:=	FALSE;
         		IF (LastX+1>xpos-2) AND (LastX-1<xpos+2) AND (LastY+1>ypos-2)
		 	  AND (LastY-1<ypos+2) THEN
            			Flag:=TRUE;
            			DrawBlock (LastX,LastY,LastX-xpos+2,LastY-ypos+2);
         		END;
               		DrawBlock (NextX,NextY,NextX-xpos+2,NextY-ypos+2);
            		IF  CARDINAL(Random(10)) >6 THEN
               			Say ('AH.!');
            		END;
		END;
        	IF Flag=TRUE THEN
        		Flag:=FALSE;
        	END;
	END;
   END;
 END;*)
END WDR.
