home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / fgl / fglight / manuals.arj / USER05.DOC < prev    next >
Text File  |  1995-02-06  |  75KB  |  1,606 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6. Chapter 5
  7.  
  8.  
  9.  
  10.  
  11.  
  12. The Use of Color                                                               
  13. 68   Fastgraph User's Guide
  14.  
  15.  
  16. Overview
  17.  
  18.      The use of color is an important part of any text or graphics
  19. application. This chapter explains color as it applies to text and graphics
  20. modes. It also describes palettes and video DAC registers for the graphics
  21. video modes that offer this functionality. Finally, an explanation of
  22. Fastgraph's virtual colors is provided.
  23.  
  24.  
  25. Text Modes
  26.  
  27.      The term color is not really correct in text modes because each character
  28. cell has an associated attribute that controls the character's appearance in
  29. that cell. The meaning of the attribute differs for color and monochrome text
  30. modes.
  31.  
  32.  
  33. Color Text Modes
  34.  
  35.      In color text modes (modes 0, 1, 2, and 3), the attribute determines a
  36. character's foreground color (the color of the character itself), its
  37. background color (the color of that part of the character cell not covered by
  38. the character), and whether or not it blinks. Sixteen foreground colors
  39. (numbered 0 to 15) are available, but only eight background colors (numbered 0
  40. to 7) are available. The colors assigned to these values are listed in the
  41. following table.
  42.  
  43.                       number     color    number     color
  44.  
  45.                          0       black       8     dark gray
  46.                          1       blue        9    light blue
  47.                          2       green      10    light green
  48.                          3       cyan       11    light cyan
  49.                          4        red       12     light red
  50.                          5      magenta     13   light magenta
  51.                          6       brown      14      yellow
  52.                          7       gray       15       white
  53.  
  54. At first it may seem the numbers have been arbitrarily assigned to the colors.
  55. Upon further inspection, however, it becomes apparent this is not the case.
  56. Each color number is a four bit quantity of the form IRGB, with I representing
  57. the intensity, R the red component, G the green component, and B the blue
  58. component. If the corresponding bit is 1, it means the intensity or color
  59. component is set. For example, normal red would be represented by the IRGB bit
  60. pattern 0100, which is 4 decimal, the color number for red.
  61.  
  62.      The fg_setattr routine defines the current text attribute. Once
  63. fg_setattr is called, Fastgraph displays all subsequent text using that
  64. attribute. The first argument of fg_setattr defines the foreground color,
  65. which must be an integer between 0 and 15. Its second argument defines the
  66. background color, which must be between 0 and 7. Its third argument determines
  67. if the foreground color blinks (1 means it blinks, 0 means it does not). For
  68. example, the statement
  69.  
  70.                               fg_setattr(14,1,0);                              
  71.                                              Chapter 5:  The Use of Color   69
  72.  
  73.  
  74. specifies subsequent text will be displayed with a yellow foreground (14) on a
  75. blue background (1) and will not blink (0).
  76.  
  77.      Another Fastgraph routine, fg_setcolor, also can define text attributes.
  78. The fg_setcolor routine packs the three values passed to fg_setattr into a
  79. single argument, as shown here:
  80.  
  81.                             bits         attribute
  82.  
  83.                              0-3     foreground color
  84.                              4-6     background color
  85.                               7          blinking
  86.  
  87. For example, calling fg_setcolor with an argument of 30 (1E hex) is equivalent
  88. to calling fg_setattr with arguments of 14, 1, and 0.
  89.  
  90.      The Fastgraph routine fg_getcolor returns the current text attribute, as
  91. defined in the most recent call to fg_setattr or fg_setcolor. The fg_getcolor
  92. routine has no arguments and returns the attribute as its function value. The
  93. returned value is encoded using the same scheme for passing a text attribute
  94. to fg_setcolor.
  95.  
  96.  
  97. Monochrome Text Mode
  98.  
  99.      In the monochrome text mode (mode 7), colors are obviously not available.
  100. The attribute instead determines whether a character is invisible, normal,
  101. bold, reversed, or certain combinations of these. The following table shows
  102. the values assigned to the available display characteristics.
  103.  
  104.                     foreground     background   characteristic
  105.  
  106.                          0              0          invisible
  107.                          0              7          reversed
  108.                          1              0         underlined
  109.                          7              0           normal
  110.                          9              0       underlined bold
  111.                         15              0            bold
  112.  
  113. Additionally, you can turn blinking on or off for each of these combinations.
  114. Any combination of foreground and background values not listed in the above
  115. table produces a normal display characteristic.
  116.  
  117.      As in the color modes, the Fastgraph routines fg_setattr and fg_setcolor
  118. define the current text attribute. For example, the statement
  119.  
  120.                               fg_setattr(0,7,1);
  121.  
  122. specifies subsequent text will be displayed in reverse video (0,7) and will
  123. blink (1). The same attribute could be defined by calling fg_setcolor with an
  124. argument of 240 (F0 hex). The fg_getcolor routine is also available and works
  125. as it does in the color text modes.                                            
  126. 70   Fastgraph User's Guide
  127.  
  128.  
  129. Graphics Modes
  130.  
  131.      In graphics modes, each pixel has an associated color value that
  132. determines the color in which the pixel is displayed. The number of available
  133. colors depends on the video mode and can be obtained through the fg_colors
  134. function. Some graphics modes also have palette registers or video DAC
  135. registers to provide additional color capabilities, such as choosing a set of
  136. colors from a larger palette of colors. The example programs presented in this
  137. section show the use of color in specific graphics video modes.
  138.  
  139.      The following subsections will discuss the use of color in each graphics
  140. video mode. In these discussions, there will be several references to a group
  141. of colors called the standard color set. This is a set of 16 colors common to
  142. many of the graphics video modes (and to the color text modes). The colors in
  143. the standard color set are listed in the following table.
  144.  
  145.                       number     color    number     color
  146.  
  147.                          0       black       8     dark gray
  148.                          1       blue        9    light blue
  149.                          2       green      10    light green
  150.                          3       cyan       11    light cyan
  151.                          4        red       12     light red
  152.                          5      magenta     13   light magenta
  153.                          6       brown      14      yellow
  154.                          7       gray       15       white
  155.  
  156.      At this point we must understand the difference between the terms color
  157. number and color value. Color number refers to the number that defines a color
  158. in the standard color set (for example, green is color number 2). Color value
  159. refers to the actual value of a pixel in video memory, which ultimately
  160. determines the color in which that pixel is displayed. The color value is
  161. sometimes just called the color.
  162.  
  163.      In each graphics mode, video memory is cleared when the fg_setmode
  164. routine is called. This means all pixels are initially set to color value 0,
  165. which by default is black. For this reason, color value 0 is often called the
  166. background color in graphics video modes.
  167.  
  168.      Fastgraph's fg_setcolor routine defines the color in which subsequent
  169. graphics operations are performed. This color is called the current color.
  170. Depending on the video mode, the current color can reference a color value (in
  171. CGA and Hercules graphics modes), a palette register (in Tandy, EGA, and VGA
  172. graphics modes), or a video DAC register (in 256-color modes). The fg_setcolor
  173. routine takes a single integer argument that specifies the color. When
  174. fg_setmode is called, it sets the current color to 0. The Fastgraph routine
  175. fg_getcolor returns the current color, as defined in the most recent call to
  176. fg_setcolor. The fg_getcolor routine has no arguments and returns the current
  177. color as its function value.
  178.  
  179.  
  180. CGA Color Modes
  181.  
  182.      The CGA color modes (modes 4 and 5) have six sets of available colors,
  183. called palettes, numbered 0 to 5. Each palette consists of four colors,        
  184.                                              Chapter 5:  The Use of Color   71
  185.  
  186. numbered 0 to 3. In each palette, the background color (color value 0) can be
  187. selected from the standard color set, but the other 3 colors are fixed. The
  188. following table shows the fixed colors assigned to each palette.
  189.  
  190.  
  191.                       palette 0       palette 1       palette 2
  192.  
  193.             color 1   light green     light cyan      light cyan
  194.             color 2   light red       light magenta   light red
  195.             color 3   yellow          white           white
  196.  
  197.                       palette 3       palette 4       palette 5
  198.  
  199.             color 1   green           cyan            cyan
  200.             color 2   red             magenta         red
  201.             color 3   brown           gray            gray
  202.  
  203.  
  204. Palette 1, with a black background, is the default palette when you select
  205. mode 4. Palette 2, with a black background, is the default palette when you
  206. select mode 5.
  207.  
  208.      The CGA color modes have a border area called the overscan between the
  209. addressable pixel space and the physical edges of the screen. The overscan
  210. area is always displayed in the background color, regardless of which CGA
  211. palette is used.
  212.  
  213.      In CGA color modes, fg_setcolor defines the current color by referencing
  214. one of the four color values. The fg_palette routine selects one of the six
  215. palettes and defines the background color for that palette. The first argument
  216. of fg_palette is an integer between 0 and 5 that specifies the palette number.
  217. The second argument is an integer between 0 and 15 that defines the background
  218. color, using the color numbers in the standard color set.
  219.  
  220.      Example 5-1 demonstrates the use of fg_palette and fg_setcolor in mode 4.
  221. After establishing the video mode, the program selects palette 0 and makes the
  222. background color blue (color number 1). It then makes color 3 in palette 0
  223. (yellow) the current color and displays the word "Hello". Finally, it restores
  224. the original video mode and screen attributes before returning to DOS.
  225.  
  226.                                  Example 5-1.
  227.  
  228.                             #include <fastgraf.h>
  229.                             void main(void);
  230.  
  231.                             void main()
  232.                             {
  233.                                int mode;
  234.  
  235.                                fg_initpm();
  236.                                mode = fg_getmode();
  237.                                fg_setmode(4);
  238.  
  239.                                fg_palette(0,1);
  240.                                fg_setcolor(3);
  241.                                fg_text("Hello",5);                             
  242. 72   Fastgraph User's Guide
  243.  
  244.                                fg_waitkey();
  245.  
  246.                                fg_setmode(mode);
  247.                                fg_reset();
  248.                             }
  249.  
  250.  
  251.  
  252. CGA Two-Color Mode
  253.  
  254.      The CGA two-color mode (mode 6) has a fixed background color (color value
  255. 0) and a user-definable foreground color (color value 1). The background color
  256. is always black. The foreground color is white by default but can be changed
  257. to any of the colors in the standard color set. We should mention that
  258. changing the foreground color works on true CGA adapters, but there are very
  259. few EGA, VGA, and SVGA adapters that correctly implement changing the
  260. foreground color in their mode 6 emulation.
  261.  
  262.      In mode 6, fg_setcolor defines the current color by referencing one of
  263. the two color values. The fg_palette routine defines the actual foreground
  264. color (that is, the color of pixels whose color value is 1). For consistency
  265. with other graphics modes, fg_palette has two arguments, but the first one is
  266. not used. The second argument is an integer between 0 and 15 that defines the
  267. foreground color, using the color numbers in the standard color set.
  268.  
  269.      Example 5-2 demonstrates the use of fg_palette and fg_setcolor in mode 6.
  270. After establishing the video mode, the program makes the foreground color
  271. yellow (color number 14). It then makes color 1 the current color and displays
  272. the word "Hello". Finally, it restores the original video mode and screen
  273. attributes before returning to DOS.
  274.  
  275.                                  Example 5-2.
  276.  
  277.                             #include <fastgraf.h>
  278.                             void main(void);
  279.  
  280.                             void main()
  281.                             {
  282.                                int mode;
  283.  
  284.                                fg_initpm();
  285.                                mode = fg_getmode();
  286.                                fg_setmode(6);
  287.  
  288.                                fg_palette(0,14);
  289.                                fg_setcolor(1);
  290.                                fg_text("Hello",5);
  291.                                fg_waitkey();
  292.  
  293.                                fg_setmode(mode);
  294.                                fg_reset();
  295.                             }                                                  
  296.                                              Chapter 5:  The Use of Color   73
  297.  
  298.  
  299. Tandy and PCjr Modes
  300.  
  301.      The supported Tandy 1000 or PCjr graphics mode (mode 9) has 16 color
  302. values, numbered 0 to 15. Each color value references one of 16 user-definable
  303. palette registers, often simply called palettes, also numbered 0 to 15. The
  304. values assigned to the palette registers determine the colors in which pixels
  305. are displayed. For example, if you assign palette register 2 the value for
  306. red, then pixels whose color value is 2 will be red.
  307.  
  308.      Each palette can assume one of the 16 colors in the standard color set.
  309. By default, the values assigned to the 16 palettes correspond to the
  310. identically numbered colors in the standard color set. In other words, palette
  311. 0 is assigned the value for black, palette 1 is assigned the value for blue,
  312. and so forth.
  313.  
  314.      In mode 9, fg_setcolor defines the current color by referencing one of
  315. the 16 palette registers. The fg_palette routine defines the actual color
  316. assigned to a specific palette register. The first argument of fg_palette is
  317. an integer between 0 and 15 that specifies the palette number. The second
  318. argument is an integer between 0 and 15 that defines the palette value (the
  319. color assigned to the palette), using the IRGB color numbers in the standard
  320. color set.
  321.  
  322.      You also can use the Fastgraph routine fg_setrgb to define the color
  323. assigned to a specific palette register. While fg_palette does this using a
  324. color number from the standard color set, fg_setrgb defines a palette register
  325. using red, green, and blue color components plus an intensity component. The
  326. first argument of fg_setrgb is an integer between 0 and 15 that specifies the
  327. palette register number. The remaining three arguments are each integer values
  328. between -1 and 1 that respectively specify the red, green, and blue color
  329. components for that palette register. The meanings of the color components
  330. are:
  331.  
  332.      -1 = color bit and intensity bit are set
  333.       0 = color bit is reset
  334.       1 = color bit is set
  335.  
  336. Since there is only one intensity bit in mode 9 color values, specifying -1
  337. for any of the RGB color components produces an intense color. For example,
  338. the color light cyan is color number 11 in the standard color set, and it is
  339. produced by combining green and blue and setting the intensity bit. This means
  340. any of these four statements
  341.  
  342.  
  343.                              fg_palette(1,11);
  344.                              fg_setrgb(1,0,-1,1);
  345.                              fg_setrgb(1,0,1,-1);
  346.                              fg_setrgb(1,0,-1,-1);
  347.  
  348.  
  349. could be used to define palette register 1 as light cyan in mode 9.
  350.  
  351.      Example 5-3 demonstrates the use of fg_palette and fg_setcolor in mode 9.
  352. After establishing the video mode, the program defines palette 0 to be blue
  353. (1) and palette 1 to be yellow (14). Note that defining palette 0 changes the  
  354. 74   Fastgraph User's Guide
  355.  
  356. background color. It then makes color 1 the current color and displays the
  357. word "Hello". After waiting for a keystroke, the program changes the color of
  358. "Hello" by changing palette 1 to white (15). Finally, it restores the original
  359. video mode and screen attributes before returning to DOS.
  360.  
  361.                                  Example 5-3.
  362.  
  363.                             #include <fastgraf.h>
  364.                             void main(void);
  365.  
  366.                             void main()
  367.                             {
  368.                                int mode;
  369.  
  370.                                fg_initpm();
  371.                                mode = fg_getmode();
  372.                                fg_setmode(9);
  373.  
  374.                                fg_palette(0,1);
  375.                                fg_palette(1,14);
  376.  
  377.                                fg_setcolor(1);
  378.                                fg_text("Hello",5);
  379.                                fg_waitkey();
  380.  
  381.                                fg_palette(1,15);
  382.                                fg_waitkey();
  383.  
  384.                                fg_setmode(mode);
  385.                                fg_reset();
  386.                             }
  387.  
  388.  
  389.  
  390. Hercules Mode
  391.  
  392.      The Hercules graphics mode (mode 11) has a fixed background color (color
  393. value 0) and a fixed foreground color (color value 1). The background color is
  394. always black, and the foreground color is dependent on the monochrome display
  395. being used (typically it is green, amber, or white).
  396.  
  397.      The fg_setcolor routine defines the current color value by referencing
  398. one of the two color values. The fg_palette routine has no effect in mode 11.
  399.  
  400.      Example 5-4 demonstrates the use of fg_setcolor in mode 11. After
  401. establishing the video mode, the program makes color 1 the current color and
  402. displays the word "Hello". It then restores the original video mode and screen
  403. attributes before returning to DOS.
  404.  
  405.                                  Example 5-4.
  406.  
  407.                             #include <fastgraf.h>
  408.                             void main(void);
  409.  
  410.                             void main()
  411.                             {                                                  
  412.                                              Chapter 5:  The Use of Color   75
  413.  
  414.                                int mode;
  415.  
  416.                                fg_initpm();
  417.                                mode = fg_getmode();
  418.                                fg_setmode(11);
  419.  
  420.                                fg_setcolor(1);
  421.                                fg_text("Hello",5);
  422.                                fg_waitkey();
  423.  
  424.                                fg_setmode(mode);
  425.                                fg_reset();
  426.                             }
  427.  
  428.  
  429.  
  430. Hercules Low-Resolution Mode
  431.  
  432.      The Hercules low-resolution graphics mode (mode 12) has four color
  433. values, numbered 0 to 3. The background color is always black, colors 1 and 2
  434. are normal intensity, and color 3 is full intensity. Colors 1 and 2 both
  435. produce normal intensity colors, but they do so with different pixel
  436. patterns -- color 1 turns on the odd-numbered physical pixels, while color 2
  437. turns on the even-numbered physical pixels. The appearance of colors 1 to 3 is
  438. dependent on the monochrome display being used (typically it is green, amber,
  439. or white).
  440.  
  441.      The fg_setcolor routine defines the current color value by referencing
  442. one of the four color values. The fg_palette routine has no effect in mode 12.
  443.  
  444.      Example 5-5 demonstrates the use of fg_setcolor in mode 12. After
  445. establishing the video mode, the program makes color 3 the current color and
  446. displays the word "Hello". It then restores the original video mode and screen
  447. attributes before returning to DOS.
  448.  
  449.                                  Example 5-5.
  450.  
  451.                             #include <fastgraf.h>
  452.                             void main(void);
  453.  
  454.                             void main()
  455.                             {
  456.                                int mode;
  457.  
  458.                                fg_initpm();
  459.                                mode = fg_getmode();
  460.                                fg_setmode(12);
  461.  
  462.                                fg_setcolor(3);
  463.                                fg_text("Hello",5);
  464.                                fg_waitkey();
  465.  
  466.                                fg_setmode(mode);
  467.                                fg_reset();
  468.                             }                                                  
  469. 76   Fastgraph User's Guide
  470.  
  471.  
  472.  
  473. EGA 200-Line Modes
  474.  
  475.      The 200-line EGA graphics modes (modes 13 and 14) have 16 color values,
  476. numbered 0 to 15. Each color value references one of 16 user-definable palette
  477. registers, often simply called palettes, also numbered 0 to 15. The values
  478. assigned to the palette registers determine the colors in which pixels are
  479. displayed. For example, if you assign palette register 2 the value for red,
  480. then pixels whose color value is 2 will be red.
  481.  
  482.      Each palette can assume one of the 16 colors in the standard color set.
  483. By default, the values assigned to the 16 palettes correspond to the
  484. identically numbered colors in the standard color set. In other words, palette
  485. 0 is assigned the value for black, palette 1 is assigned the value for blue,
  486. and so forth.
  487.  
  488.      In modes 13 and 14, fg_setcolor defines the current color by referencing
  489. one of 16 available palette registers. The fg_palette routine defines the
  490. actual color assigned to a specific palette register. The first argument of
  491. fg_palette is an integer between 0 and 15 that specifies the palette number.
  492. The second argument is an integer that defines the palette value (the color
  493. assigned to the palette). Although the actual colors are taken from the
  494. standard color set, the binary structure of a palette value is different from
  495. the IRGB format used in the standard color set. In modes 13 and 14, the binary
  496. structure of a palette value is IxRGB; bit 3 is ignored. The mode 13 and mode
  497. 14 palette values that correspond to the standard color set are thus:
  498.  
  499.                        value     color     value     color
  500.  
  501.                          0       black      16     dark gray
  502.                          1       blue       17    light blue
  503.                          2       green      18    light green
  504.                          3       cyan       19    light cyan
  505.                          4        red       20     light red
  506.                          5      magenta     21   light magenta
  507.                          6       brown      22      yellow
  508.                          7       gray       23       white
  509.  
  510.      You also can use the Fastgraph routine fg_setrgb to define the color
  511. assigned to a specific palette register. While fg_palette does this using a
  512. color number from the standard color set, fg_setrgb defines a palette register
  513. using red, green, and blue color components, plus an intensity component. The
  514. first argument of fg_setrgb is an integer between 0 and 15 that specifies the
  515. palette register number. The remaining three arguments are each integer values
  516. between -1 and 1 that respectively specify the red, green, and blue color
  517. components for that palette register. The meanings of the color components
  518. are:
  519.  
  520.      -1 = color bit and intensity bit are set
  521.       0 = color bit is reset
  522.       1 = color bit is set
  523.  
  524. Since there is only one intensity bit in mode 13 and 14 color values,
  525. specifying -1 for any of the RGB color components produces an intense color.
  526. For example, light cyan is represented by the color value 19, and it is        
  527.                                              Chapter 5:  The Use of Color   77
  528.  
  529. produced by combining green and blue and setting the intensity bit. This means
  530. any of these four statements
  531.  
  532.  
  533.                              fg_palette(1,19);
  534.                              fg_setrgb(1,0,-1,1);
  535.                              fg_setrgb(1,0,1,-1);
  536.                              fg_setrgb(1,0,-1,-1);
  537.  
  538.  
  539. could be used to define palette register 1 as light cyan in modes 13 and 14.
  540.  
  541.      The Fastgraph routine fg_setcolor defines the color value (that is, the
  542. palette number) in which subsequent graphics operations are performed. The
  543. fg_setcolor routine takes a single integer argument that specifies this color.
  544. When fg_setmode is called, it sets the color value to 0. The Fastgraph routine
  545. fg_getcolor returns the current color value, as defined in the most recent
  546. call to fg_setcolor. The fg_getcolor routine has no arguments and returns the
  547. current color as the function value.
  548.  
  549.      Example 5-6 demonstrates the use of fg_palette and fg_setcolor in mode
  550. 13. After establishing the video mode, the program defines palette 0 to be
  551. blue (1) and palette 1 to be yellow (22). Note that defining palette 0 changes
  552. the background color. It then makes color 1 the current color and displays the
  553. word "Hello". After waiting for a keystroke, the program changes the color of
  554. "Hello" by changing palette 1 to white (23). Finally, it restores the original
  555. video mode and screen attributes before returning to DOS.
  556.  
  557.                                  Example 5-6.
  558.  
  559.                             #include <fastgraf.h>
  560.                             void main(void);
  561.  
  562.                             void main()
  563.                             {
  564.                                int mode;
  565.  
  566.                                fg_initpm();
  567.                                mode = fg_getmode();
  568.                                fg_setmode(13);
  569.  
  570.                                fg_palette(0,1);
  571.                                fg_palette(1,22);
  572.  
  573.                                fg_setcolor(1);
  574.                                fg_text("Hello",5);
  575.                                fg_waitkey();
  576.  
  577.                                fg_palette(1,23);
  578.                                fg_waitkey();
  579.  
  580.                                fg_setmode(mode);
  581.                                fg_reset();
  582.                             }                                                  
  583. 78   Fastgraph User's Guide
  584.  
  585.  
  586. EGA Monochrome Mode
  587.  
  588.      The EGA monochrome graphics mode (mode 15) assigns display attributes to
  589. its four color values, numbered 0 to 3. Each color value references one of
  590. four user-definable palette registers, often simply called palettes, numbered
  591. 0, 1, 4, and 5. This strange numbering results from the disabling of two of
  592. the four video memory bit planes in mode 15. The values assigned to the
  593. palette registers determine the pixel display attribute. For example, if you
  594. assign palette register 1 the value for bold, then pixels whose value is 1
  595. will be bold.
  596.  
  597.      In mode 15, fg_setcolor defines the current color (actually, a display
  598. attribute) by referencing one of the four palette registers. The fg_palette
  599. routine defines the actual display attribute assigned to a specific palette
  600. register. The first argument of fg_palette is an integer that specifies the
  601. palette number. The second argument is an integer that defines the palette
  602. value (the display attribute assigned to the palette). For each palette
  603. register, the following table shows the default palette value and its
  604. associated display attribute.
  605.  
  606.                            palette   palette   display
  607.                            number     value   attribute
  608.  
  609.                               0         0     invisible
  610.                               1         8      normal
  611.                               4        24       bold
  612.                               5        24       bold
  613.  
  614.      Example 5-7 demonstrates the use of fg_palette and fg_setcolor in mode
  615. 15. After establishing the video mode, the program makes color 4 (actually,
  616. palette 4, which is bold by default) the current color and displays the word
  617. "Hello". After waiting for a keystroke, the program changes the display
  618. attribute of "Hello" by changing palette 4 to normal intensity (palette value
  619. 8). Finally, it restores the original video mode and screen attributes before
  620. returning to DOS.
  621.  
  622.                                  Example 5-7.
  623.  
  624.                             #include <fastgraf.h>
  625.                             void main(void);
  626.  
  627.                             void main()
  628.                             {
  629.                                int mode;
  630.  
  631.                                fg_initpm();
  632.                                mode = fg_getmode();
  633.                                fg_setmode(15);
  634.  
  635.                                fg_setcolor(4);
  636.                                fg_text("Hello",5);
  637.                                fg_waitkey();
  638.  
  639.                                fg_palette(4,8);
  640.                                fg_waitkey();                                   
  641.                                              Chapter 5:  The Use of Color   79
  642.  
  643.  
  644.                                fg_setmode(mode);
  645.                                fg_reset();
  646.                             }
  647.  
  648.  
  649.  
  650. EGA Enhanced Mode
  651.  
  652.      The EGA enhanced graphics mode (mode 16) has 16 color values, numbered 0
  653. to 15. Each color value references one of 16 user-definable palette registers,
  654. often simply called palettes, also numbered 0 to 15. The values assigned to
  655. the palette registers determine the colors in which pixels are displayed. For
  656. example, if you assign palette register 2 the value for red, then pixels whose
  657. color value is 2 will be red.
  658.  
  659.      Each palette can assume one of 64 available colors. By default, the
  660. values assigned to the 16 palettes correspond to the identically numbered
  661. colors in the standard color set. In other words, palette 0 is assigned the
  662. value for black, palette 1 is assigned the value for blue, and so forth. There
  663. are a few EGA-compatible adapters that do not properly assign the default
  664. colors to the 16 palette registers, so it is a good practice to do this
  665. explicitly in mode 16.
  666.  
  667.      In mode 16, fg_setcolor defines the current color value by referencing
  668. one of the 16 palette registers. The fg_palette routine defines the actual
  669. color assigned to a specific palette register. The first argument of
  670. fg_palette is an integer between 0 and 15 that specifies the palette number.
  671. The second argument is an integer that defines the palette value (the color
  672. assigned to the palette). The binary structure of a palette value is different
  673. from the IRGB format used in the standard color set. In mode 16, the binary
  674. structure of a palette value is a 6-bit quantity of the form rgbRGB, where the
  675. lower case letters represent the low intensity (1/3 intensity) color
  676. components, and the upper case letters represent the normal intensity (2/3
  677. intensity) color components. The mode 16 palette values that correspond to the
  678. standard color set are:
  679.  
  680.              value        color          value        color
  681.  
  682.                0          black           56          dark gray
  683.                1          blue            57          light blue
  684.                2          green           58          light green
  685.                3          cyan            59          light cyan
  686.                4          red             60          light red
  687.                5          magenta         61          light magenta
  688.               20          brown           62          yellow
  689.                7          gray            63          white
  690.  
  691.      The normal intensity components in mode 16 produce the same normal
  692. intensity colors as in other 16-color graphics modes. Similarly, combining the
  693. low and normal intensities in mode 16 produces the high intensity colors of
  694. the other modes. The only exception to this is for the default brown, formed
  695. from the bit pattern 010100 (20 decimal). This value produces a more true
  696. brown than the value 6 decimal, which is really an olive green.                
  697. 80   Fastgraph User's Guide
  698.  
  699.      The palette values used in mode 16 are 6-bit quantities, which means
  700. there are 64 different colors available in mode 16. This group of 64 colors
  701. consists of the 16 colors in the standard color set plus 48 additional colors
  702. that are not available in any other EGA modes. However, because the EGA
  703. palette registers hold 4-bit quantities, only 16 of these colors can be
  704. displayed at the same time. In other words, the EGA enhanced mode provides the
  705. capability of displaying 16 simultaneous colors from a group of 64.
  706.  
  707.      You also can use the Fastgraph routine fg_setrgb to define the color
  708. assigned to a specific palette register. While fg_palette does this using a
  709. value between 0 and 63, fg_setrgb defines a palette register using red, green,
  710. and blue color components. The first argument of fg_setrgb is an integer
  711. between 0 and 15 that specifies the palette register number. The remaining
  712. three arguments are each integer values between 0 and 3 that respectively
  713. specify the intensities in thirds of the red, green, and blue color components
  714. for that palette register. For example, the color cyan is represented by the
  715. value 3 in the above table, and it is produced by combining normal intensity
  716. (2/3 intensity) green and blue. This means either of the statements
  717.  
  718.  
  719.                               fg_palette(1,3);
  720.                               fg_setrgb(1,0,2,2);
  721.  
  722.  
  723. could be used to define palette register 1 as cyan.
  724.  
  725.      Example 5-8 demonstrates the use of fg_palette and fg_setcolor in mode
  726. 16. It uses the Fastgraph routine fg_rect (discussed in the next chapter) to
  727. draw rectangles of a specified size. After establishing the video mode, the
  728. program uses a for loop to draw 16 equal-size rectangles, one in each of the
  729. 16 color values. In the same loop, the program uses fg_palette to change each
  730. palette to black. The while loop that follows performs four iterations. The
  731. first iteration changes palette 0 to 0, palette 1 to 1, and so forth. Hence,
  732. the 16 rectangles appear in the palette values 0 to 15. The rectangles remain
  733. in these colors until is key is pressed to begin the next iteration. The
  734. second iteration changes palette 0 to 16, palette 1 to 17, and so forth. This
  735. makes the 16 rectangles appear in the palette values 16 to 31. Iterations
  736. three and four are similar, so the overall effect of the program is to display
  737. all 64 colors, 16 at a time. Finally, the program restores the original video
  738. mode and screen attributes before returning to DOS.
  739.  
  740.                                  Example 5-8.
  741.  
  742.                 #include <fastgraf.h>
  743.                 void main(void);
  744.  
  745.                 #define COLORS 16
  746.                 #define WIDTH  40
  747.  
  748.                 void main()
  749.                 {
  750.                    int base;
  751.                    int color;
  752.                    int minx, maxx;
  753.                    int mode;                                                   
  754.                                              Chapter 5:  The Use of Color   81
  755.  
  756.                    fg_initpm();
  757.                    mode = fg_getmode();
  758.                    fg_setmode(16);
  759.  
  760.                    base = 0;
  761.                    minx = 0;
  762.                    maxx = WIDTH - 1;
  763.  
  764.                    for (color = 0; color < COLORS; color++) {
  765.                       fg_palette(color,0);
  766.                       fg_setcolor(color);
  767.                       fg_rect(minx,maxx,0,349);
  768.                       minx = maxx + 1;
  769.                       maxx = maxx + WIDTH;
  770.                       }
  771.  
  772.                    while (base < COLORS*4) {
  773.                       for (color = 0; color < COLORS; color++)
  774.                          fg_palette(color,base+color);
  775.                       base += COLORS;
  776.                       fg_waitkey();
  777.                       }
  778.  
  779.                    fg_setmode(mode);
  780.                    fg_reset();
  781.                 }
  782.  
  783.  
  784.  
  785. VGA and MCGA Two-Color Mode
  786.  
  787.      The VGA and MCGA two-color mode (mode 17) has a background color (color
  788. value 0) and a foreground color (color value 1). Each color value references
  789. one of two user-definable palette registers, often simply called palettes,
  790. also numbered 0 and 1. Each palette register in turn references one of 16
  791. user-definable 18-bit video DAC registers, numbered 0 to 15. The values
  792. assigned to the palette registers and video DAC registers determine the colors
  793. in which pixels are displayed. For example, if palette register 1 contains the
  794. value 3, and video DAC register 3 contains the color value for red, then
  795. pixels whose color value is 1 (that is, the foreground pixels) will be red.
  796.  
  797.      By default, palette register 0 references video DAC register 0, and
  798. palette register 1 references video DAC register 1. In addition, video DAC
  799. register 0 initially contains the color value for black, while the other 15
  800. video DAC registers (1 through 15) contain the color value for white. This
  801. means background pixels (color value 0) are black by default, while foreground
  802. pixels (color value 1) are white.
  803.  
  804.      The 18-bit video DAC values consist of three 6-bit red, green, and blue
  805. color components. Hence, each color component is an integer between 0 and 63;
  806. increasing values produce more intense colors. The default color components
  807. for DAC register 0 are red=0, blue=0, and green=0, which produces black. The
  808. default values for the other DAC registers are red=63, blue=63, and green=63,
  809. which produces white. Because the video DAC registers are 18 bits long, each
  810. DAC can specify one of 262,144 (2**18) colors. However, because the palette
  811. registers hold 1-bit quantities, only two of these colors can be displayed at  
  812. 82   Fastgraph User's Guide
  813.  
  814. the same time. In other words, mode 17 provides the capability of displaying
  815. two simultaneous colors from a group of 262,144.
  816.  
  817.      In mode 17, fg_setcolor defines the current color by referencing one of
  818. the two palette registers. The fg_palette routine defines the value of a
  819. palette register by referencing one of the 16 video DAC registers. That is,
  820. fg_palette specifies the video DAC register that a palette register
  821. references. The first argument of fg_palette is either 0 or 1 and specifies
  822. the palette number. The second argument is an integer between 0 and 15 that
  823. specifies the video DAC register for that palette.
  824.  
  825.      The Fastgraph routine fg_setrgb defines the value of a video DAC register
  826. in mode 17. The first argument of fg_setrgb is an integer between 0 and 15
  827. that specifies the DAC register number. The remaining three arguments are each
  828. integer values between 0 and 63 that respectively specify the red, green, and
  829. blue color components for that DAC register.
  830.  
  831.      Example 5-9 demonstrates the use of fg_palette, fg_setrgb, and
  832. fg_setcolor in mode 17. After establishing the video mode, the program defines
  833. DAC register 0 to be blue (red=0, green=0, blue=42) and DAC register 1 to be
  834. yellow (red=63, green=63, blue=21). Note that defining DAC register 0 changes
  835. the background color because palette 0 references DAC register 0. The program
  836. then makes color 1 the current color (palette 1 still references DAC register
  837. 1) and displays the word "Hello" in yellow. After waiting for a keystroke, the
  838. program changes the color of "Hello" by making palette 1 reference DAC
  839. register 15 (which still contains its default value, white). Finally, it
  840. restores the original video mode and screen attributes before returning to
  841. DOS.
  842.  
  843.                                  Example 5-9.
  844.  
  845.                            #include <fastgraf.h>
  846.                            void main(void);
  847.  
  848.                            void main()
  849.                            {
  850.                               int mode;
  851.  
  852.                               fg_initpm();
  853.                               mode = fg_getmode();
  854.                               fg_setmode(17);
  855.  
  856.                               fg_setrgb(0,0,0,42);
  857.                               fg_setrgb(1,63,63,21);
  858.  
  859.                               fg_setcolor(1);
  860.                               fg_text("Hello",5);
  861.                               fg_waitkey();
  862.  
  863.                               fg_palette(1,15);
  864.                               fg_waitkey();
  865.  
  866.                               fg_setmode(mode);
  867.                               fg_reset();
  868.                            }                                                   
  869.                                              Chapter 5:  The Use of Color   83
  870.  
  871.  
  872.  
  873. VGA/SVGA 16-Color Modes
  874.  
  875.      The VGA and SVGA 16-color modes (modes 18, 28, and 29) have 16 color
  876. values, numbered 0 to 15. Each color value references one of 16 user-definable
  877. palette registers, often simply called palettes, also numbered 0 to 15. Each
  878. palette register in turn references one of 16 user-definable 18-bit video DAC
  879. registers, also numbered 0 to 15. The values assigned to the palette registers
  880. and video DAC registers determine the colors in which pixels are displayed.
  881. For example, if palette register 1 contains the value 3, and video DAC
  882. register 3 contains the color value for red, then pixels whose color value is
  883. 1 will be red.
  884.  
  885.      By default, each of the 16 palette registers references the video DAC
  886. register of the same number. In addition, the 16 video DAC registers
  887. respectively contain the color values for the 16 colors in the standard color
  888. set.
  889.  
  890.      The 18-bit video DAC values consist of three 6-bit red, green, and blue
  891. color components. Hence, each color component is an integer between 0 and 63;
  892. increasing values produce more intense colors. The default RGB color
  893. components for the 16 video DAC registers are:
  894.  
  895.          DAC  R  G   B    color      DAC  R  G   B      color
  896.  
  897.           0   0  0   0    black       8  21  21 21    dark gray
  898.           1   0  0  42    blue        9  21  21 63   light blue
  899.           2   0  42  0    green      10  21  63 21   light green
  900.           3   0  42 42    cyan       11  21  63 63   light cyan
  901.           4  42  0   0     red       12  63  21 21    light red
  902.           5  42  0  42   magenta     13  63  21 63  light magenta
  903.           6  42  21  0    brown      14  63  63 21     yellow
  904.           7  42  42 42    gray       15  63  63 63      white
  905.  
  906. Because the video DAC registers are 18 bits long, each DAC can specify one of
  907. 262,144 (2**18) colors. However, because the palette registers hold 4-bit
  908. quantities, only 16 of these colors can be displayed at the same time. In
  909. other words, mode 18 provides the capability of displaying 16 simultaneous
  910. colors from a group of 262,144.
  911.  
  912.      In the 16-color VGA and SVGA modes, fg_setcolor, fg_palette, and
  913. fg_setrgb behave exactly as in mode 17 with one exception: there are 16
  914. palette registers instead of just two. Example 5-9 demonstrates the use of
  915. these routines in mode 17, but it also would work in mode 18, 28, or 29 if the
  916. call to fg_setmode were changed accordingly.
  917.  
  918.  
  919. 256-Color Modes
  920.  
  921.      The 256-color modes (modes 19 through 27) have 256 color values, numbered
  922. 0 to 255. Each color value directly references one of 256 user-definable 18-
  923. bit video DAC registers, also numbered 0 to 255. The values assigned to the
  924. video DAC registers determine the colors in which pixels are displayed. For
  925. example, if video DAC register 3 contains the color value for red, then pixels
  926. whose color value is 3 will be red.                                            
  927. 84   Fastgraph User's Guide
  928.  
  929.  
  930.      By default, the first 16 video DAC registers (0 to 15) contain the color
  931. values for the standard color set. The next 16 DAC registers (16 to 31)
  932. contain the color values for a gray scale of gradually increasing intensity.
  933. The next 216 DAC registers (32 to 247) contain three groups of 72 colors each,
  934. with the first group (32 to 103) at high intensity, the second group (104 to
  935. 175) at moderate intensity, and the third group (176 to 247) at low intensity.
  936. Each group consists of three ranges of decreasing saturation (increasing
  937. whiteness), with each range varying in hue from blue to red to green. Finally,
  938. the last 8 DAC registers (248 to 255) alternate between black and white. This
  939. information is summarized in the following table.
  940.  
  941.      DACs         default color values
  942.  
  943.      0 to 15      standard color set
  944.      16 to 31     gray scale of gradually increasing intensity
  945.      32 to 55     high saturation, high intensity colors
  946.      56 to 79     moderate saturation, high intensity colors
  947.      80 to 103    low saturation, high intensity colors
  948.      104 to 127   high saturation, moderate intensity colors
  949.      128 to 151   moderate saturation, moderate intensity colors
  950.      152 to 175   low saturation, moderate intensity colors
  951.      176 to 199   high saturation, low intensity colors
  952.      200 to 223   moderate saturation, low intensity colors
  953.      224 to 247   low saturation, low intensity colors
  954.      248 to 255   alternate between black and white
  955.  
  956.      The 18-bit video DAC values consist of three 6-bit red, green, and blue
  957. color components. Hence, each color component is an integer between 0 and 63;
  958. increasing values produce more intense colors. Because the video DAC registers
  959. are 18 bits long, each DAC can specify one of 262,144 (2**18) colors. However,
  960. because the color values are 8-bit quantities, only 256 of these colors can be
  961. displayed at the same time. In other words, modes 19 through 27 provide the
  962. capability of displaying 256 simultaneous colors from a group of 262,144.
  963.  
  964.      In the 256-color graphics modes, fg_setcolor defines the current color by
  965. referencing one of the 256 video DAC registers. The fg_setrgb routine defines
  966. the actual color of a video DAC register. The first argument of fg_setrgb is
  967. an integer between 0 and 255 that specifies the DAC register number. The
  968. remaining three arguments are each integer values between 0 and 63 that
  969. respectively specify the red, green, and blue color components for that DAC
  970. register. Another Fastgraph routine, fg_getrgb, returns the color components
  971. for a specified DAC register. Its arguments are the same as for fg_setrgb,
  972. except the last three arguments (the return values) are passed by reference
  973. rather than by value.
  974.  
  975.      You also can use the Fastgraph routine fg_palette to define the value of
  976. a video DAC register in modes 19 through 27. The first argument of fg_palette
  977. is an integer between 0 and 255 that specifies the DAC register number. The
  978. second argument is an integer between 0 and 63 that specifies the color value
  979. for that video DAC register, using the same 64 values as in the EGA enhanced
  980. mode (mode 16).
  981.  
  982.      Example 5-10 demonstrates the use of fg_setcolor in mode 19. The program
  983. uses the Fastgraph routine fg_rect to draw vertical lines. After establishing
  984. the video mode, the program uses a for loop to draw 256 vertical lines, one in 
  985.                                              Chapter 5:  The Use of Color   85
  986.  
  987. each of the 256 colors (using the default DAC values). Finally, the program
  988. restores the original video mode and screen attributes before returning to
  989. DOS.
  990.  
  991.                                  Example 5-10.
  992.  
  993.                  #include <fastgraf.h>
  994.                  void main(void);
  995.  
  996.                  #define COLORS 256
  997.  
  998.                  void main()
  999.                  {
  1000.                     int base;
  1001.                     int color;
  1002.                     int mode;
  1003.                     int x;
  1004.  
  1005.                     fg_initpm();
  1006.                     mode = fg_getmode();
  1007.                     fg_setmode(19);
  1008.  
  1009.                     x = 0;
  1010.  
  1011.                     for (color = 0; color < COLORS; color++) {
  1012.                        fg_setcolor(color);
  1013.                        fg_rect(x,x,0,199);
  1014.                        x++;
  1015.                        }
  1016.                     fg_waitkey();
  1017.  
  1018.                     fg_setmode(mode);
  1019.                     fg_reset();
  1020.                  }
  1021.  
  1022.  
  1023.      Example 5-11 shows an interesting effect available in video modes that
  1024. support DAC registers. The program uses the Fastgraph routine fg_waitfor
  1025. (discussed in Chapter 16) to delay the program's execution. After establishing
  1026. the video mode, the program displays the word "Hello" in color 103, which by
  1027. default is a pastel blue. It then uses fg_getrgb to retrieve the color
  1028. components for this color. The while loop gradually decreases the color
  1029. components until all three components are zero, which makes the word "Hello"
  1030. smoothly fade to black. Finally, the program restores the original video mode
  1031. and screen attributes before returning to DOS.
  1032.  
  1033.                                  Example 5-11.
  1034.  
  1035.                      #include <fastgraf.h>
  1036.                      void main(void);
  1037.  
  1038.                      void main()
  1039.                      {
  1040.                         int old_mode;
  1041.                         int red, green, blue;                                  
  1042. 86   Fastgraph User's Guide
  1043.  
  1044.                         fg_initpm();
  1045.                         old_mode = fg_getmode();
  1046.                         fg_setmode(19);
  1047.  
  1048.                         fg_setcolor(103);
  1049.                         fg_text("Hello",5);
  1050.                         fg_waitfor(18);
  1051.  
  1052.                         fg_getrgb(103,&red,&green,&blue);
  1053.  
  1054.                         while (red+green+blue > 0) {
  1055.                            if (red > 0) red--;
  1056.                            if (green > 0) green--;
  1057.                            if (blue > 0) blue--;
  1058.                            fg_setrgb(103,red,green,blue);
  1059.                            fg_waitfor(1);
  1060.                            }
  1061.  
  1062.                         fg_setmode(old_mode);
  1063.                         fg_reset();
  1064.                      }
  1065.  
  1066.  
  1067.      The fg_setrgb and fg_getrgb routines work with individual DAC registers.
  1068. If you want to define or retrieve a block of consecutive DAC registers,
  1069. fg_setdacs and fg_getdacs are more efficient. The fg_setdacs routine defines
  1070. the values of a block of consecutive DAC registers. Its first argument is the
  1071. index of the first DAC register to define (between 0 and 255), and its second
  1072. argument is the number of DAC registers to define (between 1 and 256). The
  1073. third argument is a byte array containing the RGB color components for the DAC
  1074. registers being defined. The array's first three bytes contain the red, green,
  1075. and blue components for the first DAC, the next three for the second DAC, and
  1076. so forth. The size of this array must be at least three times the value of the
  1077. second argument. The fg_getdacs arguments are the same as those for
  1078. fg_setdacs, but the RGB array instead receives the current values of the
  1079. specified DAC registers. Both routines treat the DAC register numbers in a
  1080. circular fashion (for example, defining four DACs starting with number 254
  1081. will define DACs 254, 255, 0, and 1).
  1082.  
  1083.      Example 5-12 is similar to example 5-11, but it fades many colors
  1084. simultaneously. The program displays seven asterisks, one each in colors 9
  1085. through 15. It uses fg_getdacs to obtain the current settings of the
  1086. corresponding DAC registers; these values are stored in the array RGBvalues.
  1087. The while loop gradually fades the RGB components to zero, using fg_setdacs to
  1088. update their values, similar to the method of example 5-11. This illustrates
  1089. an attractive way of turning an image into a blank screen.
  1090.  
  1091.                                  Example 5-12.
  1092.  
  1093.                        #include <fastgraf.h>
  1094.                        void main(void);
  1095.  
  1096.                        void main()
  1097.                        {
  1098.                           int decreasing;
  1099.                           int i;                                               
  1100.                                              Chapter 5:  The Use of Color   87
  1101.  
  1102.                           int old_mode;
  1103.                           char RGBvalues[21];
  1104.  
  1105.                           fg_initpm();
  1106.                           old_mode = fg_getmode();
  1107.                           fg_setmode(19);
  1108.  
  1109.                           for (i = 9; i <= 15; i++) {
  1110.                              fg_setcolor(i);
  1111.                              fg_text("*",1);
  1112.                              }
  1113.  
  1114.                           fg_getdacs(9,7,RGBvalues);
  1115.                           fg_waitfor(18);
  1116.  
  1117.                           do {
  1118.                              decreasing = 0;
  1119.                              for (i = 0; i < 21; i++)
  1120.                                 if (RGBvalues[i] > 0) {
  1121.                                    RGBvalues[i]--;
  1122.                                    decreasing = 1;
  1123.                                    }
  1124.                              fg_setdacs(9,7,RGBvalues);
  1125.                              fg_waitfor(1);
  1126.                              }
  1127.                           while (decreasing);
  1128.  
  1129.                           fg_setmode(old_mode);
  1130.                           fg_reset();
  1131.                        }
  1132.  
  1133.  
  1134. Note that examples 5-11 and 5-12 also would work in 16-color VGA and SVGA
  1135. video modes as long as you just use the first 16 video DAC registers.
  1136.  
  1137.  
  1138. Using Video DAC Registers in EGA Modes
  1139.  
  1140.      The fg_getdacs and fg_setdacs routines also work in modes 13, 14, and 16
  1141. when used on a VGA or SVGA system. This lets you choose 16 colors from a
  1142. palette of 262,144 colors, as in mode 18. If you try to use these routines on
  1143. an EGA system, the results are unpredictable. Applications that use these
  1144. routines should therefore first insure they are running on a VGA or SVGA
  1145. system by checking if fg_testmode(18,0) returns a nonzero value.
  1146.  
  1147.      Before trying to use fg_getdacs and fg_setdacs in modes 13, 14, and 16,
  1148. you should first be aware of the relationship between VGA palettes and DAC
  1149. registers. On the EGA, palette values directly determine the color displayed.
  1150. On the VGA and SVGA, however, there is an added level of indirection. VGA and
  1151. SVGA palette registers can be thought of as pointers to video DAC registers
  1152. whose RGB components determine the displayed color.
  1153.  
  1154.      Each palette register in the VGA 640x480 16-color graphics mode (mode 18)
  1155. initially points to the DAC register of the same number. We can thus pretend
  1156. the indirection does not exist because changing DAC register n affects those
  1157. pixels whose color value is n (unless, of course, we've changed the value of   
  1158. 88   Fastgraph User's Guide
  1159.  
  1160. palette register n). In modes 13, 14, and 16, we can't ignore the indirection
  1161. because the palette registers contain different values. In mode 13, for
  1162. instance, palette register 8 contains the value 16 by default, not the value 8
  1163. as in mode 18.
  1164.  
  1165.      The easiest way around this inconsistency is to set the palette and DAC
  1166. registers explicitly so they correspond to the default values of mode 18.
  1167. There are two cases to consider -- one for modes 13 and 14, and the other for
  1168. mode 16.
  1169.  
  1170.      In modes 13 and 14, palettes 0 to 7 contain the values 0 to 7, but
  1171. palettes 8 to 15 contain the values 16 to 23. Hence, if you want to use
  1172. fg_getdacs and fg_setdacs in these modes, you should include the following
  1173. code after calling fg_setmode.
  1174.  
  1175.  
  1176.                         char RGBvalues[3];
  1177.                         int i;
  1178.  
  1179.                         for (i = 8; i < 16; i++) {
  1180.                            fg_getdacs(i+8,1,RGBvalues);
  1181.                            fg_setdacs(i,1,RGBvalues);
  1182.                            fg_palette(i,i);
  1183.                         }
  1184.  
  1185.  
  1186. This code will set the values of DACs 8 to 15 to the values of DACs 16 to 23.
  1187. It also sets palettes 8 to 15 to point to DACs 8 to 15. You can then ignore
  1188. the palette-DAC indirection because setting DAC register n affects pixels of
  1189. color n.
  1190.  
  1191.      In mode 16, palette 6 is initially assigned the value 20, and palettes 8
  1192. to 15 are assigned the values 56 to 63. All other palettes point to the DAC of
  1193. the same number. Hence, if you want to use fg_getdacs and fg_setdacs in mode
  1194. 16, you should include the following code after calling fg_setmode.
  1195.  
  1196.  
  1197.                         char RGBvalues[3];
  1198.                         int i;
  1199.  
  1200.                         fg_getdacs(20,1,RGBvalues);
  1201.                         fg_setdacs(6,1,RGBvalues);
  1202.                         fg_palette(6,6);
  1203.  
  1204.                         for (i = 8; i < 16; i++) {
  1205.                            fg_getdacs(i+48,1,RGBvalues);
  1206.                            fg_setdacs(i,1,RGBvalues);
  1207.                            fg_palette(i,i);
  1208.                         }
  1209.  
  1210.  
  1211. This code will set the values of DAC 6 to the values of DAC 20, and also DACs
  1212. 8 to 15 to the values of DACs 56 to 63. It also sets palettes 6 and 8-15 to
  1213. point to the identically-numbered DACs. You can then ignore the palette-DAC
  1214. indirection because setting DAC register n affects pixels of color n.          
  1215.                                              Chapter 5:  The Use of Color   89
  1216.  
  1217.      While this might all seem complicated at first, it really isn't once you
  1218. understand the relationship between palettes and DACs. The ability to select
  1219. colors from a palette of 256K colors instead of 16 or 64 is usually well worth
  1220. the extra effort.
  1221.  
  1222.  
  1223. RGB Color Mapping
  1224.  
  1225.      If you're developing an application that runs in 256-color and 16-color
  1226. graphics modes, you've probably noticed the inherent differences in defining
  1227. color values. In fact, the palette register values even use different
  1228. structures within the various 16-color modes. The Fastgraph routine fg_maprgb
  1229. helps simplify these differences. It maps three RGB color components (each
  1230. between 0 and 63) into a 16-color palette value suitable for the current video
  1231. mode. Of course, the range of available colors is much more restricted in the
  1232. 16-color modes than in the 256-color modes, so fg_maprgb must map the RGB
  1233. components to the closest available color.
  1234.  
  1235.      Example 5-13 runs in any 16-color or 256-color graphics mode and
  1236. demonstrates the use of the fg_maprgb routine. In 256-color modes, the program
  1237. simply uses fg_setrgb to define DAC register 1 to a pastel blue (red=45,
  1238. green=49, blue=63). In 16-color modes, however, the program calls fg_maprgb to
  1239. convert the color components into a palette value in IRGB, IxRGB, or rgbRGB
  1240. format (depending on the current video mode). The fg_maprgb return value is
  1241. passed to fg_palette to set palette register 1 to the closest available color
  1242. defined by the specified RGB components.
  1243.  
  1244.                                  Example 5-13.
  1245.  
  1246.            #include <fastgraf.h>
  1247.            #include <stdio.h>
  1248.            #include <stdlib.h>
  1249.            void main(void);
  1250.  
  1251.            void main()
  1252.            {
  1253.               int new_mode, old_mode;
  1254.  
  1255.               fg_initpm();
  1256.               new_mode = fg_bestmode(320,200,1);
  1257.               if (new_mode < 0 || new_mode == 4 || new_mode == 12) {
  1258.                  printf("This program requires a 320 x 200 ");
  1259.                  printf("16-color or 256-color graphics mode.\n");
  1260.                  exit(1);
  1261.                  }
  1262.               old_mode = fg_getmode();
  1263.               fg_setmode(new_mode);
  1264.  
  1265.               fg_setcolor(1);
  1266.               if (new_mode <= 16)
  1267.                  fg_palette(1,fg_maprgb(45,49,63));
  1268.               else
  1269.                  fg_setrgb(1,45,49,63);
  1270.               fg_text("Hello",5);
  1271.               fg_waitkey();                                                    
  1272. 90   Fastgraph User's Guide
  1273.  
  1274.               fg_setmode(old_mode);
  1275.               fg_reset();
  1276.            }
  1277.  
  1278.  
  1279.  
  1280. Defining All Palette Registers
  1281.  
  1282.      Fastgraph includes a routine fg_palettes that defines all 16 palette
  1283. registers in 16-color graphics modes. You also can use fg_palettes to define
  1284. the first 16 video DAC registers in 256-color modes. It has no effect in other
  1285. video modes.
  1286.  
  1287.      Using fg_palettes is much faster than calling fg_palette 16 times. The
  1288. argument to fg_palettes is a 16-element integer array that contains the color
  1289. values assigned respectively to palette registers (or video DAC registers) 0
  1290. to 15. Example 5-14 demonstrates how to zero the palette registers (that is,
  1291. change them all to black) in mode 13.
  1292.  
  1293.                                  Example 5-14.
  1294.  
  1295.                #include <fastgraf.h>
  1296.                void main(void);
  1297.  
  1298.                int zeroes[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  1299.  
  1300.                void main()
  1301.                {
  1302.                   int mode;
  1303.  
  1304.                   fg_initpm();
  1305.                   mode = fg_getmode();
  1306.                   fg_setmode(13);
  1307.  
  1308.                   fg_palettes(zeroes);
  1309.  
  1310.                   fg_setmode(mode);
  1311.                   fg_reset();
  1312.                }
  1313.  
  1314.  
  1315. Of course, as this example is written, it appears to do nothing more than
  1316. blank the screen. Its purpose is to show an example of the fg_palettes
  1317. routine.
  1318.  
  1319.  
  1320. Virtual Colors
  1321.  
  1322.      By this time it should be clear the use of color is rather specific to
  1323. each graphics video mode. One of the most obvious differences is the number of
  1324. available colors in each mode; it ranges from 2 to 256. By available colors,
  1325. we mean the number of colors that can be displayed simultaneously.
  1326.  
  1327.      To simplify programming in graphics modes, Fastgraph provides 256 virtual
  1328. colors. The virtual colors are used in the graphics video modes having fewer
  1329. than 256 available colors. Virtual colors allow you to use 256 color indices   
  1330.                                              Chapter 5:  The Use of Color   91
  1331.  
  1332. in all graphics modes, even if a particular mode does not have 256 available
  1333. colors.
  1334.  
  1335.      When you establish a video mode with fg_setmode, Fastgraph initializes
  1336. all the virtual color indices. It does this by replicating the video mode's
  1337. color values through the 256 virtual color indices. For example, the CGA color
  1338. modes (4 and 5) have four color values, numbered 0 through 3. In these modes,
  1339. fg_setmode initializes color indices 0, 4, 8, ... , 252 to 0; color indices 1,
  1340. 5, 9, ... , 253 to 1; color indices 2, 6, 10, ... , 254 to 2; and color
  1341. indices 3, 7, 11, ... , 255 to 3. Similarly, in 16-color graphics modes the
  1342. color indices 0, 16, 32, ... , 240 are set to 0, and so forth. In the
  1343. monochrome EGA graphics video mode (mode 15), the color values are numbered 0,
  1344. 1, 4, and 5, so fg_setmode replicates the color indices in groups of eight,
  1345. even though there are only four available colors. An analysis of the color
  1346. value sequences reveals an often useful feature: by default, virtual color 0
  1347. is black and virtual colors 15 and 255 are white in all graphics video modes.
  1348.  
  1349.      It is thus possible to write a multiple-mode program using the same color
  1350. indices for each graphics mode. For example, a program that contains the
  1351. statement fg_setcolor(5) would produce subsequent graphics in color 5 (magenta
  1352. by default) when running in a 16-color graphics mode. It would produce
  1353. subsequent graphics in color 1 (light cyan by default) when running in a CGA
  1354. color mode. This is because 1 is the default value assigned to virtual color
  1355. index 5 in the CGA color modes.
  1356.  
  1357.      The fg_setmode routine establishes default values for the 256 virtual
  1358. color indices, but it might be desirable to assign other available colors to
  1359. them. Going back to the discussion in the previous paragraph, color number 2
  1360. is light magenta in the default CGA mode 4 palette. It might make more sense
  1361. if the color value 2 were assigned to virtual color index 5, as this would
  1362. make the graphics drawn in color 5 the same color in mode 4 as in other color
  1363. modes. The Fastgraph routine fg_defcolor is provided for this purpose.
  1364.  
  1365.      The fg_defcolor routine assigns a color value to a virtual color index.
  1366. It has two arguments: the first specifies the virtual color index (between 0
  1367. and 255), and the second specifies the color value (between 0 and one less
  1368. than the number of available colors in the current video mode). For example,
  1369. the statement
  1370.  
  1371.                                fg_defcolor(5,2);
  1372.  
  1373. would assign the color value 2 to the color index 5. Another Fastgraph
  1374. routine, fg_getindex, returns the current value assigned to a specified color
  1375. index. After executing the above call to fg_defcolor, the statement
  1376.  
  1377.                             color = fg_getindex(5);
  1378.  
  1379. would store the value 2 (the current value of color index 5) in the integer
  1380. variable color.
  1381.  
  1382.      We must be sure to understand the difference between virtual colors and
  1383. palette registers. Modifying the value of a palette register changes the color
  1384. of all pixels already drawn using that palette. Modifying a virtual color
  1385. index does not do this; it only specifies any graphics drawn in that color
  1386. from this point on will appear in the new color.                               
  1387. 92   Fastgraph User's Guide
  1388.  
  1389.      Example 5-15 demonstrates virtual colors in mode 4. After establishing
  1390. the video mode, the program uses fg_defcolor to define virtual color indices 0
  1391. and 255 to be 1, which by default is light cyan in mode 4. It then draws
  1392. characters using color indices 0, 1, and 255, and in each case the characters
  1393. appear in light cyan. Finally, the program restores the original video mode
  1394. and screen attributes before returning to DOS.
  1395.  
  1396.                                  Example 5-15.
  1397.  
  1398.                             #include <fastgraf.h>
  1399.                             void main(void);
  1400.  
  1401.                             void main()
  1402.                             {
  1403.                                int mode;
  1404.  
  1405.                                fg_initpm();
  1406.                                mode = fg_getmode();
  1407.                                fg_setmode(4);
  1408.  
  1409.                                fg_defcolor(0,1);
  1410.                                fg_defcolor(255,1);
  1411.  
  1412.                                fg_setcolor(0);
  1413.                                fg_text("0",1);
  1414.                                fg_setcolor(1);
  1415.                                fg_text(" 1",2);
  1416.                                fg_setcolor(255);
  1417.                                fg_text(" 255",4);
  1418.                                fg_waitkey();
  1419.  
  1420.                                fg_setmode(mode);
  1421.                                fg_reset();
  1422.                             }
  1423.  
  1424.  
  1425.  
  1426. A Multiple-Mode Example
  1427.  
  1428.      Although the color capabilities differ between the supported video modes,
  1429. Fastgraph makes it easy to write a program that runs in many video modes. This
  1430. section will present an example of such a program.
  1431.  
  1432.      Example 5-16 illustrates a program that will run in any of Fastgraph's
  1433. supported video modes. The program first asks for the video mode number,
  1434. checks if the mode number is valid, and then checks if the requested mode is
  1435. available on the user's system. After doing this, the program establishes the
  1436. video mode and performs its mode-specific code. It then displays a brief
  1437. message that includes the video mode number in which the program is running.
  1438. This information remains on the screen until a key is pressed, at which time
  1439. the program restores the original video mode and screen attributes before
  1440. returning to DOS.
  1441.  
  1442.                                  Example 5-16.
  1443.  
  1444.        #include <fastgraf.h>                                                   
  1445.                                              Chapter 5:  The Use of Color   93
  1446.  
  1447.        #include <stdio.h>
  1448.        #include <stdlib.h>
  1449.        void main(void);
  1450.  
  1451.        void main()
  1452.        {
  1453.           int mode, old_mode;
  1454.           char string[5];
  1455.  
  1456.        /* Ask for the video mode number */
  1457.           printf("Which video mode? ");
  1458.           scanf("%d",&mode);
  1459.  
  1460.        /* Make sure the entered value is valid */
  1461.           if (mode < 0 || mode > 29) {
  1462.              printf("%d is not a valid video mode number.\n",mode);
  1463.              exit(1);
  1464.              }
  1465.  
  1466.        /* Make sure the requested video mode is available */
  1467.           fg_initpm();
  1468.           if (mode > 23) fg_svgainit(0);
  1469.           if (fg_testmode(mode,1) == 0) {
  1470.              printf("Mode %d is not available on this system.\n",mode);
  1471.              exit(1);
  1472.              }
  1473.  
  1474.        /* Establish the video mode */
  1475.           old_mode = fg_getmode();
  1476.           fg_setmode(mode);
  1477.  
  1478.        /* Perform mode-specific initializations */
  1479.           if (mode <= 3 || mode == 7)   /* text modes */
  1480.              fg_cursor(0);
  1481.  
  1482.           else if (mode == 4 || mode == 5) { /* CGA color modes */
  1483.              fg_palette(0,0);
  1484.              fg_defcolor(14,3);
  1485.              }
  1486.  
  1487.           else if (mode == 6) {         /* CGA two-color mode */
  1488.              fg_palette(0,14);
  1489.              fg_defcolor(14,1);
  1490.              }
  1491.  
  1492.           else if (mode == 11)          /* Hercules mode */
  1493.              fg_defcolor(14,1);
  1494.  
  1495.           else if (mode == 12)          /* Hercules low-res mode */
  1496.              fg_defcolor(14,3);
  1497.  
  1498.           else if (mode == 17) {        /* VGA two-color mode */
  1499.              fg_palette(1,14);
  1500.              fg_setrgb(14,63,63,21);
  1501.              fg_defcolor(14,1);
  1502.              }                                                                 
  1503. 94   Fastgraph User's Guide
  1504.  
  1505.  
  1506.        /* Display a message that includes the video mode number */
  1507.           fg_setcolor(14);
  1508.           fg_text("I'm running in mode ",20);
  1509.           sprintf(string,"%d. ",mode);
  1510.           fg_text(string,3);
  1511.  
  1512.        /* Wait for a keystroke */
  1513.           fg_waitkey();
  1514.  
  1515.        /* Restore the original video mode and screen attributes */
  1516.           fg_setmode(old_mode);
  1517.           fg_reset();
  1518.        }
  1519.  
  1520.  
  1521.      Example 5-16 displays its message in yellow for those video modes that
  1522. offer color. In monochrome video modes, it displays the message in normal
  1523. intensity. The program uses virtual color 14, which by default is yellow in
  1524. many video modes; the mode-specific code in example 5-16 makes color 14 yellow
  1525. in other video modes. In text video modes (modes 0 to 3 and 7), the program
  1526. uses fg_cursor to make the cursor invisible. In CGA color modes (modes 4 and
  1527. 5), the program uses fg_palette to select a CGA palette that contains yellow
  1528. as color 3 and then uses fg_defcolor to assign color 3 to virtual color 14. In
  1529. CGA two-color mode (mode 6), the program uses fg_palette to make color 1
  1530. yellow and then uses fg_defcolor to assign color 1 to virtual color 14. In the
  1531. Hercules modes (modes 11 and 12), the program uses fg_defcolor to assign the
  1532. value for normal intensity pixels to color 14. In VGA two-color mode (mode
  1533. 17), the program uses fg_palette to assign video DAC register 14 to palette
  1534. register 1. It then defines video DAC register 14 to be yellow with fg_setrgb
  1535. and finally uses fg_defcolor to assign color 1 (that is, palette register 1)
  1536. to virtual color 14. In all other video modes, no color manipulation is needed
  1537. because color 14 is yellow by default.
  1538.  
  1539.  
  1540. Summary of Color-Related Routines
  1541.  
  1542.      This section summarizes the functional descriptions of the Fastgraph
  1543. routines presented in this chapter. More detailed information about these
  1544. routines, including their arguments and return values, may be found in the
  1545. Fastgraph Reference Manual.
  1546.  
  1547.      FG_COLORS returns the number of simultaneously available colors in the
  1548. current video mode. In text video modes, fg_colors returns zero.
  1549.  
  1550.      FG_DEFCOLOR assigns a color value to a virtual color index. This routine
  1551. is only meaningful in graphics video modes that have fewer than 256 available
  1552. colors.
  1553.  
  1554.      FG_GETCOLOR returns the current text attribute (in text modes) or color
  1555. index (in graphics modes), as specified in the most recent call to fg_setattr
  1556. or fg_setcolor.
  1557.  
  1558.      FG_GETDACS retrieves the red, green, and blue color components for a
  1559. block of consecutively numbered video DAC registers. This routine is only
  1560. meaningful modes that use DAC registers.                                       
  1561.                                              Chapter 5:  The Use of Color   95
  1562.  
  1563.  
  1564.      FG_GETINDEX returns the color value assigned to a specified virtual color
  1565. index. In text modes and in graphics modes that have 256 available colors,
  1566. this routine returns the value passed to it.
  1567.  
  1568.      FG_GETRGB returns the red, green, and blue color components for a
  1569. specified video DAC register. This routine is only meaningful in modes that
  1570. use DAC registers.
  1571.  
  1572.       FG_MAPRGB maps six-bit red, green, and blue color components into a
  1573. suitable palette value for the current video mode. You can then pass this
  1574. value to fg_palette. This routine is meaningful only in 16-color graphics
  1575. video modes.
  1576.  
  1577.      FG_PALETTE has different functions depending on the current graphics
  1578. video mode. For the CGA four-color modes, it establishes the current palette
  1579. (of six available) and defines the background color for that palette. In the
  1580. CGA two-color mode, it defines the foreground color. For the Tandy/PCjr, EGA,
  1581. and VGA graphics modes, it defines the value of a single palette register. For
  1582. 256-color graphics modes, it defines the value of a single video DAC register.
  1583. The fg_palette routine has no effect in text modes or Hercules graphics modes.
  1584.  
  1585.      FG_PALETTES defines all 16 palette registers (in 16-color graphics
  1586. modes), or the first 16 video DAC registers (in 256-color graphics modes). The
  1587. fg_palettes routine has no effect in text modes, CGA graphics modes, or
  1588. Hercules graphics modes.
  1589.  
  1590.      FG_SETATTR establishes the current text attribute in text video modes.
  1591. This routine has no effect in graphics modes.
  1592.  
  1593.      FG_SETCOLOR establishes the current color index (which may be a virtual
  1594. color index in graphics modes). In text modes, fg_setcolor provides an
  1595. alternate method of establishing the current text attribute.
  1596.  
  1597.      FG_SETDACS defines the values of a block of consecutively numbered video
  1598. DAC registers by specifying their red, green, and blue color components. This
  1599. routine is only meaningful in modes that use DAC registers.
  1600.  
  1601.      FG_SETRGB defines the value of a single palette register (in Tandy/PCjr
  1602. and EGA graphics modes) or video DAC register (in VGA, MCGA, and SVGA modes)
  1603. by specifying its red, green, and blue color components. The fg_setrgb routine
  1604. has no effect in text modes, CGA graphics modes, or Hercules graphics modes.   
  1605. 96   Fastgraph User's Guide
  1606.