File: common\rotate.c
1 /*
2 rotate.c - Routines that manipulate the Video DAC on VGA Adapters
3 */
4
5 #include <string.h>
6 #include <time.h>
7
8 /* see Fractint.c for a description of the "include" hierarchy */
9 #include "port.h"
10 #include "prototyp.h"
11 #include "helpdefs.h"
12
13 /* routines in this module */
14
15 static void pauserotate(void);
16 static void set_palette(BYTE start[3], BYTE finish[3]);
17 static void set_palette2(BYTE start[3], BYTE finish[3]);
18 static void set_palette3(BYTE start[3], BYTE middle[3], BYTE finish[3]);
19
20 static int paused; /* rotate-is-paused flag */
21 static BYTE Red[3] = {63, 0, 0}; /* for shifted-Fkeys */
22 static BYTE Green[3] = { 0,63, 0};
23 static BYTE Blue[3] = { 0, 0,63};
24 static BYTE Black[3] = { 0, 0, 0};
25 static BYTE White[3] = {63,63,63};
26 static BYTE Yellow[3] = {63,63, 0};
27 static BYTE Brown[3] = {31,31, 0};
28
29 char mapmask[13] = {"*.map"};
30
31 void rotate(int direction) /* rotate-the-palette routine */
32 {
33 int kbdchar, more, last, next;
34 int fkey, step, fstep, istep, jstep, oldstep;
35 int incr, fromred=0, fromblue=0, fromgreen=0, tored=0, toblue=0, togreen=0;
36 int i, changecolor, changedirection;
37 int oldhelpmode;
38 int rotate_max,rotate_size;
39
40 static int fsteps[] = {2,4,8,12,16,24,32,40,54,100}; /* (for Fkeys) */
41
42 #ifndef XFRACT
43 if (gotrealdac == 0 /* ??? no DAC to rotate! */
46 #endif
47 || colors < 16) { /* strange things happen in 2x modes */
48 buzzer(2);
49 return;
50 }
51
52 oldhelpmode = helpmode; /* save the old help mode */
53 helpmode = HELPCYCLING; /* new help mode */
54
55 paused = 0; /* not paused */
56 fkey = 0; /* no random coloring */
57 oldstep = step = 1; /* single-step */
58 fstep = 1;
59 changecolor = -1; /* no color (rgb) to change */
60 changedirection = 0; /* no color direction to change */
61 incr = 999; /* ready to randomize */
62 srand((unsigned)time(NULL)); /* randomize things */
63
64 if (direction == 0) { /* firing up in paused mode? */
65 pauserotate(); /* then force a pause */
66 direction = 1; /* and set a rotate direction */
67 }
68
69 rotate_max = (rotate_hi < colors) ? rotate_hi : colors-1;
70 rotate_size = rotate_max - rotate_lo + 1;
71 last = rotate_max; /* last box that was filled */
72 next = rotate_lo; /* next box to be filled */
73 if (direction < 0) {
74 last = rotate_lo;
75 next = rotate_max;
76 }
77
78 more = 1;
79 while (more) {
80 if (dotmode == 11) {
81 if (!paused)
82 pauserotate();
83 }
84 else while(!keypressed()) { /* rotate until key hit, at least once so step=oldstep ok */
85 if (fkey > 0) { /* randomizing is on */
86 for (istep = 0; istep < step; istep++) {
87 jstep = next + (istep * direction);
88 while (jstep < rotate_lo) jstep += rotate_size;
89 while (jstep > rotate_max) jstep -= rotate_size;
90 if (++incr > fstep) { /* time to randomize */
91 incr = 1;
92 fstep = ((fsteps[fkey-1]* (rand15() >> 8)) >> 6) + 1;
93 fromred = dacbox[last][0];
94 fromgreen = dacbox[last][1];
95 fromblue = dacbox[last][2];
96 tored = rand15() >> 9;
97 togreen = rand15() >> 9;
98 toblue = rand15() >> 9;
99 }
100 dacbox[jstep][0] = (BYTE)(fromred + (((tored - fromred )*incr)/fstep));
101 dacbox[jstep][1] = (BYTE)(fromgreen + (((togreen - fromgreen)*incr)/fstep));
102 dacbox[jstep][2] = (BYTE)(fromblue + (((toblue - fromblue )*incr)/fstep));
103 }
104 }
105 if (step >= rotate_size) step = oldstep;
106 spindac(direction, step);
107 }
108 if (step >= rotate_size) step = oldstep;
109 kbdchar = getakey();
110 if (paused && (kbdchar != ' '
111 && kbdchar != 'c'
112 && kbdchar != HOME
113 && kbdchar != 'C' ))
114 paused = 0; /* clear paused condition */
115 switch (kbdchar) {
116 case '+': /* '+' means rotate forward */
117 case RIGHT_ARROW: /* RightArrow = rotate fwd */
118 fkey = 0;
119 direction = 1;
120 last = rotate_max;
121 next = rotate_lo;
122 incr = 999;
123 break;
124 case '-': /* '-' means rotate backward */
125 case LEFT_ARROW: /* LeftArrow = rotate bkwd */
126 fkey = 0;
127 direction = -1;
128 last = rotate_lo;
129 next = rotate_max;
130 incr = 999;
131 break;
132 case UP_ARROW: /* UpArrow means speed up */
133 daclearn = 1;
134 if (++daccount >= colors) --daccount;
135 break;
136 case DOWN_ARROW: /* DownArrow means slow down */
137 daclearn = 1;
138 if (daccount > 1) daccount--;
139 break;
140 case '1':
141 case '2':
142 case '3':
143 case '4':
144 case '5':
145 case '6':
146 case '7':
147 case '8':
148 case '9':
149 step = kbdchar - '0'; /* change step-size */
150 if (step > rotate_size) step = rotate_size;
151 break;
152 case F1: /* F1 - F10: */
153 case F2: /* select a shading factor */
154 case F3:
155 case F4:
156 case F5:
157 case F6:
158 case F7:
159 case F8:
160 case F9:
161 case F10:
162 #ifndef XFRACT
163 fkey = kbdchar-1058;
187 #endif
188 if (reallyega) fkey = (fkey+1)>>1; /* limit on EGA */
189 fstep = 1;
190 incr = 999;
191 break;
192 case ENTER: /* enter key: randomize all colors */
193 case ENTER_2: /* also the Numeric-Keypad Enter */
194 fkey = rand15()/3277 + 1;
195 if (reallyega) /* limit on EGAs */
196 fkey = (fkey+1)>>1;
197 fstep = 1;
198 incr = 999;
199 oldstep = step;
200 step = rotate_size;
201 break;
202 case 'r': /* color changes */
203 if (changecolor == -1) changecolor = 0;
204 case 'g': /* color changes */
205 if (changecolor == -1) changecolor = 1;
206 case 'b': /* color changes */
207 if (changecolor == -1) changecolor = 2;
208 if (changedirection == 0) changedirection = -1;
209 case 'R': /* color changes */
210 if (changecolor == -1) changecolor = 0;
211 case 'G': /* color changes */
212 if (changecolor == -1) changecolor = 1;
213 case 'B': /* color changes */
214 if (dotmode == 11) break;
215 if (changecolor == -1) changecolor = 2;
216 if (changedirection == 0) changedirection = 1;
217 if (reallyega) break; /* no sense on real EGAs */
218 for (i = 1; i < 256; i++) {
219 dacbox[i][changecolor] = (BYTE)(dacbox[i][changecolor] + changedirection);
220 if (dacbox[i][changecolor] == 64)
221 dacbox[i][changecolor] = 63;
222 if (dacbox[i][changecolor] == 255)
223 dacbox[i][changecolor] = 0;
224 }
225 changecolor = -1; /* clear flags for next time */
226 changedirection = 0;
227 paused = 0; /* clear any pause */
228 case ' ': /* use the spacebar as a "pause" toggle */
229 case 'c': /* for completeness' sake, the 'c' too */
230 case 'C':
231 pauserotate(); /* pause */
232 break;
233 case '>': /* single-step */
234 case '.':
235 case '<':
236 case ',':
237 if (kbdchar == '>' || kbdchar == '.') {
238 direction = -1;
239 last = rotate_lo;
240 next = rotate_max;
241 incr = 999;
242 }
243 else {
244 direction = 1;
245 last = rotate_max;
246 next = rotate_lo;
247 incr = 999;
248 }
249 fkey = 0;
250 spindac(direction,1);
251 if (! paused)
252 pauserotate(); /* pause */
253 break;
254 case 'd': /* load colors from "default.map" */
255 case 'D':
256 if (ValidateLuts("default") != 0)
257 break;
258 fkey = 0; /* disable random generation */
259 pauserotate(); /* update palette and pause */
260 break;
261 case 'a': /* load colors from "altern.map" */
262 case 'A':
263 if (ValidateLuts("altern") != 0)
264 break;
265 fkey = 0; /* disable random generation */
266 pauserotate(); /* update palette and pause */
267 break;
268 case 'l': /* load colors from a specified map */
269 #ifndef XFRACT /* L is used for RIGHT_ARROW in Unix keyboard mapping */
270 case 'L':
271 #endif
272 load_palette();
273 fkey = 0; /* disable random generation */
274 pauserotate(); /* update palette and pause */
275 break;
276 case 's': /* save the palette */
277 case 'S':
278 save_palette();
279 fkey = 0; /* disable random generation */
280 pauserotate(); /* update palette and pause */
281 break;
282 case ESC: /* escape */
283 more = 0; /* time to bail out */
284 break;
285 case HOME: /* restore palette */
286 memcpy(dacbox,olddacbox,256*3);
287 pauserotate(); /* pause */
288 break;
289 default: /* maybe a new palette */
290 if (reallyega) break; /* no sense on real EGAs */
291 fkey = 0; /* disable random generation */
292 if (kbdchar == 1084) set_palette(Black, White);
293 if (kbdchar == SF2) set_palette(Red, Yellow);
294 if (kbdchar == SF3) set_palette(Blue, Green);
295 if (kbdchar == SF4) set_palette(Black, Yellow);
296 if (kbdchar == SF5) set_palette(Black, Red);
297 if (kbdchar == SF6) set_palette(Black, Blue);
298 if (kbdchar == SF7) set_palette(Black, Green);
299 if (kbdchar == SF8) set_palette(Blue, Yellow);
300 if (kbdchar == SF9) set_palette(Red, Green);
301 if (kbdchar == 1093) set_palette(Green, White);
302 if (kbdchar == 1094) set_palette2(Black, White);
303 if (kbdchar == 1095) set_palette2(Red, Yellow);
304 if (kbdchar == 1096) set_palette2(Blue, Green);
305 if (kbdchar == 1097) set_palette2(Black, Yellow);
306 if (kbdchar == 1098) set_palette2(Black, Red);
307 if (kbdchar == 1099) set_palette2(Black, Blue);
308 if (kbdchar == 1100) set_palette2(Black, Green);
309 if (kbdchar == 1101) set_palette2(Blue, Yellow);
310 if (kbdchar == 1102) set_palette2(Red, Green);
311 if (kbdchar == 1103) set_palette2(Green, White);
312 if (kbdchar == 1104) set_palette3(Blue, Green, Red);
313 if (kbdchar == 1105) set_palette3(Blue, Yellow, Red);
314 if (kbdchar == 1106) set_palette3(Red, White, Blue);
315 if (kbdchar == 1107) set_palette3(Red, Yellow, White);
316 if (kbdchar == 1108) set_palette3(Black, Brown, Yellow);
317 if (kbdchar == 1109) set_palette3(Blue, Brown, Green);
318 if (kbdchar == 1110) set_palette3(Blue, Green, Green);
319 if (kbdchar == 1111) set_palette3(Blue, Green, White);
320 if (kbdchar == 1112) set_palette3(Green, Green, White);
321 if (kbdchar == 1113) set_palette3(Red, Blue, White);
322 pauserotate(); /* update palette and pause */
323 break;
324 }
325 }
326
327 helpmode = oldhelpmode; /* return to previous help mode */
328 }
329
330 static void pauserotate() /* pause-the-rotate routine */
331 {
332 int olddaccount; /* saved dac-count value goes here */
333 BYTE olddac0,olddac1,olddac2;
334
335 if (paused) /* if already paused , just clear */
336 paused = 0;
337 else { /* else set border, wait for a key */
338 olddaccount = daccount;
339 olddac0 = dacbox[0][0];
340 olddac1 = dacbox[0][1];
341 olddac2 = dacbox[0][2];
342 daccount = 256;
343 dacbox[0][0] = 48;
344 dacbox[0][1] = 48;
345 dacbox[0][2] = 48;
346 spindac(0,1); /* show white border */
347 if (dotmode == 11)
348 {
349 static FCODE o_msg[] = {" Paused in \"color cycling\" mode "};
350 char msg[sizeof(o_msg)];
351 far_strcpy(msg,o_msg);
352 dvid_status(100,msg);
353 }
354 #ifndef XFRACT
355 while (!keypressed()); /* wait for any key */
356 #else
357 waitkeypressed(0); /* wait for any key */ 358 #endif
359 if (dotmode == 11)
360 dvid_status(0,"");
361 dacbox[0][0] = olddac0;
362 dacbox[0][1] = olddac1;
363 dacbox[0][2] = olddac2;
364 spindac(0,1); /* show black border */
365 daccount = olddaccount;
366 paused = 1;
367 }
368 }
369
370 static void set_palette(BYTE start[3], BYTE finish[3])
371 {
372 int i, j;
373 dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
374 for(i=1;i<=255;i++) /* fill the palette */
375 for (j = 0; j < 3; j++)
376 #ifdef __SVR4
378 #else
379 dacbox[i][j] = (BYTE)((i*start[j] + (256-i)*finish[j])/255);
380 #endif
381 }
382
383 static void set_palette2(BYTE start[3], BYTE finish[3])
384 {
385 int i, j;
386 dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
387 for(i=1;i<=128;i++)
388 for (j = 0; j < 3; j++) {
389 #ifdef __SVR4
392 #else
393 dacbox[i][j] = (BYTE)((i*finish[j] + (128-i)*start[j] )/128);
394 dacbox[i+127][j] = (BYTE)((i*start[j] + (128-i)*finish[j])/128);
395 #endif
396 }
397 }
398
399 static void set_palette3(BYTE start[3], BYTE middle[3], BYTE finish[3])
400 {
401 int i, j;
402 dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0;
403 for(i=1;i<=85;i++)
404 for (j = 0; j < 3; j++) {
405 #ifdef __SVR4
409 #else
410 dacbox[i][j] = (BYTE)((i*middle[j] + (86-i)*start[j] )/85);
411 dacbox[i+85][j] = (BYTE)((i*finish[j] + (86-i)*middle[j])/85);
412 dacbox[i+170][j] = (BYTE)((i*start[j] + (86-i)*finish[j])/85);
413 #endif
414 }
415 }
416
417
418 void save_palette()
419 {
420 char palname[FILE_MAX_PATH];
421 static FCODE o_msg[] = {"Name of map file to write"};
422 char msg[sizeof(o_msg)];
423 FILE *dacfile;
424 int i,oldhelpmode;
425 far_strcpy(msg,o_msg);
426 strcpy(palname,MAP_name);
427 oldhelpmode = helpmode;
428 stackscreen();
429 temp1[0] = 0;
430 helpmode = HELPCOLORMAP;
431 i = field_prompt(0,msg,NULL,temp1,60,NULL);
432 unstackscreen();
433 if (i != -1 && temp1[0]) {
434 if (strchr(temp1,'.') == NULL)
435 strcat(temp1,".map");
436 merge_pathnames(palname,temp1,2);
437 dacfile = fopen(palname,"w");
438 if (dacfile == NULL)
439 buzzer(2);
440 else {
441 #ifndef XFRACT
442 for (i = 0; i < colors; i++)
445 #endif
446 fprintf(dacfile, "%3d %3d %3d\n",
447 dacbox[i][0] << 2,
448 dacbox[i][1] << 2,
449 dacbox[i][2] << 2);
450 memcpy(olddacbox,dacbox,256*3);
451 colorstate = 2;
452 strcpy(colorfile,temp1);
453 }
454 fclose(dacfile);
455 }
456 helpmode = oldhelpmode;
457 }
458
459
460 int load_palette(void)
461 {
462 int i,oldhelpmode;
463 char filename[FILE_MAX_PATH];
464 oldhelpmode = helpmode;
465 strcpy(filename,MAP_name);
466 stackscreen();
467 helpmode = HELPCOLORMAP;
468 i = getafilename("Select a MAP File",mapmask,filename);
469 unstackscreen();
470 if (i >= 0)
471 {
472 if (ValidateLuts(filename) == 0)
473 memcpy(olddacbox,dacbox,256*3);
474 merge_pathnames(MAP_name,filename,0);
475 }
476 helpmode = oldhelpmode;
477 return (i);
478 }
479
480