home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / l / l045 / 2.ddi / GRAFEGA.DVR < prev    next >
Encoding:
Text File  |  1987-12-23  |  15.4 KB  |  590 lines

  1. (********************************************************************)
  2. (*                         GRAPHIX TOOLBOX 4.0                      *)
  3. (*       Copyright (c) 1985, 87 by  Borland International, Inc.     *)
  4. (*                                                                  *)
  5. (*         Graphics module for IBM Enhanced Graphics Adapter        *)
  6. (********************************************************************)
  7.  
  8. unit GDriver;
  9.  
  10. interface
  11.  
  12. {$I Float.inc}  { Determines what type Float means. }
  13.  
  14. uses
  15.   Dos, Crt;
  16.  
  17. {$IFOPT N+}
  18. type
  19.   Float = Double; { 8 byte real, requires 8087 math chip }
  20.  
  21. {$ELSE}
  22. type
  23.   Float = real;   { 6 byte real, no math chip required }
  24.  
  25. {$ENDIF}
  26.  
  27. const
  28.   MaxWorldsGlb = 4;
  29.   MaxWindowsGlb = 16;
  30.   MaxPiesGlb = 10;
  31.   MaxPlotGlb = 100;
  32.   StringSizeGlb = 80;
  33.   HeaderSizeGlb = 10;
  34.   RamScreenGlb : boolean = true;
  35.   CharFile : string[StringSizeGlb] = '4x6.fon';
  36.   MaxProcsGlb = 27;
  37.   MaxErrsGlb = 7;
  38.   AspectFactor   = 0.86;           { Aspect ratio for a true circle }
  39.   ScreenSizeGlb  = 16383;          { Total size -1 of the screen in words }
  40.   HardwareGrafBase : word = $A000; { Location of the hardware screen }
  41.   XMaxGlb        = 79;             { Number of bytes -1 in one screen line }
  42.   XScreenMaxGlb  = 639;            { Number of pixels -1 in one screen line }
  43.   YMaxGlb        = 349;            { Number of lines -1 on the screen }
  44.   IVStepGlb      = 2;              { Initial value of VStepGlb }
  45.   MinForeground : word = 0;        { Lowest allowable foreground color }
  46.   MaxForeground : word = 15;       { Highest allowable foreground color }
  47.   MinBackground : word = 0;        { Lowest allowable background color }
  48.   MaxBackground : word = 0;        { Highest allowable background color }
  49.  
  50. type
  51.   WrkString = string[StringSizeGlb];
  52.   WrkStringPtr = ^WrkString;
  53.   WorldType = record
  54.                 X1, Y1, X2, Y2 : Float;
  55.               end;
  56.   WindowType = record
  57.                  X1, Y1, X2, Y2 : integer;
  58.                  Header : WrkString;
  59.                  Drawn, Top : boolean;
  60.                  Size : word;
  61.                end;
  62.   Worlds = array[1..MaxWorldsGlb] of WorldType;
  63.   Windows = array[1..MaxWindowsGlb] of WindowType;
  64.   PlotArray = array[1..MaxPlotGlb, 1..2] of Float;
  65.   Character = array[1..3] of byte;
  66.   CharArray = array[32..126] of character;
  67.   PieType = record
  68.               Area : Float;
  69.               Text : WrkString;
  70.             end;
  71.   PieArray = array[1..MaxPiesGlb] of PieType;
  72.   BackgroundArray = array[0..7] of byte;
  73.   LineStyleArray = array[0..7] of boolean;
  74.   ScreenType        = array[0..ScreenSizeGlb] of word;
  75.   ScreenPointer     = ^ScreenType;
  76.   WindowStackRecord = record
  77.                         W : WindowType;
  78.                         Contents : ScreenPointer;
  79.                       end;
  80.   Stacks            = array[1..MaxWindowsGlb] of WindowStackRecord;
  81.  
  82. var
  83.   X1WldGlb, X2WldGlb, Y1WldGlb, Y2WldGlb, AxGlb, AyGlb, BxGlb, ByGlb : Float;
  84.   X1RefGlb, X2RefGlb, Y1RefGlb, Y2RefGlb : integer;
  85.   LinestyleGlb, MaxWorldGlb, MaxWindowGlb, WindowNdxGlb, WorldNdxGlb : integer;
  86.   X1Glb, X2Glb, Y1Glb, Y2Glb : integer;
  87.   XTextGlb, YTextGlb, VStepGlb : integer;
  88.   PieGlb, DirectModeGlb, ClippingGlb, AxisGlb, HatchGlb : boolean;
  89.   MessageGlb, BrkGlb, HeaderGlb, TopGlb, GrafModeGlb : boolean;
  90.   CntGlb, ColorGlb : byte;
  91.   ErrCodeGlb : integer;
  92.   LineStyleArrayGlb : LineStyleArray;
  93.   ErrorProc : array[0..MaxProcsGlb] of WrkStringPtr;
  94.   ErrorCode : array[0..MaxErrsGlb] of WrkStringPtr;
  95.   PcGlb : string[40];
  96.   AspectGlb : Float;
  97.   GrafBase : word;
  98.   World : Worlds;
  99.   GrafWindow : Windows;
  100.   CharSet : CharArray;
  101.   ScreenGlb : ScreenPointer;
  102.   Stack : Stacks;
  103.  
  104. function BaseAddress(Y : word) : word;
  105. { Calculate address of scanline Y }
  106.  
  107. procedure Error(ErrProc, ErrCode : integer);
  108.  
  109. function HardwarePresent : boolean;
  110. { Test for the presence of a graphics card }
  111.  
  112. procedure AllocateRAMScreen;
  113. { Allocates the RAM screen and makes sure that
  114.   ScreenGlb is on a segment (16 byte) boundary }
  115.  
  116. procedure LeaveGraphic;
  117. { Exit from graphics mode and clear the screen }
  118.  
  119. procedure DC(C : byte);
  120. { Draw the character C at the position XTextGlb, YTextGlb }
  121.  
  122. procedure SetIBMPalette(PaletteNumber, Color : word);
  123. { Set up the palette registers on the IBM CGA }
  124.  
  125. procedure SetForegroundColor(Color : word);
  126. { Set the foreground color }
  127.  
  128. procedure SetBackgroundColor(Color : word);
  129. { Set the background color }
  130.  
  131. procedure ClearScreen;
  132. { Clear the displayed screen }
  133.  
  134. procedure EnterGraphic;
  135. { Enter graphics mode }
  136.  
  137. procedure DP(X, Y : word);
  138. { Plot a pixel at (X, Y) }
  139.  
  140. function PD(X, Y : word) : boolean;
  141. { Return true if the color of the pixel at (X, Y) matches ColorGlb }
  142.  
  143. procedure SetBackground8(Background : BackgroundArray);
  144. { Fills the active display with the specified bit pattern }
  145.  
  146. procedure SetBackground(Byt : byte);
  147. { Determines the background pattern of the active window }
  148.  
  149. procedure DrawStraight(X1, X2, Y : word);
  150. { Draw a horizontal line from X1,Y to X2,Y }
  151.  
  152. procedure SaveScreen(FileName : WrkString);
  153. { Save the current screen on disk using FileName }
  154.  
  155. procedure LoadScreen(FileName : WrkString);
  156. { Load screen from file FileName }
  157.  
  158. procedure SwapScreen;
  159. { Exchanges the contents of the displayed
  160.   screen with the contents of the RAM screen  }
  161.  
  162. procedure CopyScreen;
  163. { Copies the active screen onto the inactive screen }
  164.  
  165. procedure InvertScreen;
  166. { Inverts the image on the active screen }
  167.  
  168. implementation
  169.  
  170. const
  171.   FontLoaded         : boolean =  false; { Has the font been loaded yet? }
  172.  
  173.   ForegroundColorGlb : word = 15;
  174.  
  175. type
  176.   FontChar = array[0..13] of byte;
  177.   GrfFont  = array[0..255] of FontChar;
  178.  
  179. var
  180.   Font          : GrfFont;
  181.   DisplayType   : (Other, EGAColor, EGAMono);
  182.   SaveStateGlb  : word;
  183.   GrafMode      : word;
  184.   DisplayMem    : byte;
  185.  
  186. function BaseAddress{(Y : word) : word};
  187. { Calculate the address of scanline Y }
  188. begin
  189.    BaseAddress := Y * 80;
  190. end; { BaseAddress }
  191.  
  192. procedure Error{(ErrProc, ErrCode : integer)};
  193. var
  194.   XLoc, YLoc : integer;
  195.   Ch : char;
  196.  
  197. begin { Error }
  198.   if not (ErrProc in [0..MaxProcsGlb]) then
  199.   begin
  200.     LeaveGraphic;
  201.     WriteLn('FATAL Error 1: illegal procedure number ', ErrProc);
  202.     Halt;
  203.   end;
  204.   if not (ErrCode in [0..MaxErrsGlb]) then
  205.   begin
  206.     LeaveGraphic;
  207.     WriteLn('FATAL Error 2: illegal Error code ', ErrCode);
  208.     Halt;
  209.   end;
  210.   ErrCodeGlb := ErrCode;
  211.   if BrkGlb then
  212.     LeaveGraphic;
  213.   if MessageGlb or BrkGlb then
  214.   begin
  215.     XLoc := XTextGlb;
  216.     YLoc := YTextGlb;
  217.     GotoXY(1, 24);
  218.     ClrEOL;
  219.     WriteLn('Turbo Graphix Error #', ErrCode, ' in procedure #', ErrProc);
  220.     if MessageGlb then
  221.     begin
  222.       ClrEOL;
  223.       Write('(', ErrorCode[ErrCode]^, ' in ', ErrorProc[ErrProc]^, ')');
  224.     end;
  225.   end;
  226.   if BrkGlb then
  227.     Halt
  228.   else if MessageGlb then
  229.     begin
  230.       Write('.  Hit enter: ');
  231.       repeat
  232.         Ch := ReadKey;
  233.       until (Ch = ^M) or (Ch = ^C);
  234.       if Ch = ^C then
  235.       begin
  236.         LeaveGraphic;
  237.         Halt;
  238.       end;
  239.       GotoXY(XLoc, YLoc);
  240.     end;
  241. end; { Error }
  242.  
  243. function HardwarePresent{ : boolean};
  244. { Test for the presence of a graphics card }
  245. var
  246.   Regs : Registers;
  247.  
  248. begin
  249.   with Regs do
  250.   begin
  251.     AH := $12;
  252.     BX := $FF10;
  253.     Intr($10, Regs);
  254.     if BH = $FF then     { EGA not installed }
  255.       DisplayType := Other
  256.     else if CL = 9 then     { EGA present with enhanced color display }
  257.       begin
  258.         GrafMode := $0010;
  259.         MinForeground := 0;
  260.         MaxForeground := 15;
  261.         MinBackground := 0;
  262.         MaxBackground := 15;
  263.         DisplayType := EGAColor;
  264.       end
  265.     else if CL = 11 then { EGA present with monochrome display }
  266.       begin
  267.         GrafMode := $000F;
  268.         MinForeground := 0;
  269.         MaxForeground := 3;
  270.         MinBackground := 0;
  271.         MaxBackground := 3;
  272.         DisplayType := EGAMono;
  273.       end
  274.     else
  275.       DisplayType := Other;
  276.     DisplayMem := BL;
  277.   end;
  278.   HardwarePresent := DisplayType <> Other;
  279. end; { HardwarePresent }
  280.  
  281. procedure AllocateRAMScreen;
  282. { Allocates the RAM screen and makes sure that
  283.   ScreenGlb is on a segment (16 byte) boundary }
  284. var
  285.   BytePtr : ^byte;
  286. begin
  287.   New(ScreenGlb);
  288.   while Ofs(ScreenGlb^) <> 0 do
  289.   begin
  290.     Dispose(ScreenGlb);
  291.     New(BytePtr);
  292.     New(ScreenGlb);
  293.   end;
  294. end; { AllocateRAMScreen }
  295.  
  296. {$L GrafEGA.OBJ}
  297. procedure DC{(C : byte)}; external;
  298.  
  299. procedure DP{(X, Y : word)}; external;
  300.  
  301. procedure SwapScreen; external;
  302.  
  303. procedure InvertScreen; external;
  304.  
  305. {$F+}
  306. function WriteGrafChars(var F : TextRec) : integer;
  307. { Used to output graphics characters through the standard output channel. }
  308. const
  309.   BackSpace = #8;
  310.   LineFeed  = #10;
  311.   Return    = #13;
  312. var
  313.   I : integer;
  314. begin
  315.   with F do
  316.     if Mode = fmOutput then
  317.     begin
  318.       if BufPos > BufEnd then
  319.       begin
  320.         for I := BufEnd to Pred(BufPos) do  { Flush the output buffer }
  321.         begin
  322.           case BufPtr^[I] of
  323.             BackSpace : if XTextGlb > 1 then
  324.                           DEC(XTextGlb);
  325.  
  326.             LineFeed  : if YTextGlb < 25 then
  327.                           INC(YTextGlb);
  328.  
  329.             Return    : XTextGlb := 1;
  330.           else
  331.             DC(ORD(BufPtr^[I]));
  332.             if XTextGlb < 80 then
  333.               INC(XTextGlb);
  334.           end; { case }
  335.         end; { for }
  336.       end;
  337.       BufPos := BufEnd;
  338.     end; { if }
  339.   WriteGrafChars := 0;
  340. end; { WriteGrafChars }
  341.  
  342. function GrafCharZero(var F : TextRec) : integer;
  343. { Called when standard output is opened and closed }
  344. begin
  345.   GrafCharZero := 0;
  346. end; { GrafCharZero }
  347. {$F-}
  348.  
  349. var
  350.   OldOutput : Text; { Stores output I/O channel }
  351.  
  352. procedure GrafCharsON;
  353. { Redirects standard output to the WriteGrafChars function. }
  354. begin
  355.   Move(Output, OldOutput, SizeOf(Output));  { Save old output channel }
  356.   with TextRec(Output) do
  357.   begin
  358.     OpenFunc:=@GrafCharZero;       { no open necessary }
  359.     InOutFunc:=@WriteGrafChars;    { WriteGrafChars gets called for I/O }
  360.     FlushFunc:=@WriteGrafChars;    { WriteGrafChars flushes automatically }
  361.     CloseFunc:=@GrafCharZero;      { no close necessary }
  362.     Name[0]:=#0;
  363.   end;
  364. end; { GrafCharsON }
  365.  
  366. procedure GrafCharsOFF;
  367. { Restores original output I/O channel }
  368. begin
  369.   Move(OldOutput, Output, SizeOf(OldOutput));
  370. end; { GrafCharsOFF }
  371.  
  372. procedure LeaveGraphic;
  373. { Exit from graphics mode and clear the screen }
  374. var
  375.   Regs : Registers;
  376. begin
  377.   Regs.AX := SaveStateGlb;
  378.   Intr($10, Regs);
  379.   GrafCharsOFF;
  380.   GrafModeGlb := false;
  381. end; { LeaveGraphic }
  382.  
  383. procedure SetIBMPalette{(PaletteNumber, Color : word)};
  384. { Set the palette registers on the IBM EGA }
  385. var
  386.   Regs : Registers;
  387. begin
  388.   with Regs do
  389.   begin
  390.     AX := $1000;
  391.     BH := Color;
  392.     BL := PaletteNumber;
  393.     Intr($10, Regs);
  394.   end;
  395. end; { SetIBMPalette }
  396.  
  397. procedure SetForegroundColor{(Color : word)};
  398. { Set the foreground color }
  399. begin
  400.   if DisplayType = EGAMono then
  401.     SetIBMPalette(2, Color)
  402.   else if DisplayMem = 0 then
  403.     SetIBMPalette(5, Color)
  404.   else
  405.     SetIBMPalette(15, Color);
  406.   ForegroundColorGlb := Color;
  407. end; { SetForegroundColor }
  408.  
  409. procedure SetBackgroundColor{(Color : word)};
  410. { Set the background color }
  411. begin
  412.   SetIBMPalette(0, Color);
  413. end; { SetBackgroundColor }
  414.  
  415. procedure ClearScreen;
  416. { Clear the graphics screen }
  417. begin
  418.   FillChar(Mem[GrafBase:0000], ScreenSizeGlb shl 1, 0);
  419. end; { ClearScreen }
  420.  
  421. procedure EnterGraphic;
  422. { Enter graphics mode }
  423. var
  424.   Regs     : Registers;
  425.   FontFile : file of GrfFont;
  426. begin
  427.   if not FontLoaded then
  428.   begin
  429.     Assign(FontFile, '14x9.FON');
  430.     {$I-} Reset(FontFile); {$I+}
  431.     if IOresult = 0 then
  432.       begin
  433.         Read(FontFile, Font);
  434.         Close(FontFile);
  435.       end
  436.     else
  437.       FillChar(Font, SizeOf(Font), 0);
  438.     FontLoaded := true;
  439.   end;
  440.   SaveStateGlb := 10;
  441.   Regs.AX := $0F00;
  442.   Intr($10, Regs);
  443.   if (Regs.AL < 4) or (SaveStateGlb = 10) then
  444.     SaveStateGlb := Regs.AL;
  445.   Regs.AX := GrafMode;
  446.   Intr($10, Regs);
  447.   SetForegroundColor(MaxForeground);
  448.   if not GrafModeGlb then
  449.     GrafCharsON;
  450.   GrafModeGlb := true;
  451. end; { EnterGraphics }
  452.  
  453. function PD{(X, Y : word) : boolean};
  454. { Return true if the color of the pixel at (X, Y) matches ColorGlb }
  455. begin
  456.   PD := (ColorGlb = 0) xor (Mem[GrafBase:BaseAddress(Y) + X shr 3]
  457.                        and (128 shr (X and 7)) <> 0);
  458. end; { PD }
  459.  
  460. procedure SetBackground8{(Background : BackgroundArray)};
  461. { Fills the active display with the specified bit pattern }
  462. var
  463.   I : word;
  464. begin
  465.   for I := Y1RefGlb to Y2RefGlb do
  466.     FillChar(Mem[GrafBase:BaseAddress(I) + X1RefGlb], X2RefGlb - X1RefGlb + 1,
  467.              Background[I and 7]);
  468. end; { SetBackground8 }
  469.  
  470. procedure SetBackground{(Byt : byte)};
  471. { Determines the background pattern of the active window }
  472. var
  473.   Bk : BackgroundArray;
  474. begin
  475.   FillChar(Bk, 8, Byt);
  476.   SetBackground8(Bk);
  477. end; { SetBackground }
  478.  
  479. procedure DrawStraight{(X1, X2, Y : word)};
  480. { Draw a horizontal line from X1,Y to X2,Y }
  481. var
  482.   I, X : word;
  483.   DirectModeLoc : boolean;
  484. begin
  485.   if (not ((X1 < 0) or (X1 > XMaxGlb shl 3 + 7)) and not ((X2 < 0) or
  486.      (X2 > XMaxGlb shl 3 + 7)) and ((Y >= 0) and (Y <= YMaxGlb))) then
  487.     begin
  488.       DirectModeLoc := DirectModeGlb;
  489.       DirectModeGlb := true;
  490.       if X1 > X2 then
  491.       begin
  492.         X := X1;
  493.         X1 := X2;
  494.         X2 := X;
  495.       end;
  496.       if X2 - X1 < 16 then
  497.         for X := X1 to X2 do
  498.           DP(X, Y)
  499.       else
  500.         begin
  501.           X1 := X1 + 8;
  502.           for I := (X1 - 8) to (X1 and -8) do
  503.             DP(I, Y);
  504.           for I:= (X2 and -8) to X2 do DP(I, Y);
  505.           FillChar(Mem[GrafBase:BaseAddress(Y) + (X1 shr 3)],
  506.                   (X2 shr 3) - (X1 shr 3), ColorGlb);
  507.         end;
  508.       DirectModeGlb := DirectModeLoc;
  509.     end;
  510. end; { DrawStraight }
  511.  
  512. procedure SaveScreen{(FileName : WrkString)};
  513. { Save the current screen on disk using FileName }
  514. type
  515.   PicFile = file of ScreenType;
  516. var
  517.   Picture : ScreenPointer;
  518.   PictureFile : PicFile;
  519.   IOerr : boolean;
  520.  
  521. procedure IOCheck;
  522. begin
  523.   IOerr := IOresult <> 0;
  524.   if IOerr then
  525.     Error(27, 5);
  526. end; { IOCheck }
  527.  
  528. begin { SaveScreen }
  529.   if FileName <> '' then
  530.     begin
  531.       IOerr := false;
  532.       Picture := Ptr(GrafBase, 0);
  533.       Assign(PictureFile, FileName);
  534.       {$I-} Rewrite(PictureFile); {$I+}
  535.       IOCheck;
  536.       if not IOerr then
  537.       begin
  538.         {$I-} Write(PictureFile, Picture^); {$I+}
  539.         IOCheck;
  540.       end;
  541.       if not IOerr then
  542.       begin
  543.         {$I-} Close(PictureFile); {$I+}
  544.         IOCheck;
  545.       end;
  546.     end
  547.   else
  548.     Error(27, 5);
  549. end; { SaveScreen }
  550.  
  551. procedure LoadScreen{(FileName : WrkString)};
  552. { Load screen from file FileName }
  553. type
  554.   PicFile = file of ScreenType;
  555. var
  556.   Picture : ScreenPointer;
  557.   PictureFile : PicFile;
  558. begin
  559.   if FileName <> '' then
  560.     begin
  561.       Picture := Ptr(GrafBase, 0);
  562.       Assign(PictureFile, FileName);
  563.       {$I-} Reset(PictureFile); {$I+}
  564.       if IOresult <> 0 then
  565.         Error(11, 5)
  566.       else
  567.         begin
  568.           Read(PictureFile, Picture^);
  569.           Close(PictureFile);
  570.         end;
  571.     end
  572.   else
  573.     Error(11, 5);
  574. end; { LoadScreen }
  575.  
  576. procedure CopyScreen;
  577. var
  578.   ToBase : word;
  579. begin
  580.   if RamScreenGlb then
  581.   begin
  582.     if GrafBase = HardwareGrafBase then
  583.       ToBase := Seg(ScreenGlb^)
  584.     else
  585.       ToBase := HardwareGrafBase;
  586.     Move(Mem[GrafBase:0000], Mem[ToBase:0000], ScreenSizeGlb shl 1);
  587.   end;
  588. end; { CopyScreen }
  589.  
  590. end. { GDriver }