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

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