home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1989 / 04 / palett.asc < prev    next >
Text File  |  1989-03-27  |  10KB  |  316 lines

  1. _GRAPHICS PROGRAMMING COLUMN_
  2. by Kent Porter
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7. /* COLORS.C: Shows all colors in default palette */
  8.  
  9. #include "grafix.h"
  10. #include <conio.h>
  11.  
  12. void main ()
  13. {
  14. int r, c, color;
  15.  
  16.   if (init_video (EGA)) {
  17.     for (r = 0; r < 4; r++)
  18.       for (c = 0; c < 4; c++) {
  19.         color = (r * 4) + c;       /* next color */
  20.         set_color1 (color);
  21.         fill_rect ((c*160), (r*80), 158, 79);
  22.       }
  23.     getch();                /* wait for keypress */
  24.   }
  25. }
  26.  
  27.  
  28. [LISTING TWO]
  29.  
  30.  
  31. /* Include file for GRAFIX.LIB                */
  32. /* EGA/VGA graphics subsystem                 */
  33. /* K. Porter, DDJ Graphics Programming Column */
  34. /* ------------------------------------------ */
  35.  
  36. /* Color constants from April, 89 */
  37. #define Black     0        /* standard colors */
  38. #define Blue      1
  39. #define Green     2
  40. #define Cyan      3
  41. #define Red       4
  42. #define Magenta   5
  43. #define Brown     0x14
  44. #define LtGray    7
  45. #define DkGray    0x38
  46. #define LtBlue    0x39
  47. #define LtGreen   0x3A
  48. #define LtCyan    0x3B
  49. #define LtRed     0x3C
  50. #define LtMagenta 0x3D
  51. #define Yellow    0x3E
  52. #define White     0x3F
  53.  
  54. #define RED0      0x00  /* basic hues for mixing */
  55. #define RED1      0x20
  56. #define RED2      0x04
  57. #define RED3      0x24
  58. #define GRN0      0x00
  59. #define GRN1      0x10
  60. #define GRN2      0x02
  61. #define GRN3      0x12
  62. #define BLU0      0x00
  63. #define BLU1      0x08
  64. #define BLU2      0x01
  65. #define BLU3      0x09
  66.  
  67. #if !defined byte
  68. #define byte unsigned char
  69. #endif
  70.  
  71. /* Supported video modes */
  72. #define  EGA       0x10              /* EGA 640 x 350, 16/64 colors */
  73. #define  VGA16     0x11              /* VGA 640 x 480, 16/64 colors */
  74.  
  75. /* Function prototypes */
  76. /* From February, '89 */
  77. /* ------------------ */
  78. int far init_video (int mode);        /* init display in video mode */
  79.  
  80. void far pc_textmode (void);                        /* PC text mode */
  81.  
  82. void far draw_point (int x, int y);        /* write pixel in color1 */
  83.  
  84. void far set_color1 (int palette_reg);      /* set foreground color */
  85.  
  86. /* From March, '89 */
  87. /* --------------- */
  88. void far draw_line (int x1, int y1, int x2, int y2);
  89.                                 /* Bresenham line drawing algorithm */
  90.  
  91. void far draw_rect (int left, int top, int width, int height);
  92.                              /* draw rectangle from top left corner */
  93.  
  94. void far polyline (int edges, int vertices[]);     /* draw polyline */
  95.  
  96. void far hline (int x, int y, int len);          /* horizontal line */
  97.  
  98. void far fill_rect (int left, int top, int width, int height);
  99.       /* draw solid rectangle in color1 starting at top left corner */
  100.  
  101. /* From April, '89 */
  102. /* --------------- */
  103. byte far ega_palreg (int preg);         /* color in EGA palette reg */
  104.  
  105. void far set_ega_palreg (int reg, int color);    /* set palette reg */
  106.  
  107. byte far ega_blend (byte c1, byte c2, byte c3);  /* blend primaries */
  108.  
  109. void far get_ega_colormix (int preg, int *r, int *g, int *b);
  110.         /* get mix of red, green, and blue in EGA pal register preg */
  111.  
  112.  
  113. [LISTING THREE]
  114.  
  115. /* EGAPALET.C: Palette control for EGA/VGA 16-color modes      */
  116. /* Compile separately, then add to GRAFIX.LIB                  */
  117. /* K. Porter, DDJ Graphics Programming Column, April '89       */
  118. /* ----------------------------------------------------------- */
  119.  
  120. #include "grafix.h"
  121. #include <dos.h>
  122.  
  123. byte ega_palette [16] = {          /* current palette contents */
  124.    Black, Blue, Green, Cyan, Red, Magenta, Brown, LtGray,
  125.    DkGray, LtBlue, LtGreen, LtCyan, LtRed, LtMagenta, Yellow,
  126.    White
  127. };
  128. extern int grafixmode;                        /* from GRAFIX.C */
  129. /* ----------------------------------------------------------- */
  130.  
  131. byte far ega_palreg (int preg)
  132.     /* return contents of palette register preg */
  133. {
  134.   return ega_palette [preg];
  135. } /* --------------------------------------------------------- */
  136.  
  137. byte far ega_blend (byte c1, byte c2, byte c3)
  138.     /* blend three primary colors, return color pattern */
  139. {
  140.   return c1 | c2 | c3;
  141. } /* --------------------------------------------------------- */
  142.  
  143. void far get_ega_colormix (int preg, int *r, int *g, int *b)
  144.     /* break color in palette reg preg into its components */
  145. {
  146.   *r = ega_palette [preg] & RED3;
  147.   *g = ega_palette [preg] & GRN3;
  148.   *b = ega_palette [preg] & BLU3;
  149. } /* --------------------------------------------------------- */
  150.  
  151. void far set_ega_palreg (int preg, int color)
  152.     /* change palette register preg to new color */
  153.     /* use only for EGA 16-color mode */
  154. {
  155. union REGS r;
  156.  
  157.   if (grafixmode == EGA) {
  158.     ega_palette [preg] = color;  /* update our copy of palette */
  159.     r.h.ah = 0x10;              /* use ROM BIOS video services */
  160.     r.h.al = 0;                  /* to update the real palette */
  161.     r.h.bh = color;
  162.     r.h.bl = preg;
  163.     int86 (0x10, &r, &r);
  164.   }
  165. } /* --------------------------------------------------------- */
  166.  
  167.  
  168. [LISTING FOUR]
  169.  
  170. /* MIX.C: Utility for mixing colors with EGA */
  171.  
  172. #include "grafix.h"
  173. #include <conio.h>
  174. #include <stdio.h>
  175.  
  176. #define ESC   27     /* Esc char */
  177. #define ERASE  0
  178. #define SHOW  15
  179.  
  180. int col[] = {30, 190, 350, 510};    /* box horiz locations */
  181. int row[] = {30, 110, 190};         /* box vert locations  */
  182. int rr = 1, gr = 5, br = 9;     /* reg index for color set */
  183. int base_red[] = {RED0, RED1, RED2, RED3};
  184. int base_grn[] = {GRN0, GRN1, GRN2, GRN3};
  185. int base_blu[] = {BLU0, BLU1, BLU2, BLU3};
  186.  
  187. void main ()
  188. {
  189. int r, g, b;
  190.  
  191. void setup_palette (void), setup_screen (void),
  192.      mix_colors (void);
  193.  
  194.   if (init_video (EGA)) {
  195.     setup_palette();
  196.     setup_screen();
  197.     mix_colors();
  198.     pc_textmode();
  199.   }
  200.  
  201.   /* Report results */
  202.   get_ega_colormix (13, &r, &g, &b);
  203.   printf ("\nMixed color has value 0x%02X", ega_palreg (13));
  204.   printf ("\nComponent breakdown:");
  205.   printf ("\n    Red:   0x%02X  ", r);
  206.   switch (r) {
  207.     case RED0: puts ("(RED0)"); break;
  208.     case RED1: puts ("(RED1)"); break;
  209.     case RED2: puts ("(RED2)"); break;
  210.     case RED3: puts ("(RED3)"); break;
  211.   }
  212.   printf ("    Green: 0x%02X  ", g);
  213.   switch (g) {
  214.     case GRN0: puts ("(GRN0)"); break;
  215.     case GRN1: puts ("(GRN1)"); break;
  216.     case GRN2: puts ("(GRN2)"); break;
  217.     case GRN3: puts ("(GRN3)"); break;
  218.   }
  219.   printf ("    Blue:  0x%02X  ", b);
  220.   switch (b) {
  221.     case BLU0: puts ("(BLU0)"); break;
  222.     case BLU1: puts ("(BLU1)"); break;
  223.     case BLU2: puts ("(BLU2)"); break;
  224.     case BLU3: puts ("(BLU3)"); break;
  225.   }
  226. } /* ----------------------------------------------------- */
  227.  
  228. void setup_palette (void)   /* put basic colors in palette */
  229. {
  230.   set_ega_palreg ( 1, RED0); set_ega_palreg ( 2, RED1);
  231.   set_ega_palreg ( 3, RED2); set_ega_palreg ( 4, RED3);
  232.  
  233.   set_ega_palreg ( 5, GRN0); set_ega_palreg ( 6, GRN1);
  234.   set_ega_palreg ( 7, GRN2); set_ega_palreg ( 8, GRN3);
  235.  
  236.   set_ega_palreg ( 9, BLU0); set_ega_palreg (10, BLU1);
  237.   set_ega_palreg (11, BLU2); set_ega_palreg (12, BLU3);
  238.  
  239.   set_ega_palreg (13, White);     /* used for mixed colors */
  240. } /* ----------------------------------------------------- */
  241.  
  242. void draw_box (int reg, int c, int r)  /* box around color */
  243. {
  244.   set_color1 (reg);
  245.   draw_rect (col[c]-5, row[r]-5, 110, 70);
  246. } /* ----------------------------------------------------- */
  247.  
  248. void setup_screen (void)          /* construct work screen */
  249. {
  250. int r, c, reg = 1;
  251.  
  252.   for (r = 0; r < 3; r++)
  253.     for (c = 0; c < 4; c++) {
  254.       set_color1 (reg++);              /* select color reg */
  255.       fill_rect (col[c], row[r], 100, 60);         /* fill */
  256.     }
  257.   set_color1 (13);
  258.   fill_rect (col[0], 280, 580, 60);    /* mixed color area */
  259.  
  260.   for (r = 0; r < 3; r++)       /* rubberband most intense */
  261.     draw_box (SHOW, 3, r);
  262. } /* ----------------------------------------------------- */
  263.  
  264. void mix_colors (void)              /* interactive portion */
  265. {
  266. #define RAISE(col) col = (col < 3) ? ++col : 3
  267. #define LOWER(col) col = (col > 0) ? --col : 0
  268.  
  269. char reply;
  270. int  r, rc = 3, gc = 3, bc = 3, mixture;
  271.  
  272.   do {
  273.     reply = getch();
  274.     switch (reply) {
  275.       case ESC : break;                    /* quit program */
  276.       case 'r' : r = 0;                       /* lower red */
  277.                  draw_box (ERASE, rc, r);
  278.                  LOWER (rc);
  279.                  draw_box (SHOW, rc, r);
  280.                  break;
  281.       case 'R' : r = 0;                       /* raise red */
  282.                  draw_box (ERASE, rc, r);
  283.                  RAISE (rc);
  284.                  draw_box (SHOW, rc, r);
  285.                  break;
  286.       case 'g' : r = 1;                     /* lower green */
  287.                  draw_box (ERASE, gc, r);
  288.                  LOWER (gc);
  289.                  draw_box (SHOW, gc, r);
  290.                  break;
  291.       case 'G' : r = 1;                     /* raise green */
  292.                  draw_box (ERASE, gc, r);
  293.                  RAISE (gc);
  294.                  draw_box (SHOW, gc, r);
  295.                  break;
  296.       case 'b' : r = 2;                      /* lower blue */
  297.                  draw_box (ERASE, bc, r);
  298.                  LOWER (bc);
  299.                  draw_box (SHOW, bc, r);
  300.                  break;
  301.       case 'B' : r = 2;                      /* raise blue */
  302.                  draw_box (ERASE, bc, r);
  303.                  RAISE (bc);
  304.                  draw_box (SHOW, bc, r);
  305.                  break;
  306.     }
  307.     mixture = ega_blend (base_red[rc], base_grn[gc],
  308.                           base_blu[bc]);
  309.     set_ega_palreg (13, mixture);      /* update color mix */
  310.   } while (reply != ESC);
  311. }
  312.  
  313.  
  314.  
  315.  
  316.