home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / Pascal / BPASCAL.700 / D11 / BGIDEMO.ZIP / BGIDEMO.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-10-01  |  39.1 KB  |  1,426 lines

  1. {************************************************}
  2. {                                                }
  3. {   BGI Demo Program                             }
  4. {   Copyright (c) 1992 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. program BGIDemo;
  9.  
  10. (*
  11.   Borland Graphics Interface (BGI) demonstration
  12.   program. This program shows how to use many features of
  13.   the Graph unit.
  14.  
  15.   NOTE: to have this demo use the IBM8514 driver, specify a
  16.   conditional define constant "Use8514" (using the {$DEFINE}
  17.   directive or Options\Compiler\Conditional defines) and then
  18.   re-compile.
  19. *)
  20.  
  21. uses
  22.   Crt, Dos, Graph;
  23.  
  24.  
  25. const
  26.   { The five fonts available }
  27.   Fonts : array[0..4] of string[13] =
  28.   ('DefaultFont', 'TriplexFont', 'SmallFont', 'SansSerifFont', 'GothicFont');
  29.  
  30.   { The five predefined line styles supported }
  31.   LineStyles : array[0..4] of string[9] =
  32.   ('SolidLn', 'DottedLn', 'CenterLn', 'DashedLn', 'UserBitLn');
  33.  
  34.   { The twelve predefined fill styles supported }
  35.   FillStyles : array[0..11] of string[14] =
  36.   ('EmptyFill', 'SolidFill', 'LineFill', 'LtSlashFill', 'SlashFill',
  37.    'BkSlashFill', 'LtBkSlashFill', 'HatchFill', 'XHatchFill',
  38.    'InterleaveFill', 'WideDotFill', 'CloseDotFill');
  39.  
  40.   { The two text directions available }
  41.   TextDirect : array[0..1] of string[8] = ('HorizDir', 'VertDir');
  42.  
  43.   { The Horizontal text justifications available }
  44.   HorizJust  : array[0..2] of string[10] = ('LeftText', 'CenterText', 'RightText');
  45.  
  46.   { The vertical text justifications available }
  47.   VertJust   : array[0..2] of string[10] = ('BottomText', 'CenterText', 'TopText');
  48.  
  49. var
  50.   GraphDriver : integer;  { The Graphics device driver }
  51.   GraphMode   : integer;  { The Graphics mode value }
  52.   MaxX, MaxY  : word;     { The maximum resolution of the screen }
  53.   ErrorCode   : integer;  { Reports any graphics errors }
  54.   MaxColor    : word;     { The maximum color value available }
  55.   OldExitProc : Pointer;  { Saves exit procedure address }
  56.  
  57. {$F+}
  58. procedure MyExitProc;
  59. begin
  60.   ExitProc := OldExitProc; { Restore exit procedure address }
  61.   CloseGraph;              { Shut down the graphics system }
  62. end; { MyExitProc }
  63. {$F-}
  64.  
  65. procedure Initialize;
  66. { Initialize graphics and report any errors that may occur }
  67. var
  68.   InGraphicsMode : boolean; { Flags initialization of graphics mode }
  69.   PathToDriver   : string;  { Stores the DOS path to *.BGI & *.CHR }
  70. begin
  71.   { when using Crt and graphics, turn off Crt's memory-mapped writes }
  72.   DirectVideo := False;
  73.   OldExitProc := ExitProc;                { save previous exit proc }
  74.   ExitProc := @MyExitProc;                { insert our exit proc in chain }
  75.   PathToDriver := '';
  76.   repeat
  77.  
  78. {$IFDEF Use8514}                          { check for Use8514 $DEFINE }
  79.     GraphDriver := IBM8514;
  80.     GraphMode := IBM8514Hi;
  81. {$ELSE}
  82.     GraphDriver := Detect;                { use autodetection }
  83. {$ENDIF}
  84.  
  85.     InitGraph(GraphDriver, GraphMode, PathToDriver);
  86.     ErrorCode := GraphResult;             { preserve error return }
  87.     if ErrorCode <> grOK then             { error? }
  88.     begin
  89.       Writeln('Graphics error: ', GraphErrorMsg(ErrorCode));
  90.       if ErrorCode = grFileNotFound then  { Can't find driver file }
  91.       begin
  92.         Writeln('Enter full path to BGI driver or type <Ctrl-Break> to quit:');
  93.         Readln(PathToDriver);
  94.         Writeln;
  95.       end
  96.       else
  97.         Halt(1);                          { Some other error: terminate }
  98.     end;
  99.   until ErrorCode = grOK;
  100.   Randomize;                { init random number generator }
  101.   MaxColor := GetMaxColor;  { Get the maximum allowable drawing color }
  102.   MaxX := GetMaxX;          { Get screen resolution values }
  103.   MaxY := GetMaxY;
  104. end; { Initialize }
  105.  
  106. function Int2Str(L : LongInt) : string;
  107. { Converts an integer to a string for use with OutText, OutTextXY }
  108. var
  109.   S : string;
  110. begin
  111.   Str(L, S);
  112.   Int2Str := S;
  113. end; { Int2Str }
  114.  
  115. function RandColor : word;
  116. { Returns a Random non-zero color value that is within the legal
  117.   color range for the selected device driver and graphics mode.
  118.   MaxColor is set to GetMaxColor by Initialize }
  119. begin
  120.   RandColor := Random(MaxColor)+1;
  121. end; { RandColor }
  122.  
  123. procedure DefaultColors;
  124. { Select the maximum color in the Palette for the drawing color }
  125. begin
  126.   SetColor(MaxColor);
  127. end; { DefaultColors }
  128.  
  129. procedure DrawBorder;
  130. { Draw a border around the current view port }
  131. var
  132.   ViewPort : ViewPortType;
  133. begin
  134.   DefaultColors;
  135.   SetLineStyle(SolidLn, 0, NormWidth);
  136.   GetViewSettings(ViewPort);
  137.   with ViewPort do
  138.     Rectangle(0, 0, x2-x1, y2-y1);
  139. end; { DrawBorder }
  140.  
  141. procedure FullPort;
  142. { Set the view port to the entire screen }
  143. begin
  144.   SetViewPort(0, 0, MaxX, MaxY, ClipOn);
  145. end; { FullPort }
  146.  
  147. procedure MainWindow(Header : string);
  148. { Make a default window and view port for demos }
  149. begin
  150.   DefaultColors;                           { Reset the colors }
  151.   ClearDevice;                             { Clear the screen }
  152.   SetTextStyle(DefaultFont, HorizDir, 1);  { Default text font }
  153.   SetTextJustify(CenterText, TopText);     { Left justify text }
  154.   FullPort;                                { Full screen view port }
  155.   OutTextXY(MaxX div 2, 2, Header);        { Draw the header }
  156.   { Draw main window }
  157.   SetViewPort(0, TextHeight('M')+4, MaxX, MaxY-(TextHeight('M')+4), ClipOn);
  158.   DrawBorder;                              { Put a border around it }
  159.   { Move the edges in 1 pixel on all sides so border isn't in the view port }
  160.   SetViewPort(1, TextHeight('M')+5, MaxX-1, MaxY-(TextHeight('M')+5), ClipOn);
  161. end; { MainWindow }
  162.  
  163. procedure StatusLine(Msg : string);
  164. { Display a status line at the bottom of the screen }
  165. begin
  166.   FullPort;
  167.   DefaultColors;
  168.   SetTextStyle(DefaultFont, HorizDir, 1);
  169.   SetTextJustify(CenterText, TopText);
  170.   SetLineStyle(SolidLn, 0, NormWidth);
  171.   SetFillStyle(EmptyFill, 0);
  172.   Bar(0, MaxY-(TextHeight('M')+4), MaxX, MaxY);      { Erase old status line }
  173.   Rectangle(0, MaxY-(TextHeight('M')+4), MaxX, MaxY);
  174.   OutTextXY(MaxX div 2, MaxY-(TextHeight('M')+2), Msg);
  175.   { Go back to the main window }
  176.   SetViewPort(1, TextHeight('M')+5, MaxX-1, MaxY-(TextHeight('M')+5), ClipOn);
  177. end; { StatusLine }
  178.  
  179. procedure WaitToGo;
  180. { Wait for the user to abort the program or continue }
  181. const
  182.   Esc = #27;
  183. var
  184.   Ch : char;
  185. begin
  186.   StatusLine('Esc aborts or press a key...');
  187.   repeat until KeyPressed;
  188.   Ch := ReadKey;
  189.   if ch = #0 then ch := readkey;      { trap function keys }
  190.   if Ch = Esc then
  191.     Halt(0)                           { terminate program }
  192.   else
  193.     ClearDevice;                      { clear screen, go on with demo }
  194. end; { WaitToGo }
  195.  
  196. procedure GetDriverAndMode(var DriveStr, ModeStr : string);
  197. { Return strings describing the current device driver and graphics mode
  198.   for display of status report }
  199. begin
  200.   DriveStr := GetDriverName;
  201.   ModeStr := GetModeName(GetGraphMode);
  202. end; { GetDriverAndMode }
  203.  
  204. procedure ReportStatus;
  205. { Display the status of all query functions after InitGraph }
  206. const
  207.   X = 10;
  208. var
  209.   ViewInfo   : ViewPortType;     { Parameters for inquiry procedures }
  210.   LineInfo   : LineSettingsType;
  211.   FillInfo   : FillSettingsType;
  212.   TextInfo   : TextSettingsType;
  213.   Palette    : PaletteType;
  214.   DriverStr  : string;           { Driver and mode strings }
  215.   ModeStr    : string;
  216.   Y          : word;
  217.  
  218. procedure WriteOut(S : string);
  219. { Write out a string and increment to next line }
  220. begin
  221.   OutTextXY(X, Y, S);
  222.   Inc(Y, TextHeight('M')+2);
  223. end; { WriteOut }
  224.  
  225. begin { ReportStatus }
  226.   GetDriverAndMode(DriverStr, ModeStr);   { Get current settings }
  227.   GetViewSettings(ViewInfo);
  228.   GetLineSettings(LineInfo);
  229.   GetFillSettings(FillInfo);
  230.   GetTextSettings(TextInfo);
  231.   GetPalette(Palette);
  232.  
  233.   Y := 4;
  234.   MainWindow('Status report after InitGraph');
  235.   SetTextJustify(LeftText, TopText);
  236.   WriteOut('Graphics device    : '+DriverStr);
  237.   WriteOut('Graphics mode      : '+ModeStr);
  238.   WriteOut('Screen resolution  : (0, 0, '+Int2Str(GetMaxX)+', '+Int2Str(GetMaxY)+')');
  239.   with ViewInfo do
  240.   begin
  241.     WriteOut('Current view port  : ('+Int2Str(x1)+', '+Int2Str(y1)+', '+Int2Str(x2)+', '+Int2Str(y2)+')');
  242.     if ClipOn then
  243.       WriteOut('Clipping           : ON')
  244.     else
  245.       WriteOut('Clipping           : OFF');
  246.   end;
  247.   WriteOut('Current position   : ('+Int2Str(GetX)+', '+Int2Str(GetY)+')');
  248.   WriteOut('Palette entries    : '+Int2Str(Palette.Size));
  249.   WriteOut('GetMaxColor        : '+Int2Str(GetMaxColor));
  250.   WriteOut('Current color      : '+Int2Str(GetColor));
  251.   with LineInfo do
  252.   begin
  253.     WriteOut('Line style         : '+LineStyles[LineStyle]);
  254.     WriteOut('Line thickness     : '+Int2Str(Thickness));
  255.   end;
  256.   with FillInfo do
  257.   begin
  258.     WriteOut('Current fill style : '+FillStyles[Pattern]);
  259.     WriteOut('Current fill color : '+Int2Str(Color));
  260.   end;
  261.   with TextInfo do
  262.   begin
  263.     WriteOut('Current font       : '+Fonts[Font]);
  264.     WriteOut('Text direction     : '+TextDirect[Direction]);
  265.     WriteOut('Character size     : '+Int2Str(CharSize));
  266.     WriteOut('Horizontal justify : '+HorizJust[Horiz]);
  267.     WriteOut('Vertical justify   : '+VertJust[Vert]);
  268.   end;
  269.   WaitToGo;
  270. end; { ReportStatus }
  271.  
  272. procedure FillEllipsePlay;
  273. { Random filled ellipse demonstration }
  274. const
  275.   MaxFillStyles = 12; { patterns 0..11 }
  276. var
  277.   MaxRadius : word;
  278.   FillColor : integer;
  279. begin
  280.   MainWindow('FillEllipse demonstration');
  281.   StatusLine('Esc aborts or press a key');
  282.   MaxRadius := MaxY div 10;
  283.   SetLineStyle(SolidLn, 0, NormWidth);
  284.   repeat
  285.     FillColor := RandColor;
  286.     SetColor(FillColor);
  287.     SetFillStyle(Random(MaxFillStyles), FillColor);
  288.     FillEllipse(Random(MaxX), Random(MaxY),
  289.                 Random(MaxRadius), Random(MaxRadius));
  290.   until KeyPressed;
  291.   WaitToGo;
  292. end; { FillEllipsePlay }
  293.  
  294. procedure SectorPlay;
  295. { Draw random sectors on the screen }
  296. const
  297.   MaxFillStyles = 12; { patterns 0..11 }
  298. var
  299.   MaxRadius : word;
  300.   FillColor : integer;
  301.   EndAngle  : integer;
  302. begin
  303.   MainWindow('Sector demonstration');
  304.   StatusLine('Esc aborts or press a key');
  305.   MaxRadius := MaxY div 10;
  306.   SetLineStyle(SolidLn, 0, NormWidth);
  307.   repeat
  308.     FillColor := RandColor;
  309.     SetColor(FillColor);
  310.     SetFillStyle(Random(MaxFillStyles), FillColor);
  311.     EndAngle := Random(360);
  312.     Sector(Random(MaxX), Random(MaxY), Random(EndAngle), EndAngle,
  313.            Random(MaxRadius), Random(MaxRadius));
  314.   until KeyPressed;
  315.   WaitToGo;
  316. end; { SectorPlay }
  317.  
  318. procedure WriteModePlay;
  319. { Demonstrate the SetWriteMode procedure for XOR lines }
  320. const
  321.   DelayValue = 50;  { milliseconds to delay }
  322. var
  323.   ViewInfo      : ViewPortType;
  324.   Color         : word;
  325.   Left, Top     : integer;
  326.   Right, Bottom : integer;
  327.   Step          : integer; { step for rectangle shrinking }
  328. begin
  329.   MainWindow('SetWriteMode demonstration');
  330.   StatusLine('Esc aborts or press a key');
  331.   GetViewSettings(ViewInfo);
  332.   Left := 0;
  333.   Top := 0;
  334.   with ViewInfo do
  335.   begin
  336.     Right := x2-x1;
  337.     Bottom := y2-y1;
  338.   end;
  339.   Step := Bottom div 50;
  340.   SetColor(GetMaxColor);
  341.   Line(Left, Top, Right, Bottom);
  342.   Line(Left, Bottom, Right, Top);
  343.   SetWriteMode(XORPut);                    { Set XOR write mode }
  344.   repeat
  345.     Line(Left, Top, Right, Bottom);        { Draw XOR lines }
  346.     Line(Left, Bottom, Right, Top);
  347.     Rectangle(Left, Top, Right, Bottom);   { Draw XOR rectangle }
  348.     Delay(DelayValue);                     { Wait }
  349.     Line(Left, Top, Right, Bottom);        { Erase lines }
  350.     Line(Left, Bottom, Right, Top);
  351.     Rectangle(Left, Top, Right, Bottom);   { Erase rectangle }
  352.     if (Left+Step < Right) and (Top+Step < Bottom) then
  353.       begin
  354.         Inc(Left, Step);                  { Shrink rectangle }
  355.         Inc(Top, Step);
  356.         Dec(Right, Step);
  357.         Dec(Bottom, Step);
  358.       end
  359.     else
  360.       begin
  361.         Color := RandColor;                { New color }
  362.         SetColor(Color);
  363.         Left := 0;                         { Original large rectangle }
  364.         Top := 0;
  365.         with ViewInfo do
  366.         begin
  367.           Right := x2-x1;
  368.           Bottom := y2-y1;
  369.         end;
  370.       end;
  371.   until KeyPressed;
  372.   SetWriteMode(CopyPut);                   { back to overwrite mode }
  373.   WaitToGo;
  374. end; { WriteModePlay }
  375.  
  376. procedure AspectRatioPlay;
  377. { Demonstrate  SetAspectRatio command }
  378. var
  379.   ViewInfo   : ViewPortType;
  380.   CenterX    : integer;
  381.   CenterY    : integer;
  382.   Radius     : word;
  383.   Xasp, Yasp : word;
  384.   i          : integer;
  385.   RadiusStep : word;
  386. begin
  387.   MainWindow('SetAspectRatio demonstration');
  388.   GetViewSettings(ViewInfo);
  389.   with ViewInfo do
  390.   begin
  391.     CenterX := (x2-x1) div 2;
  392.     CenterY := (y2-y1) div 2;
  393.     Radius := 3*((y2-y1) div 5);
  394.   end;
  395.   RadiusStep := (Radius div 30);
  396.   Circle(CenterX, CenterY, Radius);
  397.   GetAspectRatio(Xasp, Yasp);
  398.   for i := 1 to 30 do
  399.   begin
  400.     SetAspectRatio(Xasp, Yasp+(I*GetMaxX));    { Increase Y aspect factor }
  401.     Circle(CenterX, CenterY, Radius);
  402.     Dec(Radius, RadiusStep);                   { Shrink radius }
  403.   end;
  404.   Inc(Radius, RadiusStep*30);
  405.   for i := 1 to 30 do
  406.   begin
  407.     SetAspectRatio(Xasp+(I*GetMaxX), Yasp);    { Increase X aspect factor }
  408.     if Radius > RadiusStep then
  409.       Dec(Radius, RadiusStep);                 { Shrink radius }
  410.     Circle(CenterX, CenterY, Radius);
  411.   end;
  412.   SetAspectRatio(Xasp, Yasp);                  { back to original aspect }
  413.   WaitToGo;
  414. end; { AspectRatioPlay }
  415.  
  416. procedure TextPlay;
  417. { Demonstrate text justifications and text sizing }
  418. var
  419.   Size : word;
  420.   W, H, X, Y : word;
  421.   ViewInfo : ViewPortType;
  422. begin
  423.   MainWindow('SetTextJustify / SetUserCharSize demo');
  424.   GetViewSettings(ViewInfo);
  425.   with ViewInfo do
  426.   begin
  427.     SetTextStyle(TriplexFont, VertDir, 4);
  428.     Y := (y2-y1) - 2;
  429.     SetTextJustify(CenterText, BottomText);
  430.     OutTextXY(2*TextWidth('M'), Y, 'Vertical');
  431.     SetTextStyle(TriplexFont, HorizDir, 4);
  432.     SetTextJustify(LeftText, TopText);
  433.     OutTextXY(2*TextWidth('M'), 2, 'Horizontal');
  434.     SetTextJustify(CenterText, CenterText);
  435.     X := (x2-x1) div 2;
  436.     Y := TextHeight('H');
  437.     for Size := 1 to 4 do
  438.     begin
  439.       SetTextStyle(TriplexFont, HorizDir, Size);
  440.       H := TextHeight('M');
  441.       W := TextWidth('M');
  442.       Inc(Y, H);
  443.       OutTextXY(X, Y, 'Size '+Int2Str(Size));
  444.     end;
  445.     Inc(Y, H div 2);
  446.     SetTextJustify(CenterText, TopText);
  447.     SetUserCharSize(5, 6, 3, 2);
  448.     SetTextStyle(TriplexFont, HorizDir, UserCharSize);
  449.     OutTextXY((x2-x1) div 2, Y, 'User defined size!');
  450.   end;
  451.   WaitToGo;
  452. end; { TextPlay }
  453.  
  454. procedure TextDump;
  455. { Dump the complete character sets to the screen }
  456. const
  457.   CGASizes  : array[0..4] of word = (1, 3, 7, 3, 3);
  458.   NormSizes : array[0..4] of word = (1, 4, 7, 4, 4);
  459. var
  460.   Font : word;
  461.   ViewInfo : ViewPortType;
  462.   Ch : char;
  463. begin
  464.   for Font := 0 to 4 do
  465.   begin
  466.     MainWindow(Fonts[Font]+' character set');
  467.     GetViewSettings(ViewInfo);
  468.     with ViewInfo do
  469.     begin
  470.       SetTextJustify(LeftText, TopText);
  471.       MoveTo(2, 3);
  472.       if Font = DefaultFont then
  473.         begin
  474.           SetTextStyle(Font, HorizDir, 1);
  475.           Ch := #0;
  476.           repeat
  477.             OutText(Ch);
  478.             if (GetX + TextWidth('M')) > (x2-x1) then
  479.               MoveTo(2, GetY + TextHeight('M')+3);
  480.             Ch := Succ(Ch);
  481.           until (Ch >= #255);
  482.         end
  483.       else
  484.         begin
  485.           if MaxY < 200 then
  486.             SetTextStyle(Font, HorizDir, CGASizes[Font])
  487.           else
  488.             SetTextStyle(Font, HorizDir, NormSizes[Font]);
  489.           Ch := '!';
  490.           repeat
  491.             OutText(Ch);
  492.             if (GetX + TextWidth('M')) > (x2-x1) then
  493.               MoveTo(2, GetY + TextHeight('M')+3);
  494.             Ch := Succ(Ch);
  495.           until (Ch >= #255);
  496.         end;
  497.     end; { with }
  498.     WaitToGo;
  499.   end; { for loop }
  500. end; { TextDump }
  501.  
  502. procedure LineToPlay;
  503. { Demonstrate MoveTo and LineTo commands }
  504. const
  505.   MaxPoints = 15;
  506. var
  507.   Points     : array[0..MaxPoints] of PointType;
  508.   ViewInfo   : ViewPortType;
  509.   I, J       : integer;
  510.   CenterX    : integer;   { The center point of the circle }
  511.   CenterY    : integer;
  512.   Radius     : word;
  513.   StepAngle  : word;
  514.   Xasp, Yasp : word;
  515.   Radians    : real;
  516.  
  517. function AdjAsp(Value : integer) : integer;
  518. { Adjust a value for the aspect ratio of the device }
  519. begin
  520.   AdjAsp := (LongInt(Value) * Xasp) div Yasp;
  521. end; { AdjAsp }
  522.  
  523. begin
  524.   MainWindow('MoveTo, LineTo demonstration');
  525.   GetAspectRatio(Xasp, Yasp);
  526.   GetViewSettings(ViewInfo);
  527.   with ViewInfo do
  528.   begin
  529.     CenterX := (x2-x1) div 2;
  530.     CenterY := (y2-y1) div 2;
  531.     Radius := CenterY;
  532.     while (CenterY+AdjAsp(Radius)) < (y2-y1)-20 do
  533.       Inc(Radius);
  534.   end;
  535.   StepAngle := 360 div MaxPoints;
  536.   for I := 0 to MaxPoints - 1 do
  537.   begin
  538.     Radians := (StepAngle * I) * Pi / 180;
  539.     Points[I].X := CenterX + round(Cos(Radians) * Radius);
  540.     Points[I].Y := CenterY - AdjAsp(round(Sin(Radians) * Radius));
  541.   end;
  542.   Circle(CenterX, CenterY, Radius);
  543.   for I := 0 to MaxPoints - 1 do
  544.   begin
  545.     for J := I to MaxPoints - 1 do
  546.     begin
  547.       MoveTo(Points[I].X, Points[I].Y);
  548.       LineTo(Points[J].X, Points[J].Y);
  549.     end;
  550.   end;
  551.   WaitToGo;
  552. end; { LineToPlay }
  553.  
  554. procedure LineRelPlay;
  555. { Demonstrate MoveRel and LineRel commands }
  556. const
  557.   MaxPoints = 12;
  558. var
  559.   Poly     : array[1..MaxPoints] of PointType; { Stores a polygon for filling }
  560.   CurrPort : ViewPortType;
  561.  
  562. procedure DrawTesseract;
  563. { Draw a Tesseract on the screen with relative move and
  564.   line drawing commands, also create a polygon for filling }
  565. const
  566.   CheckerBoard : FillPatternType = (0, $10, $28, $44, $28, $10, 0, 0);
  567. var
  568.   X, Y, W, H   : integer;
  569.  
  570. begin
  571.   GetViewSettings(CurrPort);
  572.   with CurrPort do
  573.   begin
  574.     W := (x2-x1) div 9;
  575.     H := (y2-y1) div 8;
  576.     X := ((x2-x1) div 2) - round(2.5 * W);
  577.     Y := ((y2-y1) div 2) - (3 * H);
  578.  
  579.     { Border around viewport is outer part of polygon }
  580.     Poly[1].X := 0;     Poly[1].Y := 0;
  581.     Poly[2].X := x2-x1; Poly[2].Y := 0;
  582.     Poly[3].X := x2-x1; Poly[3].Y := y2-y1;
  583.     Poly[4].X := 0;     Poly[4].Y := y2-y1;
  584.     Poly[5].X := 0;     Poly[5].Y := 0;
  585.     MoveTo(X, Y);
  586.  
  587.     { Grab the whole in the polygon as we draw }
  588.     MoveRel(0, H);      Poly[6].X := GetX;  Poly[6].Y := GetY;
  589.     MoveRel(W, -H);     Poly[7].X := GetX;  Poly[7].Y := GetY;
  590.     MoveRel(4*W, 0);    Poly[8].X := GetX;  Poly[8].Y := GetY;
  591.     MoveRel(0, 5*H);    Poly[9].X := GetX;  Poly[9].Y := GetY;
  592.     MoveRel(-W, H);     Poly[10].X := GetX; Poly[10].Y := GetY;
  593.     MoveRel(-4*W, 0);   Poly[11].X := GetX; Poly[11].Y := GetY;
  594.     MoveRel(0, -5*H);   Poly[12].X := GetX; Poly[12].Y := GetY;
  595.  
  596.     { Fill the polygon with a user defined fill pattern }
  597.     SetFillPattern(CheckerBoard, MaxColor);
  598.     FillPoly(12, Poly);
  599.  
  600.     MoveRel(W, -H);
  601.     LineRel(0, 5*H);   LineRel(2*W, 0);    LineRel(0, -3*H);
  602.     LineRel(W, -H);    LineRel(0, 5*H);    MoveRel(0, -5*H);
  603.     LineRel(-2*W, 0);  LineRel(0, 3*H);    LineRel(-W, H);
  604.     MoveRel(W, -H);    LineRel(W, 0);      MoveRel(0, -2*H);
  605.     LineRel(-W, 0);
  606.  
  607.     { Flood fill the center }
  608.     FloodFill((x2-x1) div 2, (y2-y1) div 2, MaxColor);
  609.   end;
  610. end; { DrawTesseract }
  611.  
  612. begin
  613.   MainWindow('LineRel / MoveRel demonstration');
  614.   GetViewSettings(CurrPort);
  615.   with CurrPort do
  616.     { Move the viewport out 1 pixel from each end }
  617.     SetViewPort(x1-1, y1-1, x2+1, y2+1, ClipOn);
  618.   DrawTesseract;
  619.   WaitToGo;
  620. end; { LineRelPlay }
  621.  
  622. procedure PiePlay;
  623. { Demonstrate  PieSlice and GetAspectRatio commands }
  624. var
  625.   ViewInfo   : ViewPortType;
  626.   CenterX    : integer;
  627.   CenterY    : integer;
  628.   Radius     : word;
  629.   Xasp, Yasp : word;
  630.   X, Y       : integer;
  631.  
  632. function AdjAsp(Value : integer) : integer;
  633. { Adjust a value for the aspect ratio of the device }
  634. begin
  635.   AdjAsp := (LongInt(Value) * Xasp) div Yasp;
  636. end; { AdjAsp }
  637.  
  638. procedure GetTextCoords(AngleInDegrees, Radius : word; var X, Y : integer);
  639. { Get the coordinates of text for pie slice labels }
  640. var
  641.   Radians : real;
  642. begin
  643.   Radians := AngleInDegrees * Pi / 180;
  644.   X := round(Cos(Radians) * Radius);
  645.   Y := round(Sin(Radians) * Radius);
  646. end; { GetTextCoords }
  647.  
  648. begin
  649.   MainWindow('PieSlice / GetAspectRatio demonstration');
  650.   GetAspectRatio(Xasp, Yasp);
  651.   GetViewSettings(ViewInfo);
  652.   with ViewInfo do
  653.   begin
  654.     CenterX := (x2-x1) div 2;
  655.     CenterY := ((y2-y1) div 2) + 20;
  656.     Radius := (y2-y1) div 3;
  657.     while AdjAsp(Radius) < round((y2-y1) / 3.6) do
  658.       Inc(Radius);
  659.   end;
  660.   SetTextStyle(TriplexFont, HorizDir, 4);
  661.   SetTextJustify(CenterText, TopText);
  662.   OutTextXY(CenterX, 0, 'This is a pie chart!');
  663.  
  664.   SetTextStyle(TriplexFont, HorizDir, 3);
  665.  
  666.   SetFillStyle(SolidFill, RandColor);
  667.   PieSlice(CenterX+10, CenterY-AdjAsp(10), 0, 90, Radius);
  668.   GetTextCoords(45, Radius, X, Y);
  669.   SetTextJustify(LeftText, BottomText);
  670.   OutTextXY(CenterX+10+X+TextWidth('H'), CenterY-AdjAsp(10+Y), '25 %');
  671.  
  672.   SetFillStyle(HatchFill, RandColor);
  673.   PieSlice(CenterX, CenterY, 225, 360, Radius);
  674.   GetTextCoords(293, Radius, X, Y);
  675.   SetTextJustify(LeftText, TopText);
  676.   OutTextXY(CenterX+X+TextWidth('H'), CenterY-AdjAsp(Y), '37.5 %');
  677.  
  678.   SetFillStyle(InterleaveFill, RandColor);
  679.   PieSlice(CenterX-10, CenterY, 135, 225, Radius);
  680.   GetTextCoords(180, Radius, X, Y);
  681.   SetTextJustify(RightText, CenterText);
  682.   OutTextXY(CenterX-10+X-TextWidth('H'), CenterY-AdjAsp(Y), '25 %');
  683.  
  684.   SetFillStyle(WideDotFill, RandColor);
  685.   PieSlice(CenterX, CenterY, 90, 135, Radius);
  686.   GetTextCoords(112, Radius, X, Y);
  687.   SetTextJustify(RightText, BottomText);
  688.   OutTextXY(CenterX+X-TextWidth('H'), CenterY-AdjAsp(Y), '12.5 %');
  689.  
  690.   WaitToGo;
  691. end; { PiePlay }
  692.  
  693. procedure Bar3DPlay;
  694. { Demonstrate Bar3D command }
  695. const
  696.   NumBars   = 7;  { The number of bars drawn }
  697.   BarHeight : array[1..NumBars] of byte = (1, 3, 2, 5, 4, 2, 1);
  698.   YTicks    = 5;  { The number of tick marks on the Y axis }
  699. var
  700.   ViewInfo : ViewPortType;
  701.   H        : word;
  702.   XStep    : real;
  703.   YStep    : real;
  704.   I, J     : integer;
  705.   Depth    : word;
  706.   Color    : word;
  707. begin
  708.   MainWindow('Bar3D / Rectangle demonstration');
  709.   H := 3*TextHeight('M');
  710.   GetViewSettings(ViewInfo);
  711.   SetTextJustify(CenterText, TopText);
  712.   SetTextStyle(TriplexFont, HorizDir, 4);
  713.   OutTextXY(MaxX div 2, 6, 'These are 3D bars !');
  714.   SetTextStyle(DefaultFont, HorizDir, 1);
  715.   with ViewInfo do
  716.     SetViewPort(x1+50, y1+40, x2-50, y2-10, ClipOn);
  717.   GetViewSettings(ViewInfo);
  718.   with ViewInfo do
  719.   begin
  720.     Line(H, H, H, (y2-y1)-H);
  721.     Line(H, (y2-y1)-H, (x2-x1)-H, (y2-y1)-H);
  722.     YStep := ((y2-y1)-(2*H)) / YTicks;
  723.     XStep := ((x2-x1)-(2*H)) / NumBars;
  724.     J := (y2-y1)-H;
  725.     SetTextJustify(CenterText, CenterText);
  726.  
  727.     { Draw the Y axis and ticks marks }
  728.     for I := 0 to Yticks do
  729.     begin
  730.       Line(H div 2, J, H, J);
  731.       OutTextXY(0, J, Int2Str(I));
  732.       J := Round(J-Ystep);
  733.     end;
  734.  
  735.  
  736.     Depth := trunc(0.25 * XStep);    { Calculate depth of bar }
  737.  
  738.     { Draw X axis, bars, and tick marks }
  739.     SetTextJustify(CenterText, TopText);
  740.     J := H;
  741.     for I := 1 to Succ(NumBars) do
  742.     begin
  743.       SetColor(MaxColor);
  744.       Line(J, (y2-y1)-H, J, (y2-y1-3)-(H div 2));
  745.       OutTextXY(J, (y2-y1)-(H div 2), Int2Str(I-1));
  746.       if I <> Succ(NumBars) then
  747.       begin
  748.         Color := RandColor;
  749.         SetFillStyle(I, Color);
  750.         SetColor(Color);
  751.         Bar3D(J, round((y2-y1-H)-(BarHeight[I] * Ystep)),
  752.                  round(J+Xstep-Depth), round((y2-y1)-H-1), Depth, TopOn);
  753.         J := Round(J+Xstep);
  754.       end;
  755.     end;
  756.  
  757.   end;
  758.   WaitToGo;
  759. end; { Bar3DPlay }
  760.  
  761. procedure BarPlay;
  762. { Demonstrate Bar command }
  763. const
  764.   NumBars   = 5;
  765.   BarHeight : array[1..NumBars] of byte = (1, 3, 5, 2, 4);
  766.   Styles    : array[1..NumBars] of byte = (1, 3, 10, 5, 9);
  767. var
  768.   ViewInfo  : ViewPortType;
  769.   BarNum    : word;
  770.   H         : word;
  771.   XStep     : real;
  772.   YStep     : real;
  773.   I, J      : integer;
  774.   Color     : word;
  775. begin
  776.   MainWindow('Bar / Rectangle demonstration');
  777.   H := 3*TextHeight('M');
  778.   GetViewSettings(ViewInfo);
  779.   SetTextJustify(CenterText, TopText);
  780.   SetTextStyle(TriplexFont, HorizDir, 4);
  781.   OutTextXY(MaxX div 2, 6, 'These are 2D bars !');
  782.   SetTextStyle(DefaultFont, HorizDir, 1);
  783.   with ViewInfo do
  784.     SetViewPort(x1+50, y1+30, x2-50, y2-10, ClipOn);
  785.   GetViewSettings(ViewInfo);
  786.   with ViewInfo do
  787.   begin
  788.     Line(H, H, H, (y2-y1)-H);
  789.     Line(H, (y2-y1)-H, (x2-x1)-H, (y2-y1)-H);
  790.     YStep := ((y2-y1)-(2*H)) / NumBars;
  791.     XStep := ((x2-x1)-(2*H)) / NumBars;
  792.     J := (y2-y1)-H;
  793.     SetTextJustify(CenterText, CenterText);
  794.  
  795.     { Draw Y axis with tick marks }
  796.     for I := 0 to NumBars do
  797.     begin
  798.       Line(H div 2, J, H, J);
  799.       OutTextXY(0, J, Int2Str(i));
  800.       J := Round(J-Ystep);
  801.     end;
  802.  
  803.     { Draw X axis, bars, and tick marks }
  804.     J := H;
  805.     SetTextJustify(CenterText, TopText);
  806.     for I := 1 to Succ(NumBars) do
  807.     begin
  808.       SetColor(MaxColor);
  809.       Line(J, (y2-y1)-H, J, (y2-y1-3)-(H div 2));
  810.       OutTextXY(J, (y2-y1)-(H div 2), Int2Str(I));
  811.       if I <> Succ(NumBars) then
  812.       begin
  813.         Color := RandColor;
  814.         SetFillStyle(Styles[I], Color);
  815.         SetColor(Color);
  816.         Bar(J, round((y2-y1-H)-(BarHeight[I] * Ystep)), round(J+Xstep), (y2-y1)-H-1);
  817.         Rectangle(J, round((y2-y1-H)-(BarHeight[I] * Ystep)), round(J+Xstep), (y2-y1)-H-1);
  818.       end;
  819.       J := Round(J+Xstep);
  820.     end;
  821.  
  822.   end;
  823.   WaitToGo;
  824. end; { BarPlay }
  825.  
  826. procedure CirclePlay;
  827. { Draw random circles on the screen }
  828. var
  829.   MaxRadius : word;
  830. begin
  831.   MainWindow('Circle demonstration');
  832.   StatusLine('Esc aborts or press a key');
  833.   MaxRadius := MaxY div 10;
  834.   SetLineStyle(SolidLn, 0, NormWidth);
  835.   repeat
  836.     SetColor(RandColor);
  837.     Circle(Random(MaxX), Random(MaxY), Random(MaxRadius));
  838.   until KeyPressed;
  839.   WaitToGo;
  840. end; { CirclePlay }
  841.  
  842.  
  843. procedure RandBarPlay;
  844. { Draw random bars on the screen }
  845. var
  846.   MaxWidth  : integer;
  847.   MaxHeight : integer;
  848.   ViewInfo  : ViewPortType;
  849.   Color     : word;
  850. begin
  851.   MainWindow('Random Bars');
  852.   StatusLine('Esc aborts or press a key');
  853.   GetViewSettings(ViewInfo);
  854.   with ViewInfo do
  855.   begin
  856.     MaxWidth := x2-x1;
  857.     MaxHeight := y2-y1;
  858.   end;
  859.   repeat
  860.     Color := RandColor;
  861.     SetColor(Color);
  862.     SetFillStyle(Random(CloseDotFill)+1, Color);
  863.     Bar3D(Random(MaxWidth), Random(MaxHeight),
  864.           Random(MaxWidth), Random(MaxHeight), 0, TopOff);
  865.   until KeyPressed;
  866.   WaitToGo;
  867. end; { RandBarPlay }
  868.  
  869. procedure ArcPlay;
  870. { Draw random arcs on the screen }
  871. var
  872.   MaxRadius : word;
  873.   EndAngle : word;
  874.   ArcInfo : ArcCoordsType;
  875. begin
  876.   MainWindow('Arc / GetArcCoords demonstration');
  877.   StatusLine('Esc aborts or press a key');
  878.   MaxRadius := MaxY div 10;
  879.   repeat
  880.     SetColor(RandColor);
  881.     EndAngle := Random(360);
  882.     SetLineStyle(SolidLn, 0, NormWidth);
  883.     Arc(Random(MaxX), Random(MaxY), Random(EndAngle), EndAngle, Random(MaxRadius));
  884.     GetArcCoords(ArcInfo);
  885.     with ArcInfo do
  886.     begin
  887.       Line(X, Y, XStart, YStart);
  888.       Line(X, Y, Xend, Yend);
  889.     end;
  890.   until KeyPressed;
  891.   WaitToGo;
  892. end; { ArcPlay }
  893.  
  894. procedure PutPixelPlay;
  895. { Demonstrate the PutPixel and GetPixel commands }
  896. const
  897.   Seed   = 1962; { A seed for the random number generator }
  898.   NumPts = 2000; { The number of pixels plotted }
  899.   Esc    = #27;
  900. var
  901.   I : word;
  902.   X, Y, Color : word;
  903.   XMax, YMax  : integer;
  904.   ViewInfo    : ViewPortType;
  905. begin
  906.   MainWindow('PutPixel / GetPixel demonstration');
  907.   StatusLine('Esc aborts or press a key...');
  908.  
  909.   GetViewSettings(ViewInfo);
  910.   with ViewInfo do
  911.   begin
  912.     XMax := (x2-x1-1);
  913.     YMax := (y2-y1-1);
  914.   end;
  915.  
  916.   while not KeyPressed do
  917.   begin
  918.     { Plot random pixels }
  919.     RandSeed := Seed;
  920.     I := 0;
  921.     while (not KeyPressed) and (I < NumPts) do
  922.     begin
  923.       Inc(I);
  924.       PutPixel(Random(XMax)+1, Random(YMax)+1, RandColor);
  925.     end;
  926.  
  927.     { Erase pixels }
  928.     RandSeed := Seed;
  929.     I := 0;
  930.     while (not KeyPressed) and (I < NumPts) do
  931.     begin
  932.       Inc(I);
  933.       X := Random(XMax)+1;
  934.       Y := Random(YMax)+1;
  935.       Color := GetPixel(X, Y);
  936.       if Color = RandColor then
  937.         PutPixel(X, Y, 0);
  938.     end;
  939.   end;
  940.   WaitToGo;
  941. end; { PutPixelPlay }
  942.  
  943. procedure PutImagePlay;
  944. { Demonstrate the GetImage and PutImage commands }
  945.  
  946. const
  947.   r  = 20;
  948.   StartX = 100;
  949.   StartY = 50;
  950.  
  951. var
  952.   CurPort : ViewPortType;
  953.  
  954. procedure MoveSaucer(var X, Y : integer; Width, Height : integer);
  955. var
  956.   Step : integer;
  957. begin
  958.   Step := Random(2*r);
  959.   if Odd(Step) then
  960.     Step := -Step;
  961.   X := X + Step;
  962.   Step := Random(r);
  963.   if Odd(Step) then
  964.     Step := -Step;
  965.   Y := Y + Step;
  966.  
  967.   { Make saucer bounce off viewport walls }
  968.   with CurPort do
  969.   begin
  970.     if (x1 + X + Width - 1 > x2) then
  971.       X := x2-x1 - Width + 1
  972.     else
  973.       if (X < 0) then
  974.         X := 0;
  975.     if (y1 + Y + Height - 1 > y2) then
  976.       Y := y2-y1 - Height + 1
  977.     else
  978.       if (Y < 0) then
  979.         Y := 0;
  980.   end;
  981. end; { MoveSaucer }
  982.  
  983. var
  984.   Pausetime : word;
  985.   Saucer    : pointer;
  986.   X, Y      : integer;
  987.   ulx, uly  : word;
  988.   lrx, lry  : word;
  989.   Size      : word;
  990.   I         : word;
  991. begin
  992.   ClearDevice;
  993.   FullPort;
  994.  
  995.   { PaintScreen }
  996.   ClearDevice;
  997.   MainWindow('GetImage / PutImage Demonstration');
  998.   StatusLine('Esc aborts or press a key...');
  999.   GetViewSettings(CurPort);
  1000.  
  1001.   { DrawSaucer }
  1002.   Ellipse(StartX, StartY, 0, 360, r, (r div 3)+2);
  1003.   Ellipse(StartX, StartY-4, 190, 357, r, r div 3);
  1004.   Line(StartX+7, StartY-6, StartX+10, StartY-12);
  1005.   Circle(StartX+10, StartY-12, 2);
  1006.   Line(StartX-7, StartY-6, StartX-10, StartY-12);
  1007.   Circle(StartX-10, StartY-12, 2);
  1008.   SetFillStyle(SolidFill, MaxColor);
  1009.   FloodFill(StartX+1, StartY+4, GetColor);
  1010.  
  1011.   { ReadSaucerImage }
  1012.   ulx := StartX-(r+1);
  1013.   uly := StartY-14;
  1014.   lrx := StartX+(r+1);
  1015.   lry := StartY+(r div 3)+3;
  1016.  
  1017.   Size := ImageSize(ulx, uly, lrx, lry);
  1018.   GetMem(Saucer, Size);
  1019.   GetImage(ulx, uly, lrx, lry, Saucer^);
  1020.   PutImage(ulx, uly, Saucer^, XORput);               { erase image }
  1021.  
  1022.   { Plot some "stars" }
  1023.   for I := 1 to 1000 do
  1024.     PutPixel(Random(MaxX), Random(MaxY), RandColor);
  1025.   X := MaxX div 2;
  1026.   Y := MaxY div 2;
  1027.   PauseTime := 70;
  1028.  
  1029.   { Move the saucer around }
  1030.   repeat
  1031.     PutImage(X, Y, Saucer^, XORput);                 { draw image }
  1032.     Delay(PauseTime);
  1033.     PutImage(X, Y, Saucer^, XORput);                 { erase image }
  1034.     MoveSaucer(X, Y, lrx - ulx + 1, lry - uly + 1);  { width/height }
  1035.   until KeyPressed;
  1036.   FreeMem(Saucer, size);
  1037.   WaitToGo;
  1038. end; { PutImagePlay }
  1039.  
  1040. procedure PolyPlay;
  1041. { Draw random polygons with random fill styles on the screen }
  1042. const
  1043.   MaxPts = 5;
  1044. type
  1045.   PolygonType = array[1..MaxPts] of PointType;
  1046. var
  1047.   Poly : PolygonType;
  1048.   I, Color : word;
  1049. begin
  1050.   MainWindow('FillPoly demonstration');
  1051.   StatusLine('Esc aborts or press a key...');
  1052.   repeat
  1053.     Color := RandColor;
  1054.     SetFillStyle(Random(11)+1, Color);
  1055.     SetColor(Color);
  1056.     for I := 1 to MaxPts do
  1057.       with Poly[I] do
  1058.       begin
  1059.         X := Random(MaxX);
  1060.         Y := Random(MaxY);
  1061.       end;
  1062.     FillPoly(MaxPts, Poly);
  1063.   until KeyPressed;
  1064.   WaitToGo;
  1065. end; { PolyPlay }
  1066.  
  1067. procedure FillStylePlay;
  1068. { Display all of the predefined fill styles available }
  1069. var
  1070.   Style    : word;
  1071.   Width    : word;
  1072.   Height   : word;
  1073.   X, Y     : word;
  1074.   I, J     : word;
  1075.   ViewInfo : ViewPortType;
  1076.  
  1077. procedure DrawBox(X, Y : word);
  1078. begin
  1079.   SetFillStyle(Style, MaxColor);
  1080.   with ViewInfo do
  1081.     Bar(X, Y, X+Width, Y+Height);
  1082.   Rectangle(X, Y, X+Width, Y+Height);
  1083.   OutTextXY(X+(Width div 2), Y+Height+4, Int2Str(Style));
  1084.   Inc(Style);
  1085. end; { DrawBox }
  1086.  
  1087. begin
  1088.   MainWindow('Pre-defined fill styles');
  1089.   GetViewSettings(ViewInfo);
  1090.   with ViewInfo do
  1091.   begin
  1092.     Width := 2 * ((x2+1) div 13);
  1093.     Height := 2 * ((y2-10) div 10);
  1094.   end;
  1095.   X := Width div 2;
  1096.   Y := Height div 2;
  1097.   Style := 0;
  1098.   for J := 1 to 3 do
  1099.   begin
  1100.     for I := 1 to 4 do
  1101.     begin
  1102.       DrawBox(X, Y);
  1103.       Inc(X, (Width div 2) * 3);
  1104.     end;
  1105.     X := Width div 2;
  1106.     Inc(Y, (Height div 2) * 3);
  1107.   end;
  1108.   SetTextJustify(LeftText, TopText);
  1109.   WaitToGo;
  1110. end; { FillStylePlay }
  1111.  
  1112. procedure FillPatternPlay;
  1113. { Display some user defined fill patterns }
  1114. const
  1115.   Patterns : array[0..11] of FillPatternType = (
  1116.   ($AA, $55, $AA, $55, $AA, $55, $AA, $55),
  1117.   ($33, $33, $CC, $CC, $33, $33, $CC, $CC),
  1118.   ($F0, $F0, $F0, $F0, $F, $F, $F, $F),
  1119.   (0, $10, $28, $44, $28, $10, 0, 0),
  1120.   (0, $70, $20, $27, $25, $27, $4, $4),
  1121.   (0, 0, 0, $18, $18, 0, 0, 0),
  1122.   (0, 0, $3C, $3C, $3C, $3C, 0, 0),
  1123.   (0, $7E, $7E, $7E, $7E, $7E, $7E, 0),
  1124.   (0, 0, $22, $8, 0, $22, $1C, 0),
  1125.   ($FF, $7E, $3C, $18, $18, $3C, $7E, $FF),
  1126.   (0, $10, $10, $7C, $10, $10, 0, 0),
  1127.   (0, $42, $24, $18, $18, $24, $42, 0));
  1128. var
  1129.   Style    : word;
  1130.   Width    : word;
  1131.   Height   : word;
  1132.   X, Y     : word;
  1133.   I, J     : word;
  1134.   ViewInfo : ViewPortType;
  1135.  
  1136. procedure DrawBox(X, Y : word);
  1137. begin
  1138.   SetFillPattern(Patterns[Style], MaxColor);
  1139.   with ViewInfo do
  1140.     Bar(X, Y, X+Width, Y+Height);
  1141.   Rectangle(X, Y, X+Width, Y+Height);
  1142.   Inc(Style);
  1143. end; { DrawBox }
  1144.  
  1145. begin
  1146.   MainWindow('User defined fill styles');
  1147.   GetViewSettings(ViewInfo);
  1148.   with ViewInfo do
  1149.   begin
  1150.     Width := 2 * ((x2+1) div 13);
  1151.     Height := 2 * ((y2-10) div 10);
  1152.   end;
  1153.   X := Width div 2;
  1154.   Y := Height div 2;
  1155.   Style := 0;
  1156.   for J := 1 to 3 do
  1157.   begin
  1158.     for I := 1 to 4 do
  1159.     begin
  1160.       DrawBox(X, Y);
  1161.       Inc(X, (Width div 2) * 3);
  1162.     end;
  1163.     X := Width div 2;
  1164.     Inc(Y, (Height div 2) * 3);
  1165.   end;
  1166.   SetTextJustify(LeftText, TopText);
  1167.   WaitToGo;
  1168. end; { FillPatternPlay }
  1169.  
  1170. procedure ColorPlay;
  1171. { Display all of the colors available for the current driver and mode }
  1172. var
  1173.   Color    : word;
  1174.   Width    : word;
  1175.   Height   : word;
  1176.   X, Y     : word;
  1177.   I, J     : word;
  1178.   ViewInfo : ViewPortType;
  1179.  
  1180. procedure DrawBox(X, Y : word);
  1181. begin
  1182.   SetFillStyle(SolidFill, Color);
  1183.   SetColor(Color);
  1184.   with ViewInfo do
  1185.     Bar(X, Y, X+Width, Y+Height);
  1186.   Rectangle(X, Y, X+Width, Y+Height);
  1187.   Color := GetColor;
  1188.   if Color = 0 then
  1189.   begin
  1190.     SetColor(MaxColor);
  1191.     Rectangle(X, Y, X+Width, Y+Height);
  1192.   end;
  1193.   OutTextXY(X+(Width div 2), Y+Height+4, Int2Str(Color));
  1194.   Color := Succ(Color) mod (MaxColor + 1);
  1195. end; { DrawBox }
  1196.  
  1197. begin
  1198.   MainWindow('Color demonstration');
  1199.   Color := 1;
  1200.   GetViewSettings(ViewInfo);
  1201.   with ViewInfo do
  1202.   begin
  1203.     Width := 2 * ((x2+1) div 16);
  1204.     Height := 2 * ((y2-10) div 10);
  1205.   end;
  1206.   X := Width div 2;
  1207.   Y := Height div 2;
  1208.   for J := 1 to 3 do
  1209.   begin
  1210.     for I := 1 to 5 do
  1211.     begin
  1212.       DrawBox(X, Y);
  1213.       Inc(X, (Width div 2) * 3);
  1214.     end;
  1215.     X := Width div 2;
  1216.     Inc(Y, (Height div 2) * 3);
  1217.   end;
  1218.   WaitToGo;
  1219. end; { ColorPlay }
  1220.  
  1221. procedure PalettePlay;
  1222. { Demonstrate the use of the SetPalette command }
  1223. const
  1224.   XBars = 15;
  1225.   YBars = 10;
  1226. var
  1227.   I, J     : word;
  1228.   X, Y     : word;
  1229.   Color    : word;
  1230.   ViewInfo : ViewPortType;
  1231.   Width    : word;
  1232.   Height   : word;
  1233.   OldPal   : PaletteType;
  1234. begin
  1235.   GetPalette(OldPal);
  1236.   MainWindow('Palette demonstration');
  1237.   StatusLine('Press any key...');
  1238.   GetViewSettings(ViewInfo);
  1239.   with ViewInfo do
  1240.   begin
  1241.     Width := (x2-x1) div XBars;
  1242.     Height := (y2-y1) div YBars;
  1243.   end;
  1244.   X := 0; Y := 0;
  1245.   Color := 0;
  1246.   for J := 1 to YBars do
  1247.   begin
  1248.     for I := 1 to XBars do
  1249.     begin
  1250.       SetFillStyle(SolidFill, Color);
  1251.       Bar(X, Y, X+Width, Y+Height);
  1252.       Inc(X, Width+1);
  1253.       Inc(Color);
  1254.       Color := Color mod (MaxColor+1);
  1255.     end;
  1256.     X := 0;
  1257.     Inc(Y, Height+1);
  1258.   end;
  1259.   repeat
  1260.     SetPalette(Random(GetMaxColor + 1), Random(65));
  1261.   until KeyPressed;
  1262.   SetAllPalette(OldPal);
  1263.   WaitToGo;
  1264. end; { PalettePlay }
  1265.  
  1266. procedure CrtModePlay;
  1267. { Demonstrate the use of RestoreCrtMode and SetGraphMode }
  1268. var
  1269.   ViewInfo : ViewPortType;
  1270.   Ch       : char;
  1271. begin
  1272.   MainWindow('SetGraphMode / RestoreCrtMode demo');
  1273.   GetViewSettings(ViewInfo);
  1274.   SetTextJustify(CenterText, CenterText);
  1275.   with ViewInfo do
  1276.   begin
  1277.     OutTextXY((x2-x1) div 2, (y2-y1) div 2, 'Now you are in graphics mode');
  1278.     StatusLine('Press any key for text mode...');
  1279.     repeat until KeyPressed;
  1280.     Ch := ReadKey;
  1281.     if ch = #0 then ch := readkey;    { trap function keys }
  1282.     RestoreCrtmode;
  1283.     Writeln('Now you are in text mode.');
  1284.     Write('Press any key to go back to graphics...');
  1285.     repeat until KeyPressed;
  1286.     Ch := ReadKey;
  1287.     if ch = #0 then ch := readkey;    { trap function keys }
  1288.     SetGraphMode(GetGraphMode);
  1289.     MainWindow('SetGraphMode / RestoreCrtMode demo');
  1290.     SetTextJustify(CenterText, CenterText);
  1291.     OutTextXY((x2-x1) div 2, (y2-y1) div 2, 'Back in graphics mode...');
  1292.   end;
  1293.   WaitToGo;
  1294. end; { CrtModePlay }
  1295.  
  1296. procedure LineStylePlay;
  1297. { Demonstrate the predefined line styles available }
  1298. var
  1299.   Style    : word;
  1300.   Step     : word;
  1301.   X, Y     : word;
  1302.   ViewInfo : ViewPortType;
  1303.  
  1304. begin
  1305.   ClearDevice;
  1306.   DefaultColors;
  1307.   MainWindow('Pre-defined line styles');
  1308.   GetViewSettings(ViewInfo);
  1309.   with ViewInfo do
  1310.   begin
  1311.     X := 35;
  1312.     Y := 10;
  1313.     Step := (x2-x1) div 11;
  1314.     SetTextJustify(LeftText, TopText);
  1315.     OutTextXY(X, Y, 'NormWidth');
  1316.     SetTextJustify(CenterText, TopText);
  1317.     for Style := 0 to 3 do
  1318.     begin
  1319.       SetLineStyle(Style, 0, NormWidth);
  1320.       Line(X, Y+20, X, Y2-40);
  1321.       OutTextXY(X, Y2-30, Int2Str(Style));
  1322.       Inc(X, Step);
  1323.     end;
  1324.     Inc(X, 2*Step);
  1325.     SetTextJustify(LeftText, TopText);
  1326.     OutTextXY(X, Y, 'ThickWidth');
  1327.     SetTextJustify(CenterText, TopText);
  1328.     for Style := 0 to 3 do
  1329.     begin
  1330.       SetLineStyle(Style, 0, ThickWidth);
  1331.       Line(X, Y+20, X, Y2-40);
  1332.       OutTextXY(X, Y2-30, Int2Str(Style));
  1333.       Inc(X, Step);
  1334.     end;
  1335.   end;
  1336.   SetTextJustify(LeftText, TopText);
  1337.   WaitToGo;
  1338. end; { LineStylePlay }
  1339.  
  1340. procedure UserLineStylePlay;
  1341. { Demonstrate user defined line styles }
  1342. var
  1343.   Style    : word;
  1344.   X, Y, I  : word;
  1345.   ViewInfo : ViewPortType;
  1346. begin
  1347.   MainWindow('User defined line styles');
  1348.   GetViewSettings(ViewInfo);
  1349.   with ViewInfo do
  1350.   begin
  1351.     X := 4;
  1352.     Y := 10;
  1353.     Style := 0;
  1354.     I := 0;
  1355.     while X < X2-4 do
  1356.     begin
  1357.       {$B+}
  1358.       Style := Style or (1 shl (I mod 16));
  1359.       {$B-}
  1360.       SetLineStyle(UserBitLn, Style, NormWidth);
  1361.       Line(X, Y, X, (y2-y1)-Y);
  1362.       Inc(X, 5);
  1363.       Inc(I);
  1364.       if Style = 65535 then
  1365.       begin
  1366.         I := 0;
  1367.         Style := 0;
  1368.       end;
  1369.     end;
  1370.   end;
  1371.   WaitToGo;
  1372. end; { UserLineStylePlay }
  1373.  
  1374.  
  1375. procedure SayGoodbye;
  1376. { Say goodbye and then exit the program }
  1377. var
  1378.   ViewInfo : ViewPortType;
  1379. begin
  1380.   MainWindow('');
  1381.   GetViewSettings(ViewInfo);
  1382.   SetTextStyle(TriplexFont, HorizDir, 4);
  1383.   SetTextJustify(CenterText, CenterText);
  1384.   with ViewInfo do
  1385.     OutTextXY((x2-x1) div 2, (y2-y1) div 2, 'That''s all folks!');
  1386.   StatusLine('Press any key to quit...');
  1387.   repeat until KeyPressed;
  1388. end; { SayGoodbye }
  1389.  
  1390. begin { program body }
  1391.   Initialize;
  1392.   ReportStatus;
  1393.  
  1394.   AspectRatioPlay;
  1395.   FillEllipsePlay;
  1396.   SectorPlay;
  1397.   WriteModePlay;
  1398.  
  1399.   ColorPlay;
  1400.   { PalettePlay only intended to work on these drivers: }
  1401.   if (GraphDriver = EGA) or
  1402.      (GraphDriver = EGA64) or
  1403.      (GraphDriver = VGA) then
  1404.     PalettePlay;
  1405.   PutPixelPlay;
  1406.   PutImagePlay;
  1407.   RandBarPlay;
  1408.   BarPlay;
  1409.   Bar3DPlay;
  1410.   ArcPlay;
  1411.   CirclePlay;
  1412.   PiePlay;
  1413.   LineToPlay;
  1414.   LineRelPlay;
  1415.   LineStylePlay;
  1416.   UserLineStylePlay;
  1417.   TextDump;
  1418.   TextPlay;
  1419.   CrtModePlay;
  1420.   FillStylePlay;
  1421.   FillPatternPlay;
  1422.   PolyPlay;
  1423.   SayGoodbye;
  1424.   CloseGraph;
  1425. end.
  1426.