home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / PALETT.ZIP / _DAC.C next >
C/C++ Source or Header  |  1994-01-19  |  6KB  |  269 lines

  1. /*
  2.    DAC Palette Example.  For VGA cards only.
  3.  
  4.    Copyright (c) 1994 Jeffrey C. Moxon    CIS:  73561,1431
  5.  
  6.    Adapted from 'PC Intern' by Michael Tischer
  7.  
  8.    Provides three example functions to set the palette.
  9.  
  10.    1.  The assembly routines:  setdac() and getdac()
  11.    2.  The C Interrupt based routines:  csetdac() and cgetdac()
  12.    3.  The C VGA DAC register routines:  csetreg() and cgetreg()
  13.  
  14.    This routine will work in either graphics mode, or in text mode.
  15.  
  16. */
  17.  
  18. #include <conio.h>
  19. #include <dos.h>
  20. #include <graphics.h>    /* For detection routine */
  21. #include <stdio.h>
  22.  
  23. union dac
  24.      {
  25.       struct
  26.        {
  27.         char Red;      /* Red portion of color 0..63 */
  28.         char Green;   /* Green portion of color 0..63 */
  29.         char Blue;    /* Blue portion of color 0..63 */
  30.        } color;
  31.       char RGB[3];
  32.      };
  33.  
  34. /*
  35.    Declaration for assembly routines.
  36.    Uncomment declarations and replace all calls to csetdac with
  37.    setdac, and all calls to cgetdac with getdac.
  38.    Compile and link with:  BCC _dac.c, dac.asm
  39. */
  40.  
  41. extern void far getdac(int start, int number, union dac far *dac_block);
  42. extern void far setdac(int start, int number, union dac far *dac_block);
  43. extern void far setborder(unsigned char color);
  44. extern void far setvideomode(unsigned char mode);
  45.  
  46. /*
  47.   These two functions change the DACs using interrupt 0x10
  48. */
  49.  
  50. void csetdac(int start, int number, union dac *dac_block);
  51. void cgetdac(int start, int num, union dac *dac_block);
  52.  
  53. /*
  54.   These two functions are the same as the assembly routines,
  55.   except written in C.  Replace all calls to csetdac with csetreg,
  56.   and all calls to cgetdac with cgetreg.
  57. */
  58.  
  59. void csetreg(int start, int number, union dac *dac_block);
  60. void cgetreg(int start, int num, union dac *dac_block);
  61.  
  62.  
  63. void csetborder(unsigned char color);
  64.  
  65. /* See if VGA card present */
  66. int  detect_VGA(void);
  67.  
  68. void main(void)
  69. {
  70.  union dac my_block[16];  /* Variable to hold first 16 colors */
  71.  int x, y;          /* Index variables */
  72.  int key = 0;
  73.  
  74.  
  75.  /* Check for VGA */
  76.  if (!detect_VGA())
  77.  {
  78.   printf("Requires VGA card.\n");
  79.   return;
  80.  }
  81.  
  82.  
  83.  clrscr();
  84.  
  85.  /* Fill the screen with characters */
  86.  for (y = 1; y < 26; y++)
  87.   for (x = 1; x < 80; x++)
  88.   {
  89.    gotoxy(x,y);
  90.    cprintf("%c", y + 'A');
  91.   }
  92.  
  93.   /* Fade from black to red */
  94.  for(y = 0; y < 63; y++)
  95.  {
  96.     my_block[BLACK].RGB[0] = y;
  97.     my_block[BLACK].RGB[1] = 0;
  98.     my_block[BLACK].RGB[2] = 0;
  99.     csetdac(0, 1, my_block);
  100.     delay(20);
  101.  }
  102.  
  103.   /* Reset black color */
  104.   my_block[BLACK].RGB[0] = 0;
  105.   csetdac(0, 1, my_block);
  106.  
  107.   /* Fade from black to green */
  108.  for(y = 0; y < 63; y++)
  109.  {
  110.     my_block[BLACK].RGB[0] = 0;
  111.     my_block[BLACK].RGB[1] = y;
  112.     my_block[BLACK].RGB[2] = 0;
  113.     csetdac(0, 1, my_block);
  114.     delay(20);
  115.  }
  116.  
  117.   /* Reset black color */
  118.   my_block[BLACK].RGB[1] = 0;
  119.   csetdac(0, 1, my_block);
  120.  
  121.  
  122.   /* Fade from black to blue */
  123.  for(y = 0; y < 63; y++)
  124.  {
  125.     my_block[BLACK].RGB[0] = 0;
  126.     my_block[BLACK].RGB[1] = 0;
  127.     my_block[BLACK].RGB[2] = y;
  128.     csetdac(0, 1, my_block);
  129.     delay(20);
  130.  }
  131.  
  132.  
  133.   /* Reset black color */
  134.   my_block[BLACK].RGB[2] = 0;
  135.   csetdac(0, 1, my_block);
  136.  
  137.  textcolor(RED);
  138.  
  139.  /* Turn on border */
  140.  csetborder(RED);
  141.  
  142.  gotoxy(17,13);
  143.  cprintf("Watch the RED as you hit keys, Press ESC to exit.");
  144.  
  145.  
  146.  /* Read in all 16 active DAC registers */
  147.  cgetdac(0, 16, my_block);
  148.  
  149.  x = 0;
  150.  
  151.     while(key != 27)    /* 27 is ESC */
  152.     {
  153.      key = getch();
  154.  
  155.      /* change red block to each color as key is pressed */
  156.      csetdac(RED, 1, &my_block[x]);
  157.      if (x > 15) x = 0;
  158.      x++;
  159.     }
  160.  
  161.  
  162.  
  163. /* Reset all values by changing video mode */
  164. asm mov ah, 0;
  165. asm mov al, 0x03;    /* Mode in al */
  166. asm int 0x10;
  167.  
  168. return;
  169. }
  170.  
  171. /*
  172.   Set a block of DAC registers using interrupt 0x10.  This routine produces
  173.   large amounts of screen flicker, and therefore should be written in ASM
  174.   with a wait for vertical retrace prior to executing the int.
  175. */
  176.  
  177. void csetdac(int start, int number, union dac *dac_block)
  178. {
  179.  union REGS r;
  180.  struct SREGS s;
  181.  
  182.  s.es = FP_SEG(dac_block);    //dac_block is a pointer to DAC structure
  183.  r.x.dx = FP_OFF(dac_block);
  184.  
  185.  r.x.ax = 0x1012;    //Function 1012 is set block of DAC registers
  186.  r.x.bx = start;    //BX holds number to begin with (0 to 255)
  187.  r.x.cx = number;    //CX holds how many to set
  188.  int86x(0x10, &r, &r, &s);
  189.  
  190. return;
  191. }
  192.  
  193. /* Read block of DAC registers from start to number using int 0x10 */
  194. void cgetdac(int start, int number, union dac *dac_block)
  195. {
  196.  union REGS r;
  197.  struct SREGS s;
  198.  
  199.  s.es = FP_SEG(dac_block);
  200.  r.x.dx = FP_OFF(dac_block);
  201.  
  202.  r.x.ax = 0x1017;
  203.  r.x.bx = start;
  204.  r.x.cx = number;
  205.  int86x(0x10, &r, &r, &s);
  206.  
  207. return;
  208. }
  209.  
  210. /* Set Overscan color to produce border */
  211. void csetborder(unsigned char color)
  212. {
  213.  union REGS r;
  214.  
  215.  r.x.ax = 0x1001;
  216.  r.h.bh = color;
  217.  int86(0x10, &r, &r);
  218.  
  219. return;
  220. }
  221.  
  222. /* Set DAC's without using interrupt */
  223. void csetreg(int start, int number, union dac *dac_block)
  224. {
  225.  int i;
  226.  
  227.    outp(0x3c6,0xff);
  228.    outp(0x3c8, start);
  229.    for(i=0;i<number;i++)
  230.    {
  231.     outp(0x3c9, dac_block->RGB[0]); /* Red */
  232.     outp(0x3c9, dac_block->RGB[1]); /* Green */
  233.     outp(0x3c9, dac_block->RGB[2]); /* Blue */
  234.     dac_block++;
  235.    }
  236.  
  237.  return;
  238. }
  239.  
  240. /* Get DAC's without using interrrupt */
  241. void cgetreg(int start, int number, union dac *dac_block)
  242. {
  243.  int i;
  244.  
  245.    outp(0x3c7, start);
  246.    for(i=0;i<number;i++)
  247.    {
  248.     dac_block->RGB[0] = inp(0x3c9); /* Red */
  249.     dac_block->RGB[1] = inp(0x3c9); /* Green */
  250.     dac_block->RGB[2] = inp(0x3c9); /* Blue */
  251.     dac_block++;
  252.    }
  253.  
  254.  return;
  255. }
  256.  
  257. int detect_VGA(void)
  258. {
  259.  int g_driver, g_mode;
  260.  
  261.  g_driver = DETECT;
  262.  
  263.  detectgraph(&g_driver, &g_mode);
  264.  
  265.  if (g_driver != VGA) return(0);
  266.  
  267. return(1);
  268. }
  269.