home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / ASM / GR110.ZIP / GR.INC < prev    next >
Encoding:
Text File  |  1985-08-26  |  13.1 KB  |  469 lines

  1. {
  2.        Graphics Routines
  3.          Version 1.1.0
  4.             8/16/85
  5.  
  6.      By Michael A. Quinlan
  7.  
  8.   See file GR.DOC for documentation
  9. }
  10.  
  11.   Type GrString = String[80];      { general purpose string }
  12.        _GrBuffT = array [0..32767] of byte;
  13.  
  14.   const _GrGraphMode : (_GrTextMode, _GrHGCMode, _GrCGAMode) = _GrTextMode;
  15.  
  16.   Var GrBytes   : integer;         { # bytes in the screen refresh buffer }
  17.       GrWords   : integer;         { # words in the screen refresh buffer }
  18.       GrBase    : integer;         { segment base for screen refresh buffer }
  19.       GrBuffer  : ^_GrBuffT;       { ptr to screen refresh buffer }
  20.  
  21.       ScrMaxX    : integer;        { max X screen coordinate }
  22.       ScrMaxY    : integer;        { max Y screen coordinate }
  23.       ScrAspect  : real;           { screen aspect }
  24.  
  25.       WindX1     : integer;        { screen coord for U.L. corner of window }
  26.       WindY1     : integer;
  27.       WindMaxX   : integer;        { max X window coordinate }
  28.       WindMaxY   : integer;        { max Y window coordinate }
  29.       WindMaxRow : integer;        { max window row }
  30.       WindMaxCol : integer;        { max window column }
  31.  
  32.       WorldX1    : real;           { World coord of U.L. corner of window }
  33.       WorldY1    : real;
  34.       WorldXRange: real;           { range of X values; X2-X1 }
  35.       WorldYRange: real;           { range of Y values; Y2-Y1 }
  36.  
  37.       WhereX, WhereY : integer;
  38.  
  39.       _ScrWriteDot   : integer;
  40.       _ScrReadDot    : integer;
  41.       _ScrDrawLine   : integer;
  42.       _ScrDrawChar   : integer;
  43.       _GrFillWindow  : integer;
  44.       _GrSaveWindow  : integer;
  45.       _GrRestoreWindow : integer;
  46.  
  47.       _GrOldConOut   : integer;
  48.  
  49. procedure _Gr;               external 'GR.COM';  {*** DO NOT CALL ***}
  50. function _GrHGCThere : boolean;   external _Gr[0];
  51. function _GrCGAThere : boolean;   external _Gr[3];
  52. procedure _GrInitHGC;        external _Gr[6];
  53. procedure _GrInitCGA;        external _Gr[9];
  54. procedure _GrTermHGC;        external _Gr[12];
  55. procedure _GrTermCGA;        external _Gr[15];
  56. procedure _ScrWriteDotHGC;   external _Gr[18];   {*** DO NOT CALL ***}
  57. procedure _ScrWriteDotCGA;   external _Gr[21];   {*** DO NOT CALL ***}
  58. procedure _ScrDrawLineHGC;   external _Gr[24];   {*** DO NOT CALL ***}
  59. procedure _ScrDrawLineCGA;   external _Gr[27];   {*** DO NOT CALL ***}
  60. procedure _GrFillWindowHGC;  external _Gr[30];   {*** DO NOT CALL ***}
  61. procedure _GrFillWindowCGA;  external _Gr[33];   {*** DO NOT CALL ***}
  62. procedure _ScrDrawCharHGC;   external _Gr[36];   {*** DO NOT CALL ***}
  63. procedure _ScrDrawCharCGA;   external _Gr[39];   {*** DO NOT CALL ***}
  64. procedure _GrSaveWindowHGC;  external _Gr[42];   {*** DO NOT CALL ***}
  65. procedure _GrSaveWindowCGA;  external _Gr[45];   {*** DO NOT CALL ***}
  66. procedure _GrRestoreWindowHGC; external _Gr[48]; {*** DO NOT CALL ***}
  67. procedure _GrRestoreWindowCGA; external _Gr[51]; {*** DO NOT CALL ***}
  68. function _GrOutcode(x, y, XMax, YMax : integer) : integer;
  69.   external _Gr[54];
  70. procedure _ScrReadDotHGC;    external _Gr[57];   {*** DO NOT CALL ***}
  71. procedure _ScrReadDotCGA;    external _Gr[60];   {*** DO NOT CALL ***}
  72. procedure _GrISwap(var i, j : integer); external _Gr[63];
  73.  
  74. procedure _GrGotoXY(x, y : integer);
  75.   begin
  76.     GotoXY(x, y)
  77.   end;
  78.  
  79. procedure _GrClrScr;
  80.   begin
  81.     ClrScr;
  82.     WhereX := 1;
  83.     WhereY := 1
  84.   end;
  85.  
  86. procedure _GrClrEol;
  87.   begin
  88.     ClrEol
  89.   end;
  90.  
  91. procedure ScrDrawChar(x, y : integer; c : char);
  92.   begin
  93.     Inline($FF/$26/_ScrDrawChar)   { Jmp [_ScrDrawChar] }
  94.   end;
  95.  
  96. procedure ScrWriteDot(x, y, color : integer);
  97.   begin
  98.     Inline($FF/$26/_ScrWriteDot)   { Jmp [_ScrWriteDot] }
  99.   end;
  100.  
  101. function ScrReadDot(x, y : integer) : integer;
  102.   begin
  103.     Inline($FF/$26/_ScrReadDot)    { Jmp [_ScrReadDot] }
  104.   end;
  105.  
  106. procedure ScrDrawLine(x1, y1, x2, y2, color : integer);
  107.   var m, b : real;
  108.       i    : integer;
  109.   begin
  110.     Inline($FF/$26/_ScrDrawLine)   { Jmp [_ScrDrawLine] }
  111.   end;
  112.  
  113. procedure ScrDrawText(x, y : integer; t : GrString);
  114.   var i : integer;
  115.   begin
  116.     for i := 1 to length(t) do begin
  117.       ScrDrawChar(x, y, t[i]);
  118.       x := x + 8
  119.     end
  120.   end;
  121.  
  122. procedure ScrDrawBox(x1, y1, x2, y2, color : integer);
  123.   begin
  124.     ScrDrawLine(x1, y1, x2, y1, color);
  125.     ScrDrawLine(x2, y1, x2, y2, color);
  126.     ScrDrawLine(x2, y2, x1, y2, color);
  127.     ScrDrawLine(x1, y2, x1, y1, color)
  128.   end;
  129.  
  130. procedure WindWriteDot(x, y, color : integer);
  131.   begin
  132.     if (x >= 0) and (x <= WindMaxX) and (y >= 0) and (y <= WindMaxY) then
  133.       ScrWriteDot(x + WindX1, y + WindY1, color)
  134.   end;
  135.  
  136. function WindReadDot(x, y : integer) : integer;
  137.   begin
  138.     if (x < 0) or (x > WindMaxX) or (y < 0) or (y > WindMaxY) then
  139.       WindReadDot := 0
  140.     else WindReadDot := ScrReadDot(x + WindX1, y + WindY1)
  141.   end;
  142.  
  143. function _WindClipLine(var x1, y1, x2, y2 : integer) : boolean;
  144.  
  145. { Cohen-Sutherland Clipping Algorithm
  146.   See "Fundamentals of Interactive Computer Graphics" p. 148 }
  147.  
  148.   var done : boolean;
  149.       outcode1, outcode2 : integer;
  150.   begin
  151.     done := FALSE;
  152.     _WindClipLine := FALSE;
  153.     outcode2 := _GrOutcode(x2, y2, WindMaxX, WindMaxY);
  154.     repeat
  155.       outcode1 := _GrOutcode(x1, y1, WindMaxX, WindMaxY);
  156.       if (outcode1 or outcode2) = 0 then begin
  157.         _WindClipLine := TRUE;
  158.         done := TRUE
  159.       end else if (outcode1 and outcode2) <> 0 then begin
  160.         _WindClipLine := FALSE;
  161.         done := TRUE
  162.       end else begin
  163.         if outcode1 = 0 then begin
  164.           _GrISwap(outcode1, outcode2);
  165.           _GrISwap(x1, x2);
  166.           _GrISwap(y1, y2)
  167.         end;
  168.         if (outcode1 and $01) <> 0 then begin
  169.           x1 := x1 + (x2 - x1) * Trunc((WindMaxY - y1) / (y2 - y1));
  170.           y1 := WindMaxY
  171.         end else if (outcode1 and $02) <> 0 then begin
  172.           x1 := x1 + (x2 - x1) * Trunc((-y1) / (y2 - y1));
  173.           y1 := 0
  174.         end else if (outcode1 and $04) <> 0 then begin
  175.           y1 := y1 + (y2 - y1) * Trunc((WindMaxX - x1) / (x2 - x1));
  176.           x1 := WindMaxX
  177.         end else if (outcode1 and $08) <> 0 then begin
  178.           y1 := y1 + (y2 - y1) * Trunc((-x1) / (x2 - x1));
  179.           x1 := 0
  180.         end
  181.       end
  182.     until done
  183.   end;
  184.  
  185. procedure WindDrawLine(x1, y1, x2, y2, color : integer);
  186.   begin
  187.     if _WindClipLine(x1, y1, x2, y2) then
  188.       ScrDrawLine(x1 + WindX1, y1 + WindY1, x2 + WindX1, y2 + WindY1, color)
  189.   end;
  190.  
  191. procedure WindDrawBox(x1, y1, x2, y2, color : integer);
  192.   var DrawTop, DrawBot, DrawLeft, DrawRight : boolean;
  193.  
  194.   begin
  195.     if x1 > x2 then _GrISwap(x1, x2);
  196.     if y1 > y2 then _GrISwap(y1, y2);
  197.  
  198.     if x1 > WindMaxX then exit;
  199.     if y1 > WindMaxY then exit;
  200.     if x2 < 0 then exit;
  201.     if y2 < 0 then exit;
  202.  
  203.     DrawTop := TRUE;
  204.     DrawBot := TRUE;
  205.     DrawLeft := TRUE;
  206.     DrawRight := TRUE;
  207.  
  208.     if x1 < 0 then begin
  209.       x1 := 0;
  210.       DrawLeft := FALSE
  211.     end;
  212.     if y1 < 0 then begin
  213.       y1 := 0;
  214.       DrawTop := FALSE
  215.     end;
  216.     if x2 > WindMaxX then begin
  217.       x2 := WindMaxX;
  218.       DrawRight := FALSE
  219.     end;
  220.     if y2 > WindMaxY then begin
  221.       y2 := WindMaxY;
  222.       DrawBot := FALSE
  223.     end;
  224.  
  225.     x1 := x1 + WindX1;
  226.     x2 := x2 + WindX1;
  227.     y1 := y1 + WindY1;
  228.     y2 := y2 + WindY1;
  229.  
  230.     if DrawTop then ScrDrawLine(x1, y1, x2, y1, color);
  231.     if DrawRight then ScrDrawLine(x2, y1, x2, y2, color);
  232.     if DrawBot then ScrDrawLine(x2, y2, x1, y2, color);
  233.     if DrawLeft then ScrDrawLine(x1, y2, x1, y1, color)
  234.   end;
  235.  
  236. procedure WindDrawChar(x, y : integer; c : char);
  237.   begin
  238.     x := (x + 7) and $FFF8;
  239.     if x < 0 then exit;
  240.     if (x + 7) > WindMaxX then exit;
  241.     if y < 0 then exit;
  242.     if (y + 7) > WindMaxY then exit;
  243.     ScrDrawChar(x + WindX1, y + WindY1, c)
  244.   end;
  245.  
  246. procedure WindDrawText(x, y : integer; t : GrString);
  247.   var i : integer;
  248.   begin
  249.     for i := 1 to length(t) do begin
  250.       WindDrawChar(x, y, t[i]);
  251.       x := x + 8
  252.     end
  253.   end;
  254.  
  255. function _WorldToWindowX(x : real) : integer;
  256.   begin
  257.     _WorldToWindowX := Round(((x - WorldX1) * WindMaxX) / WorldXRange)
  258.   end;
  259.  
  260. function _WorldToWindowY(y : real) : integer;
  261.   begin
  262.     _WorldToWindowY := Round(((y - WorldY1) * WindMaxY) / WorldYRange)
  263.   end;
  264.  
  265. procedure WorldWriteDot(x, y : real; color : integer);
  266.   begin
  267.     WindWriteDot(_WorldToWindowX(x), _WorldToWindowY(y), color)
  268.   end;
  269.  
  270. function WorldReadDot(x, y : real) : integer;
  271.   begin
  272.     WorldReadDot := WindReadDot(_WorldToWindowX(x), _WorldToWindowY(y))
  273.   end;
  274.  
  275. procedure WorldDrawLine(x1, y1, x2, y2 : real; color : integer);
  276.   begin
  277.     WindDrawLine(_WorldToWindowX(x1), _WorldToWindowY(y1),
  278.                  _WorldToWindowX(x2), _WorldToWindowY(y2), color)
  279.   end;
  280.  
  281. procedure WorldDrawBox(x1, y1, x2, y2 : real; color : integer);
  282.   begin
  283.     WindDrawBox(_WorldToWindowX(x1), _WorldToWindowY(y1),
  284.                 _WorldToWindowX(x2), _WorldToWindowY(y2), color)
  285.   end;
  286.  
  287. procedure WorldDrawChar(x, y : real; c : char);
  288.   begin
  289.     WindDrawChar(_WorldToWindowX(x), _WorldToWindowY(y), c)
  290.   end;
  291.  
  292. procedure WorldDrawText(x, y : real; t : GrString);
  293.   begin
  294.     WindDrawText(_WorldToWindowX(x), _WorldToWIndowY(y), t)
  295.   end;
  296.  
  297. procedure GotoXY(x, y : integer);
  298.   begin
  299.     WhereX := x;
  300.     WhereY := y;
  301.     if _GrGraphMode = _GrTextMode then _GrGotoXY(x, y)
  302.   end;
  303.  
  304. procedure ClrScr;
  305.   begin
  306.     if _GrGraphMode = _GrTextMode then _GrClrScr
  307.     else begin
  308.       FillChar(GrBuffer^, GrBytes, 0);
  309.       WhereX := 1;
  310.       WhereY := 1
  311.     end
  312.   end;
  313.  
  314. procedure ClrEol;
  315.   var i, x, y : integer;
  316.   begin
  317.     if _GrGraphMode = _GrTextMode then _GrClrEol
  318.     else begin
  319.       y := (WhereY - 1) * 8;
  320.       x := (WhereX - 1) * 8;
  321.       for i := WhereX to WindMaxCol do begin
  322.         WindDrawChar(x, y, ' ');
  323.         x := x + 8
  324.       end
  325.     end
  326.   end;
  327.  
  328. procedure _GrBeep;
  329.   begin
  330.     Sound(1000);
  331.     Delay(100);
  332.     NoSound
  333.   end;
  334.  
  335. procedure _GrScroll;
  336. { scroll the window up 1 line }
  337.   begin
  338.     WhereY := 1   { for now, forget about scrolling }
  339.   end;
  340.  
  341. procedure _GrNewLine;
  342. { advance to the next line }
  343.   begin
  344.     if WhereY >= WindMaxRow then _GrScroll
  345.     else WhereY := WhereY + 1;
  346.     WhereX := 1
  347.   end;
  348.  
  349. procedure _GrNextCol;
  350. { advance to the next column }
  351.   begin
  352.     if WhereX >= WindMaxCol then _GrNewLine
  353.     else WhereX := WhereX + 1
  354.   end;
  355.  
  356. procedure GrWriteChar(c : char);
  357.   begin
  358.     if (c >= ' ') and (c < Chr(127)) then begin
  359.       WindDrawChar((WhereX - 1) * 8, (WhereY - 1) * 8, c);
  360.       _GrNextCol
  361.     end else case c of
  362.       ^G : _GrBeep;
  363.       ^J : _GrNewLine;
  364.       ^M : WhereX := 1
  365.     end
  366.   end;
  367.  
  368. procedure GrWorld(x1, y1, x2, y2 : real);
  369.   begin
  370.     WorldX1 := x1;
  371.     WorldY1 := y1;
  372.     WorldXRange := x2 - x1;
  373.     WorldYRange := y2 - y1
  374.   end;
  375.  
  376. procedure GrWindow(x1, y1, x2, y2 : integer);
  377.   begin
  378.     x1 := (x1 + 7) and $7ff8;
  379.     WindX1 := x1;
  380.     WindY1 := y1;
  381.     WindMaxX := x2 - x1;
  382.     if WindMaxX < 7 then WindMaxX := 7;
  383.     WindMaxY := y2 - y1;
  384.     if WindMaxY < 1 then WindMaxY := 1;
  385.     WindMaxRow := (WindMaxY + 1) div 8;
  386.     WindMaxCol := (WindMaxX + 1) div 8;
  387.     WhereX := 1;
  388.     WhereY := 1;
  389.     GrWorld(x1, y1, x2, y2)
  390.   end;
  391.  
  392. procedure _GrDoInitHGC;
  393.   begin
  394.     ScrMaxX := 719;
  395.     ScrMaxY := 347;
  396.     ScrAspect := 0.75;
  397.     GrBytes := $8000;
  398.     GrWords := 16384;
  399.     GrBase  := $B000;
  400.     _ScrWriteDot     := Ofs(_ScrWriteDotHGC);
  401.     _ScrReadDot      := Ofs(_ScrReadDotHGC);
  402.     _ScrDrawLine     := Ofs(_ScrDrawLineHGC);
  403.     _GrFillWindow    := Ofs(_GrFillWindowHGC);
  404.     _ScrDrawChar     := Ofs(_ScrDrawCharHGC);
  405.     _GrSaveWindow    := Ofs(_GrSaveWindowHGC);
  406.     _GrRestoreWindow := Ofs(_GrRestoreWIndowHGC);
  407.     _GrInitHGC;
  408.     _GrGraphMode := _GrHGCMode
  409.   end;
  410.  
  411. procedure _GrDoInitCGA;
  412.   begin
  413.     ScrMaxX := 639;
  414.     ScrMaxY := 199;
  415.     ScrAspect := 0.44;
  416.     GrBytes := 16384;
  417.     GrWords := 8192;
  418.     GrBase  := $B800;
  419.     _ScrWriteDot     := Ofs(_ScrWriteDotCGA);
  420.     _ScrReadDot      := Ofs(_ScrReadDotCGA);
  421.     _ScrDrawLine     := Ofs(_ScrDrawLineCGA);
  422.     _GrFillWindow    := Ofs(_GrFillWindowCGA);
  423.     _ScrDrawChar     := Ofs(_ScrDrawCharCGA);
  424.     _GrSaveWindow    := Ofs(_GrSaveWindowCGA);
  425.     _GrRestoreWindow := Ofs(_GrRestoreWindowCGA);
  426.     _GrInitCGA;
  427.     _GrGraphMode := _GrCGAMode
  428.   end;
  429.  
  430. procedure GrInit;
  431.   begin
  432.     if _GrHGCThere then _GrDoInitHGC
  433.     else if _GrCGAThere then _GrDoInitCGA
  434.     else begin
  435.       writeln('***GrInit: Graphics Adaptor Card not found');
  436.       halt
  437.     end;
  438.     GrBuffer := Ptr(GrBase, 0);
  439.     GrWindow(0, 0, ScrMaxX, ScrMaxY);
  440.     GrWorld(0.0, 0.0, ScrMaxX, ScrMaxY);
  441.     _GrOldConOut := ConOutPtr;
  442.     ConOutPtr := Ofs(GrWriteChar)
  443.   end;
  444.  
  445. procedure GrTerm;
  446.   begin
  447.     case _GrGraphMode of
  448.       _GrHGCMode : _GrTermHGC;
  449.       _GrCGAMode : _GrTermCGA
  450.     end;
  451.     _GrGraphMode := _GrTextMode;
  452.     ConOutPtr := _GrOldConOut
  453.   end;
  454.  
  455. procedure GrSaveWindow(var area; x1, y1, x2, y2 : integer);
  456.   begin
  457.     Inline($FF/$26/_GrSaveWindow)  { JMP [_GrSaveWindow] }
  458.   end;
  459.  
  460. procedure GrRestoreWindow(x1, y1, x2, y2 : integer; var area);
  461.   begin
  462.     Inline($FF/$26/_GrRestoreWindow) { JMP [_GrRestoreWindow] }
  463.   end;
  464.  
  465. procedure GrFillWindow(x1, y1, x2, y2, color : integer);
  466.   begin
  467.     Inline($FF/$26/_GrFillWindow)   { Jmp [_GrFillWindow] }
  468.   end;
  469.