home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / fractint / fras1611.zip / ROTATE.C < prev    next >
C/C++ Source or Header  |  1991-07-20  |  14KB  |  426 lines

  1. /*
  2.     rotate.c - Routines that manipulate the Video DAC on VGA Adapters
  3.     This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
  4. */
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "fractint.h"
  10. #include "helpdefs.h"
  11.  
  12. /* routines in this module    */
  13.  
  14. void rotate_overlay(void);
  15. void rotate(int);
  16. void save_palette(void);
  17. void load_palette(void);
  18.  
  19. static void pauserotate(void);
  20. static void set_palette(),set_palette2(),set_palette3();
  21.  
  22. extern char temp1[];
  23.  
  24. extern    int    colors;         /* maximum colors available */
  25.  
  26. extern unsigned char dacbox[256][3];    /* Video-DAC (filled in by SETVIDEO) */
  27. extern    int    gotrealdac;        /* dacbox valid? */
  28. extern unsigned char olddacbox[256][3];
  29. extern int    daclearn, daccount;    /* used by the color-cyclers */
  30. extern int    reallyega;        /* == 0 if it's really an EGA */
  31. extern int    rotate_lo,rotate_hi;    /* range of colors to cycle */
  32. extern int    colorstate; /* comments in cmdfiles */
  33. extern char    colorfile[];
  34. extern int    dotmode;
  35.  
  36. static int paused;            /* rotate-is-paused flag */
  37.  
  38. extern int field_prompt(int options, char *hdg, char *instr, char *fld, int len,
  39.         int (*checkkey)() );
  40.  
  41. static unsigned char Red[3]    = {63, 0, 0};    /* for shifted-Fkeys */
  42. static unsigned char Green[3]  = { 0,63, 0};
  43. static unsigned char Blue[3]   = { 0, 0,63};
  44. static unsigned char Black[3]  = { 0, 0, 0};
  45. static unsigned char White[3]  = {63,63,63};
  46. static unsigned char Yellow[3] = {63,63, 0};
  47. static unsigned char Brown[3]  = {31,31, 0};
  48.  
  49. char mapmask[13] = {"*.map"};
  50.  
  51.  
  52. void rotate_overlay() { }    /* for restore_active_ovly */
  53.  
  54. void rotate(int direction)    /* rotate-the-palette routine */
  55. {
  56. int  kbdchar, more, last, next;
  57. int fkey, step, fstep, istep, jstep, oldstep;
  58. int incr, fromred, fromblue, fromgreen, tored, toblue, togreen;
  59. int i, changecolor, changedirection;
  60. int oldhelpmode;
  61. int rotate_max,rotate_size;
  62.  
  63. static int fsteps[] = {2,4,8,12,16,24,32,40,54,100}; /* (for Fkeys) */
  64.  
  65.    ENTER_OVLY(OVLY_ROTATE);
  66.  
  67.    if (gotrealdac == 0            /* ??? no DAC to rotate! */
  68.      || colors < 16) {            /* strange things happen in 2x modes */
  69.       buzzer(2);
  70.       EXIT_OVLY;
  71.       return;
  72.       }
  73.  
  74.    oldhelpmode = helpmode;        /* save the old help mode    */
  75.    helpmode = HELPCYCLING;        /* new help mode        */
  76.  
  77.    paused = 0;                /* not paused            */
  78.    fkey = 0;                /* no random coloring        */
  79.    oldstep = step = 1;            /* single-step            */
  80.    fstep = 1;
  81.    changecolor = -1;            /* no color (rgb) to change    */
  82.    changedirection = 0;         /* no color direction to change */
  83.    incr = 999;                /* ready to randomize        */
  84.    srand((unsigned)time(NULL));     /* randomize things        */
  85.  
  86.    if (direction == 0) {        /* firing up in paused mode?    */
  87.       pauserotate();            /* then force a pause        */
  88.       direction = 1;            /* and set a rotate direction    */
  89.       }
  90.  
  91.    rotate_max = (rotate_hi < colors) ? rotate_hi : colors-1;
  92.    rotate_size = rotate_max - rotate_lo + 1;
  93.    last = rotate_max;            /* last box that was filled    */
  94.    next = rotate_lo;            /* next box to be filled    */
  95.    if (direction < 0) {
  96.       last = rotate_lo;
  97.       next = rotate_max;
  98.       }
  99.  
  100.    more = 1;
  101.    while (more) {
  102.       if (dotmode == 11) {
  103.      if (!paused)
  104.         pauserotate();
  105.      }
  106.       else while(1) { /* rotate until key hit, at least once so step=oldstep ok */
  107.      if (fkey > 0) {        /* randomizing is on */
  108.         for (istep = 0; istep < step; istep++) {
  109.            jstep = next + (istep * direction);
  110.            while (jstep < rotate_lo)  jstep += rotate_size;
  111.            while (jstep > rotate_max) jstep -= rotate_size;
  112.            if (++incr > fstep) {    /* time to randomize */
  113.           incr = 1;
  114.           fstep = ((fsteps[fkey-1]* (rand() >> 8)) >> 6) + 1;
  115.           fromred   = dacbox[last][0];
  116.           fromgreen = dacbox[last][1];
  117.           fromblue  = dacbox[last][2];
  118.           tored     = rand() >> 9;
  119.           togreen   = rand() >> 9;
  120.           toblue    = rand() >> 9;
  121.           }
  122.            dacbox[jstep][0] = fromred   + (((tored     - fromred  )*incr)/fstep);
  123.            dacbox[jstep][1] = fromgreen + (((togreen - fromgreen)*incr)/fstep);
  124.            dacbox[jstep][2] = fromblue  + (((toblue  - fromblue )*incr)/fstep);
  125.            }
  126.         }
  127.      if (step >= rotate_size) step = oldstep;
  128.      if (keypressed()) break;
  129.      spindac(direction, step);
  130.      }
  131.       kbdchar = getakey();
  132.       if (paused && (kbdchar != ' ' && kbdchar != 'c' && kbdchar != 'C' ))
  133.      paused = 0;            /* clear paused condition    */
  134.       switch (kbdchar) {
  135.      case '+':                      /* '+' means rotate forward     */
  136.      case 1077:            /* RightArrow = rotate fwd    */
  137.         fkey = 0;
  138.         direction = 1;
  139.         last = rotate_max;
  140.         next = rotate_lo;
  141.         incr = 999;
  142.         break;
  143.      case '-':                      /* '-' means rotate backward    */
  144.      case 1075:            /* LeftArrow = rotate bkwd    */
  145.         fkey = 0;
  146.         direction = -1;
  147.         last = rotate_lo;
  148.         next = rotate_max;
  149.         incr = 999;
  150.         break;
  151.      case 1072:            /* UpArrow means speed up    */
  152.         daclearn = 1;
  153.         if (++daccount >= colors) --daccount;
  154.         break;
  155.      case 1080:            /* DownArrow means slow down    */
  156.         daclearn = 1;
  157.         if (daccount > 1) daccount--;
  158.         break;
  159.      case '1':
  160.      case '2':
  161.      case '3':
  162.      case '4':
  163.      case '5':
  164.      case '6':
  165.      case '7':
  166.      case '8':
  167.      case '9':
  168.         step = kbdchar - '0';   /* change step-size */
  169.         if (step > rotate_size) step = rotate_size;
  170.         break;
  171.      case 1059:            /* F1 - F10:            */
  172.      case 1060:            /* select a shading factor    */
  173.      case 1061:
  174.      case 1062:
  175.      case 1063:
  176.      case 1064:
  177.      case 1065:
  178.      case 1066:
  179.      case 1067:
  180.      case 1068:
  181.         fkey = kbdchar-1058;
  182.         if (reallyega) fkey = (fkey+1)>>1; /* limit on EGA */
  183.         fstep = 1;
  184.         incr = 999;
  185.         break;
  186.      case 13:            /* enter key: randomize all colors */
  187.      case 1013:            /* also the Numeric-Keypad Enter */
  188.         fkey = rand()/3277 + 1;
  189.         if (reallyega)        /* limit on EGAs */
  190.            fkey = (fkey+1)>>1;
  191.         fstep = 1;
  192.         incr = 999;
  193.         oldstep = step;
  194.         step = rotate_size;
  195.         break;
  196.      case 'r':                      /* color changes */
  197.         if (changecolor    == -1) changecolor = 0;
  198.      case 'g':                      /* color changes */
  199.         if (changecolor    == -1) changecolor = 1;
  200.      case 'b':                      /* color changes */
  201.         if (changecolor    == -1) changecolor = 2;
  202.         if (changedirection == 0) changedirection = -1;
  203.      case 'R':                      /* color changes */
  204.         if (changecolor    == -1) changecolor = 0;
  205.      case 'G':                      /* color changes */
  206.         if (changecolor    == -1) changecolor = 1;
  207.      case 'B':                      /* color changes */
  208.         if (dotmode == 11) break;
  209.         if (changecolor    == -1) changecolor = 2;
  210.         if (changedirection == 0) changedirection = 1;
  211.         if (reallyega) break;    /* no sense on real EGAs */
  212.         for (i = 1; i < 256; i++) {
  213.            dacbox[i][changecolor] += changedirection;
  214.            if (dacbox[i][changecolor] == 64)
  215.            dacbox[i][changecolor] = 63;
  216.            if (dacbox[i][changecolor] == 255)
  217.           dacbox[i][changecolor] = 0;
  218.            }
  219.         changecolor    = -1;    /* clear flags for next time */
  220.         changedirection = 0;
  221.         paused        = 0;    /* clear any pause */
  222.      case ' ':                      /* use the spacebar as a "pause" toggle */
  223.      case 'c':                      /* for completeness' sake, the 'c' too */
  224.      case 'C':
  225.         pauserotate();        /* pause */
  226.         break;
  227.      case '>':            /* single-step */
  228.      case '.':
  229.      case '<':
  230.      case ',':
  231.         if (! paused)
  232.            pauserotate();        /* pause */
  233.         fkey = 0;
  234.         if (kbdchar == '>' || kbdchar == '.')
  235.            spindac(1,1);
  236.         else
  237.            spindac(-1,1);
  238.         break;
  239.      case 'd':                      /* load colors from "default.map" */
  240.      case 'D':
  241.         if (ValidateLuts("default") != 0)
  242.            break;
  243.         fkey = 0;            /* disable random generation */
  244.         pauserotate();        /* update palette and pause */
  245.         break;
  246.      case 'a':                      /* load colors from "altern.map" */
  247.      case 'A':
  248.         if (ValidateLuts("altern") != 0)
  249.            break;
  250.         fkey = 0;            /* disable random generation */
  251.         pauserotate();        /* update palette and pause */
  252.         break;
  253.      case 'l':                      /* load colors from a specified map */
  254.      case 'L':
  255.         load_palette();
  256.         fkey = 0;            /* disable random generation */
  257.         pauserotate();        /* update palette and pause */
  258.         break;
  259.      case 's':                      /* save the palette */
  260.      case 'S':
  261.         save_palette();
  262.         fkey = 0;            /* disable random generation */
  263.         pauserotate();        /* update palette and pause */
  264.         break;
  265.      case 27:            /* escape */
  266.         more = 0;            /* time to bail out */
  267.         break;
  268.      default:            /* maybe a new palette */
  269.         if (reallyega) break;    /* no sense on real EGAs */
  270.         fkey = 0;            /* disable random generation */
  271.         if (kbdchar == 1084) set_palette(Black, White);
  272.         if (kbdchar == 1085) set_palette(Red, Yellow);
  273.         if (kbdchar == 1086) set_palette(Blue, Green);
  274.         if (kbdchar == 1087) set_palette(Black, Yellow);
  275.         if (kbdchar == 1088) set_palette(Black, Red);
  276.         if (kbdchar == 1089) set_palette(Black, Blue);
  277.         if (kbdchar == 1090) set_palette(Black, Green);
  278.         if (kbdchar == 1091) set_palette(Blue, Yellow);
  279.         if (kbdchar == 1092) set_palette(Red, Green);
  280.         if (kbdchar == 1093) set_palette(Green, White);
  281.         if (kbdchar == 1094) set_palette2(Black, White);
  282.         if (kbdchar == 1095) set_palette2(Red, Yellow);
  283.         if (kbdchar == 1096) set_palette2(Blue, Green);
  284.         if (kbdchar == 1097) set_palette2(Black, Yellow);
  285.         if (kbdchar == 1098) set_palette2(Black, Red);
  286.         if (kbdchar == 1099) set_palette2(Black, Blue);
  287.         if (kbdchar == 1100) set_palette2(Black, Green);
  288.         if (kbdchar == 1101) set_palette2(Blue, Yellow);
  289.         if (kbdchar == 1102) set_palette2(Red, Green);
  290.         if (kbdchar == 1103) set_palette2(Green, White);
  291.         if (kbdchar == 1104) set_palette3(Blue, Green, Red);
  292.         if (kbdchar == 1105) set_palette3(Blue, Yellow, Red);
  293.         if (kbdchar == 1106) set_palette3(Red, White, Blue);
  294.         if (kbdchar == 1107) set_palette3(Red, Yellow, White);
  295.         if (kbdchar == 1108) set_palette3(Black, Brown, Yellow);
  296.         if (kbdchar == 1109) set_palette3(Blue, Brown, Green);
  297.         if (kbdchar == 1110) set_palette3(Blue, Green, Green);
  298.         if (kbdchar == 1111) set_palette3(Blue, Green, White);
  299.         if (kbdchar == 1112) set_palette3(Green, Green, White);
  300.         if (kbdchar == 1113) set_palette3(Red, Blue, White);
  301.         pauserotate();  /* update palette and pause */
  302.         break;
  303.      }
  304.       }
  305.  
  306.    helpmode = oldhelpmode;        /* return to previous help mode */
  307.    EXIT_OVLY;
  308. }
  309.  
  310. static void pauserotate()        /* pause-the-rotate routine */
  311. {
  312. int olddaccount;            /* saved dac-count value goes here */
  313. unsigned char olddac0,olddac1,olddac2;
  314.  
  315.    if (paused)                /* if already paused , just clear */
  316.       paused = 0;
  317.    else {                /* else set border, wait for a key */
  318.       olddaccount = daccount;
  319.       olddac0 = dacbox[0][0];
  320.       olddac1 = dacbox[0][1];
  321.       olddac2 = dacbox[0][2];
  322.       daccount = 256;
  323.       dacbox[0][0] = 48;
  324.       dacbox[0][1] = 48;
  325.       dacbox[0][2] = 48;
  326.       spindac(0,1);            /* show white border */
  327.       if (dotmode == 11)
  328.      dvid_status(100," Paused in ""color cycling"" mode ");
  329.       while (!keypressed());        /* wait for any key */
  330.       if (dotmode == 11)
  331.      dvid_status(0,"");
  332.       dacbox[0][0] = olddac0;
  333.       dacbox[0][1] = olddac1;
  334.       dacbox[0][2] = olddac2;
  335.       spindac(0,1);            /* show black border */
  336.       daccount = olddaccount;
  337.       paused = 1;
  338.       }
  339. }
  340.  
  341. static void set_palette(start, finish)
  342. unsigned char start[3], finish[3];
  343. {
  344.    int i, j;
  345.    dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
  346.    for(i=1;i<=255;i++)            /* fill the palette    */
  347.       for (j = 0; j < 3; j++)
  348.      dacbox[i][j] = (i*start[j] + (256-i)*finish[j])/255;
  349. }
  350.  
  351. static void set_palette2(start, finish)
  352. unsigned char start[3], finish[3];
  353. {
  354.    int i, j;
  355.    dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
  356.    for(i=1;i<=128;i++)
  357.       for (j = 0; j < 3; j++) {
  358.      dacbox[i][j]      = (i*finish[j] + (128-i)*start[j] )/128;
  359.      dacbox[i+127][j] = (i*start[j]  + (128-i)*finish[j])/128;
  360.       }
  361. }
  362.  
  363. static void set_palette3(start, middle, finish)
  364. unsigned char start[3], middle[3], finish[3];
  365. {
  366.    int i, j;
  367.    dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
  368.    for(i=1;i<=85;i++)
  369.       for (j = 0; j < 3; j++) {
  370.      dacbox[i][j]      = (i*middle[j] + (86-i)*start[j] )/85;
  371.      dacbox[i+85][j]  = (i*finish[j] + (86-i)*middle[j])/85;
  372.      dacbox[i+170][j] = (i*start[j]  + (86-i)*finish[j])/85;
  373.       }
  374. }
  375.  
  376.  
  377. void save_palette()
  378. {
  379.    FILE *dacfile;
  380.    int i,oldhelpmode;
  381.    oldhelpmode = helpmode;
  382.    stackscreen();
  383.    temp1[0] = 0;
  384.    helpmode = HELPCOLORMAP;
  385.    i = field_prompt(0,"Name of map file to write",NULL,temp1,60,NULL);
  386.    unstackscreen();
  387.    if (i != -1 && temp1[0]) {
  388.       if (strchr(temp1,'.') == NULL)
  389.      strcat(temp1,".map");
  390.       dacfile = fopen(temp1,"w");
  391.       if (dacfile == NULL)
  392.      buzzer(2);
  393.       else {
  394.      for (i = 0; i < colors; i++)
  395.         fprintf(dacfile, "%3d %3d %3d\n",
  396.             dacbox[i][0] << 2,
  397.             dacbox[i][1] << 2,
  398.             dacbox[i][2] << 2);
  399.      memcpy(olddacbox,dacbox,256*3);
  400.      colorstate = 2;
  401.      strcpy(colorfile,temp1);
  402.      }
  403.       fclose(dacfile);
  404.       }
  405.    helpmode = oldhelpmode;
  406. }
  407.  
  408.  
  409. void load_palette(void)
  410. {
  411.    int i,oldhelpmode;
  412.    char filename[80];
  413.    oldhelpmode = helpmode;
  414.    strcpy(filename,colorfile);
  415.    stackscreen();
  416.    helpmode = HELPCOLORMAP;
  417.    i = getafilename("Select a MAP File",mapmask,filename);
  418.    unstackscreen();
  419.    if (i >= 0)
  420.       if (ValidateLuts(filename) == 0)
  421.      memcpy(olddacbox,dacbox,256*3);
  422.    helpmode = oldhelpmode;
  423. }
  424.  
  425.  
  426.