home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / PLOT / SURFUTI3.ZIP / PLAYPAL.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-11-20  |  18.8 KB  |  614 lines

  1. { PLAYPAL.PAS: Program to allow the user to play with the graphics
  2.   palette for SURFMODL material definitions.
  3. }
  4. {$I defines.inc }
  5. {$ifdef BIGMEM}
  6. {$undef BIGMEM}
  7. {$endif}
  8. {$define PLAYPAL}   { Short-circuits some code in INITIAL.INC }
  9.  
  10. program PLAYPAL;
  11. uses
  12. {$IFDEF ANSICRT}
  13.      ansicrt,
  14. {$ELSE}
  15.      crt,
  16. {$ENDIF}
  17.      dos,
  18.      SURFGRAF,       { Graphics Routines }
  19.      SHAREDEC,
  20.      graph;
  21.  
  22. {$IFDEF USE8087}
  23. type
  24.   REAL = single;
  25. {$ENDIF}
  26.  
  27. const MAXNODES = 1024;      { maximum # of nodes in the entire solid }
  28.       MAXCONNECT = 4096;    { maximum # of connections in entire solid }
  29.       MAXSURF = 1365;       { maximum # of surfaces in entire solid }
  30.                             { (MAXSURF = MAXCONNECT / 3) }
  31.  
  32. { Watch out for MAXMATL - This constant is repeated in SURFGRAF.PAS, so change
  33.   it there too if you change it here: }
  34.       MAXMATL = 50;         { maximum # of materials in entire solid }
  35.       MAXPTS = 600;         { maximum # of line points (in fillsurf) }
  36.       MAXVAR = 20;          { maximum # of numeric inputs on a line }
  37.       MAXLITE = 20;         { maximum # of light sources }
  38.  
  39.       NSURF_MAT = 16;       { # surfaces to draw per material in PLAYPAL }
  40.       SugTol = 0.05;        { suggestion tolerance is 5% }
  41.  
  42.       MAXFILES = 150;       { maximum # of files to select from }
  43.  
  44.  
  45. type  points = array[1..MAXPTS] of integer;
  46.       realpts = array[1..MAXPTS] of real;
  47.       text80 = string[80];
  48.       text255 = string[255];
  49.       vartype = array[1..MAXVAR] of real;
  50.       surfaces = array[1..MAXSURF] of real;
  51.       vector = array[1..3] of real;
  52.       nodearray= array[1..MAXNODES] of real;
  53.       matlarray = array[1..MAXMATL] of integer;
  54.       filename = string[12];
  55.       filelist = array[1..MAXFILES] of filename;
  56.  
  57.  
  58. type prim_color = ( Red, Grn, Blu );
  59.  
  60. var   Xworld, Yworld, Zworld: nodearray;
  61.         { world coordinates of each node }
  62.       Xtran, Ytran, Ztran: nodearray;
  63.         { transformed coordinates of each node }
  64.       Connect: array[1..MAXCONNECT] of integer;
  65.         { surface connectivity data }
  66.       Nvert: array[1..MAXSURF] of integer;
  67.         { # vertices per surface }
  68.       Matl: array[1..MAXSURF] of integer;
  69.         { material number of each surface }
  70.       { NOTE: The Shades, Surfmin, Surfmax, Nshades and Sshade arrays are
  71.         defined in the individual procedures that require them, to save
  72.         global variable space. }
  73.       R1, R2, R3: array[1..MAXMATL] of real;
  74.         { material reflectivity constants }
  75.       Color: array[1..MAXMATL] of integer;
  76.         { material color number }
  77.       Ambient: array[1..MAXMATL] of real;
  78.         { ambient light intensity for each material }
  79.       Xlite, Ylite, Zlite: array[1..MAXLITE] of real;
  80.         { coords of light sources }
  81.       Intensity: array[1..MAXLITE] of real;
  82.         { light source intensities }
  83.       Matchanged: array[1..MAXMATL] of boolean;
  84.         { has this material's colors been changed? }
  85.  
  86.       Xeye, Yeye, Zeye: real;              { coords of eye }
  87.       Xfocal, Yfocal, Zfocal: real;        { coords of focal point }
  88.       Maxvert: integer;                    { max # vertices per surface }
  89.       Nsurf: integer;                      { # surfaces }
  90.       Nnodes: integer;                     { # nodes }
  91.       Nlite: integer;                      { # light sources }
  92.       Magnify: real;                       { magnification factor }
  93.       Viewtype: integer;                   { code for viewing type: }
  94.                                            { 0=perspective, 1=XY, 2=XZ, 3=YZ }
  95.       Fileread: boolean;                   { flag first file read }
  96.       Nmatl: integer;                      { number of materials }
  97.       Nsides: integer;                     { #sides of surface used (1 or 2)}
  98.       Interpolate: boolean;                { flag for Gouraud interpolation }
  99.       Epsilon: real;                       { Gouraud interpolation range }
  100.       Shadowing: boolean;                  { flag shadowing option }
  101.       Filemask: text80;                    { mask for naming data files }
  102.       Inifile: text80;                     { name of INI file }
  103.       Grfcmmdfile: text80;
  104.       XYadjust: real;                      { factor for screen width }
  105.       Showaxes: integer;                   { code to show (0) no axes; (1) }
  106.                                            { axis directions; (2) full axes }
  107.       Xaxislen,Yaxislen,Zaxislen: real;    { lengths of axes }
  108.       Axiscolor: integer;                  { color to draw axes }
  109.       Nwindow: integer;                    { # graphics windows on screen }
  110.       Xfotran, Yfotran, Zfotran: real;     { transformed focal point }
  111.       XYmax: real;                         { limits of transformed coords }
  112.       memerr : boolean;                    { True if a memory error occured }
  113.       ShowAllBorders: integer;             { code to (1) show surface borders}
  114.                                            { in shaded plots or (0) not }
  115.       Zmin,Zmax: real;                     { min & max Z coords }
  116.  
  117.       curmat: integer;                     { current matl in playpal }
  118.       curcol: prim_color;                  { current color being changed }
  119.       Lastplot: integer;
  120. {$ifdef DEBUG}
  121.       Dbgfile: text;                       { debugging file }
  122. {$endif}
  123.  
  124. { An important function for decoding the Connect array: }
  125.  
  126. function KONNEC (Surf, Vert: integer): integer;
  127. { Decode the Connect array to yield the connection data: Vertex Vert of
  128. surface Surf. This function returns an index to the global Xtran, Ytran,
  129. and Ztran arrays (i.e., a node number) }
  130. begin
  131.   Konnec := Connect[(Surf-1) * Maxvert + Vert];
  132. end; { function KONNEC }
  133.  
  134. { Procedure include files }
  135.  
  136. { Graphics Functions }
  137. {$I COLORMOD.INC}         { COLORMOD }
  138. {$I DITHER.INC  }         { Graphics Dithering functions }
  139. {$I OPENWIN.INC }         { procedure BRIGHT, OPENWIN }
  140. {$I MENUMSG.INC }         { procedure MENUMSG }
  141.  
  142. { Math routines and number input routines}
  143. {$I ARCCOS.INC  }         { function  ARCCOS }
  144. {$I MINMAX.INC }          { procedure MINMAX }
  145. {$I GETKEY.INC  }         { function  GETKEY }
  146. {$I CHKCMMD.INC }         { procedure CHKCMMD }
  147. {$I INREAL.INC }          { procedure INREAL }
  148. {$I GETONE.INC }          { functions GETONEREAL, GETONEINT }
  149.  
  150. { startup routines }
  151. {$I READCFG.INC }         { procedure READCFG }
  152. {$I INITIAL.INC }         { procedure INITIAL }
  153.  
  154. { Modeling Functions }
  155. {$I ONSCREEN.INC }        { function  ONSCREEN }
  156. {$I STORLINE.INC }        { procedure STORLINE }
  157. {$I SWAPS.INC }           { procedure SWAPINT, SWAPREAL }
  158. {$I SHELLPTS.INC }        { procedure SHELLPTS, SHELLSHADES }
  159. {$I FILLSURF.INC }        { procedure BADSURF, FILLSURF }
  160.  
  161. { Local variables for main }
  162. var i: integer;
  163.     mat: integer;
  164.     surf: integer;
  165.     node: integer;
  166.     x: real;
  167.     y: real;
  168.     dx: real;
  169.     dy: real;
  170.  
  171. { put_rgb: Display the value of one of Red, Grn or Blu }
  172. procedure put_rgb (var x: integer; y: integer; textstring: string;
  173.   col: integer);
  174. begin
  175.   puttext (x, y, textstring, col);
  176.   x := x + width_of_text (textstring);
  177. end; { put_rgb }
  178.  
  179. { fillrect: Draw a filled rectangle }
  180. procedure fillrect (x1, y1, x2, y2, color: integer);
  181. var bpts: array[1..5] of pointtype;
  182. begin
  183.   bpts[1].x := x1;
  184.   bpts[1].y := y1;
  185.   bpts[2].x := x2;
  186.   bpts[2].y := y1;
  187.   bpts[3].x := x2;
  188.   bpts[3].y := y2;
  189.   bpts[4].x := x1;
  190.   bpts[4].y := y2;
  191.   bpts[5].x := x1;
  192.   bpts[5].y := y1;
  193.   setcolor(color);
  194.   setfillstyle (SolidFill, color);
  195.   fillpoly (5, bpts);
  196. end; { procedure fillrect }
  197.  
  198. { refresh_text: Refresh the text for a single colorbar }
  199. procedure refresh_text (mat: integer);
  200. var surf: integer;
  201.     node1: integer;
  202.     x, y: integer;
  203.     dx, dy: integer;
  204.     temp: string[20];
  205.     msg: string[80];
  206. begin
  207.   { Add text at end of line (RGB value) }
  208.  
  209.   surf := (mat-1) * NSURF_MAT + 1;
  210.   node1 := konnec (surf, 1);
  211.   y := round (Ytran[node1]);
  212.   x := round (0.675 * Gxmax);
  213.  
  214.   { First clear out the old text (draw a black box) }
  215.   dx := width_of_text ('(000,000,000)') - 1;
  216.   dy := height_of_text ('0');
  217.   fillrect (x, y, x+dx, y+dy, 0);
  218.  
  219.   put_rgb (x, y, '(', CYAN);
  220.   str (Redmax[mat], msg);
  221.   if (mat = curmat) and (curcol = Red) then
  222.     put_rgb (x, y, msg, GREEN)
  223.   else
  224.     put_rgb (x, y, msg, CYAN);
  225.  
  226.   put_rgb (x, y, ',', CYAN);
  227.   str (Grnmax[mat], msg);
  228.   if (mat = curmat) and (curcol = Grn) then
  229.     put_rgb (x, y, msg, GREEN)
  230.   else
  231.     put_rgb (x, y, msg, CYAN);
  232.  
  233.   put_rgb (x, y, ',', CYAN);
  234.   str (Blumax[mat], msg);
  235.   if (mat = curmat) and (curcol = Blu) then
  236.     put_rgb (x, y, msg, GREEN)
  237.   else
  238.     put_rgb (x, y, msg, CYAN);
  239.  
  240.   put_rgb (x, y, ')', CYAN);
  241.  
  242. end; { refresh_text }
  243.  
  244. { refresh_bars: Refresh the entire color bar display }
  245. procedure refresh_bars (Full_refresh: boolean);
  246. var surf: integer;
  247.     mat: integer;
  248.     i: integer;
  249.     shade: real;
  250. begin
  251.   if Full_refresh then
  252.     { Clear the window }
  253.     setgmode(Nmatl)
  254.   else
  255.     { Just redefine the graphics palette }
  256.     def_palette (Nmatl);
  257.   for mat := 1 to Nmatl do begin
  258.     if (Full_refresh) or (Matchanged[mat]) then begin
  259.       surf := (mat-1) * NSURF_MAT + 1;
  260.       shade := 0;
  261.       for i := 1 to NSURF_MAT do begin
  262.         fillsurf (surf, mat, shade);
  263.         surf := surf + 1;
  264.         shade := shade + 1.0/(NSURF_MAT-1.0);
  265.       end;
  266.       refresh_text (mat);
  267.     end;
  268.     Matchanged[mat] := FALSE;
  269.   end;
  270. end; { refresh_bars }
  271.  
  272. { palhelp: Provide help on the use of playpal }
  273. procedure palhelp (Cmmdline: boolean);
  274. var c: char;
  275. begin
  276.   if (not Cmmdline) then begin
  277.     { Switch back to text mode }
  278.     exgraphic;
  279.     clrscr;
  280.   end;
  281.   writeln('                        PLAYPAL COMMANDS:');
  282.   writeln(' ');
  283.   writeln('  UP,DOWN        SELECT NEXT MATERIAL');
  284.   writeln('  TAB            SELECT NEXT COLOR (R, G, OR B)');
  285.   writeln('  LEFT,RIGHT     LOWER, RAISE CURRENT COLOR VALUE');
  286.   writeln('  HOME           SET CURRENT COLOR VALUE TO 1');
  287.   writeln('  END            SET CURRENT COLOR VALUE TO 256');
  288.   writeln('  ENTER          REFRESH COLOR BAR DISPLAY');
  289.   writeln('  I              TOGGLE INCREMENT BETWEEN 16 (DEFAULT) AND 1');
  290.   writeln('  S              SUGGEST NEW RGB VALUES');
  291.   writeln('  Q              QUIT');
  292.   writeln('  F1             HELP (THIS SCREEN)');
  293.   writeln;
  294.  
  295.   if (not Cmmdline) then begin
  296.     writeln('  (Press any key to continue)');
  297.     repeat until keypressed;
  298.     c := readkey;
  299.     refresh_bars(TRUE);
  300.   end;
  301. end; { procedure palhelp }
  302.  
  303. { update_color: Increment or decrement the current color value of the
  304.   current material.
  305. }
  306. procedure update_color (delta: integer);
  307. begin
  308.   Matchanged[curmat] := TRUE;
  309.   case curcol of
  310.     Red: begin
  311.       Redmax[Curmat] := Redmax[Curmat] + delta;
  312.       if Redmax[Curmat] < 1 then
  313.         Redmax[Curmat] := 1;
  314.       if Redmax[Curmat] > 256 then
  315.         Redmax[Curmat] := 256;
  316.       { Note there is one special case: If we are incrementing from 1
  317.         with a step of 16, then we want the result to be 16 instead of
  318.         17 (so we can stay with multiples of 16).
  319.       }
  320.       if (Redmax[Curmat] = 17) and (delta = 16) then
  321.         Redmax[Curmat] := 16;
  322.     end;
  323.     Grn: begin
  324.       Grnmax[Curmat] := Grnmax[Curmat] + delta;
  325.       if Grnmax[Curmat] < 1 then
  326.         Grnmax[Curmat] := 1;
  327.       if Grnmax[Curmat] > 256 then
  328.         Grnmax[Curmat] := 256;
  329.       if (Grnmax[Curmat] = 17) and (delta = 16) then
  330.         Grnmax[Curmat] := 16;
  331.     end;
  332.     Blu: begin
  333.       Blumax[Curmat] := Blumax[Curmat] + delta;
  334.       if Blumax[Curmat] < 1 then
  335.         Blumax[Curmat] := 1;
  336.       if Blumax[Curmat] > 256 then
  337.         Blumax[Curmat] := 256;
  338.       if (Blumax[Curmat] = 17) and (delta = 16) then
  339.         Blumax[Curmat] := 16;
  340.     end;
  341.   end; { case curcol }
  342. end; { procedure update_color }
  343.  
  344. { suggestRGB: Find a new RGB value that is within 10% of the current one
  345.   that has a larger common denominator (to increase the number of pure
  346.   RGB colors).  This is probably somewhat more complex than it needs to be.
  347. }
  348. procedure suggestRGB (Redmax, Grnmax, Blumax: integer);
  349. var RGratio, GBratio, RBratio: real;
  350.     SugRed, SugGrn, SugBlu: real;
  351.     fact: integer;
  352.     Tred, Tgrn, Tblu: integer;
  353.     n: integer;
  354.     fact2: integer;
  355.     RGnew, GBnew, RBnew: real;
  356.     tmp: string[20];
  357.     msg: string[80];
  358.     x, y, dx, dy: integer;
  359. label DONE;
  360. begin
  361.  
  362.   RGratio := Redmax / Grnmax;
  363.   GBratio := Grnmax / Blumax;
  364.   RBratio := Redmax / Blumax;
  365.   fact := 32;
  366.  
  367.   repeat
  368.     fact2 := fact div 2;
  369.     { Pick a new RGB that is a multiple of fact }
  370.     n := (Redmax + fact2) div fact;
  371.     Tred := n * fact;
  372.     if Tred < 1 then
  373.       Tred := 1;
  374.     if Tred > 256 then
  375.       Tred := 256;
  376.     n := (Grnmax + fact2) div fact;
  377.     Tgrn := n * fact;
  378.     if Tgrn < 1 then
  379.       Tgrn := 1;
  380.     if Tgrn > 256 then
  381.       Tgrn := 256;
  382.     n := (Blumax + fact2) div fact;
  383.     Tblu := n * fact;
  384.     if Tblu < 1 then
  385.       Tblu := 1;
  386.     if Tblu > 256 then
  387.       Tblu := 256;
  388.  
  389.     { Use only if it is within SugTol percent of original RGB ratios }
  390.     RGnew := Tred / Tgrn;
  391.     GBnew := Tgrn / Tblu;
  392.     RBnew := Tred / Tblu;
  393.     if (abs (RGnew - RGratio)/RGratio < SugTol) and
  394.        (abs (GBnew - GBratio)/GBratio < SugTol) and
  395.        (abs (RBnew - RBratio)/RBratio < SugTol) then begin
  396.       SugRed := Tred;
  397.       SugGrn := Tgrn;
  398.       SugBlu := Tblu;
  399.       goto DONE;
  400.     end;
  401.     fact := fact2;
  402.  
  403.   until (fact < 2);
  404.  
  405.   { No suggested colors within tolerance - return originals }
  406.   SugRed := Redmax;
  407.   SugGrn := Grnmax;
  408.   SugBlu := Blumax;
  409.  
  410. DONE:
  411.   { First clear out the old text (draw a black box) }
  412.   x := round (Gxmax * 0.025);
  413.   y := round (gymax * 0.9);
  414.   dx := width_of_text ('Suggest: RED=000 GREEN=000 BLUE=000');
  415.   dy := height_of_text ('0');
  416.   fillrect (x, y, x+dx, y+dy, 0);
  417.  
  418.   { Now show the user what we found }
  419.   str (SugRed:3:0, tmp);
  420.   msg := 'Suggest: RED=' + tmp;
  421.   str (SugGrn:3:0, tmp);
  422.   msg := msg + ' GREEN=' + tmp;
  423.   str (SugBlu:3:0, tmp);
  424.   msg := msg + ' BLUE=' + tmp;
  425.   puttext (x, y, msg, GREEN);
  426.  
  427. end; { procedure SuggestRGB }
  428.  
  429. { colorbars: Interactive color bar update procedure }
  430. procedure colorbars;
  431. var c: char;
  432.     Color_Increment: integer;
  433. begin
  434.   curmat := 1;
  435.   curcol := Red;
  436.   Color_Increment := 16;
  437.   refresh_bars(TRUE);
  438.  
  439.   { Interactive loop }
  440.   repeat
  441.     c := upcase (readkey);
  442.     if c = chr(0) then begin
  443.       { Pressed function or arrow key - get second value }
  444.       c := readkey;
  445.       case c of
  446.         ';':          { F1 }
  447.           palhelp (FALSE);
  448.         'H': begin    { Up arrow }
  449.           if curmat > 1 then begin
  450.             curmat := curmat - 1;
  451.             refresh_text (curmat+1);
  452.             refresh_text (curmat);
  453.           end;
  454.         end;
  455.         'P': begin    { Down arrow }
  456.           if curmat < Nmatl then begin
  457.             curmat := curmat + 1;
  458.             refresh_text (curmat-1);
  459.             refresh_text (curmat);
  460.           end;
  461.         end;
  462.         'K': begin    { Left arrow }
  463.           { Decrement current color value }
  464.           update_color (-Color_Increment);
  465.           refresh_text (curmat);
  466.         end;
  467.         'M': begin    { Right arrow }
  468.           { Increment current color value }
  469.           update_color (Color_Increment);
  470.           refresh_text (curmat);
  471.         end;
  472.         'G': begin    { Home }
  473.           { Set current color value to 1 }
  474.           update_color (-256);
  475.           refresh_text (curmat);
  476.         end;
  477.         'O': begin    { End }
  478.           { Set current color value to 256 }
  479.           update_color (256);
  480.           refresh_text (curmat);
  481.         end;
  482.         else
  483.           write (^G)
  484.       end; { case c of }
  485.     end else begin
  486.       { Evaluate normal keypress }
  487.       case c of
  488.         chr(9): begin { Tab }
  489.           if curcol = Red then
  490.             curcol := Grn
  491.           else if curcol = Grn then
  492.             curcol := Blu
  493.           else
  494.             curcol := Red;
  495.           refresh_text (curmat);
  496.         end;
  497.         chr(13): begin { Enter }
  498.           refresh_bars(FALSE);
  499.         end;
  500.         'I': begin
  501.           if Color_Increment = 16 then
  502.             Color_Increment := 1
  503.           else
  504.             Color_Increment := 16;
  505.         end;
  506.         'P': begin
  507.           { Hidden command to update palette without full refresh }
  508.           def_palette (Nmatl);
  509.         end;
  510.         'S': begin
  511.           SuggestRGB (Redmax[curmat], Grnmax[curmat], Blumax[curmat]);
  512.         end;
  513.         'Q': begin
  514.           { Quit - Update files }
  515.         end;
  516.         else
  517.           write (^G)
  518.       end; { case c of }
  519.     end; { if c = chr(0) }
  520.   until (c = 'Q');
  521. end; { colorbars }
  522.  
  523.  
  524. begin  { main }
  525.  
  526.   if (paramcount > 0) then begin
  527.     { Any parameter triggers help. }
  528.     writeln ('usage: PLAYPAL [help]');
  529.     writeln ('  (Any command-line parameter brings up this help display;');
  530.     writeln ('  just type PLAYPAL to start the program.');
  531.     palhelp (TRUE);
  532.     halt;
  533.   end;
  534.  
  535.   initial;
  536.  
  537.   { Enter graphics mode }
  538.   { setgmode (1); }
  539.  
  540.   { Initializations for drawing boxes: 8 materials, NSURF_MAT surfaces each. }
  541.   Fileread := true;
  542.   Nsides := 1;
  543.   Interpolate := true;
  544.   Magnify := 1.0;
  545.   ViewType := 1;
  546.   Maxvert := 4;
  547.   Flpurpose := 'VGA Palette Selector (F1 For Help)';
  548.   Mono := FALSE;
  549.  
  550.   Nmatl := 8;
  551.   surf := 1;
  552.   node := 1;
  553.   dx := (gxmax * 0.62) / NSURF_MAT;
  554.   dy := gymax / (Nmatl * 3.75);
  555.   y := 4*dy;
  556.   for mat := 1 to Nmatl do begin
  557.     Matchanged[mat] := TRUE;
  558.     { Set initial RGB values according to the standard DOS color #'s }
  559.     color_to_RGB (mat, Redmax[mat], Grnmax[mat], Blumax[mat]);
  560.     Color[mat]  := mat;     { for non-VGA users only }
  561.     { Shouldn't need rest of the material constants }
  562.  
  563.     { Each material gets NSURF_MAT surfaces }
  564.     x := dx;
  565.     { First set the leftmost 2 nodes }
  566.     Xtran[node] := x;
  567.     Ytran[node] := y;
  568.     Xtran[node+1] := x;
  569.     Ytran[node+1] := y+dy;
  570.     node := node + 2;
  571.     x := x + dx;
  572.  
  573.     for i := 1 to NSURF_MAT do begin
  574.       { Create 2 new nodes }
  575.       Xtran[node] := x;
  576.       Ytran[node] := y;
  577.       Xtran[node+1] := x;
  578.       Ytran[node+1] := y+dy;
  579.       node := node + 2;
  580.       x := x + dx;
  581.       { Form a surface by connecting this column of nodes to the prev one }
  582.       Nvert[surf] := 4;
  583.       Matl[surf] := mat;
  584.       Connect[(surf-1)*Maxvert+1] := node-4;
  585.       Connect[(surf-1)*Maxvert+2] := node-3;
  586.       Connect[(surf-1)*Maxvert+3] := node-1;
  587.       Connect[(surf-1)*Maxvert+4] := node-2;
  588.       surf := surf + 1;
  589.     end; { for i }
  590.  
  591.     y := y + 3 * dy;
  592.  
  593.   end; { for mat }
  594.  
  595.   Nsurf := surf-1;
  596.   Nnodes := node-1;
  597.   if (Nsurf <> NSURF_MAT * Nmatl) or (Nnodes <> (NSURF_MAT*2+2) * Nmatl) 
  598.       then begin
  599.     { exgraphic; }
  600.     clrscr;
  601.     writeln('Error: Nsurf=', Nsurf, ' Nnodes=', Nnodes);
  602.     halt;
  603.   end;
  604.  
  605.   { Done with the setup - Here is the main function call }
  606.   colorbars;
  607.     
  608.   { Exit graphics mode }
  609.   exgraphic;
  610.   window (1,1,80,25);
  611.   clrscr;
  612.  
  613. end. { program PLAYPAL }
  614.