home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Graphics / graphics-16000.iso / msdos / animutil / fastgfx / fg303b / manuals.arj / USER05.DOC < prev    next >
Text File  |  1993-10-02  |  73KB  |  1,583 lines

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