home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MADTRB16.ZIP / PIBLORES.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1986-02-06  |  23.3 KB  |  594 lines

  1. (*R-,V-,C-,U-*)
  2. PROGRAM PibLoRes;
  3.  
  4. (*--------------------------------------------------------------------------*)
  5. (*                                                                          *)
  6. (*     Program:  PibLoRes                                                   *)
  7. (*                                                                          *)
  8. (*     Purpose:  Demonstrates low resolution (160x100x16 colors) graphics   *)
  9. (*               mode on IBM and compatible color cards.                    *)
  10. (*                                                                          *)
  11. (*     Author:   Philip R. Burns                                            *)
  12. (*     Version:  1.0                                                        *)
  13. (*     Date:     May, 1985                                                  *)
  14. (*                                                                          *)
  15. (*     Requires: IBM PC or close compatible, color graphics card            *)
  16. (*                                                                          *)
  17. (*     Use:      This program demonstrates these three lo-res graphics      *)
  18. (*               procedures:                                                *)
  19. (*                                                                          *)
  20. (*                  Lores_GraphMode                                         *)
  21. (*                  Lores_Move                                              *)
  22. (*                  Lores_Draw                                              *)
  23. (*                                                                          *)
  24. (*               The low resolution graphics mode provides resolution       *)
  25. (*               of 160 horizontal by 100 vertical pixels in 16 colors.     *)
  26. (*               This mode is not directly supported by the BIOS, so        *)
  27. (*               special programming of the CRT registers is required.      *)
  28. (*                                                                          *)
  29. (*               The three procedures listed above are sufficient to        *)
  30. (*               use the lo-res graphics mode.  You should call another     *)
  31. (*               Turbo graphics mode procedure -- say, GraphMode --         *)
  32. (*               at the end of a program which uses these lo-res routines,  *)
  33. (*               otherwise you will find your display in a very peculiar    *)
  34. (*               state indeed.                                              *)
  35. (*                                                                          *)
  36. (*               This low-resolution mode is not really adequate for        *)
  37. (*               serious graphics work, but it is useful for games and      *)
  38. (*               wherever multiple colors are more important than the       *)
  39. (*               degree of resolution.                                      *)
  40. (*                                                                          *)
  41. (*     Credits:  The setup routine is based upon a Basic program called     *)
  42. (*               LOWRES.BAS published in PC WORLD, April, 1985.  The        *)
  43. (*               author was Bernie Lawrence.                                *)
  44. (*                                                                          *)
  45. (*               The line-drawing routine is a straightforward              *)
  46. (*               implementation of an incremental plotter algorithm         *)
  47. (*               adapted for the CRT screen.                                *)
  48. (*                                                                          *)
  49. (*     Problems: Send bug reports, enhancements, etc. to PHILIP BURNS       *)
  50. (*               on either of the following two Chicago BBSs:               *)
  51. (*                                                                          *)
  52. (*                  Gene Plantz's IBBS   (312) 885 4227                     *)
  53. (*                  Ron Fox's RBBS       (312) 940 6496                     *)
  54. (*                                                                          *)
  55. (*               If you make interesting changes, please upload them        *)
  56. (*               so that everyone else can enjoy them too!                  *)
  57. (*                                                                          *)
  58. (*     P.S.      It would be nice if someone would come up with an          *)
  59. (*               alphanumeric display routine so text could be easily       *)
  60. (*               displayed in lo-res mode.                                  *)
  61. (*                                                                          *)
  62. (*--------------------------------------------------------------------------*)
  63.  
  64. CONST
  65.                                    (* Control registers *)
  66.    Mode_Reg     = $3D8;
  67.    Color_Reg    = $3D9;
  68.                                    (* BIOS saves registers here *)
  69.    Mode_Save    = $465;
  70.    Color_Save   = $466;
  71.                                    (* 6845 CRT controller registers *)
  72.    Crt_Reg      = $3D4;
  73.    Crt_Data     = $3D5;
  74.                                    (* Lo-res is form of 80x25 text  *)
  75.    HiRes_Mode   = 1;
  76.    Video_Mode   = 8;
  77.  
  78. (* Structured *) CONST
  79.                                    (* 6845 register data        *)
  80.  
  81.    Reg_Data: ARRAY[ 0 .. 11 ] OF INTEGER
  82.  
  83.              = ( 113,              (* Horizontal total          *)
  84.                  80,               (* Horizontal displayed      *)
  85.                  90,               (* Horizontal sync position  *)
  86.                  10,               (* Horizontal sync width     *)
  87.                  127,              (* Vertical total            *)
  88.                  6,                (* Vertical adjust           *)
  89.                  100,              (* Vertical displayed        *)
  90.                  112,              (* Vertical sync position    *)
  91.                  2,                (* Non-interlace mode        *)
  92.                  1,                (* Maximum scan line address *)
  93.                  32,               (* Disable cursor display    *)
  94.                  0                 (* Cursor end                *)
  95.                     );
  96.  
  97. VAR
  98.    Register:     INTEGER;
  99.    Mode:         INTEGER;
  100.                                    (* Color card memory mapped address *)
  101.    Color_Screen: ARRAY[ 0 .. 16000 ] OF BYTE ABSOLUTE $B800:0000;
  102.    I:            INTEGER;
  103.    PixCol:       INTEGER;
  104.    Y:            INTEGER;
  105.    T:            INTEGER;
  106.    X:            INTEGER;
  107.    C:            CHAR;
  108.  
  109. (*--------------------------------------------------------------------------*)
  110. (*           Lores_GraphMode -- Set Low Resolution Graphics Mode            *)
  111. (*--------------------------------------------------------------------------*)
  112.  
  113. PROCEDURE Lores_GraphMode;
  114.  
  115. (*--------------------------------------------------------------------------*)
  116. (*                                                                          *)
  117. (*    Procedure:  Lores_GraphMode                                           *)
  118. (*                                                                          *)
  119. (*    Purpose:    Initiates low resolution graphics mode                    *)
  120. (*                                                                          *)
  121. (*    Calling Sequence:                                                     *)
  122. (*                                                                          *)
  123. (*       Lores_GraphMode;                                                   *)
  124. (*                                                                          *)
  125. (*    Calls:  None                                                          *)
  126. (*                                                                          *)
  127. (*--------------------------------------------------------------------------*)
  128.  
  129. BEGIN (* Lores_GraphMode *)
  130.  
  131.                                    (* Clear out current 6845 settings *)
  132.    MemW[Cseg:Mode_Save]  := 0;
  133.    MemW[Cseg:Color_Save] := 0;
  134.    PORT[Mode_Reg]        := 0;
  135.    PORT[Color_Reg]       := 0;
  136.  
  137.                                    (* Reprogram 6845 for lo-res       *)
  138.    FOR Register := 0 TO 11 DO
  139.       BEGIN
  140.          PORT[Crt_Reg]  := Register;
  141.          PORT[Crt_Data] := Reg_Data[Register];
  142.       END;
  143.                                    (* Lo-res is actually form of 80x25 *)
  144.                                    (* text mode                        *)
  145.  
  146.    Mode := HiRes_Mode + Video_Mode;
  147.  
  148.    MemW[Cseg:Mode_Save] := Mode;
  149.    PORT[Mode_Reg]       := Mode;
  150.  
  151.                                    (* Clear the screen                *)
  152.  
  153.    FillChar( Color_Screen, 16000, 0 );
  154.  
  155.                                    (* Fill graphics memory with 222s.  *)
  156.                                    (* This is character which fills    *)
  157.                                    (* left half of character cell with *)
  158.                                    (* background color and right half  *)
  159.                                    (* with foreground color.           *)
  160.    FOR I := 0 TO 7999 DO
  161.       Color_Screen[2 * I]     := 222;
  162.  
  163. END   (* Lores_GraphMode *);
  164.  
  165. (*--------------------------------------------------------------------------*)
  166. (*           Lores_Plot -- Plot Point in Low Resolution Graphics Mode       *)
  167. (*--------------------------------------------------------------------------*)
  168.  
  169. PROCEDURE Lores_Plot( X , Y , PixCol: INTEGER );
  170.  
  171. (*--------------------------------------------------------------------------*)
  172. (*                                                                          *)
  173. (*    Procedure:  Lores_Plot                                                *)
  174. (*                                                                          *)
  175. (*    Purpose:    Plots point in low-resolution graphics mode               *)
  176. (*                                                                          *)
  177. (*    Calling Sequence:                                                     *)
  178. (*                                                                          *)
  179. (*       Lores_Plot( X , Y , PixCol : INTEGER );                            *)
  180. (*                                                                          *)
  181. (*           X      -- Horizontal postion (0 through 159)                   *)
  182. (*           Y      -- Vertical position (0 through 119)                    *)
  183. (*           PixCol -- Color (0 through 15) of point                        *)
  184. (*                     See the Turbo manual for color assignments.          *)
  185. (*                                                                          *)
  186. (*    Calls:  None                                                          *)
  187. (*                                                                          *)
  188. (*    Remarks:  Requests for point positions outside the correct range,     *)
  189. (*              or for colors outside the correct range, are ignored.       *)
  190. (*              For extra speed, remove the check.                          *)
  191. (*                                                                          *)
  192. (*--------------------------------------------------------------------------*)
  193.  
  194.  
  195. VAR
  196.    Pixel:      INTEGER;
  197.    Pixel_Addr: INTEGER;
  198.    Nibble:     INTEGER;
  199.    Legal:      BOOLEAN;
  200.  
  201. BEGIN (* Lores_Plot *)
  202.  
  203.    Legal := ( X >= 0 ) AND ( X <= 159 ) AND ( Y >= 0 ) AND ( Y <= 119 ) AND
  204.             ( PixCol >= 0 ) AND ( PixCol <= 15 );
  205.  
  206.    IF Legal THEN
  207.       BEGIN
  208.  
  209.          Pixel      := X + ( Y * 160 );
  210.          Pixel_Addr := ( Pixel AND $FFFE ) + 1;
  211.          Nibble     := Pixel MOD 2;
  212.  
  213.          IF Nibble = 0 THEN
  214.             Color_Screen[Pixel_Addr] := ( Color_Screen[Pixel_Addr] AND $0F )
  215.                                         + PixCol * 16
  216.          ELSE
  217.             Color_Screen[Pixel_Addr] := ( Color_Screen[Pixel_Addr] AND $F0 )
  218.                                         + PixCol;
  219.       END;
  220.  
  221. END   (* Lores_Plot *);
  222.  
  223. (*--------------------------------------------------------------------------*)
  224. (*           Lores_Draw -- Draw line between two points, low res. mode      *)
  225. (*--------------------------------------------------------------------------*)
  226.  
  227. PROCEDURE Lores_Draw( X1, Y1, X2, Y2, LineCol: INTEGER );
  228.  
  229. (*--------------------------------------------------------------------------*)
  230. (*                                                                          *)
  231. (*    Procedure:  Lores_Draw                                                *)
  232. (*                                                                          *)
  233. (*    Purpose:    Draws line between two points in low-res. graphics mode   *)
  234. (*                                                                          *)
  235. (*    Calling Sequence:                                                     *)
  236. (*                                                                          *)
  237. (*       Lores_Draw( X1 , Y1 , X2, Y2, LineCol : INTEGER );                 *)
  238. (*                                                                          *)
  239. (*           X1      -- Horizontal postion (0 through 159), 1st point       *)
  240. (*           Y1      -- Vertical position (0 through 119), 1st point        *)
  241. (*           X2      -- Horizontal postion (0 through 159), 2nd point       *)
  242. (*           Y2      -- Vertical position (0 through 119), 2nd point        *)
  243. (*           LineCol -- Color (0 through 15) of line                        *)
  244. (*                                                                          *)
  245. (*    Calls:  Lores_Plot                                                    *)
  246. (*                                                                          *)
  247. (*    Remarks: An incremental plotter algorithm is used.                    *)
  248. (*                                                                          *)
  249. (*--------------------------------------------------------------------------*)
  250.  
  251. VAR
  252.    Xinc:       INTEGER;
  253.    Yinc:       INTEGER;
  254.    Dx:         INTEGER;
  255.    Cdx:        INTEGER;
  256.    Dy:         INTEGER;
  257.    Cdy:        INTEGER;
  258.    X:          INTEGER;
  259.    Y:          INTEGER;
  260.    Correc_Inc: INTEGER;
  261.    Plotit:     BOOLEAN;
  262.  
  263. BEGIN (* Lores_Draw *)
  264.                                    (* Starting point *)
  265.    X  := X1;
  266.    Y  := Y1;
  267.                                    (* Changes in (x,y) direction *)
  268.    Dx := X2 - X1;
  269.    Dy := Y2 - Y1;
  270.                                    (* Set increments *)
  271.    IF Dx > 0 THEN
  272.       Xinc := 1
  273.    ELSE
  274.       BEGIN
  275.          Xinc := -1;
  276.          Dx   := -Dx;
  277.       END;
  278.  
  279.    IF Dy > 0 THEN
  280.       Yinc := 1
  281.    ELSE
  282.       BEGIN
  283.          Yinc := -1;
  284.          Dy   := -Dy;
  285.       END;
  286.                                    (* Reset_Inc is correction value *)
  287.    IF Dy > Dx THEN
  288.       Correc_Inc := Dy
  289.    ELSE
  290.       Correc_Inc := Dx;
  291.  
  292.    Cdx := Correc_Inc;
  293.    Cdy := Correc_Inc;
  294.  
  295.                                    (* Plot first point *)
  296.    Lores_Plot( X, Y, LineCol );
  297.  
  298.                                    (* Plot remaining points *)
  299.  
  300.    WHILE( ( X <> X2 ) AND ( Y <> Y2 ) ) DO
  301.       BEGIN
  302.  
  303.          PlotIt := FALSE;
  304.  
  305.          Cdx    := Cdx - Dx;
  306.  
  307.          IF Cdx < 0 THEN
  308.             BEGIN
  309.                PlotIt := TRUE;
  310.                X      := X + Xinc;
  311.                Cdx    := Cdx + Correc_Inc;
  312.             END;
  313.  
  314.          Cdy := Cdy - Dy;
  315.  
  316.          IF Cdy < 0 THEN
  317.             BEGIN
  318.                PlotIt := TRUE;
  319.                Y      := Y + Yinc;
  320.                Cdy    := Cdy + Correc_Inc;
  321.             END;
  322.  
  323.          IF PlotIt THEN Lores_Plot( X, Y, LineCol );
  324.  
  325.       END;
  326.  
  327. END   (* Lores_Draw *);
  328.  
  329. (*--------------------------------------------------------------------------*)
  330. (*               D E M O N S T R A T I O N   R O U T I N E S                *)
  331. (*--------------------------------------------------------------------------*)
  332.  
  333. (*--------------------------------------------------------------------------*)
  334. (*         Lores_Demo1 -- Draw embedded frames using Lo-Res graphics        *)
  335. (*--------------------------------------------------------------------------*)
  336.  
  337. PROCEDURE Lores_Demo1;
  338.  
  339. (*--------------------------------------------------------------------------*)
  340. (*                                                                          *)
  341. (*    Procedure:  Lores_Demo1                                               *)
  342. (*                                                                          *)
  343. (*    Purpose:    Draws series of embedded frames                           *)
  344. (*                                                                          *)
  345. (*    Calling Sequence:                                                     *)
  346. (*                                                                          *)
  347. (*       Lores_Demo1;                                                       *)
  348. (*                                                                          *)
  349. (*    Calls:  Lores_Plot                                                    *)
  350. (*                                                                          *)
  351. (*--------------------------------------------------------------------------*)
  352.  
  353. BEGIN (* Lores_Demo1 *)
  354.  
  355.    PixCol := 0;
  356.    Y      := 0;
  357.  
  358.    FOR T := 1 TO 99 DO
  359.       BEGIN
  360.          Y := Y + 1;
  361.          IF ( T MOD 5 ) = 0 THEN
  362.             PixCol := ( PixCol + 1 ) MOD 15;
  363.          FOR X := 1 TO T DO
  364.             Lores_Plot( X , Y , PixCol );
  365.       END;
  366.  
  367.    X      := 1;
  368.    PixCol := 8;
  369.  
  370.    FOR T := 1 TO 99 DO
  371.       BEGIN
  372.          X := X + 1;
  373.          IF ( T MOD 5 ) = 0 THEN PixCol := ( PixCol + 1 ) MOD 15;
  374.          FOR Y := 1 TO T DO
  375.             Lores_Plot( X , Y , PixCol );
  376.       END;
  377.  
  378. END   (* Lores_Demo1 *);
  379.  
  380.  
  381. (*--------------------------------------------------------------------------*)
  382. (*         Lores_Demo2 -- Borland's ART.PAS for lores graphics              *)
  383. (*--------------------------------------------------------------------------*)
  384.  
  385. PROCEDURE Lores_Demo2;
  386.  
  387. (*--------------------------------------------------------------------------*)
  388. (*                                                                          *)
  389. (*    Procedure:  Lores_Demo2                                               *)
  390. (*                                                                          *)
  391. (*    Purpose:    Draws series of lines at various angles and colors.       *)
  392. (*                From Borland's ART.PAS demonstration program for          *)
  393. (*                medium-resolution graphics.                               *)
  394. (*                                                                          *)
  395. (*    Calling Sequence:                                                     *)
  396. (*                                                                          *)
  397. (*       Lores_Demo2;                                                       *)
  398. (*                                                                          *)
  399. (*    Calls:  Lores_Plot                                                    *)
  400. (*                                                                          *)
  401. (*--------------------------------------------------------------------------*)
  402.  
  403. Const
  404.   Memory = 150;
  405.  
  406. var
  407.   Line:  array [1..Memory] of record
  408.                                 LX1,LY1: integer;
  409.                                 LX2,LY2: integer;
  410.                                 LColor:  integer;
  411.                               end;
  412.   X1,X2,Y1,Y2,
  413.   CurrentLine,
  414.   ColorCount,
  415.   IncrementCount,
  416.   DeltaX1,DeltaY1,DeltaX2,DeltaY2,
  417.   I,Color:            integer;
  418.   Ch: char;
  419.  
  420. procedure Init;
  421. begin
  422.   for I:=1 to Memory do
  423.   with Line[I] do
  424.   begin
  425.     LX1:=0; LX2:=0;
  426.     LY1:=0; LY2:=0;
  427.   end;
  428.   X1:=0; Y1:=0; X2:=0; Y2:=0;
  429.   CurrentLine:=1;
  430.   ColorCount:=0;
  431.   IncrementCount:=0;
  432.   Ch:=' ';
  433. end;
  434.  
  435. procedure AdjustX(var X,DeltaX: integer);
  436. var
  437.   TestX: integer;
  438. begin
  439.   TestX:=X+DeltaX;
  440.   if (TestX<1) or (TestX>160) then
  441.   begin
  442.     TestX:=X;
  443.     DeltaX:=-DeltaX;
  444.   end;
  445.   X:=TestX;
  446. end;
  447.  
  448. procedure AdjustY(var Y,DeltaY: integer);
  449. var
  450.   TestY: integer;
  451. begin
  452.   TestY:=Y+DeltaY;
  453.   if (TestY<1) or (TestY>90) then
  454.   begin
  455.     TestY:=Y;
  456.     DeltaY:=-DeltaY;
  457.   end;
  458.   Y:=TestY;
  459. end;
  460.  
  461. procedure SelectNewColor;
  462. begin
  463.   Repeat
  464.      Color:=Random(16)+1;
  465.   Until not ( Color in [0,8] ) ;
  466.   ColorCount:=5*(1+Random(10));
  467. end;
  468.  
  469. procedure SelectNewDeltaValues;
  470. begin
  471.   DeltaX1:=Random(7)-3;
  472.   DeltaX2:=Random(7)-3;
  473.   DeltaY1:=Random(7)-3;
  474.   DeltaY2:=Random(7)-3;
  475.   IncrementCount:=4*(1+Random(9));
  476. end;
  477.  
  478.  
  479. procedure SaveCurrentLine;
  480. begin
  481.   with Line[CurrentLine] do
  482.   begin
  483.     LX1:=X1;
  484.     LY1:=Y1;
  485.     LX2:=X2;
  486.     LY2:=Y2;
  487.     LColor:=Color;
  488.   end;
  489. end;
  490.  
  491.  
  492. procedure Regenerate;
  493. var
  494.   I: integer;
  495. begin
  496.  
  497.   NoSound;
  498.  
  499.   Lores_GraphMode;
  500.   for I:=1 to Memory do with Line[I] do Lores_Draw(LX1,LY1,LX2,LY2,LColor);
  501.   read(Kbd,Ch);
  502. end;
  503.  
  504. begin (* Lores_Demo2 *)
  505.  
  506.   Init;
  507.                                    (* Set up lo-res color graphics mode *)
  508.   Lores_GraphMode;
  509.  
  510.   Color:=2;
  511.   gotoxy(1,11);
  512.   repeat
  513.     with Line[CurrentLine] do Lores_Draw(LX1,LY1,LX2,LY2,0);
  514.  
  515.     if ColorCount=0 then SelectNewColor;
  516.     if IncrementCount=0 then SelectNewDeltaValues;
  517.  
  518.     AdjustX(X1,DeltaX1); AdjustX(X2,DeltaX2);
  519.     AdjustY(Y1,DeltaY1); AdjustY(Y2,DeltaY2);
  520.  
  521.     Lores_Draw(X1,Y1,X2,Y2,Color);
  522.  
  523.     SaveCurrentLine;
  524.  
  525.     CurrentLine:=Succ(CurrentLine);
  526.     if CurrentLine>Memory then CurrentLine:=1;
  527.     ColorCount:=Pred(ColorCount); IncrementCount:=Pred(IncrementCount);
  528.  
  529.     if KeyPressed then
  530.     begin
  531.       read(Kbd,Ch);
  532.       if Ch<>#27 then
  533.       begin
  534.         Regenerate;
  535.       end;
  536.     end;
  537.   until Ch=#27;
  538.   TextMode;
  539.  
  540. END   (* Lores_Demo2 *);
  541.  
  542.  
  543. (*--------------------------------------------------------------------------*)
  544. (*                       PibLoRes --- Main Program                          *)
  545. (*--------------------------------------------------------------------------*)
  546.  
  547. BEGIN (* PibLoRes *)
  548.  
  549.    ClrScr;
  550.                                    (* Announce demonstration *)
  551.  
  552.    WRITELN('This program demonstrates a low-resolution graphics mode');
  553.    WRITELN('of 160 horizontal by 100 vertical positions, with 16 colors');
  554.    WRITELN('available for each plotting position.');
  555.    WRITELN(' ');
  556.    WRITELN('The first demonstration produces a series of embedded frames.');
  557.    WRITELN('After the frames appear, hit the carriage return key to ');
  558.    WRITELN('go on to the next demonstration.' );
  559.    WRITELN(' ');
  560.    WRITELN('Hit the carriage return (enter) key to start the demo.');
  561.  
  562.    WHILE( NOT KeyPressed ) DO;
  563.    WHILE KeyPressed DO READ( KBD , C );
  564.  
  565.                                    (* Do frame demo *)
  566.    Lores_GraphMode;
  567.    Lores_Demo1;
  568.                                    (* Wait for input to clear screen *)
  569.    WHILE( NOT KeyPressed ) DO;
  570.    WHILE KeyPressed DO READ( KBD , C );
  571.  
  572.                                    (* Announce second demo *)
  573.    GraphMode;
  574.    TextMode( C80 );
  575.  
  576.    WRITELN('The second demonstration is a modified version of the');
  577.    WRITELN('sample ART.PAS program from the Turbo Pascal release disk.');
  578.    WRITELN('To exit this demonstration, hit the ESCAPE key.  To restart');
  579.    WRITELN('this demonstration, hit the return key.');
  580.    WRITELN(' ');
  581.    WRITELN('Hit the carriage return (enter) key to start the demo.');
  582.  
  583.    WHILE( NOT KeyPressed ) DO;
  584.    WHILE KeyPressed DO READ( KBD , C );
  585.  
  586.                                    (* Do ART demo *)
  587.    Lores_GraphMode;
  588.    Lores_Demo2;
  589.  
  590.                                    (* Ensure screen left in text mode *)
  591.    GraphMode;
  592.    TextMode( C80 );
  593.  
  594. END   (* PibLoRes *).