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

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