home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / das_buch / grafik / bgidemo.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-03-17  |  44.2 KB  |  1,620 lines

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