[Back to MENU SWAG index] [Back to Main SWAG index] [Original]

    { features include }
    { automatic string resizing }
    { hack proof, just leave the menucnst.pas available for general use}
    { easy to change colors }
    { automatic centring }
    { easy to use hot keys }
    { function to return value }
    { first declared is = 0, second is = 1, etc, etc }

    { if you use this program we take no responsiblity for anything that may
      happen to your computer }

    { THE ANDAL PROGRAMMING CORPORATION }

    { any bugs or ideas or help with dos or menus etc, please contact
      us at FERRET_@HOTMAIL.COM}

    uses
    crt,menubox;

    var
       a:byte;
       x:menu;
    begin
         x.setup;
         x.additem(' m~e~nu item 1'); {example of a hotkey }
         x.additem(' menu item 2');   {without a hotkey }
         x.additem(' ~m~enu item 3'); {with one again}
         x.additem(' menu item 4');
         a := x.run(' this is a little demo ',true);
         x.shutdown;
    end.

    { ----------------   UNITS NEEDED HERE ------------ }

    UNIT MenuBox;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    INTERFACE
    USES CRT,Shorten,MenuCnst;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                            { -- CONSTANT VALUES -- }

    CONST
         Up     = TRUE;                             {Up arrow goes up -);        }
         Down   = FALSE;                            {Down arrow does the opposite}

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                             { -- THE MENU OBJECT -- }

    TYPE

      Menu = OBJECT                                 {The Whole Kit + Kabodal     }
      Items   : ARRAY [0..24] OF ^STRING;           {Pointers to 25 strings      }
      NoItems : BYTE;                               {How many items do I have??  }
      CurItem : BYTE;                               {Which Item am I up to??     }
      PROCEDURE Setup;                              {Call this every time you run}
      PROCEDURE AddItem(Str : STRING);              {Call to add an item new line}
      PROCEDURE ShutDown;                           {Dynamic shutdown            }
      FUNCTION Run(TitleStr  : STRING;              {Run!!! - returns value = to }
                   DrawTitle : BOOLEAN) : BYTE;     {the item number 0 = the 1st }
      END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                           { -- PUBLIC PROCEDURES -- }
    PROCEDURE MenuExit;

                            { -- PUBLIC VARIABLES -- }
    VAR
       M : Menu;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    IMPLEMENTATION

                             { -- PRIVATE CALLS -- }

    {PROCEDURE MWriteXY(Index : BYTE);}
    {PROCEDURE Main(Dir : BOOLEAN);}
    {PROCEDURE ElseAnalyse;}

                           { -- PRIVATE VARIABLES -- }

    VAR
       ExitPtr : POINTER;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE Menu.Setup;                           {Do the standard object VAR  }
    BEGIN                                           {setup sequence, set to 0    }
         NoItems := 0;
         CurItem := 0;
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE Menu.AddItem(Str : STRING);           {Get's a bit tricky here...  }
    BEGIN
         GETMEM(Items[NoItems],SIZEOF(STRING));     {allocate memory for a string}
         Items[NoItems]^ := Str;                    {give it the value of param  }
         INC(NoItems);                              {you now have another item!  }
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE Menu.ShutDown;                        {  >>> MUST BE CALLED <<<    }
    VAR
       DelNo : BYTE;                                {Counter variable            }
    BEGIN
         IF NoItems >= 1 THEN
           FOR DelNo := 0 TO NoItems-1 DO           {Start at start + do all items}
             FreeMem(Items[DelNo],SIZEOF(STRING));  {deallocate all mem          }
         NoItems := 0;                              {reset stand. vars for next  }
         CurItem := 0;                              {time                        }
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE ResizeString(VAR   Str  : STRING;     { >>>>     PRIVATE     <<<<  }
                           CONST Maxl : BYTE);      {Cannot be called out of unit}
    VAR                                             {Procedure to do Auto resize }
       StrL : BYTE;                                 {on any strings              }
       D1   : BYTE;                                 {   It will append ' ' to end}
       C    : BYTE;                                 { + start of the string till }
    BEGIN                                           {it reaches the right length }
         StrL := LENGTH(Str);                       { Save String length         }
         IF POS('~',Str) <> 0 THEN                  { Adjust for '~' chars       }
           DEC(StrL,2);
         StrL := MaxL - StrL;                       {find how many chars out it  }
         D1   := StrL SHR 1;                        {is. Half that number        }
         StrL := StrL - D1;                         {put half in D1, other in    }
         FOR C := 1 TO D1 DO                        {StrL. Then append ' '''s    }
           Str := ' ' + Str;
         FOR C := 1 TO StrL DO
           Str := Str + ' ';
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    FUNCTION Menu.Run(TitleStr  : STRING;           { THIS IS IT BOYS + GIRLS    }
                      DrawTitle : BOOLEAN) : BYTE;  {Title + whether to write it }
    VAR
       X1    : BYTE;                                {frame co - ordinates        }
       Y1    : BYTE;
       X2    : BYTE;
       Y2    : BYTE;
       Ch    : CHAR;                                {letter to be read in        }
       Stop  : BOOLEAN;                             {stop check variable         }
       Count : BYTE;                                {multipurpose counting VAR   }

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                             { -- PRIVATE CALL -- }

    PROCEDURE MWriteXY(Index : BYTE);               {Menu Write at (X,Y)         }
    VAR                                             {index is the string number  }
       I : BYTE;                                    {to write. I is a counter    }
       H : BOOLEAN;                                 {H is do hotkey colors??     }
    BEGIN
         GOTOXY(X1+1,Y1+1+Index);                   {Move into position          }
         H := FALSE;                                {hotkey starts 'OFF'         }
         FOR I := 1 TO LENGTH(Items[Index]^) DO     {Check each letter           }
           BEGIN
             IF Items[Index]^[I] <> '~' THEN        {if it's a after a '~' then  }
               BEGIN                                {write in Hot Key Colors     }
                 IF H THEN
                   BEGIN
                     TC(HKCol);
                     WRITE(Items[Index]^[I]);
                   END
                 ELSE                               {... else do it standard cols}
                   BEGIN
                     TC(TCol);
                     WRITE(Items[Index]^[I]);
                   END;
               END
             ELSE                                   {code to switch from hot to  }
               BEGIN                                {non hot                     }
                 IF H THEN
                   H := FALSE
                 ELSE
                   H := TRUE
               END;
           END;
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                              { -- PRIVATE CALL -- }

    PROCEDURE Main(Dir : BOOLEAN);                  {Movement of status bar proc }
    BEGIN                                           {unhighlight last item       }
         TBG(BKCol);
         MWriteXY(CurItem);
         IF Dir = Up THEN                           {if it's going up then ...   }
           BEGIN
             IF CurItem <> 0 THEN                   {... go up ...               }
               DEC(CurItem)
             ELSE
               CurItem := NoItems - 1;              {... unless its at top then  }
           END                                      {go back to the bottom       }
         ELSE
           BEGIN                                    {as for up - but down -);    }
             IF CurItem <> NoItems -1 THEN
               INC(CurItem)
             ELSE
               CurItem := 0;
           END;
         TBG(HCol);                                 {Textcolor = Highlight color }
         MWriteXY(CurItem);                         {Write proper item highlit   }
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                             { -- PRIVATE CALL -- }

    PROCEDURE ElseAnalyse;                          {analyse non arrow key stroke}
    VAR
       I  : BYTE;                                   {multipurpose counting vars  }
       I2 : BYTE;
       L  : CHAR;
    BEGIN
         Ch := UPCASE(Ch);                          {set it to upper case        }
         IF Ch = Enter THEN BEGIN Run := CurItem; Stop := TRUE; END
         ELSE                                       {enter conditions ...        }
           FOR I := 0 TO NoItems-1 DO               { ... otherwise get Uppercase}
             BEGIN                                  {of each hotkey + compare it }
               FOR I2 := 1 TO LENGTH(Items[I]^) DO  {to that                     }
                 IF Items[I]^[I2] = '~' THEN
                   BEGIN
                     L := UPCASE(Items[I]^[I2+1]);
                     BREAK;                         {NB//: Break = Quit loop     }
                   END;
               IF Ch = L THEN BEGIN Run := I; Stop := TRUE; EXIT; END;
             END;                                   {if it is stop run + set it  }
    END;                                            {to string number            }

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    BEGIN {BODY OF RUN PROCEDURE}
                            { - INITIALIZATION PART - }
         CursorOff;
         Stop    := FALSE;
                         { - RANGE CHECKING ON STRINGS - }
         IF NoItems <= 1 THEN                       {If no items have been added }
           BEGIN                                    {then tell the user that and }
             TBG(BKCol);                            {then quit                   }
             TC(BKCol + 2);
             WriteC('Not enough Strings Initialized - Cannot Run Menu',12);
             WriteC('Press Any Key To Quit ...',13);
             READKEY;
             HALT;
           END;
                             { - FRAME X DIMENSION - }
         X1 := LENGTH(TitleStr);                    {Init max len var to title   }
         FOR Count := 0 TO NoItems-1 DO             {Do this for all items       }
           BEGIN
             X2 := LENGTH(Items[Count]^);           {Init tmp len var to str len }
             IF POS('~',Items[Count]^) <> 0 THEN    {if it has 2 '~' chars then  }
               DEC(X2,2);                           {minus them                  }
             IF X2 > X1 THEN                        {if tmp var is > max then    }
               X1 := X2;                            {reset max to show this.     }
           END;
                { - FRAME X DIMENSIONS (SUBBLOCK):- STRING RESIZING - }
         FOR Count := 0 TO NoItems-1 DO
           ResizeString(Items[Count]^,X1);          {Do string autoresize        }
                             { - FRAME X DIMENSIONS - }
         INC(X1);
         Count := X1;                               {move x1 so we can use it    }
         X1 := (80 - Count) SHR 1;                  {define the edges of the     }
         X2 := X1 + Count;                          {menu to a const for speed   }
                             { - FRAME Y DIMENSIONS - }
         Count := NoItems+1;                        {box size = number of items+1}
         IF DrawTitle THEN                          {unless you want a title     }
           INC(Count,TBlockSize);
         Y1 := (25 - Count) SHR 1;                  {calc y co - ords            }
         Y2 := Y1 + count;
                             { - BASIC SCREEN SETUP - }
         FBG(FBGS);                                 {Fill Background to constant }
         TBG(BKCol);                                {Set Text background color   }
         TC(BCol);                                  {Set Text Color              }
         Frame(X1,Y1,X2,Y2,BTyp,TRUE,' ');          {Draw the frame              }
         IF DrawTitle THEN                          {draw the title block        }
           BEGIN
             GOTOXY(X1,Y1+TBlockSize);
             IF BTyp = 1 THEN                       {adjust chars for style 1    }
               BEGIN
                 WRITE('Ã');
                 REPEAT
                   WRITE('Ä');
                 UNTIL WHEREX = X2;
                 WRITE('´');
               END;
             IF BTyp = 2 THEN                       {adjust chars for style 2    }
               BEGIN
                 WRITE('Ì');
                 REPEAT
                   WRITE('Í');
                 UNTIL WHEREX = X2;
                 WRITE('¹');
               END;
             WriteC(TitleStr,Y1 + (TBlockSize SHR 1));
             INC(Y1,TBlockSize);                    {write in the title block +  }
           END;                                     {adjust Y1 for it            }
                               { MENU ITEM LAYOUT }

         FOR Count := 1 TO NoItems-1 DO             {do the original write up    }
           MWriteXY(Count);                         {unhighlit                   }
         TBG(HCol);
         MWriteXY(0);                               {highlighted                 }
         REPEAT                                     {Repeat chance to read in    }
           Ch := READKEY;                           {key strokes                 }
           IF Ch = #0 THEN                          {trap function keys          }
             BEGIN
             Ch := READKEY;
               CASE Ch OF
                 #91       : HALT;                  {SHIFT F8 IS THE AUTO QUIT   }
                 UpArrow   : Main(Up);              {left arrow                  }
                 DownArrow : Main(Down);            {right arrow                 }
               END;
             END
           ELSE
             ElseAnalyse;                           {if not left or right analyse}
         UNTIL Stop;                                {stop when condition is true }
         CursorOn                                   {turn the cursor on          }
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                       { --=THINGS TO DO AFTER THE PROGRAM=-- }

    {$F+}
    PROCEDURE MenuExit;
    BEGIN
         EXITPROC := ExitPtr;
         M.ShutDown;
    END;
    {$F+}

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                   { --=THINGS TO DO BEFORE RUNNING THE PROGRAM=-- }

    BEGIN
         ExitPtr := EXITPROC;
         EXITPROC := @MenuExit;
         M.SetUp;
    END.
    ---------------------------- = [Cut Here] = ---------------------------------

    UNIT MenuCnst;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    INTERFACE

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    CONST
         HKCol  =  10;                              {Text Hot Key Color          }
         TCol   =  15;                              {Standard Text Color         }
         BKCol  =  1;                               {Standard Background Color   }
         HCol   =  3;                               {Highlight Background Color  }
         BTyp   =  2;                               {Boarder Type                }
         BCol   =  15;                              {Boarder Color               }
         FBGS   =  6576;                            {Fill Back Ground Style      }
         TBlockSize = 2;                            {Title Block Size            }

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    IMPLEMENTATION

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    END.
    ---------------------------- = [Cut Here] = ---------------------------------

    UNIT shorten;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    INTERFACE
    USES
        crt,graph;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
    TYPE
         Pallette = ARRAY [0..255,1..3] OF BYTE;
    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    CONST
         UpArrow    = #72;          {special keyboard calls}
         DownArrow  = #80;
         LeftArrow  = #75;
         RightArrow = #77;
         ESC        = #27;
         ALTX       = #45;
         Enter      = #13;

         DUpLeft    = #201;         {double line box operators}
         DUpRight   = #187;
         DLowLeft   = #200;
         DLowRight  = #188;
         DStraight  = #205;
         DDown      = #186;

         SUpLeft    = #218;         {single line box operators}
         SUpRight   = #191;
         SLowLeft   = #192;
         SLowRight  = #217;
         SStraight  = #196;
         SDown      = #179;

         Theta      = #233;         {math operator symbols}
         PIsym      = #227;
         SumOf      = #228;
         ExactEqual = #240;
         ApproxEqual= #247;
         GTOET      = #242;
         LTOET      = #243;
         ElementOf  = #238;
         Intersection = #239;

         Heart      = #3;           {card symbol operators}
         Spade      = #5;
         Diamond    = #4;
         Club       = #6;

         HighBG     = FALSE;
         LowBG      = TRUE;

         MyBG        = 20144;       {fill back ground styles}
         BlueGrayBG  = 5040;
         BlueWhiteBG = 8112;
         LBlueBlueBG = 6576;

         ScreenX    = 640;          {BGI screen size constants}
         ScreenY    = 480;
         HalfX      = 320;
         HalfY      = 240;

         VGA        = $A000;        {Screen memory position}
         MCGA       = $A000;
         DosScreen  = $B800;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                          { -- BGI BASIC INTERFACE -- }
    PROCEDURE GrInit;                            {Initiate the BGI               }
    PROCEDURE GrShutDown;                        {Close down the BGI             }

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                         { -- PALLETTE MANIPULATION -- }

    PROCEDURE Pal(Col : BYTE;
                  R   : BYTE;
                  G   : BYTE;
                  B   : BYTE);
    PROCEDURE GetPal(Col : BYTE;
                 VAR R   : BYTE;
                 VAR G   : BYTE;
                 VAR B   : BYTE);
    PROCEDURE WaitRetrace;
    PROCEDURE SavePallette(VAR Pall : Pallette);
    PROCEDURE RestorePallette(Pall : Pallette);
    PROCEDURE FadeToBlack;
    PROCEDURE FadeUp(Pall : Pallette);
    PROCEDURE BlackOut;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                            { -- CURSOR MANAGEMENT -- }

    PROCEDURE CursorOn;
    PROCEDURE CursorOff;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                      { -- MISCELL. FORMATTING ROUTINES -- }

    PROCEDURE WriteXY(Str : STRING;
                      X   : BYTE;
                      Y   : BYTE);
    PROCEDURE WriteC(Str : STRING;
                     Y   : BYTE);
    PROCEDURE Frame(x1, y1, x2, y2 : byte; {corner coords}
                      typ : byte;         {type of frame}
                      clr : boolean;      {clear inside?}
                      clrch : char);      {clear with what}
    PROCEDURE UpString(VAR Str : STRING);
    FUNCTION GetCh(X : BYTE;
                   Y : BYTE) : WORD;
    PROCEDURE TBG(X : BYTE);                   {Change textbackground --> abbr. }
    PROCEDURE TC(X : BYTE);                    {change textcolor --> abbr.      }
    PROCEDURE FBG(Col : WORD);                 {fill background to a word       }
    PROCEDURE FBG2(Where : WORD;               {fill bg --> to a vaddr or       }
                   Ascii : BYTE;               {to a specific ascii / color     }
                   Col   : BYTE);              {scheme                          }
    PROCEDURE SetBG(Back : BOOLEAN);           {turn on / off hi background cols}
    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                       { -- FILE MANAGEMENT ROUTINES -- }

    FUNCTION CheckForExtension(FileStr : STRING) : BOOLEAN;
    FUNCTION Exist(FileName : STRING): BOOLEAN;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                           { -- EXIT PROCEDURE -- }

    PROCEDURE MyExit;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                           { -- GLOBAL VARIABLES -- }
    VAR
       BackUpPalletteStorage : Pallette;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    IMPLEMENTATION
                          { -- PRIVATE VARIABLES -- }
    VAR
       ExitPtr : POINTER;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE Frame(x1, y1, x2, y2 : byte; {corner coords}
                      typ : byte;         {type of frame}
                      clr : boolean;      {clear inside?}
                      clrch : char);      {clear with what}
      TYPE fchars = (ulc, top, urc, side, lrc, llc);
      CONST fc : ARRAY[0..2] OF ARRAY[fchars] OF CHAR =
        ('      ', #218#196#191#179#217#192,
         #201#205#187#186#188#200);
      VAR
        ro,co : Byte;
        S     : String[80];
      BEGIN
        FillChar(S, SizeOf(S), fc[typ][top]);
        S[0] := char(pred(x2-x1));
        GotoXY(x1, y1);
        Write(fc[typ][ulc], S, fc[typ][urc]);
        GotoXY(x1, y2);
        Write(fc[typ][llc], S, fc[typ][lrc]);
        FillChar(S[1], pred(SizeOf(S)), clrch);
        FOR ro := succ(y1) TO pred(y2) DO
          IF clr THEN
            BEGIN
              GotoXY(x1, ro);
              Write(fc[typ][side], S, fc[typ][side])
            END
          ELSE
            BEGIN
              GotoXY(x1, ro); Write(fc[typ][side]);
              GotoXY(x2, ro); Write(fc[typ][side]);
            END;
      END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE FBG(Col   : WORD); ASSEMBLER;
    ASM
       push    es                           {Save ES segment on the stack        }
       mov     ax,0B800h                    {Put $0B800 in ax, start screen mem  }
       mov     es,ax                        {ES now points locat. in ax          }
       mov     cx,2000                      {CX := 2000                          }
       xor     di,di                        {Fast way of making di = 0           }
       mov     ax,[Col]                     {Hold the color in the AX register   }
       rep     stosw                        {start at ES ($B800), write AX (Fill)}
                                            {to memory at ES + DI, add 1 to DI   }
                                            {Stop when DI = CX (2000)            }
       pop     es                           {Restore ES off the stack            }
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE FBG2(Where : WORD;
                   Ascii : BYTE;
                   Col   : BYTE); ASSEMBLER;
    ASM
       push    es                           {Save ES segment on the stack        }
       mov     cx,2000                      {CX := 2000                          }
       mov     ax,[where]
       mov     es,ax                        {ES now points at start mem location }
       xor     di,di                        {Fast way of making di = 0           }
       mov     al,[Ascii]                   {Hold the character in the AX registr}
       mov     ah,[Col]                     {Hold the color in the AX register   }
       rep     stosw                        {start at ES ($B800), write AX (Fill)}
                                            {to memory at ES + DI, add 1 to DI   }
                                            {Stop when DI = CX (2000)            }
       pop     es                           {Restore ES off the stack            }
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE SetBG(Back : BOOLEAN); ASSEMBLER;
    ASM
         mov  AX,$1003
         mov  BL,Back
         int  $10
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE Pal(Col : BYTE;
                  R   : BYTE;
                  G   : BYTE;
                  B   : BYTE); ASSEMBLER;
      { This sets the Red, Green and Blue values of a certain color }
    ASM
       mov    dx,3c8h
       mov    al,[col]
       out    dx,al
       inc    dx
       mov    al,[r]
       out    dx,al
       mov    al,[g]
       out    dx,al
       mov    al,[b]
       out    dx,al
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE GetPal(Col : BYTE;
                 VAR R   : BYTE;
                 VAR G   : BYTE;
                 VAR B   : BYTE);
      { This gets the Red, Green and Blue values of a certain color }
    VAR
       rr : BYTE;
       gg : BYTE;
       bb : BYTE;
    BEGIN
       ASM
          mov    dx,3c7h
          mov    al,col
          out    dx,al

          add    dx,2

          in     al,dx
          mov    [rr],al
          in     al,dx
          mov    [gg],al
          in     al,dx
          mov    [bb],al
       END;
       r := rr;
       g := gg;
       b := bb;
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE WaitRetrace; ASSEMBLER;
    LABEL
      l1, l2;
    ASM
        mov dx,3DAh
    l1:
        in al,dx
        and al,08h
        jnz l1
    l2:
        in al,dx
        and al,08h
        jz  l2
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE SavePallette(VAR Pall : Pallette);
    VAR
       loop1 : INTEGER;
    BEGIN
         FOR loop1 := 0 TO 255 DO
           GetPal (loop1,pall[loop1,1],pall[loop1,2],pall[loop1,3]);
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE RestorePallette(Pall : Pallette);
      { This procedure restores the origional pallette }
    VAR
       loop1 : INTEGER;
    BEGIN
         WaitRetrace;
         For loop1:=0 to 255 do
           Pal (loop1,Pall[loop1,1],Pall[loop1,2],Pall[loop1,3]);
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    Procedure FadeToBlack;
      { This procedure fades the screen out to black. }
    VAR loop1,loop2:integer;
        Tmp : Array [1..3] of byte;
          { This is temporary storage for the values of a color }
    BEGIN
      For loop1:=1 to 64 do BEGIN
        WaitRetrace;
        For loop2:=0 to 255 do BEGIN
          Getpal (loop2,Tmp[1],Tmp[2],Tmp[3]);
          If Tmp[1]>0 then dec (Tmp[1]);
          If Tmp[2]>0 then dec (Tmp[2]);
          If Tmp[3]>0 then dec (Tmp[3]);
            { If the Red, Green or Blue values of color loop2 are not yet zero,
              then, decrease them by one. }
          Pal (loop2,Tmp[1],Tmp[2],Tmp[3]);
            { Set the new, altered pallette color. }
        END;
      END;
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    Procedure Fadeup(Pall : Pallette);
      { This procedure slowly fades up the new screen }
    VAR loop1,loop2:integer;
        Tmp : Array [1..3] of byte;
          { This is temporary storage for the values of a color }
    BEGIN
      For loop1:=1 to 64 do BEGIN
          { A color value for Red, green or blue is 0 to 63, so this loop only
            need be executed a maximum of 64 times }
        WaitRetrace;
        For loop2:=0 to 255 do BEGIN
          Getpal (loop2,Tmp[1],Tmp[2],Tmp[3]);
          If Tmp[1]<Pall[loop2,1] then inc (Tmp[1]);
          If Tmp[2]<Pall[loop2,2] then inc (Tmp[2]);
          If Tmp[3]<Pall[loop2,3] then inc (Tmp[3]);
            { If the Red, Green or Blue values of color loop2 are less then they
              should be, increase them by one. }
          Pal (loop2,Tmp[1],Tmp[2],Tmp[3]);
            { Set the new, altered pallette color. }
        END;
      END;
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    Procedure Blackout;
      { This procedure blackens the screen by setting the pallette values of
        all the colors to zero. }
    VAR loop1:integer;
    BEGIN
      WaitRetrace;
      For loop1:=0 to 255 do
        Pal (loop1,0,0,0);
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE CursorOff; ASSEMBLER;
    ASM
       mov  ah,3
       mov  bh,0
       int  10h
       mov  ah,1
       mov  cx,$100
       int  10h
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE CursorOn; ASSEMBLER;
    ASM
       mov  ah,1
       mov  cx,3342
       int  10h
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    FUNCTION GetCh(X : BYTE;
                   Y : BYTE) : WORD;
    VAR
       OffSet : WORD;
       ScrPtr :^WORD;
    begin
         OffSet := (((Y - 1) * 80) + X - 1) * 2;
         ScrPtr := PTR($B800,offset);
         GetCh  := ScrPtr^;
    end;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE WriteXY(Str : STRING;
                      X   : BYTE;
                      Y   : BYTE);
    BEGIN
         GOTOXY(X,Y);
         WRITE(Str);
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE grinit;
    VAR
       gd : INTEGER;
       gm : INTEGER;
    BEGIN
         gd := DETECT;
         INITGRAPH(gd, gm, '');
         IF GRAPHRESULT <> grOk THEN
           BEGIN
            gd := DETECT;
            INITGRAPH(gd, gm, 'C:\TP\BGI');
            IF GRAPHRESULT <> grOk THEN
              BEGIN
                WRITELN('GRAPHICS DRIVERS MALFUNCTION');
                READKEY;
                HALT;
              END;
           END;
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE GrShutDown;
    BEGIN
         CLEARDEVICE;
         CLOSEGRAPH;
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE TBG(X : BYTE);
    BEGIN
         TEXTBACKGROUND(X);
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE TC(X : BYTE);
    BEGIN
         TEXTCOLOR(X);
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE UpString(VAR Str : STRING);
    VAR
       StrLen : BYTE;                    {The total Length of the string         }
       StrPos : BYTE;                    {Where in the string am I               }
    BEGIN
         StrLen := LENGTH(Str);          {Get the length of the string           }
         StrPos := 1;                    {The first char in the string is 1      }
         REPEAT                          {Start repeating                        }
           Str[StrPos] := UPCASE(Str[StrPos]);
                                         {Change each letter to uppercase        }
           INC(StrPos);                  {Move to the next letter                }
         UNTIL StrPos = StrLen+1;        {Stop repeating when the word is finish }
    END;     {UpString}

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    FUNCTION CheckForExtension(FileStr : STRING) : BOOLEAN;
    VAR
       StrLen : BYTE;                    {The total Length of the string        }
       StrPos : BYTE;                    {Where in the string am I              }
       Found  : BOOLEAN;                 {Was a period found                    }

    BEGIN
         StrLen := LENGTH(FileStr);      {Get the length of the string           }
         StrPos := 1;                    {Standard Pascal strings start at byte 1}
         Found  := FALSE;                {Default is no period                   }
         REPEAT                          {Start Repeating                        }
           IF FileStr[StrPos] = '.' THEN {Stop repeating if a full stop is found }
               Found := True;            {If you find a full stop get organised..}
           INC(StrPos);                  {move to the next spot in the string    }
         UNTIL Found OR (StrPos = StrLen);
         IF Found THEN                   {if you did find an extension output it }
           CheckForExtension := TRUE
         ELSE                            {else tell it you didn't                }
           CheckForExtension := FALSE;
    END;   {CheckForExtension}

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    PROCEDURE WriteC(Str : STRING;
                     Y   : BYTE);
    BEGIN
         GOTOXY(40 - (LENGTH(Str) DIV 2),Y);
         WRITE(Str);
    END;

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

    function Exist(FileName: String): Boolean;
    { Boolean function that returns True if the file exists;otherwise,
     it returns False. Closes the file if it exists. }
    var
     F: file;
    begin
     {$I-}
     Assign(F, FileName);
     FileMode := 0;  { Set file access to read only }
     Reset(F);
     Close(F);
     {$I+}
     Exist := (IOResult = 0) and (FileName <> '');
    end;  {Exist}

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                    { --=THINGS TO DO AFTER THE PROGRAM=-- }

    {F+}
    PROCEDURE MyExit;
    BEGIN
         EXITPROC := ExitPtr;
         NOSOUND;
         RestorePallette(BackUpPalletteStorage);
         CursorOn;
         TEXTBACKGROUND(0);
         TEXTCOLOR(7);
         CLRSCR;
    END;
    {$F-}

    {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}

                 { --=THINGS TO DO BEFORE RUNNING THE PROGRAM=-- }

    BEGIN
         ExitPtr  := EXITPROC;
         EXITPROC := @MyExit;
         RANDOMIZE;
         SavePallette(BackUpPalletteStorage);
         TEXTBACKGROUND(0);
         TEXTCOLOR(7);
         CLRSCR;
    END.
    ---------------------------- = [Cut Here] = ---------------------------------

[Back to MENU SWAG index] [Back to Main SWAG index] [Original]