home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / code / pshar_ma.sit < prev    next >
Text File  |  1988-06-20  |  59KB  |  1,924 lines

  1. 18-Jun-88 14:37:19-MDT,61085;000000000000
  2. Return-Path: <u-lchoqu%sunset@cs.utah.edu>
  3. Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Sat, 18 Jun 88 14:35:47 MDT
  4. Received: by cs.utah.edu (5.54/utah-2.0-cs)
  5.     id AA22490; Sat, 18 Jun 88 14:35:44 MDT
  6. Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
  7.     id AA24691; Sat, 18 Jun 88 14:35:36 MDT
  8. Date: Sat, 18 Jun 88 14:35:36 MDT
  9. From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
  10. Message-Id: <8806182035.AA24691@sunset.utah.edu>
  11. To: rthum@simtel20.arpa
  12. Subject: Maze.p.shar
  13.  
  14. #! /bin/sh
  15. #
  16. # This is a shell archive.  Save this into a file, edit it
  17. # and delete all lines above this comment.  Then give this
  18. # file to sh by executing the command "sh file".  The files
  19. # will be extracted into the current directory owned by
  20. # you with default permissions.
  21. #
  22. # The files contained herein are:
  23. #
  24. #   53 Maze.p
  25. #    4 Maze.r
  26. #
  27. echo 'Extracting Maze.p'
  28. if test -f Maze.p; then echo 'shar: will not overwrite Maze.p'; else
  29. cat << '________This_Is_The_END________' > Maze.p
  30. {$X-}
  31. {$M+}
  32.  
  33. PROGRAM Maze;
  34.  
  35.   { Edit -- A small sample application written in Pascal }
  36.   {        by Macintosh Technical Support     }
  37.   {SK 6/18 Added Memtypes, if GetNextEvent, EraseRect in update event,
  38.    fixed for new Edit menu  }
  39.  
  40.   {    Appears to be an Appletalk maze game    }
  41.  
  42.    USES {$U-}
  43.       {$U Obj/Memtypes      } Memtypes,
  44.       {$U Obj/QuickDraw      } QuickDraw,
  45.       {$U Obj/OSIntf      } OSIntf,
  46.       {$U Obj/ToolIntf      } ToolIntf,
  47.       {$U Obj/PACKINTF      } PackIntf,
  48.       {$U AB/ABPasIntf      } ABPasIntf;
  49.  
  50.    CONST
  51.       lastMenu = 4; { number of menus }
  52.       appleMenu = 1; { menu ID for desk accessory menu }
  53.       fileMenu = 256; { menu ID for File menu }
  54.       MoveMenu = 257; { menu ID for Edit menu }
  55.       autoMenu = 258; { menu ID for autoplayer menu }
  56.  
  57.       LastStatLine = 26;
  58.  
  59.       HMazeSize = 23; { 24 -1 for 0 based }
  60.       VMazeSize = 23; { 24 -1 for 0 based }
  61.       UpStart = 15;   { Upper left corner of maze }
  62.       LeftStart = 15;
  63.       MaxPlayers = 255;     { One for each possible node number }
  64.       LastPlayer = MaxPlayers;
  65.  
  66.       SSize = 11;       { Size of a box in the maze }
  67.       KSize = 30;       { Size of soft keys }
  68.       KSpace = 5;       { Space between soft keys }
  69.       FSize = 10;       { Size of Fire keys in movement buttons }
  70.       TSize = 9;        { Size of font for symbols }
  71.       ColSep = 20;      { Size between symbol, name and score }
  72.       MaxString = 80;
  73.       NetEvt = 10;      { Event number for posting receptions }
  74.       NoCheckSum = FALSE;
  75.       AsyncCall = True;
  76.       SyncCall = FALSE;
  77.  
  78.       UpDateRate = 100;         { How often to redraw info }
  79.       ShortCount = 30;         { How many short status records/long status record }
  80.  
  81.       BulletSymbol = '*';
  82.       TickperSquare = 15;    { Speed of bullet in ticks }
  83.  
  84.    TYPE
  85.  
  86.       ButtonChoice = (Up, Left, Down, Right,
  87.                       UpFire, LeftFire, DownFire, RightFire,
  88.                       None);
  89.       MazePoint = RECORD
  90.             h: -1..HMazeSize;
  91.             v: -1..VMazeSize;
  92.             END;
  93.  
  94.       PlayerRecord =  record
  95.         Symbol: char;
  96.         UniqueID: BYTE;
  97.         FireDir : ButtonChoice;
  98.         Position: Point;
  99.         LogPos: MazePoint;
  100.         Score: Integer;
  101.         BulletPos: Point;
  102.         LogBulletPos: MazePoint;
  103.         Name: STR255;
  104.         end;
  105.  
  106.       RefPlayerRecord = ^ PlayerRecord;
  107.  
  108.       ShortReport = packed record
  109.         Size: Integer;
  110.         Symbol: char;
  111.         UniqueID: BYTE;
  112.         FireDir : ButtonChoice;
  113.         Position: Point;
  114.         LogPos: MazePoint;
  115.         Score: Integer;
  116.         BulletPos: Point;
  117.         LogBulletPos: MazePoint;
  118.         HitBy: BYTE;
  119.         END;
  120.  
  121.       Ref_ShortReport = ^ ShortReport;
  122.  
  123.       LongReport = packed record
  124.         Size: Integer;
  125.         Symbol: char;
  126.         UniqueID: BYTE;
  127.         FireDir : ButtonChoice;
  128.         Position: Point;
  129.         LogPos: MazePoint;
  130.         Score: Integer;
  131.         BulletPos: Point;
  132.         LogBulletPos: MazePoint;
  133.         HitBy: BYTE;                { $FF not hit, $0 quiting, # hitter }
  134.         Name: STR255;
  135.         END;
  136.  
  137.       Ref_LongReport = ^ LongReport;
  138.  
  139.       BitRow = packed array [0..HMazeSize] OF Boolean;
  140.  
  141.    VAR
  142.       myMenus: ARRAY [1..lastMenu] OF MenuHandle;
  143.       screenRect,dragRect,pRect: Rect;
  144.       doneFlag,temp: BOOLEAN;
  145.       myEvent: EventRecord;
  146.       code,refNum: INTEGER;
  147.       wRecord: WindowRecord;
  148.       myWindow,whichWindow: WindowPtr;
  149.       theMenu,theItem: INTEGER;
  150.       hTE: TEHandle;
  151.  
  152.       MazeMap: array [0..VMazeSize] of BitRow;
  153.  
  154.       Players: packed array [BYTE] of RefPlayerRecord;
  155.       LastSeen: packed array[BYTE] OF LongInt;
  156.       StatLines: array [1..LastStatLine] of RefPlayerRecord; { Is line being used?      }
  157.       LastUsedStat: 0..LastStatLine;             { What is last line used?  }
  158.       PlayerLine: array[BYTE] of 0..LastStatLine;    { Status line showing play }
  159.       NumShortSent: Integer;                 { Number of short msgs since
  160.                                                        last long message }
  161.    VAR
  162.       NextDeadCheck: LongInt;
  163.  
  164.       UpRect, DnRect, LRect, RRect: Rect;   { Movement rectangles }
  165.       UFRect, DFRect, LFRect, RFRect: Rect; { Firing rectangles }
  166.       KeyMidPoint: Point;            { Offset to middle of soft keys }
  167.       ButtonSelected: ButtonChoice;
  168.       UpdateCnt: Integer;            { When to send position info }
  169.       BulletUpdate: LongInt;            { When to move bullet }
  170.       Me :integer;                { Which player am I? }
  171.  
  172.    CONST
  173.       MazeProtocol = 6;
  174.  
  175.    VAR
  176.       { Network variables }
  177.       RetStatus: OSErr;               { Return status from network }
  178.       CurPlace, NewPlace: PlayerRecord;       { Say where you are }
  179.       OtherPlace: PlayerRecord;           { Where someone else is }
  180.       OutputH, InputH: ABRecHandle;
  181.       InBuf,OutBuf: LongReport;
  182.       DoDisplay : Boolean;           { Display packets as they arrive }
  183.       DoSend, DoListen: Boolean;       { Receive or send packets }
  184.       DoRemove: Boolean;           { Remove inactive players }
  185.  
  186.       FirstActivate: Boolean;
  187.  
  188.    VAR
  189.       UseSoundEffects: Boolean;
  190.       TalkDummy: Integer;
  191.       FUNCTION mSpeak( text:STR255; Volume: Integer; Pitch: Integer;
  192.                         Speed: Integer):  Integer; EXTERNAL;
  193.  
  194.       { Autopilot variables }
  195.    CONST
  196.        APWait = 30; { do something every second }
  197.    VAR
  198.        APTime: LongInt;
  199.        WhatToDo: Integer;
  200.        PilotOn: Boolean;
  201.  
  202.    CONST
  203.        NotHitIndicator = $FF;
  204.        QuitIndicator   =   0;
  205.  
  206.    PROCEDURE SendBadPkt;
  207.    { Make a bad packet and send it out }
  208.    TYPE
  209.       BMPoint = record
  210.           h: -2..24;
  211.           v: -2..24;
  212.           END;
  213.  
  214.       BShortReport = packed record
  215.         Size: Integer;
  216.         Symbol: char;
  217.         UniqueID: BYTE;
  218.         FireDir : -1..15;
  219.         Position: Point;
  220.         LogPos: BMPoint;
  221.         Score: Integer;
  222.         BulletPos: Point;
  223.         LogBulletPos: BMPoint;
  224.         HitBy: BYTE;
  225.         END;
  226.  
  227.       BRef_ShortReport = ^ BShortReport;
  228.  
  229.    VAR FakePkt: BRef_ShortReport;
  230.  
  231.    BEGIN
  232.        WHILE OutputH^^.abResult = 1 DO; { Wait for last send to finish }
  233.  
  234.        WITH OutBuf DO BEGIN
  235.            Symbol:= Players[Me]^.Symbol;
  236.            UniqueID:= Players[Me]^.UniqueID;
  237.            FireDir := Players[Me]^.FireDir;
  238.            Position:= Players[Me]^.Position;
  239.            LogPos:= Players[Me]^.LogPos;
  240.            Score:= Players[Me]^.Score;
  241.            BulletPos:= Players[Me]^.BulletPos;
  242.            LogBulletPos:= Players[Me]^.LogBulletPos;
  243.            HitBy:= 45;  { $FF not hit, $0 quitting, # hitter }
  244.            END;
  245.  
  246.       FakePkt := @OutBuf;
  247.  
  248.       WITH OutputH^^ DO BEGIN
  249.           IF (NumShortSent > ShortCount)
  250.               THEN BEGIN
  251.                   { Send a long packet }
  252.                   lapReqcount := sizeof(LongReport);
  253.                   OutBuf.Size := sizeof(LongReport);
  254.                   NumShortSent := 0;
  255.                   OutBuf.Name := Players[Me]^.Name;
  256.               END
  257.               ELSE BEGIN
  258.                   { Send a short packet }
  259.                   lapReqcount := sizeof(ShortReport);
  260.                   OutBuf.Size := sizeof(ShortReport);
  261.                   NumShortSent := NumShortSent + 1;
  262.               END;
  263.  
  264.           lapAddress.LAPProtType := MazeProtocol;
  265.           lapAddress.dstNodeID := $FF;
  266.           lapDataPtr := @OutBuf;
  267.           END;
  268.  
  269.       { Perturb the packet }
  270.       WITH FakePkt^ DO CASE (TickCount MOD 14) OF
  271.          0: BEGIN Size := 26;OutputH^^.lapReqcount := 26; END;
  272.          1: Symbol := '*';
  273.          2: UniqueID := 0;
  274.          3: FireDir := -1;
  275.          4: Position.H := 5000;
  276.          5: Position.V := -100;
  277.          6: LogPos.H := -2;
  278.          7: LogPos.V := 24;
  279.          8: OutputH^^.lapAddress.LAPProtType := MazeProtocol + 1;
  280.          9: BulletPos.H := -5;
  281.          10: BulletPos.V := 3333;
  282.          11: LogBulletPos.H := 24;
  283.          12: LogBulletPos.V := -2;
  284.          13: HitBy := 44;
  285.          END;
  286.  
  287.       RetStatus := LAPWrite(OutputH,AsyncCall);
  288.  
  289.    END;
  290.  
  291.    PROCEDURE ReportPlace(P:RefPlayerRecord;WhoHitMe:BYTE);
  292.    { Make a status packet and send it out }
  293.    BEGIN
  294.        IF NOT DoSend THEN EXIT(ReportPlace);
  295.  
  296.        WHILE OutputH^^.abResult = 1 DO; { Wait for last send to finish }
  297.  
  298.        WITH OutBuf DO BEGIN
  299.            Symbol:= P^.Symbol;
  300.            UniqueID:= P^.UniqueID;
  301.            FireDir := P^.FireDir;
  302.            Position:= P^.Position;
  303.            LogPos:= P^.LogPos;
  304.            Score:= P^.Score;
  305.            BulletPos:= P^.BulletPos;
  306.            LogBulletPos:= P^.LogBulletPos;
  307.            HitBy:= WhoHitMe;  { $FF not hit, $0 quitting, # hitter }
  308.            END;
  309.  
  310.       WITH OutputH^^ DO BEGIN
  311.           IF (NumShortSent > ShortCount)
  312.               THEN BEGIN
  313.                   { Send a long packet }
  314.                   lapReqcount := sizeof(LongReport);
  315.                   OutBuf.Size := sizeof(LongReport);
  316.                   NumShortSent := 0;
  317.                   OutBuf.Name := P^.Name;
  318.               END
  319.               ELSE BEGIN
  320.                   { Send a short packet }
  321.                   lapReqcount := sizeof(ShortReport);
  322.                   OutBuf.Size := sizeof(ShortReport);
  323.                   NumShortSent := NumShortSent + 1;
  324.               END;
  325.  
  326.           lapAddress.LAPProtType := MazeProtocol;
  327.           lapAddress.dstNodeID := $FF;
  328.           lapDataPtr := @OutBuf;
  329.           END;
  330.  
  331.       RetStatus := LAPWrite(OutputH,AsyncCall);
  332.  
  333.    END;
  334.  
  335.    PROCEDURE EraseStatus(P: RefPlayerRecord;WhichLine:Integer);
  336.    { This procedure erases the status line for a given player at a given line }
  337.    VAR t,l,i: Integer;
  338.        ScoreStr: STR255;
  339.    BEGIN
  340.        T := DnRect.Bottom + KSpace + (TSize + 2)*(WhichLine - 1);
  341.        L := LRect.Left;
  342.        TextMode(srcXor);
  343.        TextSize(TSize);
  344.        { Symbol }
  345.        MoveTo(L,T+TSize);
  346.        DrawChar(P^.Symbol);
  347.        { Name }
  348.        MoveTo(L+ColSep,T+TSize);
  349.        DrawString(P^.Name);
  350.        {Score }
  351.        MoveTo(L+ColSep+MaxString,T+TSize);
  352.        NumToString(P^.Score,ScoreStr);
  353.        DrawString(ScoreStr);
  354.    END; { end of proc }
  355.  
  356.    PROCEDURE FirstStatus(P:RefPlayerRecord);
  357.    { This procedure records the first time a player's status line is
  358.      displays. It finds an empty line and then write the information into
  359.      that display slot }
  360.    VAR t,l,i: Integer;
  361.        ScoreStr: STR255;
  362.    BEGIN
  363.        T := DnRect.Bottom + KSpace;
  364.        L := LRect.Left;
  365.        TextMode(srcXor);
  366.        TextSize(TSize);
  367.        { Find an open place }
  368.        FOR i := 1 TO LastStatLine DO
  369.            IF StatLines[i] = NIL THEN BEGIN
  370.                StatLines[i] := P;
  371.                PlayerLine[P^.UniqueID] := i;
  372.                { Symbol }
  373.                MoveTo(L,T+TSize);
  374.                DrawChar(P^.Symbol);
  375.                { Name }
  376.                MoveTo(L+ColSep,T+TSize);
  377.                DrawString(P^.Name);
  378.                {Score }
  379.                MoveTo(L+ColSep+MaxString,T+TSize);
  380.                NumToString(P^.Score,ScoreStr);
  381.                DrawString(ScoreStr);
  382.                IF i > LastUsedStat THEN LastUsedStat := i;
  383.                EXIT(FirstStatus);
  384.            END
  385.            ELSE T := T + TSize + 2;
  386.        { Couldn't find an open line, so this person doesn't get displayed! }
  387.    END; { end of proc }
  388.  
  389.    PROCEDURE UpDateStatus(P:RefPlayerRecord; NewName:STR255; NewScore: Integer);
  390.    { This procedure takes a player that has already been displayed and updates
  391.      the name and score as necessary -- note: the old symbol is always kept }
  392.    VAR T, L, i: Integer;
  393.        ScoreStr: STR255;
  394.    BEGIN
  395.        T := DnRect.Bottom + KSpace;
  396.        L := LRect.Left;
  397.        TextMode(srcXor);
  398.        TextSize(TSize);
  399.        FOR i := 2 TO PlayerLine[P^.UniqueID] DO T := T + TSize + 2;
  400.        WITH P^ DO BEGIN
  401.            IF (Name <> NewName)     THEN BEGIN
  402.                { Erase old name }
  403.                MoveTo(L+ColSep,T+TSize);
  404.                DrawString(Name);
  405.                { Write in new name }
  406.                MoveTo(L+ColSep,T+TSize);
  407.                DrawString(NewName);
  408.                Name := NewName;
  409.                END;
  410.  
  411.            { And update the score }
  412.            IF Score <> NewScore THEN BEGIN
  413.                { Erase the old }
  414.                MoveTo(L+ColSep+MaxString,T+TSize);
  415.                NumToString(Score,ScoreStr);
  416.                DrawString(ScoreStr);
  417.                { Put in the new }
  418.                MoveTo(L+ColSep+MaxString,T+TSize);
  419.                NumToString(NewScore,ScoreStr);
  420.                DrawString(ScoreStr);
  421.                END;
  422.  
  423.            END;
  424.  
  425.    END;
  426.  
  427.    PROCEDURE DisplayPkt(P:Ref_LongReport);
  428.    CONST
  429.         OKBut = 1;
  430.         CancelBut = 32;
  431.         SizeField = 2;
  432.         SymbolField = 3;
  433.         UniqueIDField = 4;
  434.         FireDirField  = 5;
  435.         PosHField = 6;
  436.         PosVField = 7;
  437.         LogHField = 8;
  438.         LogVField = 9;
  439.         ScoreField = 10;
  440.         BulHField = 11;
  441.         BulVField = 12;
  442.         LogBPHField = 13;
  443.         LogBPVField = 14;
  444.         HitByField = 15;           { $FF not hit, $0 quiting, # hitter }
  445.         NameField = 16;
  446.  
  447.         UserDialog = 2;
  448.  
  449.  
  450.    VAR
  451.         i: Integer;
  452.         ItemHit: Integer;
  453.         LocalItemHandle: Handle;
  454.         tmpStr: STR255;
  455.         theItem: INTEGER;
  456.  
  457.         MyDialog: DialogPtr;
  458.         TheItemType: Integer;
  459.         TheItemBox: Rect;
  460.  
  461.    BEGIN
  462.  
  463.      MyDialog :=  GetNewDialog(UserDialog,NIL,POINTER(-1));
  464.      tmpStr := ' ';
  465.  
  466.  
  467.      GetDItem(MyDialog,SizeField,TheItemType,LocalItemHandle,TheItemBox);
  468.      NumToString(P^.Size,tmpStr);
  469.      SetIText(LocalItemHandle,tmpStr);
  470.  
  471.      GetDItem(MyDialog,SymbolField,TheItemType,LocalItemHandle,TheItemBox);
  472.      tmpStr := ' '; tmpStr[1] := P^.Symbol;
  473.      SetIText(LocalItemHandle,tmpStr);
  474.  
  475.      GetDItem(MyDialog,UniqueIDField,TheItemType,LocalItemHandle,TheItemBox);
  476.      NumToString(P^.UniqueID,tmpStr);
  477.      SetIText(LocalItemHandle,tmpStr);
  478.  
  479.      GetDItem(MyDialog,FireDirField,TheItemType,LocalItemHandle,TheItemBox);
  480.      NumToString(ORD(P^.FireDir),tmpStr);
  481.      SetIText(LocalItemHandle,tmpStr);
  482.  
  483.      GetDItem(MyDialog,PosHField,TheItemType,LocalItemHandle,TheItemBox);
  484.      NumToString(ORD(P^.Position.H),tmpStr);
  485.      SetIText(LocalItemHandle,tmpStr);
  486.  
  487.      GetDItem(MyDialog,PosVField,TheItemType,LocalItemHandle,TheItemBox);
  488.      NumToString(ORD(P^.Position.V),tmpStr);
  489.      SetIText(LocalItemHandle,tmpStr);
  490.  
  491.      GetDItem(MyDialog,LogHField,TheItemType,LocalItemHandle,TheItemBox);
  492.      NumToString(ORD(P^.LogPos.H),tmpStr);
  493.      SetIText(LocalItemHandle,tmpStr);
  494.  
  495.      GetDItem(MyDialog,LogVField,TheItemType,LocalItemHandle,TheItemBox);
  496.      NumToString(ORD(P^.LogPos.V),tmpStr);
  497.      SetIText(LocalItemHandle,tmpStr);
  498.  
  499.      GetDItem(MyDialog,ScoreField,TheItemType,LocalItemHandle,TheItemBox);
  500.      NumToString(ORD(P^.Score),tmpStr);
  501.      SetIText(LocalItemHandle,tmpStr);
  502.  
  503.      GetDItem(MyDialog,BulHField,TheItemType,LocalItemHandle,TheItemBox);
  504.      NumToString(ORD(P^.BulletPos.H),tmpStr);
  505.      SetIText(LocalItemHandle,tmpStr);
  506.  
  507.      GetDItem(MyDialog,BulVField,TheItemType,LocalItemHandle,TheItemBox);
  508.      NumToString(ORD(P^.BulletPos.V),tmpStr);
  509.      SetIText(LocalItemHandle,tmpStr);
  510.  
  511.      GetDItem(MyDialog,LogBPHField,TheItemType,LocalItemHandle,TheItemBox);
  512.      NumToString(ORD(P^.LogBulletPos.H),tmpStr);
  513.      SetIText(LocalItemHandle,tmpStr);
  514.  
  515.      GetDItem(MyDialog,LogBPVField,TheItemType,LocalItemHandle,TheItemBox);
  516.      NumToString(ORD(P^.LogBulletPos.V),tmpStr);
  517.      SetIText(LocalItemHandle,tmpStr);
  518.  
  519.      GetDItem(MyDialog,HitByField,TheItemType,LocalItemHandle,TheItemBox);
  520.      NumToString(ORD(P^.HitBy),tmpStr);
  521.      SetIText(LocalItemHandle,tmpStr);
  522.  
  523.      GetDItem(MyDialog,NameField,TheItemType,LocalItemHandle,TheItemBox);
  524.      IF ORD(P^.Size) = Sizeof(LongReport)
  525.          THEN tmpStr := P^.Name
  526.          ELSE tmpStr := 'No name -- short packet ';
  527.      SetIText(LocalItemHandle,tmpStr);
  528.  
  529.      ModalDialog(NIL,ItemHit);
  530.      IF ItemHit = CancelBut THEN BEGIN
  531.          DoDisplay := FALSE;
  532.          CheckItem(MyMenus[4],3,FALSE);
  533.          END;
  534.      CloseDialog(MyDialog);
  535.    END;
  536.  
  537.    PROCEDURE ReadPlayerName(P:RefPlayerRecord);
  538.    { This procedure reads in the initial information about the user. Note:
  539.      it allows invisible users since a space may be given as the
  540.      symbol for the player! }
  541.    CONST
  542.         OKBut = 1;
  543.         CancelBut = 2;
  544.         NameField = 3;
  545.         SymbolField = 4;
  546.         ErrorField = 5;
  547.  
  548.         UserDialog = 1;
  549.  
  550.  
  551.    VAR
  552.         i: Integer;
  553.         ItemHit: Integer;
  554.         LocalItemHandle: Handle;
  555.         tmpStr: STR255;
  556.         theItem: INTEGER;
  557.  
  558.         MyDialog: DialogPtr;
  559.         TheItemType: Integer;
  560.         TheItemBox: Rect;
  561.         InputOK : Boolean;
  562.         Guess: Integer;
  563.  
  564.    BEGIN
  565.  
  566.      MyDialog :=  GetNewDialog(UserDialog,NIL,POINTER(-1));
  567.      tmpStr := ' ';
  568.      Guess := (GetNodeNumber MOD 51);
  569.      IF Guess < 26 THEN tmpStr[1] := CHR(ORD('A')+Guess)
  570.                    ELSE tmpStr[1] := CHR(ORD('a')+(Guess-26));
  571.      GetDItem(MyDialog,SymbolField,TheItemType,LocalItemHandle,TheItemBox);
  572.      SetIText(LocalItemHandle,tmpStr);
  573.      SelIText(MyDialog,NameField,0,9999);
  574.      REPEAT
  575.          ModalDialog(NIL,ItemHit);
  576.          IF ItemHit = CancelBut THEN DoneFlag := TRUE;
  577.          GetDItem(MyDialog,SymbolField,TheItemType,LocalItemHandle,TheItemBox);
  578.          GetIText(LocalItemHandle,tmpStr);
  579.          IF length(tmpStr) = 1 THEN BEGIN
  580.                 P^.Symbol := tmpStr[1];
  581.                 GetDItem(MyDialog,NameField,TheItemType,LocalItemHandle,TheItemBox);
  582.                 GetIText(LocalItemHandle,P^.Name);
  583.                 InputOK := true;
  584.                 END
  585.          ELSE BEGIN
  586.                 SysBeep(1);
  587.                 GetDItem(MyDialog,ErrorField,TheItemType,LocalItemHandle,TheItemBox);
  588.                 SetIText(LocalItemHandle,'Only one character symbols are allowed');
  589.                 InputOK := False;
  590.                 END;
  591.      UNTIL InputOk;
  592.  
  593.      CloseDialog(MyDialog);
  594.    END;
  595.  
  596.    PROCEDURE InitPlayer(ID:Byte);
  597.    { This procedure allocates and initializes a player record for keeping
  598.      track of positions, hits, and so on. This should be called once per
  599.      player }
  600.    BEGIN
  601.        Players[ID] := RefPlayerRecord(NewPtr(sizeof(PlayerRecord)));
  602.        { See if we ran out of room }
  603.        If Players[ID] = NIL THEN EXIT(InitPlayer);
  604.  
  605.        WITH Players[ID]^ DO BEGIN
  606.          Name := '';
  607.          UniqueID := ID;
  608.          FireDir := None;
  609.          Score := 0;
  610.          Symbol := ' ';
  611.          Position.h := 0;
  612.          Position.v := 0;
  613.          LogPos.h := 0;
  614.          LogPos.v := 0;
  615.          BulletPos.h := -1;
  616.          BulletPos.v := -1;
  617.          LogBulletPos.h := -1;
  618.          LogBulletPos.v := -1;
  619.          END;
  620.        LastSeen[ID] := TickCount;
  621.  
  622.    END;
  623.  
  624.    PROCEDURE PlacePlayer(P:RefPlayerRecord);
  625.    { This procedure is used to randomly place a player in the Maze. This
  626.      happens when a play first starts and when a player is hit }
  627.    VAR v,h : integer;
  628.        voffset, hoffset: Integer;
  629.    BEGIN
  630.         randSeed := LoWord(TickCount);
  631.         REPEAT voffset := Random MOD (VMazeSize + 1); UNTIL voffset >= 0;
  632.         REPEAT hoffset := Random MOD (HMazeSize + 1); UNTIL hoffset >= 0;
  633.         WITH P^ DO BEGIN
  634.             LogPos.v := 0;
  635.             LogPos.h := 0;
  636.             FOR h := 0 TO HMazeSize DO
  637.                     FOR v := 0 TO VMazeSize DO
  638.                         IF NOT MazeMap[(v+voffset) MOD (VMazeSize + 1)]
  639.                                       [(h+hoffset) MOD (HMazeSize + 1)] THEN BEGIN
  640.                             { Found an empty spot }
  641.                             LogPos.v := (v + voffset) MOD (VMazeSize + 1);
  642.                             LogPos.h := (h + hoffset) MOD (HMazeSize + 1);
  643.                             Position.v := UpStart + SSize - 2 + LogPos.v*SSize;
  644.                             Position.h := LeftStart + 2 + LogPos.h*SSize;
  645.                             Exit(PlacePlayer);
  646.                             END;
  647.        END;
  648.    END;
  649.  
  650.    PROCEDURE InitMaze;
  651.    { This procedure initializes the maze and global variables used by the
  652.      program. }
  653.    VAR i,j,h ,v: integer;
  654.        FireOffset : Integer;
  655.        OSStatus : OSErr;
  656.    BEGIN
  657.         { And fill in the maze }
  658.         { Note: Pascal reverses each byte in boolean arrays }
  659.         { 0 => 0, 1=>8, 2=> 4, 3=> C, 4=>2, 5=>A, 6=> 6, 7=>E,
  660.           8 => 1, 9=>9, A=> 5, B=> D, C=>3, D=>B, E=>7, F=>f }
  661.         StuffHex(@MazeMap[0],'FFFFFF'); {FFFFFF}
  662.         StuffHex(@MazeMap[1],'052EAA'); {A07455}
  663.         StuffHex(@MazeMap[2],'A528AA'); {A51455}
  664.         StuffHex(@MazeMap[3],'A5ACAA'); {A53555}
  665.         StuffHex(@MazeMap[4],'FDA9A2'); {BF9545}
  666.         StuffHex(@MazeMap[5],'01A2AA'); {804555}
  667.         StuffHex(@MazeMap[6],'7582AA'); {AE4155 }
  668.         StuffHex(@MazeMap[7],'5582AA'); {AA4155 }
  669.         StuffHex(@MazeMap[8],'15A2A8'); {A84515 }
  670.         StuffHex(@MazeMap[9],'F5A3AA'); {AFC555 }
  671.         StuffHex(@MazeMap[10],'05A0AA'); {A00555 }
  672.         StuffHex(@MazeMap[11],'7522AA'); {AE4455 }
  673.         StuffHex(@MazeMap[12],'45A2AA'); {A24555 }
  674.         StuffHex(@MazeMap[13],'D5A3BA'); {ABC55D }
  675.         StuffHex(@MazeMap[14],'57828A'); {EA4151 }
  676.         StuffHex(@MazeMap[15],'1182E8'); {884117 }
  677.         StuffHex(@MazeMap[16],'FFFF89'); {FFFF91 }
  678.         StuffHex(@MazeMap[17],'1115E9'); {88A897 }
  679.         StuffHex(@MazeMap[18],'454080'); {A20201 }
  680.         StuffHex(@MazeMap[19],'FDFF93'); {BFFFC9 }
  681.         StuffHex(@MazeMap[20],'051090'); {A00809 }
  682.         StuffHex(@MazeMap[21],'FD17F4'); {BFE82F }
  683.         StuffHex(@MazeMap[22],'01C087'); {8003E1 }
  684.         StuffHex(@MazeMap[23],'FFFFFF'); {FFFFFF }
  685.  
  686.  
  687.         { Set up magic values for the soft keys }
  688.  
  689.                       { Left, Up, Right, Down }
  690.         KeyMidPoint.h := (KSize DIV 2) - (TSize DIV 2);
  691.         KeyMidPoint.v := (KSize DIV 2) + (TSize DIV 2);
  692.         FireOffset := (KSize - FSize) DIV 2;
  693.  
  694.         LRect.Left := LeftStart+ (HMazeSize + 2)*SSize;
  695.         LRect.Right := LRect.Left + KSize;
  696.         LRect.Top := UpStart + KSize + KSpace;
  697.         LRect.Bottom := LRect.Top + KSize;
  698.  
  699.                        { Left, top, right, bottom }
  700.         SetRect(LFRect,LRect.Right - FSize,LRect.Top + FireOffset,
  701.                        LRect.Right, LRect.Top + FireOffset + FSize);
  702.  
  703.         UpRect.Left := LRect.Right + KSpace;
  704.         UpRect.Right := UpRect.Left + KSize;
  705.         UpRect.Top := UpStart;
  706.         UpRect.Bottom := UpRect.Top + KSize;
  707.  
  708.         SetRect(UFRect, UpRect.Left + FireOffset, UpRect.Bottom - FSize,
  709.                         UpRect.Left + FireOffset + FSize, UpRect.Bottom);
  710.  
  711.         RRect.Left := UpRect.Right + KSpace;
  712.         RRect.Right := RRect.Left + KSize;
  713.         RRect.Top := LRect.Top;
  714.         RRect.Bottom := LRect.Bottom;
  715.  
  716.         SetRect(RFRect, RRect.Left, RRect.Top + FireOffset,
  717.                         RRect.Left + FSize, RRect.Top + FireOffset + FSize);
  718.  
  719.         DnRect.Left := UpRect.Left;
  720.         DnRect.Right := UpRect.Right;
  721.         DnRect.Top := LRect.Bottom + KSpace;
  722.         DnRect.Bottom := DnRect.Top + KSize;
  723.  
  724.         SetRect(DFRect, DnRect.Left + FireOffset, DnRect.Top,
  725.                         DnRect.Left + FireOffset + FSize, DnRect.Top + FSize);
  726.  
  727.         ButtonSelected := None;
  728.  
  729.         { Initialize the player table }
  730.  
  731.         Me := GetNodeNumber;
  732.  
  733.         FOR i := 0 TO MaxPlayers DO BEGIN
  734.             LastSeen[i] := 0;
  735.             Players[i] := NIL;
  736.             PlayerLine[i] := 0;
  737.             END;
  738.         FOR i := 1 TO LastStatLine DO StatLines[i] := NIL; { none used }
  739.         LastUsedStat := 0;
  740.         NextDeadCheck := TickCount;
  741.  
  742.         {Set up local player }
  743.         InitPlayer(Me);
  744.         ReadPlayerName(Players[Me]);
  745.         PlacePlayer(Players[Me]);
  746.         FirstActivate := TRUE;
  747.         UseSoundEffects := FALSE;
  748.  
  749.         { Setup the fonts for everyone }
  750.         TextMode(srcXor);
  751.         TextSize(TSize);
  752.         TextFont(Geneva);
  753.  
  754.  
  755.         { ******************************************************* }
  756.         { Here is a good place to initialize the network      }
  757.         { ******************************************************* }
  758.  
  759.         OsStatus := LAPOpenProtocol(MazeProtocol,NIL);
  760.         IF OSStatus <> noErr THEN SYSBeep(30);
  761.  
  762.         { Output buffer for reporting position }
  763.         OutputH := POINTER(NewHandle(lapSize));
  764.         WITH OutputH^^ DO BEGIN
  765.             abResult := noErr;
  766.             lapAddress.LAPProtType := MazeProtocol;
  767.             lapAddress.dstNodeID := $FF;
  768.             lapReqCount := sizeof(LongReport);
  769.             OutBuf.Size := sizeof(LongReport);
  770.             lapDataPtr := @OutBuf;
  771.             END;
  772.         NumShortSent := 0;
  773.  
  774.         { Input buffer for reading positions }
  775.         InputH := POINTER(NewHandle(lapSize));
  776.         WITH InputH^^ DO BEGIN
  777.             lapAddress.LAPProtType := MazeProtocol;
  778.             lapAddress.dstNodeID := $FF;
  779.             lapReqCount := sizeof(LongReport);
  780.             InBuf.Size := sizeof(LongReport);
  781.             lapDataPtr := @InBuf;
  782.             END;
  783.  
  784.         RetStatus := LAPRead(InputH,AsyncCall);
  785.  
  786.         DoSend := true;
  787.         DoListen := true;
  788.         DoRemove := true;
  789.         DoDisplay := false;
  790.  
  791.    END;
  792.  
  793.    PROCEDURE FirstSymbol(Symbol:Char; NewPos:Point);
  794.    { This procedure is used to display a symbol in the maze for the first
  795.      time AND for the last time (xor wipes a previous symbol as well as
  796.      establishes it) }
  797.    BEGIN
  798.        {TextMode(srcXor);}
  799.        {TextSize(TSize);}
  800.        MoveTo(NewPos.h, NewPos.v);
  801.        DrawChar(Symbol);
  802.    END;
  803.  
  804.    PROCEDURE MoveSymbol(Symbol:Char; OldPos:Point; NewPos:Point);
  805.    { This procedure is used to move the display of a symbol in the maze.
  806.      It assumes that the symbol is already in the Maze at the place
  807.      specified by OldPos. Note: because of Xor's properties it does not
  808.      really matter which arg is Old and which is new. }
  809.    BEGIN
  810.        IF (OldPos.h <> NewPos.h) OR (OldPos.v <> NewPos.v) THEN BEGIN
  811.             {TextMode(srcXor);}
  812.             {TextSize(TSize);}
  813.             MoveTo(OldPos.h, OldPos.v);
  814.             DrawChar(Symbol);
  815.             MoveTo(NewPos.h, NewPos.v);
  816.             DrawChar(Symbol);
  817.             END;
  818.    END;
  819.  
  820.    PROCEDURE TurnOffBullet(P: RefPlayerRecord);
  821.    { This procedure is used to turn off a bullet from the display and
  822.      to update a player's record appropriately. A bullet should be turned
  823.      off when it hits a wall or when a player reports that he's been hit. }
  824.    BEGIN
  825.        WITH P^ DO BEGIN
  826.            { Turn off display if still showing it }
  827.            IF FireDir <> None THEN FirstSymbol(BulletSymbol,BulletPosition);
  828.            BulletPos.h := -1;
  829.            BulletPos.v := -1;
  830.            LogBulletPos.h := -1;
  831.            LogBulletPos.v := -1;
  832.            FireDir := None;
  833.            END;
  834.    END;
  835.  
  836.    FUNCTION NotFiring(P: RefPlayerRecord): Boolean;
  837.    { This procedure checks to see if a player is firing; if not, the player
  838.      is set to firing, with the appropriate parts of the record being changed. }
  839.    BEGIN
  840.        NotFiring := (P^.FireDir = None);
  841.        IF P^.FireDir = None THEN BEGIN
  842.            P^.BulletPos := P^.Position;
  843.            P^.LogBulletPos := P^.LogPos;
  844.            BulletUpdate := TickCount + TickperSquare;
  845.            IF UseSoundEffects THEN TalkDummy := mSpeak('bS2AES5NG',5,5,5);
  846.            END;
  847.    END;
  848.  
  849.    PROCEDURE FireUp(P:RefPlayerRecord);
  850.    { This procedure starts, if appropriate, a bullet going up }
  851.    BEGIN
  852.        if NotFiring(P) THEN BEGIN
  853.            P^.FireDir := UpFire;
  854.            FirstSymbol(BulletSymbol,P^.BulletPos);
  855.            END;
  856.    END;
  857.  
  858.    PROCEDURE FireDown(P:RefPlayerRecord);
  859.    { This procedure starts, if appropriate, a bullet going down }
  860.    BEGIN
  861.       if NotFiring(P) THEN BEGIN
  862.           P^.FireDir := DownFire;
  863.           FirstSymbol(BulletSymbol,P^.BulletPos);
  864.           END;
  865.    END;
  866.  
  867.    PROCEDURE FireLeft(P:RefPlayerRecord);
  868.    { This procedure starts, if appropriate, a bullet going left }
  869.    BEGIN
  870.       if NotFiring(P) THEN BEGIN
  871.           P^.FireDir := LeftFire;
  872.           FirstSymbol(BulletSymbol,P^.BulletPos);
  873.           END;
  874.    END;
  875.  
  876.    PROCEDURE FireRight(P:RefPlayerRecord);
  877.    { This procedure starts, if appropriate, a bullet going right }
  878.    BEGIN
  879.        if NotFiring(P) THEN BEGIN
  880.            P^.FireDir := RightFire;
  881.            FirstSymbol(BulletSymbol,P^.BulletPos);
  882.            END;
  883.    END;
  884.  
  885.  
  886.    PROCEDURE MoveUp(P:RefPlayerRecord);
  887.    { This procedure moves a player one square up (if possible) }
  888.    VAR NewPos: Point;
  889.    BEGIN
  890.        if NOT MazeMap[P^.LogPos.v-1][P^.LogPos.h] THEN WITH P^ DO BEGIN
  891.            NewPos.v := Position.v - SSize;
  892.            NewPos.h := Position.h;
  893.            MoveSymbol(Symbol, Position,NewPos);
  894.            Position := NewPos;
  895.            LogPos.v := LogPos.v - 1;
  896.        END;
  897.    END;
  898.  
  899.    PROCEDURE MoveDown(P:RefPlayerRecord);
  900.    { This procedure moves a player one square down (if possible) }
  901.    VAR NewPos: Point;
  902.    BEGIN
  903.       WITH P^ DO
  904.       if NOT MazeMap[LogPos.v+1][LogPos.h] THEN BEGIN
  905.           NewPos.v := Position.v + SSize;
  906.           NewPos.h := Position.h;
  907.           MoveSymbol(Symbol, Position,NewPos);
  908.           Position := NewPos;
  909.           LogPos.v := LogPos.v + 1;
  910.           END;
  911.    END;
  912.  
  913.    PROCEDURE MoveLeft(P:RefPlayerRecord);
  914.    { This procedure moves a player one square left (if possible) }
  915.    VAR NewPos: Point;
  916.    BEGIN
  917.       WITH P^ DO if NOT MazeMap[LogPos.v][LogPos.h-1] THEN BEGIN
  918.           NewPos.v := Position.v;
  919.           NewPos.h := Position.h - SSize;
  920.           MoveSymbol(Symbol,Position,NewPos);
  921.           Position := NewPos;
  922.           LogPos.h := LogPos.h - 1;
  923.       END;
  924.    END;
  925.  
  926.    PROCEDURE MoveRight(P:RefPlayerRecord);
  927.    { This procedure moves a player one square right (if possible) }
  928.    VAR NewPos: Point;
  929.    BEGIN
  930.        WITH P^ DO if NOT MazeMap[LogPos.v][LogPos.h+1] THEN BEGIN
  931.            NewPos.v := Position.v;
  932.            NewPos.h := Position.h + SSize;
  933.            MoveSymbol(Symbol, Position,NewPos);
  934.            Position := NewPos;
  935.            LogPos.h := LogPos.h + 1;
  936.        END;
  937.    END;
  938.  
  939.    PROCEDURE DrawStatus;
  940.    { This procedure is used to draw the status of all players in the game.
  941.      It is used to create the window during updates. }
  942.    VAR i : Integer;
  943.        L,T: Integer;
  944.        tr: Rect;
  945.        ScoreStr: STR255;
  946.    BEGIN
  947.        T := DnRect.Bottom + KSpace;
  948.        L := LRect.Left;
  949.        {TextMode(srcXor);}
  950.        {TextSize(TSize);}
  951.        FOR i := 1 TO LastStatUsed DO BEGIN
  952.            IF StatLines[i] <> NIL THEN WITH StatLines[i]^ DO BEGIN
  953.                MoveTo(L,T+TSize);
  954.                DrawChar(Symbol);
  955.                MoveTo(L+ColSep,T+TSize);
  956.                DrawString(Name);
  957.                MoveTo(L+ColSep+MaxString,T+TSize);
  958.                NumToString(Score,ScoreStr);
  959.                DrawString(ScoreStr);
  960.                END;
  961.            T := T + TSize + 2;
  962.            END;
  963.    END;
  964.  
  965.    PROCEDURE LabelButton(VAR R:Rect; S:Char);
  966.    { This procedure is used to draw the labls on the soft buttons }
  967.    BEGIN
  968.        TextMode(srcOr);
  969.        MoveTo(R.Left+KeyMidPoint.h,R.Top+KeyMidPoint.v);
  970.        DrawChar(S);
  971.        TextMode(srcXor);
  972.    END;
  973.  
  974.  
  975.    PROCEDURE DrawMaze;
  976.    { This procedure draws the maze, given the matrix defining it, along
  977.      with all symbols in the mazer. }
  978.    VAR
  979.         tr: Rect;
  980.         H,V,i: Integer;
  981.    BEGIN
  982.         SetRect(tr,LeftStart,UpStart,LeftStart+SSize,UpStart+SSize);
  983.         FOR V := 0 TO VMazeSize DO BEGIN
  984.             FOR H := 0 TO HMazeSize DO BEGIN
  985.                 IF MazeMap[v][h] THEN FillRect(tr,black)
  986.                                  ELSE FillRect(tr,white);
  987.                 tr.left := tr.right;
  988.                 tr.right := tr.right + SSize;
  989.                 END; { end of inner for }
  990.             tr.left := LeftStart;
  991.             tr.right := tr.left+SSize;
  992.             tr.top := tr.bottom;
  993.             tr.bottom := tr.bottom + SSize;
  994.             END;
  995.  
  996.           {TextMode(srcXor);}
  997.           {TextSize(TSize);}
  998.           FOR i := 0 TO LastPlayer DO
  999.               IF Players[i] <> NIL THEN BEGIN
  1000.                 MoveTo(Players[i]^.Position.h, Players[i]^.Position.v);
  1001.                 DrawChar(Players[i]^.Symbol);
  1002.                 END;
  1003.  
  1004.          DrawStatus;
  1005.  
  1006.          { And set up the soft buttons on the screen }
  1007.          FrameRect(LRect); FrameRect(RRect);FrameRect(UpRect);FrameRect(DnRect);
  1008.          FrameRect(LFRect); FrameRect(RFRect);FrameRect(UFRect);FrameRect(DFRect);
  1009.  
  1010.          LabelButton(LRect,'L');
  1011.          LabelButton(RRect,'R');
  1012.          LabelButton(UpRect,'U');
  1013.          LabelButton(DnRect,'D');
  1014.  
  1015.    END;
  1016.  
  1017.    PROCEDURE SetUpMenus;
  1018.    { Once-only initialization for menus }
  1019.  
  1020.       VAR
  1021.          i: INTEGER;
  1022.  
  1023.       BEGIN
  1024.          InitMenus; { initialize Menu Manager }
  1025.          myMenus[1] := GetMenu(appleMenu);
  1026.          AddResMenu(myMenus[1],'DRVR'); { desk accessories }
  1027.          myMenus[2] := GetMenu(fileMenu);
  1028.          myMenus[3] := GetMenu(MoveMenu);
  1029.          myMenus[4] := GetMenu(autoMenu);
  1030.          FOR i := 1 TO lastMenu DO InsertMenu(myMenus[i],0);
  1031.          DrawMenuBar;
  1032.       END; { of SetUpMenus }
  1033.  
  1034.    PROCEDURE DoCommand(mResult: LongInt);
  1035.  
  1036.       VAR
  1037.          name: STR255;
  1038.          NewPos: Point;
  1039.  
  1040.       BEGIN
  1041.          theMenu := HiWord(mResult); theItem := LoWord(mResult);
  1042.          CASE theMenu OF
  1043.  
  1044.             appleMenu:
  1045.                BEGIN
  1046.                GetItem(myMenus[1],theItem,name);
  1047.                refNum := OpenDeskAcc(name);
  1048.                END;
  1049.  
  1050.             fileMenu: BEGIN
  1051.                          doneFlag := TRUE; { Quit }
  1052.                          ReportPlace(Players[Me],QuitIndicator);
  1053.                       END;
  1054.  
  1055.             MoveMenu:
  1056.                   BEGIN
  1057.                   SetPort(myWindow);
  1058.                   CASE theItem OF
  1059.  
  1060.                      1: BEGIN { Down }
  1061.                             MoveDown(Players[Me]);
  1062.                         END;
  1063.  
  1064.                      2:     BEGIN {Up }
  1065.                             MoveUp(Players[Me]);
  1066.                          END;
  1067.  
  1068.                      3: BEGIN { left }
  1069.                             MoveLeft(Players[Me]);
  1070.                         END;
  1071.  
  1072.                      4: BEGIN { right}
  1073.                             MoveRight(Players[Me]);
  1074.                         END;
  1075.  
  1076.                   END; { of item case }
  1077.                   ReportPlace(Players[Me],NotHitIndicator);
  1078.                END; { of moveMenu }
  1079.  
  1080.             autoMenu: BEGIN
  1081.                       CASE theItem OF
  1082.                       1: BEGIN PilotOn := NOT PilotOn;
  1083.                                IF PilotOn THEN BEGIN
  1084.                                                SetItem(MyMenus[4],1,'Stop Autopilot');
  1085.                                                APTime := TickCount;
  1086.                                                END
  1087.                                           ELSE BEGIN
  1088.                                               SetItem(MyMenus[4],1,'Start Autopilot');
  1089.                                           END;
  1090.                          END;
  1091.                        2: BEGIN
  1092.                              UseSoundeEffects := NOT UseSoundEffects;
  1093.                              CheckItem(MyMenus[4],2,UseSoundEffects);
  1094.                              IF UseSoundEffects THEN { Just load it }
  1095.                                  TalkDummy :=  mSpeak('',0,0,0);
  1096.  
  1097.                           END;
  1098.  
  1099.                        3: BEGIN { Display received packets }
  1100.                               DoDisplay := NOT DoDisplay;
  1101.                               CheckItem(MyMenus[4],3,DoDisplay);
  1102.                           END;
  1103.  
  1104.                        4: BEGIN { Stop Listening }
  1105.                              DoListen := NOT DoListen;
  1106.                              IF DoListen
  1107.                                  THEN SetItem(MyMenus[4],4,'Stop Listening')
  1108.                                  ELSE SetItem(MyMenus[4],4,'Start Listening');
  1109.                           END;
  1110.  
  1111.                        5: BEGIN { Stop Sending }
  1112.                              DoSend := NOT DoSend;
  1113.                              IF DoSend
  1114.                                  THEN SetItem(MyMenus[4],5,'Stop Sending')
  1115.                                  ELSE SetItem(MyMenus[4],5,'Start Sending');
  1116.                           END;
  1117.  
  1118.                        6: BEGIN { Remove Inactive players }
  1119.                              DoRemove := NOT DoRemove;
  1120.                              IF DoRemove
  1121.                                  THEN SetItem(MyMenus[4],6,'Keep Inactive Players')
  1122.                                  ELSE SetItem(MyMenus[4],6,'Remove Inactive Players');
  1123.                           END;
  1124.  
  1125.                        7: BEGIN { Send Bad Packet }
  1126.                              SendBadPkt;
  1127.                           END;
  1128.                       END;
  1129.                       END;
  1130.  
  1131.          END; { of menu case }
  1132.          HiliteMenu(0);
  1133.  
  1134.       END; { of DoCommand }
  1135.  
  1136.    PROCEDURE DoKeyEvent(c:CHAR);
  1137.    { Translate keyboard keys into commands }
  1138.    BEGIN
  1139.        CASE c OF
  1140.           'a','A': FireLeft(Players[Me]);
  1141.           'd','D': FireRight(Players[Me]);
  1142.           'w','W': FireUp(Players[Me]);
  1143.           'x','X': FireDown(Players[Me]);
  1144.           'h','H': MoveLeft(Players[Me]);
  1145.           'k','K': MoveRight(Players[Me]);
  1146.           'u','U': MoveUp(Players[Me]);
  1147.           'm','M': MoveDown(Players[Me]);
  1148.        END;
  1149.        ReportPlace(Players[Me],NotHitIndicator);
  1150.    END;
  1151.  
  1152.    PROCEDURE RemovePlayer(ID:Byte);
  1153.    { Player ID has gone away by timeout or by request, so recover
  1154.      the player record and the status line. Also wipe him and his
  1155.      bullets from the maze. }
  1156.    BEGIN
  1157.        IF Players[ID] <> NIL THEN BEGIN
  1158.            { he really existed! }
  1159.            WITH Players[ID]^ DO BEGIN
  1160.                { Get rid of his player marker }
  1161.                FirstSymbol(Symbol,Position);
  1162.                { Get rid of any bullets }
  1163.                IF FireDir <> None THEN FirstSymbol(BulletSymbol,BulletPos);
  1164.                { Delete his status line from display }
  1165.                EraseStatus(Players[ID],PlayerLine[ID]);
  1166.                END;
  1167.            StatLines[PlayerLine[ID]] := NIL; { Release status line }
  1168.            PlayerLine[ID] := 0;
  1169.            DisposPtr(PTR(Players[ID]));
  1170.            Players[ID] := NIL;
  1171.            END;
  1172.    END;
  1173.  
  1174.  
  1175.    CONST
  1176.        HitAnotherScore =  20;
  1177.        HitByAnother    = -10;
  1178.  
  1179.    PROCEDURE ProcessPkt;
  1180.    VAR tmpBuf: LongReport;
  1181.        i:  Integer;
  1182.        CurSize: Integer;
  1183.        OldPlace: Point;
  1184.        RcdBad: Boolean;
  1185.        NodeFrom, NodeTo: Byte;
  1186.        ProtUsed: Byte;
  1187.  
  1188.        PROCEDURE AddNewPlayer;
  1189.        { Create a new player based on received packet }
  1190.        BEGIN
  1191.            InitPlayer(tmpBuf.UniqueID);
  1192.            IF Players[tmpBuf.UniqueID] <> NIL THEN BEGIN
  1193.              WITH Players[tmpBuf.UniqueID]^ DO BEGIN
  1194.                 Symbol := tmpBuf.Symbol;
  1195.                 UniqueID:= tmpBuf.UniqueID;
  1196.                 FireDir := tmpBuf.FireDir;
  1197.                 Position:= tmpBuf.Position;
  1198.                 LogPos := tmpBuf.LogPos;
  1199.                 Score := tmpBuf.Score;
  1200.                 BulletPos := tmpBuf.BulletPos;
  1201.                 LogBulletPos := tmpBuf.LogBulletPos;
  1202.                 IF CurSize = sizeof(LongReport)
  1203.                       THEN Name := tmpBuf.Name
  1204.                       ELSE Name := '';
  1205.                 FirstSymbol(Symbol,Position);
  1206.                 IF FireDir <> None THEN FirstSymbol(BulletSymbol,BulletPos);
  1207.                 END;
  1208.              FirstStatus(Players[tmpBuf.UniqueID]);
  1209.            END;
  1210.  
  1211.        END;
  1212.  
  1213.        FUNCTION ValidPkt: BOOLEAN;
  1214.        { See if the received packet is legal }
  1215.        BEGIN
  1216.            ValidPkt := TRUE;
  1217.            IF RcdBad THEN ValidPkt := FALSE
  1218.            ELSE IF ProtUsed <> MazeProtocol THEN ValidPkt := FALSE
  1219.            ELSE IF NodeTo <> $FF THEN ValidPkt := FALSE
  1220.            ELSE WITH tmpBuf DO BEGIN
  1221.                IF       NodeFrom <> UniqueID THEN ValidPkt := FALSE
  1222.                ELSE IF ( ORD(FireDir) < ORD(Up) ) OR
  1223.                        ( ORD(FireDir) > ORD(None) ) THEN ValidPkt := FALSE
  1224.                ELSE IF ( ORD(LogPos.h) < -1 ) OR
  1225.                        ( ORD(LogPos.h) > HMazeSize ) THEN ValidPkt := FALSE
  1226.                ELSE IF ( ORD(LogPos.v) < -1 ) OR
  1227.                        ( ORD(LogPos.v) > VMazeSize ) THEN ValidPkt := FALSE
  1228.                ELSE IF ( ORD(LogBulletPos.h) < -1 ) OR
  1229.                        ( ORD(LogBulletPos.h) > HMazeSize ) THEN ValidPkt := FALSE
  1230.                ELSE IF ( ORD(LogBulletPos.v) < -1 ) OR
  1231.                        ( ORD(LogBulletPos.v) > VMazeSize ) THEN ValidPkt := FALSE
  1232.                END;
  1233.        END;
  1234.  
  1235.    BEGIN
  1236.        { Get the data }
  1237.        tmpBuf := InBuf;
  1238.        { Reenable the read }
  1239.        WITH InputH^^ DO BEGIN
  1240.             RcdBad := ( abResult <> noErr);
  1241.             CurSize := lapActCount;
  1242.             NodeFrom := lapAddress.srcNodeID;
  1243.             NodeTo := lapAddress.dstNodeId;
  1244.             ProtUsed := lapAddress.LAPProtType;
  1245.             lapAddress.LAPProtType := MazeProtocol;
  1246.             lapAddress.dstNodeID := $FF;
  1247.             lapReqCount := sizeof(LongReport);
  1248.             InBuf.Size := sizeof(LongReport);
  1249.             lapDataPtr := @InBuf;
  1250.             END;
  1251.  
  1252.         RetStatus := LAPRead(InputH,AsyncCall);
  1253.  
  1254.         IF NOT DoListen THEN EXIT(ProcessPkt);
  1255.  
  1256.         IF DoDisplay THEN DisplayPkt(@tmpBuf);
  1257.  
  1258.         { See if the packet is believeable }
  1259.        IF NOT ValidPkt THEN BEGIN
  1260.            SysBeep(5);
  1261.            EXIT(ProcessPkt);
  1262.            END;
  1263.  
  1264.         { Mark this guy as still alive }
  1265.         LastSeen[tmpBuf.UniqueID] := TickCount;
  1266.  
  1267.         { See if you've hit someone }
  1268.         IF tmpBuf.HitBy = Players[Me]^.UniqueID THEN BEGIN
  1269.             { Yep, gotcha }
  1270.             UpDateStatus(Players[Me],Players[Me]^.Name,
  1271.                          Players[Me]^.Score + HitAnotherScore);
  1272.             Players[Me]^.Score := Players[Me]^.Score + HitAnotherScore;
  1273.             TurnOffBullet(Players[Me]);
  1274.             IF UseSoundEffects THEN TalkDummy := mSpeak('/gAAt \yAA',5,5,5);
  1275.             END;
  1276.  
  1277.         { See if you've been hit }
  1278.         IF (tmpBuf.LogBulletPos.h = Players[Me]^.LogPos.h) AND
  1279.            (tmpBuf.LogBulletPos.v = Players[Me]^.LogPos.v)
  1280.                 THEN BEGIN
  1281.                 UpDateStatus(Players[Me],Players[Me]^.Name,
  1282.                              Players[Me]^.Score + HitByAnother);
  1283.                 Players[Me]^.Score := Players[Me]^.Score + HitByAnother;
  1284.                 { Pick a new random place }
  1285.                 OldPlace := Players[Me]^.Position;
  1286.                 PlacePlayer(Players[Me]);
  1287.                 MoveSymbol(Players[Me]^.Symbol,OldPlace,Players[Me]^.Position);
  1288.                 { Send a Hit-by packet }
  1289.                 ReportPlace(Players[Me],tmpBuf.UniqueID);
  1290.                 IF UseSoundEffects THEN TalkDummy := mSpeak('UHps',5,5,5);
  1291.                 END;
  1292.  
  1293.         { See if someone is quiting }
  1294.         IF tmpBuf.HitBy = QuitIndicator THEN BEGIN
  1295.             RemovePlayer(tmpBuf.UniqueID);
  1296.             EXIT(ProcessPkt); {He's gone, so nothing to update }
  1297.             END;
  1298.  
  1299.         { See if we already know this player }
  1300.         IF PlayerLine[tmpBuf.UniqueID] <> 0 THEN
  1301.             WITH StatLines[PlayerLine[tmpBuf.UniqueID]]^ DO BEGIN
  1302.                 { Found 'em, now update info }
  1303.                 MoveSymbol(Symbol,Position,tmpBuf.Position);
  1304.                 IF (FireDir <> None) AND (tmpBuf.FireDir =  None) THEN
  1305.                     FirstSymbol(BulletSymbol,BulletPos)
  1306.                 ELSE IF (FireDir =  None) AND (tmpBuf.FireDir <> None) THEN
  1307.                     FirstSymbol(BulletSymbol,tmpBuf.BulletPos)
  1308.                 ELSE IF (FireDir <> None) AND (tmpBuf.FireDir <> None) THEN
  1309.                     MoveSymbol(BulletSymbol,BulletPos,tmpBuf.BulletPos);
  1310.                 FireDir := tmpBuf.FireDir;
  1311.                 Position := tmpBuf.Position;
  1312.                 LogPos := tmpBuf.LogPos;
  1313.                 BulletPos := tmpBuf.BulletPos;
  1314.                 LogBulletPos := tmpBuf.LogBulletPos;
  1315.                 IF CurSize = sizeof(LongReport) THEN
  1316.                     UpDateStatus(StatLines[PlayerLine[tmpBuf.UniqueID]],
  1317.                              tmpBuf.Name,tmpBuf.Score)
  1318.                 ELSE
  1319.                     UpDateStatus(StatLines[PlayerLine[tmpBuf.UniqueID]],
  1320.                              StatLines[PlayerLine[tmpBuf.UniqueID]]^.Name,
  1321.                              tmpBuf.Score);
  1322.                 Score := tmpBuf.Score;
  1323.                 EXIT(ProcessPkt);
  1324.                 END; { end of if }
  1325.  
  1326.         { Not already in the list, so add it }
  1327.         AddNewPlayer;
  1328.  
  1329.    END;
  1330.  
  1331.  
  1332.    PROCEDURE CheckNetEvent;
  1333.    { This checks to see if a packet reeception did not post an event }
  1334.    BEGIN
  1335.  
  1336.        IF (InputH^^.abResult <> 1) THEN ProcessPkt;
  1337.  
  1338.    END;
  1339.  
  1340.    PROCEDURE CheckBullet;
  1341.    { This is the routine that periodically updates the progress of
  1342.      a fired bullet as it makes it way across the screen }
  1343.    VAR NewLPos:MazePoint;
  1344.        NewPos: Point;
  1345.    BEGIN
  1346.        IF Players[Me]^.FireDir <> None THEN BEGIN
  1347.            IF TickCount > BulletUpdate THEN WITH Players[Me]^ DO BEGIN
  1348.                { Figure out which direction, see if wall in the way,
  1349.                  if not, move it and update status }
  1350.                NewLPos := LogBulletPos;
  1351.                CASE FireDir OF
  1352.                   UpFire:     NewLPos.v := NewLPos.v - 1;
  1353.                   DownFire:   NewLPos.v := NewLPos.v + 1;
  1354.                   LeftFire:   NewLPos.h := NewLPos.h - 1;
  1355.                   RightFire:  NewLPos.h := NewLPos.h + 1;
  1356.                END; { of case }
  1357.                {See if new position is legal }
  1358.                IF MazeMap[NewLPos.v][NewLPos.h] THEN BEGIN
  1359.                    { Bullet hit wall of maze, so its finished }
  1360.                    TurnOffBullet(Players[Me]);
  1361.                    BulletUpDate := TickCount + TickCount;
  1362.                    END
  1363.                ELSE BEGIN
  1364.                    { Bullet is still running, so find next place and
  1365.                      update time for update }
  1366.                     NewPos := BulletPos;
  1367.                     CASE FireDir OF
  1368.                         UpFire:        NewPos.v := NewPos.v - SSize;
  1369.                         DownFire:   NewPos.v := NewPos.v + SSize;
  1370.                         LeftFire:   NewPos.h := NewPos.h - SSize;
  1371.                         RightFire:  NewPos.h := NewPos.h + SSize;
  1372.                     END;
  1373.                     MoveSymbol(BulletSymbol,BulletPos,NewPos);
  1374.                     BulletPos := NewPos;
  1375.                     LogBulletPos := NewLPos;
  1376.                     BulletUpdate := BulletUpdate + TickperSquare;
  1377.                    END;
  1378.                ReportPlace(Players[Me],NotHitIndicator);
  1379.                END;
  1380.            END;
  1381.    END;
  1382.  
  1383.  
  1384.  
  1385.    PROCEDURE CheckPilot;
  1386.    { This is the procedure used for running in autopilot mode. It's not
  1387.      very smart, it is used only for testing purposes. }
  1388.    VAR RetStatus: OSErr;
  1389.    BEGIN
  1390.        IF PilotOn THEN IF APTime < TickCount THEN BEGIN
  1391.            { Time to make a move! }
  1392.            REPEAT WhatToDo := Random MOD 5; UNTIL WhatToDo >= 0;
  1393.            CASE WhatToDo OF
  1394.               0: {Do nothing };
  1395.               1: {move up}      MoveUp(Players[Me]);
  1396.               2: {move down}    MoveDown(Players[Me]);
  1397.               3: {move left}    MoveLeft(Players[Me]);
  1398.               4: {move right}   MoveRight(Players[Me]);
  1399.            END;
  1400.            REPEAT WhatToDo := Random MOD 5; UNTIL WhatToDo >= 0;
  1401.            CASE WhatToDo OF
  1402.               0: {Do nothing };
  1403.               1: {shoot up}     FireUp(Players[Me]);
  1404.               2: {shoot down}     FireDown(Players[Me]);
  1405.               3: {shoot left}     FireLeft(Players[Me]);
  1406.               4: {shoot right}     FireRight(Players[Me]);
  1407.            END;
  1408.            APTime := APTime + APWait;
  1409.            END;
  1410.    END;
  1411.  
  1412.    CONST
  1413.        DeadTicks = 60 * 30; { 60 ticks per second, 30 seconds idle }
  1414.    PROCEDURE CheckDead;
  1415.    { This procedure watches out for dead players -- quit or walked away }
  1416.    VAR
  1417.        OldDeadCheck: LongInt;
  1418.        i: Integer;
  1419.    BEGIN
  1420.        IF NOT DoRemove THEN EXIT(CheckDead);
  1421.  
  1422.        LastSeen[Me] := TickCount;
  1423.        IF NextDeadCheck < TickCount THEN BEGIN
  1424.            { Timer elapsed, go look at who has gone away }
  1425.            OldDeadCheck := NextDeadCheck - DeadTicks;
  1426.            {FOR i := 0 TO 255 DO
  1427.                IF (Players[i] <> NIL) AND (LastSeen[i] < OldDeadCheck)
  1428.                    THEN RemovePlayer(i);}
  1429.            FOR i := 1 To LastStatUsed DO
  1430.                IF StatLines[i] <> NIL THEN
  1431.                    IF LastSeen[StatLines[i]^.UniqueID] < OldDeadCheck THEN
  1432.                        RemovePlayer(StatLines[i]^.UniqueID);
  1433.            NextDeadCheck := TickCount + DeadTicks;
  1434.            END;
  1435.    END;
  1436.  
  1437.    BEGIN { main program }
  1438.       InitGraf(@thePort);
  1439.       InitFonts;
  1440.       FlushEvents(everyEvent,0);
  1441.       InitWindows;
  1442.       SetUpMenus;
  1443.       TEInit;
  1444.       InitDialogs(NIL);
  1445.       InitCursor;
  1446.  
  1447.       screenRect := screenBits.bounds;
  1448.       SetRect(dragRect,4,24,screenRect.right-4,screenRect.bottom-4);
  1449.       doneFlag := FALSE;
  1450.  
  1451.       myWindow := GetNewWindow(256,@wRecord,POINTER(-1));
  1452.       SetPort(myWindow);
  1453.  
  1454.       pRect := thePort^.portRect;
  1455.       InsetRect(pRect,4,0);
  1456.       {hTE := TENew(pRect,pRect);}
  1457.       UpdateCnt := 0;
  1458.       InitMaze;
  1459.       PilotOn := FALSE;
  1460.  
  1461.       REPEAT
  1462.          SystemTask;
  1463.          {TEIdle(hTE);}
  1464.          if GetNextEvent(everyEvent,myEvent) then
  1465.          CASE myEvent.what OF
  1466.  
  1467.             mouseDown:
  1468.                BEGIN
  1469.                code := FindWindow(myEvent.where,whichWindow);
  1470.                CASE code OF
  1471.  
  1472.                   inMenuBar: DoCommand(MenuSelect(myEvent.where));
  1473.  
  1474.                   inSysWindow: SystemClick(myEvent,whichWindow);
  1475.  
  1476.                   inDrag: DragWindow(whichWindow,myEvent.where,dragRect);
  1477.  
  1478.                   inGrow,inContent:
  1479.                      BEGIN
  1480.                      IF whichWindow<>FrontWindow THEN
  1481.                         SelectWindow(whichWindow)
  1482.                      ELSE
  1483.                         BEGIN
  1484.                         GlobalToLocal(myEvent.where);
  1485.                         IF PtInRect(myEvent.where,LFRect) THEN BEGIN
  1486.                             InvertRect(LFRect);
  1487.                             ButtonSelected := LeftFire;
  1488.                             FireLeft(Players[Me])
  1489.                             END
  1490.                         ELSE IF PtInRect(myEvent.where,RFRect) THEN BEGIN
  1491.                             InvertRect(RFRect);
  1492.                             ButtonSelected := RightFire;
  1493.                             FireRight(Players[Me])
  1494.                             END
  1495.                         ELSE IF PtInRect(myEvent.where,UFRect) THEN BEGIN
  1496.                             InvertRect(UFRect);
  1497.                             ButtonSelected := UpFire;
  1498.                             FireUp(Players[Me])
  1499.                             END
  1500.                         ELSE IF PtInRect(myEvent.where,DFRect) THEN BEGIN
  1501.                             InvertRect(DFRect);
  1502.                             ButtonSelected := DownFire;
  1503.                             FireDown(Players[Me])
  1504.                             END
  1505.                         ELSE IF PtInRect(myEvent.where,LRect) THEN BEGIN
  1506.                             InvertRect(LRect);
  1507.                             ButtonSelected := Left;
  1508.                             MoveLeft(Players[Me])
  1509.                             END
  1510.                         ELSE IF PtInRect(myEvent.where,RRect) THEN BEGIN
  1511.                             InvertRect(RRect);
  1512.                             ButtonSelected := Right;
  1513.                             MoveRight(Players[Me])
  1514.                             END
  1515.                         ELSE IF PtInRect(myEvent.where,UpRect) THEN BEGIN
  1516.                             InvertRect(UpRect);
  1517.                             ButtonSelected := Up;
  1518.                             MoveUp(Players[Me])
  1519.                             END
  1520.                         ELSE IF PtInRect(myEvent.where,DnRect) THEN BEGIN
  1521.                             InvertRect(DnRect);
  1522.                             ButtonSelected := Down;
  1523.                             MoveDown(Players[Me])
  1524.                             END;
  1525.                         ReportPlace(Players[Me],NotHitIndicator);
  1526.                         END;
  1527.                      END;
  1528.  
  1529.                END; { of code case }
  1530.                END; { of mouseDown }
  1531.  
  1532.             mouseUp:
  1533.                BEGIN
  1534.                code := FindWindow(myEvent.where,whichWindow);
  1535.                CASE code OF
  1536.  
  1537.                   inGrow,inContent:
  1538.                      BEGIN
  1539.                      IF whichWindow=FrontWindow THEN
  1540.                         BEGIN
  1541.                            CASE ButtonSelected OF
  1542.                                Left: InvertRect(LRect);
  1543.                                Right: InvertRect(RRect);
  1544.                                Down: InvertRect(DnRect);
  1545.                                Up: InvertRect(UpRect);
  1546.                                LeftFire: InvertRect(LFRect);
  1547.                                RightFire: InvertRect(RFRect);
  1548.                                DownFire: InvertRect(DFRect);
  1549.                                UpFire: InvertRect(UFRect);
  1550.                                None:;
  1551.                            END;
  1552.                            ButtonSelected := None;
  1553.                         END;
  1554.                      END;
  1555.  
  1556.                END; { of code case }
  1557.                END; { of mouseDown }
  1558.  
  1559.             keyDown,autoKey: DoKeyEvent(CHR(myEvent.message MOD 256));
  1560.  
  1561.             activateEvt:;
  1562.  
  1563.             NetEvt: CheckNetEvent;
  1564.  
  1565.             updateEvt:
  1566.                BEGIN
  1567.                SetPort(myWindow);
  1568.                BeginUpdate(myWindow);
  1569.                EraseRect (thePort^.visRgn^^.rgnBBox);
  1570.                DrawMaze;
  1571.                IF FirstActivate THEN BEGIN
  1572.                    FirstStatus(Players[Me]);
  1573.                    FirstActivate := FALSE;
  1574.                    END;
  1575.                EndUpdate(myWindow);
  1576.                END; { of updateEvt }
  1577.  
  1578.          END; { of event case }
  1579.  
  1580.          { Check on the bullets }
  1581.          CheckBullet;
  1582.          { Check on the autopilot }
  1583.          CheckPilot;
  1584.          { Check on players that have done away }
  1585.          CheckDead;
  1586.  
  1587.          UpdateCnt := UpdateCnt + 1;
  1588.          IF UpdateCnt > UpdateRate THEN BEGIN
  1589.                 UpdateCnt := 0;
  1590.                 ReportPlace(Players[Me],NotHitIndicator);
  1591.                 CheckNetEvent;
  1592.                 END;
  1593.  
  1594.       UNTIL doneFlag;
  1595.       RetStatus := LAPCloseProtocol(MazeProtocol);
  1596.    END.
  1597. ________This_Is_The_END________
  1598. if test `wc -l < Maze.p` -ne 1567; then
  1599.     echo 'shar: Maze.p was damaged during transit'
  1600.   echo '      (should have been 1567 bytes)'
  1601. fi
  1602. fi        ; : end of overwriting check
  1603. echo 'Extracting Maze.r'
  1604. if test -f Maze.r; then echo 'shar: will not overwrite Maze.r'; else
  1605. cat << '________This_Is_The_END________' > Maze.r
  1606. *  EditR -- Resource input for small sample application
  1607. *         Written by Macintosh Technical Support
  1608. * SK 6/18  Made Edit menu items standard, added menu 1
  1609. *
  1610.  
  1611. * Appears to be an Appletalk maze game
  1612.  
  1613. mss/maze.Rsrc
  1614.  
  1615. Type MENU
  1616.   ,1
  1617.   \14
  1618.  
  1619.   ,256
  1620.   File
  1621.     Quit
  1622.  
  1623.   ,257
  1624.   Move
  1625.     Down
  1626.     Up
  1627.     Left
  1628.     Right
  1629.  
  1630.   ,258
  1631.   Player Control
  1632.     Start Autopilot
  1633.     Sound Effects
  1634.     Display Received Packets
  1635.     Stop Listening
  1636.     Stop Sending
  1637.     Keep Inactive Players
  1638.     Send Bad Packet
  1639.  
  1640.  
  1641.  
  1642. Type WIND
  1643.   ,256
  1644.   CS 88 New Improved Maze Game
  1645.   40 20 330 490
  1646.   Visible NoGoAway
  1647.   0
  1648.   0
  1649.  
  1650. Type DLOG
  1651.  ,1(4)
  1652.  30 20 170 490
  1653.  Visible 1 NoGoAway 0
  1654.  3
  1655.  
  1656. Type DITL
  1657.   ,3(4)
  1658.   7
  1659.   BtnItem Enabled
  1660.     20 110  40 190
  1661. OK
  1662.  
  1663.   BtnItem Enabled
  1664.     20 260 40 340
  1665. Cancel
  1666.  
  1667.   EditText Disabled
  1668.      55 205 70 350
  1669. Random User
  1670.  
  1671.   EditText Disabled
  1672.      80 205 95 350
  1673. A
  1674.  
  1675.   StatText Disabled
  1676.      105 10 135 350
  1677.  
  1678.  
  1679.   StatText Disabled
  1680.      55 10 70 190
  1681. Player Name:
  1682.  
  1683.   StatText Disabled
  1684.      80 10 95 200
  1685. Player Symbol (1 symbol):
  1686.  
  1687. Type DLOG
  1688.  ,2(4)
  1689.  30 20 320 490
  1690.  Visible 1 NoGoAway 0
  1691.  4
  1692.  
  1693. Type DITL
  1694.   ,4(4)
  1695.   33
  1696.   BtnItem Enabled
  1697.     20 230  40 340
  1698. OK
  1699.  
  1700.   StatText Disabled
  1701.     20 110 35 200
  1702. Field 1
  1703.  
  1704.   StatText Disabled
  1705.     40 110 55 200
  1706. Field 2
  1707.  
  1708.   StatText Disabled
  1709.     60 110 75 200
  1710. Field 3
  1711.  
  1712.   StatText Disabled
  1713.     80 110 95 200
  1714. Field 4
  1715.  
  1716.   StatText Disabled
  1717.     100 110 115 200
  1718. Field 5
  1719.  
  1720.   StatText Disabled
  1721.     120 110 135 200
  1722. Field 6
  1723.  
  1724.   StatText Disabled
  1725.     140 110 155 200
  1726. Field 7
  1727.  
  1728.   StatText Disabled
  1729.     160 110 175 200
  1730. Field 8
  1731.  
  1732.   StatText Disabled
  1733.     180 110 195 200
  1734. Field 9
  1735.  
  1736.   StatText Disabled
  1737.     100 350 115 410
  1738. Field 10
  1739.  
  1740.   StatText Disabled
  1741.     120 350 135 410
  1742. Field 11
  1743.  
  1744.   StatText Disabled
  1745.     140 350 155 410
  1746. Field 12
  1747.  
  1748.   StatText Disabled
  1749.     160 350 175 410
  1750. Field 13
  1751.  
  1752.   StatText Disabled
  1753.     180 350 195 410
  1754. Field 14
  1755.  
  1756.   StatText Disabled
  1757.     200 110 215 350
  1758. Field 15
  1759.  
  1760.   StatText Disabled
  1761.     20 10 35 100
  1762. Size
  1763.  
  1764.   StatText Disabled
  1765.     40 10 55 100
  1766. Symbol
  1767.  
  1768.   StatText Disabled
  1769.     60 10 75 100
  1770. UniqueID
  1771.  
  1772.   StatText Disabled
  1773.     80 10 95 100
  1774. FireDir
  1775.  
  1776.   StatText Disabled
  1777.     100 10 115 100
  1778. Position.H
  1779.  
  1780.   StatText Disabled
  1781.     120 10 135 100
  1782. Position.V
  1783.  
  1784.   StatText Disabled
  1785.     140 10 155 100
  1786. LogPos.H
  1787.  
  1788.   StatText Disabled
  1789.     160 10 175 100
  1790. LogPos.V
  1791.  
  1792.   StatText Disabled
  1793.     180 10 195 100
  1794. Score
  1795.  
  1796.   StatText Disabled
  1797.     100 230 115 340
  1798. BulletPos.H
  1799.  
  1800.   StatText Disabled
  1801.     120 230 135 340
  1802. BulletPos.V
  1803.  
  1804.   StatText Disabled
  1805.     140 230 155 340
  1806. LogBulletPos.H
  1807.  
  1808.   StatText Disabled
  1809.     160 230 175 340
  1810. LogBulletPos.V
  1811.  
  1812.   StatText Disabled
  1813.     180 230 195 340
  1814. HitBy
  1815.  
  1816.   StatText Disabled
  1817.     200 10 215 100
  1818. Name
  1819.  
  1820.   BtnItem Enabled
  1821.     50 230  70 340
  1822. Stop Display
  1823.  
  1824.   StatText Disabled
  1825.     235 10 280 420
  1826. Display of latest packet. Hit "OK" to continue reading packets and "Stop Display" to disbale the packet reading feature.
  1827.  
  1828. Type ICN# = HEXA
  1829.   ,128
  1830. * Little Maze
  1831.   FFFFFFFF
  1832.   FFFFFFFF
  1833.   CC066663
  1834.   CC066663
  1835.   CFE66603
  1836.   CFE66603
  1837.   CCC66663
  1838.   C0C60663
  1839.   C0C60663
  1840.   CC067E63
  1841.   CC067E63
  1842.   CFE60663
  1843.   CFE60663
  1844.   CC060063
  1845.   CC060063
  1846.   CFE7F863
  1847.   CFE7F863
  1848.   CC000063
  1849.   CC000063
  1850.   FFFFFE63
  1851.   FFFFFE63
  1852.   C0C00663
  1853.   C0C00663
  1854.   CFCFFE03
  1855.   CFCFFE03
  1856.   C0C00603
  1857.   C0C0067F
  1858.   CCC3067F
  1859.   CC030003
  1860.   CC030003
  1861.   FFFFFFFF
  1862.   FFFFFFFF
  1863. * and the mask
  1864.   FFFFFFFF
  1865.   FFFFFFFF
  1866.   FFFFFFFF
  1867.   FFFFFFFF
  1868.   FFFFFFFF
  1869.   FFFFFFFF
  1870.   FFFFFFFF
  1871.   FFFFFFFF
  1872.   FFFFFFFF
  1873.   FFFFFFFF
  1874.   FFFFFFFF
  1875.   FFFFFFFF
  1876.   FFFFFFFF
  1877.   FFFFFFFF
  1878.   FFFFFFFF
  1879.   FFFFFFFF
  1880.   FFFFFFFF
  1881.   FFFFFFFF
  1882.   FFFFFFFF
  1883.   FFFFFFFF
  1884.   FFFFFFFF
  1885.   FFFFFFFF
  1886.   FFFFFFFF
  1887.   FFFFFFFF
  1888.   FFFFFFFF
  1889.   FFFFFFFF
  1890.   FFFFFFFF
  1891.   FFFFFFFF
  1892.   FFFFFFFF
  1893.   FFFFFFFF
  1894.   FFFFFFFF
  1895.   FFFFFFFF
  1896.  
  1897. type FREF = HEXA
  1898.   ,128
  1899.   4150504C
  1900.   0000
  1901.  
  1902. Type BNDL = HEXA
  1903.   ,128
  1904.   4D415A45 0000
  1905.   0001
  1906.   49434E23 0000
  1907.   0000 0080
  1908.   46524546 0000
  1909.   0000 0080
  1910.  
  1911. Type MAZE = STR
  1912. ,0
  1913. Maze Version 1.0    - 12 December 83
  1914.  
  1915. Type CODE
  1916.  mss/mazeL,0
  1917. ________This_Is_The_END________
  1918. if test `wc -l < Maze.r` -ne 311; then
  1919.     echo 'shar: Maze.r was damaged during transit'
  1920.   echo '      (should have been 311 bytes)'
  1921. fi
  1922. fi        ; : end of overwriting check
  1923. exit 0
  1924.