/* rotate.c - Routines that manipulate the Video DAC on VGA Adapters This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY. */ #include #include #include #include #include "fractint.h" #include "helpdefs.h" #include "prototyp.h" /* routines in this module */ static void pauserotate(void); static void set_palette(),set_palette2(),set_palette3(); extern char temp1[]; extern int colors; /* maximum colors available */ extern BYTE dacbox[256][3]; /* Video-DAC (filled in by SETVIDEO) */ extern int gotrealdac; /* dacbox valid? */ extern BYTE olddacbox[256][3]; extern int daclearn, daccount; /* used by the color-cyclers */ extern int reallyega; /* == 0 if it's really an EGA */ extern int rotate_lo,rotate_hi; /* range of colors to cycle */ extern int colorstate; /* comments in cmdfiles */ extern char colorfile[]; extern int dotmode; static int paused; /* rotate-is-paused flag */ static BYTE Red[3] = {63, 0, 0}; /* for shifted-Fkeys */ static BYTE Green[3] = { 0,63, 0}; static BYTE Blue[3] = { 0, 0,63}; static BYTE Black[3] = { 0, 0, 0}; static BYTE White[3] = {63,63,63}; static BYTE Yellow[3] = {63,63, 0}; static BYTE Brown[3] = {31,31, 0}; char mapmask[13] = {"*.map"}; void rotate_overlay() { } /* for restore_active_ovly */ void rotate(int direction) /* rotate-the-palette routine */ { int kbdchar, more, last, next; int fkey, step, fstep, istep, jstep, oldstep; int incr, fromred, fromblue, fromgreen, tored, toblue, togreen; int i, changecolor, changedirection; int oldhelpmode; int rotate_max,rotate_size; static int fsteps[] = {2,4,8,12,16,24,32,40,54,100}; /* (for Fkeys) */ ENTER_OVLY(OVLY_ROTATE); if (gotrealdac == 0 /* ??? no DAC to rotate! */ || colors < 16) { /* strange things happen in 2x modes */ buzzer(2); EXIT_OVLY; return; } oldhelpmode = helpmode; /* save the old help mode */ helpmode = HELPCYCLING; /* new help mode */ paused = 0; /* not paused */ fkey = 0; /* no random coloring */ oldstep = step = 1; /* single-step */ fstep = 1; changecolor = -1; /* no color (rgb) to change */ changedirection = 0; /* no color direction to change */ incr = 999; /* ready to randomize */ srand((unsigned)time(NULL)); /* randomize things */ if (direction == 0) { /* firing up in paused mode? */ pauserotate(); /* then force a pause */ direction = 1; /* and set a rotate direction */ } rotate_max = (rotate_hi < colors) ? rotate_hi : colors-1; rotate_size = rotate_max - rotate_lo + 1; last = rotate_max; /* last box that was filled */ next = rotate_lo; /* next box to be filled */ if (direction < 0) { last = rotate_lo; next = rotate_max; } more = 1; while (more) { if (dotmode == 11) { if (!paused) pauserotate(); } else while(!keypressed()) { /* rotate until key hit, at least once so step=oldstep ok */ if (fkey > 0) { /* randomizing is on */ for (istep = 0; istep < step; istep++) { jstep = next + (istep * direction); while (jstep < rotate_lo) jstep += rotate_size; while (jstep > rotate_max) jstep -= rotate_size; if (++incr > fstep) { /* time to randomize */ incr = 1; fstep = ((fsteps[fkey-1]* (rand15() >> 8)) >> 6) + 1; fromred = dacbox[last][0]; fromgreen = dacbox[last][1]; fromblue = dacbox[last][2]; tored = rand15() >> 9; togreen = rand15() >> 9; toblue = rand15() >> 9; } dacbox[jstep][0] = fromred + (((tored - fromred )*incr)/fstep); dacbox[jstep][1] = fromgreen + (((togreen - fromgreen)*incr)/fstep); dacbox[jstep][2] = fromblue + (((toblue - fromblue )*incr)/fstep); } } if (step >= rotate_size) step = oldstep; spindac(direction, step); } if (step >= rotate_size) step = oldstep; kbdchar = getakey(); if (paused && (kbdchar != ' ' && kbdchar != 'c' && kbdchar != 'C' )) paused = 0; /* clear paused condition */ switch (kbdchar) { case '+': /* '+' means rotate forward */ case RIGHT_ARROW: /* RightArrow = rotate fwd */ fkey = 0; direction = 1; last = rotate_max; next = rotate_lo; incr = 999; break; case '-': /* '-' means rotate backward */ case LEFT_ARROW: /* LeftArrow = rotate bkwd */ fkey = 0; direction = -1; last = rotate_lo; next = rotate_max; incr = 999; break; case UP_ARROW: /* UpArrow means speed up */ daclearn = 1; if (++daccount >= colors) --daccount; break; case DOWN_ARROW: /* DownArrow means slow down */ daclearn = 1; if (daccount > 1) daccount--; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': step = kbdchar - '0'; /* change step-size */ if (step > rotate_size) step = rotate_size; break; case F1: /* F1 - F10: */ case F2: /* select a shading factor */ case F3: case F4: case F5: case F6: case F7: case F8: case F9: case F10: #ifndef XFRACT fkey = kbdchar-1058; #else switch (kbdchar) { case F1: fkey = 1;break; case F2: fkey = 2;break; case F3: fkey = 3;break; case F4: fkey = 4;break; case F5: fkey = 5;break; case F6: fkey = 6;break; case F7: fkey = 7;break; case F8: fkey = 8;break; case F9: fkey = 9;break; case F10: fkey = 10;break; } #endif if (reallyega) fkey = (fkey+1)>>1; /* limit on EGA */ fstep = 1; incr = 999; break; case ENTER: /* enter key: randomize all colors */ case ENTER_2: /* also the Numeric-Keypad Enter */ fkey = rand15()/3277 + 1; if (reallyega) /* limit on EGAs */ fkey = (fkey+1)>>1; fstep = 1; incr = 999; oldstep = step; step = rotate_size; break; case 'r': /* color changes */ if (changecolor == -1) changecolor = 0; case 'g': /* color changes */ if (changecolor == -1) changecolor = 1; case 'b': /* color changes */ if (changecolor == -1) changecolor = 2; if (changedirection == 0) changedirection = -1; case 'R': /* color changes */ if (changecolor == -1) changecolor = 0; case 'G': /* color changes */ if (changecolor == -1) changecolor = 1; case 'B': /* color changes */ if (dotmode == 11) break; if (changecolor == -1) changecolor = 2; if (changedirection == 0) changedirection = 1; if (reallyega) break; /* no sense on real EGAs */ for (i = 1; i < 256; i++) { dacbox[i][changecolor] += changedirection; if (dacbox[i][changecolor] == 64) dacbox[i][changecolor] = 63; if (dacbox[i][changecolor] == 255) dacbox[i][changecolor] = 0; } changecolor = -1; /* clear flags for next time */ changedirection = 0; paused = 0; /* clear any pause */ case ' ': /* use the spacebar as a "pause" toggle */ case 'c': /* for completeness' sake, the 'c' too */ case 'C': pauserotate(); /* pause */ break; case '>': /* single-step */ case '.': case '<': case ',': if (kbdchar == '>' || kbdchar == '.') { direction = 1; last = rotate_max; next = rotate_lo; incr = 999; } else { direction = -1; last = rotate_lo; next = rotate_max; incr = 999; } fkey = 0; spindac(direction,1); if (! paused) pauserotate(); /* pause */ break; case 'd': /* load colors from "default.map" */ case 'D': if (ValidateLuts("default") != 0) break; fkey = 0; /* disable random generation */ pauserotate(); /* update palette and pause */ break; case 'a': /* load colors from "altern.map" */ case 'A': if (ValidateLuts("altern") != 0) break; fkey = 0; /* disable random generation */ pauserotate(); /* update palette and pause */ break; case 'l': /* load colors from a specified map */ #ifndef XFRACT /* L is used for RIGHT_ARROW in Unix keyboard mapping */ case 'L': #endif load_palette(); fkey = 0; /* disable random generation */ pauserotate(); /* update palette and pause */ break; case 's': /* save the palette */ case 'S': save_palette(); fkey = 0; /* disable random generation */ pauserotate(); /* update palette and pause */ break; case ESC: /* escape */ more = 0; /* time to bail out */ break; default: /* maybe a new palette */ if (reallyega) break; /* no sense on real EGAs */ fkey = 0; /* disable random generation */ if (kbdchar == 1084) set_palette(Black, White); if (kbdchar == SF2) set_palette(Red, Yellow); if (kbdchar == SF3) set_palette(Blue, Green); if (kbdchar == SF4) set_palette(Black, Yellow); if (kbdchar == SF5) set_palette(Black, Red); if (kbdchar == SF6) set_palette(Black, Blue); if (kbdchar == SF7) set_palette(Black, Green); if (kbdchar == SF8) set_palette(Blue, Yellow); if (kbdchar == SF9) set_palette(Red, Green); if (kbdchar == 1093) set_palette(Green, White); if (kbdchar == 1094) set_palette2(Black, White); if (kbdchar == 1095) set_palette2(Red, Yellow); if (kbdchar == 1096) set_palette2(Blue, Green); if (kbdchar == 1097) set_palette2(Black, Yellow); if (kbdchar == 1098) set_palette2(Black, Red); if (kbdchar == 1099) set_palette2(Black, Blue); if (kbdchar == 1100) set_palette2(Black, Green); if (kbdchar == 1101) set_palette2(Blue, Yellow); if (kbdchar == 1102) set_palette2(Red, Green); if (kbdchar == 1103) set_palette2(Green, White); if (kbdchar == 1104) set_palette3(Blue, Green, Red); if (kbdchar == 1105) set_palette3(Blue, Yellow, Red); if (kbdchar == 1106) set_palette3(Red, White, Blue); if (kbdchar == 1107) set_palette3(Red, Yellow, White); if (kbdchar == 1108) set_palette3(Black, Brown, Yellow); if (kbdchar == 1109) set_palette3(Blue, Brown, Green); if (kbdchar == 1110) set_palette3(Blue, Green, Green); if (kbdchar == 1111) set_palette3(Blue, Green, White); if (kbdchar == 1112) set_palette3(Green, Green, White); if (kbdchar == 1113) set_palette3(Red, Blue, White); pauserotate(); /* update palette and pause */ break; } } helpmode = oldhelpmode; /* return to previous help mode */ EXIT_OVLY; } static void pauserotate() /* pause-the-rotate routine */ { int olddaccount; /* saved dac-count value goes here */ BYTE olddac0,olddac1,olddac2; if (paused) /* if already paused , just clear */ paused = 0; else { /* else set border, wait for a key */ olddaccount = daccount; olddac0 = dacbox[0][0]; olddac1 = dacbox[0][1]; olddac2 = dacbox[0][2]; daccount = 256; dacbox[0][0] = 48; dacbox[0][1] = 48; dacbox[0][2] = 48; spindac(0,1); /* show white border */ if (dotmode == 11) dvid_status(100," Paused in \"color cycling\" mode "); #ifndef XFRACT while (!keypressed()); /* wait for any key */ #else waitkeypressed(0); /* wait for any key */ #endif if (dotmode == 11) dvid_status(0,""); dacbox[0][0] = olddac0; dacbox[0][1] = olddac1; dacbox[0][2] = olddac2; spindac(0,1); /* show black border */ daccount = olddaccount; paused = 1; } } static void set_palette(start, finish) BYTE start[3], finish[3]; { int i, j; dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0; for(i=1;i<=255;i++) /* fill the palette */ for (j = 0; j < 3; j++) dacbox[i][j] = (i*start[j] + (256-i)*finish[j])/255; } static void set_palette2(start, finish) BYTE start[3], finish[3]; { int i, j; dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0; for(i=1;i<=128;i++) for (j = 0; j < 3; j++) { dacbox[i][j] = (i*finish[j] + (128-i)*start[j] )/128; dacbox[i+127][j] = (i*start[j] + (128-i)*finish[j])/128; } } static void set_palette3(start, middle, finish) BYTE start[3], middle[3], finish[3]; { int i, j; dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0; for(i=1;i<=85;i++) for (j = 0; j < 3; j++) { dacbox[i][j] = (i*middle[j] + (86-i)*start[j] )/85; dacbox[i+85][j] = (i*finish[j] + (86-i)*middle[j])/85; dacbox[i+170][j] = (i*start[j] + (86-i)*finish[j])/85; } } void save_palette() { FILE *dacfile; int i,oldhelpmode; oldhelpmode = helpmode; stackscreen(); temp1[0] = 0; helpmode = HELPCOLORMAP; i = field_prompt(0,"Name of map file to write",NULL,temp1,60,NULL); unstackscreen(); if (i != -1 && temp1[0]) { if (strchr(temp1,'.') == NULL) strcat(temp1,".map"); dacfile = fopen(temp1,"w"); if (dacfile == NULL) buzzer(2); else { #ifndef XFRACT for (i = 0; i < colors; i++) #else for (i = 0; i < 256; i++) #endif fprintf(dacfile, "%3d %3d %3d\n", dacbox[i][0] << 2, dacbox[i][1] << 2, dacbox[i][2] << 2); memcpy(olddacbox,dacbox,256*3); colorstate = 2; strcpy(colorfile,temp1); } fclose(dacfile); } helpmode = oldhelpmode; } void load_palette(void) { int i,oldhelpmode; char filename[80]; oldhelpmode = helpmode; strcpy(filename,colorfile); stackscreen(); helpmode = HELPCOLORMAP; i = getafilename("Select a MAP File",mapmask,filename); unstackscreen(); if (i >= 0) if (ValidateLuts(filename) == 0) memcpy(olddacbox,dacbox,256*3); helpmode = oldhelpmode; }