File: common\framain2.c
1 #include <string.h>
2 #include <time.h>
3
4 #ifndef XFRACT
5 #include <io.h>
6 #endif
7
8 #ifndef USE_VARARGS
9 #include <stdarg.h>
10 #else
11 #include <varargs.h> 12 #endif
13
14 #include <ctype.h>
15 /* see Fractint.c for a description of the "include" hierarchy */
16 #include "port.h"
17 #include "prototyp.h"
18 #include "fractype.h"
19 #include "helpdefs.h"
20
21 #if 0
37 #endif
38
39 /* routines in this module */
40
41 int main_menu_switch(int*,int*,int*,char*,int);
42 int evolver_menu_switch(int*,int*,int*,char*);
43 int big_while_loop(int *kbdmore, char *stacked, int resumeflag);
44 static void move_zoombox(int);
45 char fromtext_flag = 0; /* = 1 if we're in graphics mode */
46 static int call_line3d(BYTE *pixels, int linelen);
47 static void note_zoom(void);
48 static void restore_zoom(void);
49 static void move_zoombox(int keynum);
50 static void cmp_line_cleanup(void);
51 static void _fastcall restore_history_info(int);
52 static void _fastcall save_history_info(void);
53
54 U16 evolve_handle = 0;
55 char old_stdcalcmode;
56 static char far *savezoom;
57 static int historyptr = -1; /* user pointer into history tbl */
58 static int saveptr = 0; /* save ptr into history tbl */
59 static int historyflag; /* are we backing off in history? */
60 void (*outln_cleanup) (void);
61
62 int big_while_loop(int *kbdmore, char *stacked, int resumeflag)
63 {
64 int frommandel; /* if julia entered from mandel */
65 int axmode=0, bxmode, cxmode, dxmode; /* video mode (BIOS ##) */
66 double ftemp; /* fp temp */
67 int i=0; /* temporary loop counters */
68 int kbdchar;
69 int mms_value;
70 frommandel = 0;
71 if(resumeflag)
72 goto resumeloop;
73 for(;;) { /* eternal loop */
74 if (calc_status != 2 || showfile == 0) {
75 #ifdef XFRACT
79 #endif
80 far_memcpy((char far *)&videoentry,(char far *)&videotable[adapter],
81 sizeof(videoentry));
82 axmode = videoentry.videomodeax; /* video mode (BIOS call) */
83 bxmode = videoentry.videomodebx; /* video mode (BIOS call) */
84 cxmode = videoentry.videomodecx; /* video mode (BIOS call) */
85 dxmode = videoentry.videomodedx; /* video mode (BIOS call) */
86 dotmode = videoentry.dotmode; /* assembler dot read/write */
87 xdots = videoentry.xdots; /* # dots across the screen */
88 ydots = videoentry.ydots; /* # dots down the screen */
89 colors = videoentry.colors; /* # colors available */
90 dotmode %= 1000;
91 textsafe2 = dotmode / 100;
92 dotmode %= 100;
93 sxdots = xdots;
94 sydots = ydots;
95 sxoffs = syoffs = 0;
96 rotate_hi = (rotate_hi < colors) ? rotate_hi : colors - 1;
97
98 diskvideo = 0; /* set diskvideo flag */
99 if (dotmode == 11) /* default assumption is disk */
100 diskvideo = 2;
101
102 memcpy(olddacbox,dacbox,256*3); /* save the DAC */
103 diskisactive = 1; /* flag for disk-video routines */
104
105 if (overlay3d && !initbatch) {
106 unstackscreen(); /* restore old graphics image */
107 overlay3d = 0;
108 }
109
110 else {
111 setvideomode(axmode,bxmode,cxmode,dxmode); /* switch video modes */
112 if (goodmode == 0) {
113 static FCODE msg[] = {"That video mode is not available with your adapter."};
114 #ifndef XFRACT
115 static FCODE TPlusStr[] = "This video mode requires 'noninterlaced=yes'";
116
117 if(TPlusErr) {
118 stopmsg(0, TPlusStr);
119 TPlusErr = 0;
120 }
121 else
122 #endif
123 if(dotmode == 11) {
124 askvideo = TRUE;
125 }
126 else {
127 stopmsg(0,msg);
128 askvideo = TRUE;
129 }
130 initmode = -1;
131 setvideotext(); /* switch to text mode */
132 /* goto restorestart; */
133 return(RESTORESTART);
134 }
135
136 if (virtual && (xdots > sxdots || ydots > sydots)) {
137 char buf[120];
138 static FCODE msgxy1[] = {"Can't set virtual line that long, width cut down."};
139 static FCODE msgxy2[] = {"Not enough video memory for that many lines, height cut down."};
140 if (xdots > sxdots && ydots > sydots) {
141 #ifndef XFRACT
142 sprintf(buf,"%Fs\n%Fs",(char far *)msgxy1,(char far *)msgxy2);
145 #endif
146 stopmsg(0,buf);
147 }
148 else if (ydots > sydots) {
149 stopmsg(0,msgxy2);
150 }
151 else {
152 stopmsg(0,msgxy1);
153 }
154 }
155 xdots = sxdots;
156 ydots = sydots;
157 videoentry.xdots = xdots;
158 videoentry.ydots = ydots;
159 }
160
161 diskisactive = 0; /* flag for disk-video routines */
162 if (savedac || colorpreloaded) {
163 memcpy(dacbox,olddacbox,256*3); /* restore the DAC */
164 spindac(0,1);
165 colorpreloaded = 0;
166 }
167 else { /* reset DAC to defaults, which setvideomode has done for us */
168 if (mapdacbox) { /* but there's a map=, so load that */
169 far_memcpy((char far *)dacbox,mapdacbox,768);
170 spindac(0,1);
171 }
172 else if ((dotmode == 11 && colors == 256) || !colors) {
173 /* disk video, setvideomode via bios didn't get it right, so: */
174 #ifndef XFRACT
175 ValidateLuts("default"); /* read the default palette file */
176 #endif
177 }
178 colorstate = 0;
179 }
180 if (viewwindow) {
181 ftemp = finalaspectratio /* bypass for VESA virtual screen */
182 * ((dotmode == 28 && ((vesa_xres && vesa_xres != sxdots)
183 || (vesa_yres && vesa_yres != sydots)))
184 ? 1 : (double)sydots / (double)sxdots / screenaspect);
185 if ((xdots = viewxdots) != 0) { /* xdots specified */
186 if ((ydots = viewydots) == 0) /* calc ydots? */
187 ydots = (int)((double)xdots * ftemp + 0.5);
188 }
189 else
190 if (finalaspectratio <= screenaspect) {
191 xdots = (int)((double)sxdots / viewreduction + 0.5);
192 ydots = (int)((double)xdots * ftemp + 0.5);
193 }
194 else {
195 ydots = (int)((double)sydots / viewreduction + 0.5);
196 xdots = (int)((double)ydots / ftemp + 0.5);
197 }
198 if (xdots > sxdots || ydots > sydots) {
199 static FCODE msg[] = {"View window too large; using full screen."};
200 stopmsg(0,msg);
201 viewwindow = 0;
202 xdots = viewxdots = sxdots;
203 ydots = viewydots = sydots;
204 }
205 else if (((xdots <= 1) /* changed test to 1, so a 2x2 window will */
206 || (ydots <= 1)) /* work with the sound feature */
207 && !(evolving&1)) { /* so ssg works */
208 /* but no check if in evolve mode to allow lots of small views*/
209 static FCODE msg[] = {"View window too small; using full screen."};
210 stopmsg(0,msg);
211 viewwindow = 0;
212 xdots = sxdots;
213 ydots = sydots;
214 }
215 if ((evolving&1) && (curfractalspecific->flags&INFCALC)) {
216 static FCODE msg[] = {"Fractal doesn't terminate! switching off evolution."};
217 stopmsg(0,msg);
218 evolving = evolving -1;
219 viewwindow = FALSE;
220 xdots=sxdots;
221 ydots=sydots;
222 }
223 if (evolving&1) {
224 xdots = (sxdots / gridsz)-!((evolving & NOGROUT)/NOGROUT);
225 xdots = xdots - (xdots % 4); /* trim to multiple of 4 for SSG */
226 ydots = (sydots / gridsz)-!((evolving & NOGROUT)/NOGROUT);
227 ydots = ydots - (ydots % 4);
228 }
229 else {
230 sxoffs = (sxdots - xdots) / 2;
231 syoffs = (sydots - ydots) / 3;
232 }
233 }
234 dxsize = xdots - 1; /* convert just once now */
235 dysize = ydots - 1;
236 }
237 if(savedac == 0)
238 savedac = 2; /* assume we save next time (except jb) */
239 else
240 savedac = 1; /* assume we save next time */
241 if (initbatch == 0)
242 lookatmouse = -PAGE_UP; /* mouse left button == pgup */
243
244 if(showfile == 0) { /* loading an image */
245 outln_cleanup = NULL; /* outln routine can set this */
246 if (display3d) /* set up 3D decoding */
247 outln = call_line3d;
248 else if(filetype >= 1) /* old .tga format input file */
249 outln = outlin16;
250 else if(comparegif) /* debug 50 */
251 outln = cmp_line;
252 else if(pot16bit) { /* .pot format input file */
253 if (pot_startdisk() < 0)
254 { /* pot file failed? */
255 showfile = 1;
256 potflag = 0;
257 pot16bit = 0;
258 initmode = -1;
259 calc_status = 2; /* "resume" without 16-bit */
260 setvideotext();
261 get_fracttype();
262 /* goto imagestart; */
263 return(IMAGESTART);
264 }
265 outln = pot_line;
266 }
267 else if((soundflag&7) > 1 && !evolving) /* regular gif/fra input file */
268 outln = sound_line; /* sound decoding */
269 else
270 outln = out_line; /* regular decoding */
271 if(filetype == 0)
272 {
273 if(debugflag==2224)
274 {
275 char msg[MSGLEN];
276 sprintf(msg,"floatflag=%d",usr_floatflag);
277 stopmsg(4,(char far *)msg);
278 }
279
280 i = funny_glasses_call(gifview);
281 }
282 else
283 i = funny_glasses_call(tgaview);
284 if(outln_cleanup) /* cleanup routine defined? */
285 (*outln_cleanup)();
286 if(i == 0)
287 buzzer(0);
288 else {
289 calc_status = -1;
290 if (keypressed()) {
291 static FCODE msg[] = {"*** load incomplete ***"};
292 buzzer(1);
293 while (keypressed()) getakey();
294 texttempmsg(msg);
295 }
296 }
297 }
298
299 zoomoff = 1; /* zooming is enabled */
300 if (dotmode == 11 || (curfractalspecific->flags&NOZOOM) != 0)
301 zoomoff = 0; /* for these cases disable zooming */
302 if (!evolving)
303 calcfracinit();
304 #ifdef XFRACT
306 #endif
307
308 sxmin = xxmin; /* save 3 corners for zoom.c ref points */
309 sxmax = xxmax;
310 sx3rd = xx3rd;
311 symin = yymin;
312 symax = yymax;
313 sy3rd = yy3rd;
314
315 if(bf_math)
316 {
317 copy_bf(bfsxmin,bfxmin);
318 copy_bf(bfsxmax,bfxmax);
319 copy_bf(bfsymin,bfymin);
320 copy_bf(bfsymax,bfymax);
321 copy_bf(bfsx3rd,bfx3rd);
322 copy_bf(bfsy3rd,bfy3rd);
323 }
324 save_history_info();
325 if (display3d || showfile) { /* paranoia: these vars don't get set */
326 save_system = active_system; /* unless really doing some work, */
327 } /* so simple <r> + <s> keeps number */
328
329 if(showfile == 0) { /* image has been loaded */
330 showfile = 1;
331 if (initbatch == 1 && calc_status == 2)
332 initbatch = -1; /* flag to finish calc before save */
333 if (loaded3d) /* 'r' of image created with '3' */
334 display3d = 1; /* so set flag for 'b' command */
335 }
336 else { /* draw an image */
337 diskisactive = 1; /* flag for disk-video routines */
338 if (initsavetime != 0 /* autosave and resumable? */
339 && (curfractalspecific->flags&NORESUME) == 0) {
340 savebase = readticker(); /* calc's start time */
341 saveticks = abs(initsavetime);
342 saveticks *= 1092; /* bios ticks/minute */
343 if ((saveticks & 65535L) == 0)
344 ++saveticks; /* make low word nonzero */
345 finishrow = -1;
346 }
347 browsing = FALSE; /* regenerate image, turn off browsing */
348 /*rb*/
349 name_stack_ptr = -1; /* reset pointer */
350 browsename[0] = '\0'; /* null */
351 if (viewwindow && (evolving&1) && (calc_status != 4))
352 /*generate a set of images with varied parameters on each one*/
353 {
354 int grout,ecount,tmpxdots,tmpydots,gridsqr;
355 struct evolution_info resume_e_info;
356 GENEBASE gene[NUMGENES];
357 /* get the gene array from far memory */
358 MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle);
359 if ((evolve_handle != 0) && (calc_status == 2)) {
360 MoveFromMemory((BYTE *)&resume_e_info,(U16)sizeof(resume_e_info),1L,0L,evolve_handle);
361 paramrangex = resume_e_info.paramrangex;
362 paramrangey = resume_e_info.paramrangey;
363 opx = newopx = resume_e_info.opx;
364 opy = newopy = resume_e_info.opy;
365 odpx = newodpx = (char)resume_e_info.odpx;
366 odpy = newodpy = (char)resume_e_info.odpy;
367 px = resume_e_info.px;
368 py = resume_e_info.py;
369 sxoffs = resume_e_info.sxoffs;
370 syoffs = resume_e_info.syoffs;
371 xdots = resume_e_info.xdots;
372 ydots = resume_e_info.ydots;
373 gridsz = resume_e_info.gridsz;
374 this_gen_rseed = resume_e_info.this_gen_rseed;
375 fiddlefactor = resume_e_info.fiddlefactor;
376 evolving = viewwindow = resume_e_info.evolving;
377 ecount = resume_e_info.ecount;
378 MemoryRelease(evolve_handle); /* We're done with it, release it. */
379 evolve_handle = 0;
380 }
381 else { /* not resuming, start from the beginning */
382 int mid = gridsz / 2;
383 if ((px != mid) || (py != mid)) {
384 this_gen_rseed = (unsigned int)clock_ticks(); /* time for new set */
385 }
386 param_history(0); /* save old history */
387 ecount = 0;
388 fiddlefactor = fiddlefactor * fiddle_reduction;
389 opx = newopx; opy = newopy;
390 odpx = newodpx; odpy = newodpy; /*odpx used for discrete parms like
391 inside, outside, trigfn etc */
392 }
393 prmboxcount = 0;
394 dpx=paramrangex/(gridsz-1);
395 dpy=paramrangey/(gridsz-1);
396 grout = !((evolving & NOGROUT)/NOGROUT);
397 tmpxdots = xdots+grout;
398 tmpydots = ydots+grout;
399 gridsqr = gridsz * gridsz;
400 while ( ecount < gridsqr ) {
401 spiralmap(ecount); /* sets px & py */
402 sxoffs = tmpxdots * px;
403 syoffs = tmpydots * py;
404 param_history(1); /* restore old history */
405 fiddleparms(gene, ecount);
406 calcfracinit();
407 if (calcfract() == -1)
408 goto done;
409 ecount ++;
410 }
411 done:
412 if (ecount == gridsqr) {
413 i = 0;
414 buzzer(0); /* finished!! */
415 }
416 else { /* interrupted screen generation, save info */
417 if (evolve_handle == 0)
418 evolve_handle = MemoryAlloc((U16)sizeof(resume_e_info),1L,FARMEM);
419 resume_e_info.paramrangex = paramrangex;
420 resume_e_info.paramrangey = paramrangey;
421 resume_e_info.opx = opx;
422 resume_e_info.opy = opy;
423 resume_e_info.odpx = (short)odpx;
424 resume_e_info.odpy = (short)odpy;
425 resume_e_info.px = (short)px;
426 resume_e_info.py = (short)py;
427 resume_e_info.sxoffs = (short)sxoffs;
428 resume_e_info.syoffs = (short)syoffs;
429 resume_e_info.xdots = (short)xdots;
430 resume_e_info.ydots = (short)ydots;
431 resume_e_info.gridsz = (short)gridsz;
432 resume_e_info.this_gen_rseed = (short)this_gen_rseed;
433 resume_e_info.fiddlefactor = fiddlefactor;
434 resume_e_info.evolving = (short)evolving;
435 resume_e_info.ecount = (short) ecount;
436 MoveToMemory((BYTE *)&resume_e_info,(U16)sizeof(resume_e_info),1L,0L,evolve_handle);
437 }
438 sxoffs = syoffs = 0;
439 xdots = sxdots;
440 ydots = sydots; /* otherwise save only saves a sub image and boxes get clipped */
441
442 /* set up for 1st selected image, this reuses px and py */
443 px = py = gridsz/2;
444 unspiralmap(); /* first time called, w/above line sets up array */
445 param_history(1); /* restore old history */
446 fiddleparms(gene, 0);
447 /* now put the gene array back in far memory */
448 MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle);
449 }
450 /* end of evolution loop */
451 else {
452 i = calcfract(); /* draw the fractal using "C" */
453 if (i == 0)
454 buzzer(0); /* finished!! */
455 }
456
457 saveticks = 0; /* turn off autosave timer */
458 if (dotmode == 11 && i == 0) /* disk-video */
459 {
460 static FCODE o_msg[] = {"Image has been completed"};
461 char msg[sizeof(o_msg)];
462 far_strcpy(msg,o_msg);
463 dvid_status(0,msg);
464 }
465 diskisactive = 0; /* flag for disk-video routines */
466 }
467 #ifndef XFRACT
468 boxcount = 0; /* no zoom box yet */
469 zwidth = 0;
475 #endif
476
477 if (fractype == PLASMA && cpu > 88) {
478 cyclelimit = 256; /* plasma clouds need quick spins */
479 daccount = 256;
480 daclearn = 1;
481 }
482
483 resumeloop: /* return here on failed overlays */
484
485 *kbdmore = 1;
486 while (*kbdmore == 1) { /* loop through command keys */
487 if (timedsave != 0) {
488 if (timedsave == 1) { /* woke up for timed save */
489 getakey(); /* eat the dummy char */
490 kbdchar = 's'; /* do the save */
491 resave_flag = 1;
492 timedsave = 2;
493 }
494 else { /* save done, resume */
495 timedsave = 0;
496 resave_flag = 2;
497 kbdchar = ENTER;
498 }
499 }
500 else if (initbatch == 0) { /* not batch mode */
501 #ifndef XFRACT
502 lookatmouse = (zwidth == 0 && !video_scroll) ? -PAGE_UP : 3;
505 #endif
506 if (calc_status == 2 && zwidth == 0 && !keypressed()) {
507 kbdchar = ENTER ; /* no visible reason to stop, continue */
508 } else { /* wait for a real keystroke */
509 if (autobrowse && !no_sub_images) kbdchar = 'l';
510 else
511 {
512 #ifndef XFRACT
513 while (!keypressed());/* { }*/ /* enables help */
514 #else
515 waitkeypressed(0); 516 #endif
517 kbdchar = getakey();
518 }
519 if (kbdchar == ESC || kbdchar == 'm' || kbdchar == 'M') {
520 if (kbdchar == ESC && escape_exit != 0)
521 /* don't ask, just get out */
522 goodbye();
523 stackscreen();
524 #ifndef XFRACT
525 kbdchar = main_menu(1);
535 #endif
536 if (kbdchar == '\\' || kbdchar == CTL_BACKSLASH ||
537 kbdchar == 'h' || kbdchar == 8 ||
538 check_vidmode_key(0,kbdchar) >= 0)
539 discardscreen();
540 else if (kbdchar == 'x' || kbdchar == 'y' ||
541 kbdchar == 'z' || kbdchar == 'g' ||
542 kbdchar == 'v' || kbdchar == 2 ||
543 kbdchar == 5 || kbdchar == 6)
544 fromtext_flag = 1;
545 else
546 unstackscreen();
547 }
548 }
549 }
550 else { /* batch mode, fake next keystroke */
551
552 /* initbatch == -1 flag to finish calc before save */
553 /* initbatch == 0 not in batch mode */
554 /* initbatch == 1 normal batch mode */
555 /* initbatch == 2 was 1, now do a save */
556 /* initbatch == 3 bailout with errorlevel == 2, error occurred, no save */
557 /* initbatch == 4 bailout with errorlevel == 1, interrupted, try to save */
558 /* initbatch == 5 was 4, now do a save */
559
560 if (initbatch == -1) { /* finish calc */
561 kbdchar = ENTER;
562 initbatch = 1;
563 }
564 else if (initbatch == 1 || initbatch == 4 ) { /* save-to-disk */
565 /*
566 while(keypressed())
567 getakey();
568 */
569 if (debugflag == 50)
570 kbdchar = 'r';
571 else
572 kbdchar = 's';
573 if(initbatch == 1) initbatch = 2;
574 if(initbatch == 4) initbatch = 5;
575 }
576 else {
577 if(calc_status != 4) initbatch = 3; /* bailout with error */
578 goodbye(); /* done, exit */
579 }
580 }
581
582 #ifndef XFRACT
583 if ('A' <= kbdchar && kbdchar <= 'Z')
584 kbdchar = tolower(kbdchar);
585 #endif
586 if (evolving)
587 mms_value = evolver_menu_switch(&kbdchar,&frommandel,kbdmore,stacked);
588 else
589 mms_value = main_menu_switch(&kbdchar,&frommandel,kbdmore,stacked,axmode);
590 if (quick_calc && (mms_value == IMAGESTART ||
591 mms_value == RESTORESTART ||
592 mms_value == RESTART)) {
593 quick_calc = 0;
594 usr_stdcalcmode = old_stdcalcmode;
595 }
596 if (quick_calc && calc_status != 4)
597 usr_stdcalcmode = '1';
598 switch(mms_value)
599 {
600 case IMAGESTART:
601 return(IMAGESTART);
602 case RESTORESTART:
603 return(RESTORESTART);
604 case RESTART:
605 return(RESTART);
606 case CONTINUE:
607 continue;
608 default:
609 break;
610 }
611 if (zoomoff == 1 && *kbdmore == 1) /* draw/clear a zoom box? */
612 drawbox(1);
613 #ifdef XFRACT
617 #endif
618 }
619 }
620 /* return(0); */
621 }
622
623 int main_menu_switch(int *kbdchar, int *frommandel, int *kbdmore, char *stacked, int axmode)
624 {
625 int i,k;
626 static double jxxmin, jxxmax, jyymin, jyymax; /* "Julia mode" entry point */
627 static double jxx3rd, jyy3rd;
628 long old_maxit;
629 /*
630 char drive[FILE_MAX_DRIVE];
631 char dir[FILE_MAX_DIR];
632 char fname[FILE_MAX_FNAME];
633 char ext[FILE_MAX_EXT];
634 */
635 if (quick_calc && calc_status == 4) {
636 quick_calc = 0;
637 usr_stdcalcmode = old_stdcalcmode;
638 }
639 if (quick_calc && calc_status != 4)
640 usr_stdcalcmode = old_stdcalcmode;
641 switch (*kbdchar)
642 {
643 case 't': /* new fractal type */
644 julibrot = 0;
645 clear_zoombox();
646 stackscreen();
647 if ((i = get_fracttype()) >= 0)
648 {
649 discardscreen();
650 savedac = 0;
651 save_release = release;
652 no_mag_calc = 0;
653 use_old_period = 0;
654 bad_outside = 0;
655 ldcheck = 0;
656 set_current_params();
657 odpx=odpy=newodpx=newodpy=0;
658 fiddlefactor = 1; /* reset param evolution stuff */
659 set_orbit_corners = 0;
660 param_history(0); /* save history */
661 if (i == 0)
662 {
663 initmode = adapter;
664 *frommandel = 0;
665 }
666 else if (initmode < 0) /* it is supposed to be... */
667 setvideotext(); /* reset to text mode */
668 return(IMAGESTART);
669 }
670 unstackscreen();
671 break;
672 case 24: /* Ctl-X, Ctl-Y, CTL-Z do flipping */
673 case 25:
674 case 26:
675 flip_image(*kbdchar);
676 break;
677 case 'x': /* invoke options screen */
678 case 'y':
679 case 'p': /* passes options */
680 case 'z': /* type specific parms */
681 case 'g':
682 case 'v':
683 case 2:
684 case 5:
685 case 6:
686 old_maxit = maxit;
687 clear_zoombox();
688 if (fromtext_flag == 1)
689 fromtext_flag = 0;
690 else
691 stackscreen();
692 if (*kbdchar == 'x')
693 i = get_toggles();
694 else if (*kbdchar == 'y')
695 i = get_toggles2();
696 else if (*kbdchar == 'p')
697 i = passes_options();
698 else if (*kbdchar == 'z')
699 i = get_fract_params(1);
700 else if (*kbdchar == 'v')
701 i = get_view_params(); /* get the parameters */
702 else if (*kbdchar == 2)
703 i = get_browse_params();
704 else if (*kbdchar == 5) {
705 i = get_evolve_Parms();
706 if (i > 0) {
707 start_showorbit = 0;
708 soundflag &= 0xF9; /* turn off only x,y,z */
709 Log_Auto_Calc = 0; /* turn it off */
710 }
711 }
712 else if (*kbdchar == 6)
713 i = get_sound_params();
714 else
715 i = get_cmd_string();
716 unstackscreen();
717 if (evolving && truecolor)
718 truecolor = 0; /* truecolor doesn't play well with the evolver */
719 if (maxit > old_maxit && inside >= 0 && calc_status == 4 &&
720 curfractalspecific->calctype == StandardFractal && !LogFlag &&
721 !truecolor && /* recalc not yet implemented with truecolor */
722 !(usr_stdcalcmode == 't' && fillcolor > -1) &&
723 /* tesseral with fill doesn't work */
724 !(usr_stdcalcmode == 'o') &&
725 i == 1 && /* nothing else changed */
726 outside != ATAN ) {
727 quick_calc = 1;
728 old_stdcalcmode = usr_stdcalcmode;
729 usr_stdcalcmode = '1';
730 *kbdmore = 0;
731 calc_status = 2;
732 i = 0;
733 }
734 else if (i > 0) { /* time to redraw? */
735 quick_calc = 0;
736 param_history(0); /* save history */
737 *kbdmore = calc_status = 0;
738 }
739 break;
740 #ifndef XFRACT
741 case '@': /* execute commands */
742 case '2': /* execute commands */
743 #else
744 case F2: /* execute commands */ 745 #endif
746 stackscreen();
747 i = get_commands();
748 if (initmode != -1)
749 { /* video= was specified */
750 adapter = initmode;
751 initmode = -1;
752 i |= 1;
753 savedac = 0;
754 }
755 else if (colorpreloaded)
756 { /* colors= was specified */
757 spindac(0, 1);
758 colorpreloaded = 0;
759 }
760 else if ((i & 8)) /* reset was specified */
761 savedac = 0;
762 if ((i & 4))
763 { /* 3d = was specified */
764 *kbdchar = '3';
765 unstackscreen();
766 goto do_3d_transform; /* pretend '3' was keyed */
767 }
768 if ((i & 1))
769 { /* fractal parameter changed */
770 discardscreen();
771 /* backwards_v18();*/ /* moved this to cmdfiles.c */
772 /* backwards_v19();*/
773 *kbdmore = calc_status = 0;
774 }
775 else
776 unstackscreen();
777 break;
778 case 'f': /* floating pt toggle */
779 if (usr_floatflag == 0)
780 usr_floatflag = 1;
781 else if (stdcalcmode != 'o') /* don't go there */
782 usr_floatflag = 0;
783 initmode = adapter;
784 return(IMAGESTART);
785 case 'i': /* 3d fractal parms */
786 if (get_fract3d_params() >= 0) /* get the parameters */
787 calc_status = *kbdmore = 0; /* time to redraw */
788 break;
789 #if 0
790 case 'w':
791 /*chk_keys();*/
792 /*julman();*/
793 break; 794 #endif
795 case 1: /* ^a Ant */
796 clear_zoombox();
797 {
798 int oldtype, err, i;
799 double oldparm[MAXPARAMS];
800 oldtype = fractype;
801 for(i=0;i<MAXPARAMS;i++)
802 oldparm[i] = param[i];
803 if (fractype != ANT)
804 {
805 fractype = ANT;
806 curfractalspecific = &fractalspecific[fractype];
807 load_params(fractype);
808 }
809 if (!fromtext_flag)
810 stackscreen();
811 fromtext_flag = 0;
812 if ((err = get_fract_params(2)) >= 0)
813 {
814 unstackscreen();
815 if (ant() >= 0)
816 calc_status = 0;
817 }
818 else
819 unstackscreen();
820 fractype = oldtype;
821 for(i=0;i<MAXPARAMS;i++)
822 param[i] = oldparm[i];
823 if (err >= 0)
824 return(CONTINUE);
825 }
826 break;
827 case 'k': /* ^s is irritating, give user a single key */
828 case 19: /* ^s RDS */
829 clear_zoombox();
830 if (get_rds_params() >= 0)
831 {
832 if (do_AutoStereo() >= 0)
833 calc_status = 0;
834 return(CONTINUE);
835 }
836 break;
837 case 'a': /* starfield parms */
838 clear_zoombox();
839 if (get_starfield_params() >= 0)
840 {
841 if (starfield() >= 0)
842 calc_status = 0;
843 return(CONTINUE);
844 }
845 break;
846 case 15: /* ctrl-o */
847 case 'o':
848 /* must use standard fractal and have a float variant */
849 if ((fractalspecific[fractype].calctype == StandardFractal
850 || fractalspecific[fractype].calctype == calcfroth) &&
851 (fractalspecific[fractype].isinteger == 0 ||
852 fractalspecific[fractype].tofloat != NOFRACTAL) &&
853 !bf_math && /* for now no arbitrary precision support */
854 !(istruecolor && truemode) )
855 {
856 clear_zoombox();
857 Jiim(ORBIT);
858 }
859 break;
860 case SPACE: /* spacebar, toggle mand/julia */
861 if(bf_math || evolving)
862 break;
863 if (fractype == CELLULAR)
864 {
865 if (nxtscreenflag)
866 nxtscreenflag = 0; /* toggle flag to stop generation */
867 else
868 nxtscreenflag = 1; /* toggle flag to generate next screen */
869 calc_status = 2;
870 *kbdmore = 0;
871 }
872 else
873 {
874 if(fractype == FORMULA || fractype == FFORMULA)
875 {
876 if(ismand)
877 {
878 fractalspecific[fractype].tojulia = fractype;
879 fractalspecific[fractype].tomandel = NOFRACTAL;
880 ismand = 0;
881 }
882 else
883 {
884 fractalspecific[fractype].tojulia = NOFRACTAL;
885 fractalspecific[fractype].tomandel = fractype;
886 ismand = 1;
887 }
888 }
889 if (curfractalspecific->tojulia != NOFRACTAL
890 && param[0] == 0.0 && param[1] == 0.0)
891 {
892 /* switch to corresponding Julia set */
893 int key;
894 if ((fractype == MANDEL || fractype == MANDELFP) && bf_math == 0)
895 hasinverse = 1;
896 else
897 hasinverse = 0;
898 clear_zoombox();
899 Jiim(JIIM);
900 key = getakey(); /* flush keyboard buffer */
901 if (key != SPACE)
902 {
903 ungetakey(key);
904 break;
905 }
906 fractype = curfractalspecific->tojulia;
907 curfractalspecific = &fractalspecific[fractype];
908 if (xcjul == BIG || ycjul == BIG)
909 {
910 param[0] = (xxmax + xxmin) / 2;
911 param[1] = (yymax + yymin) / 2;
912 }
913 else
914 {
915 param[0] = xcjul;
916 param[1] = ycjul;
917 xcjul = ycjul = BIG;
918 }
919 jxxmin = sxmin;
920 jxxmax = sxmax;
921 jyymax = symax;
922 jyymin = symin;
923 jxx3rd = sx3rd;
924 jyy3rd = sy3rd;
925 *frommandel = 1;
926 xxmin = curfractalspecific->xmin;
927 xxmax = curfractalspecific->xmax;
928 yymin = curfractalspecific->ymin;
929 yymax = curfractalspecific->ymax;
930 xx3rd = xxmin;
931 yy3rd = yymin;
932 if (usr_distest == 0 && usr_biomorph != -1 && bitshift != 29)
933 {
934 xxmin *= 3.0;
935 xxmax *= 3.0;
936 yymin *= 3.0;
937 yymax *= 3.0;
938 xx3rd *= 3.0;
939 yy3rd *= 3.0;
940 }
941 zoomoff = 1;
942 calc_status = 0;
943 *kbdmore = 0;
944 }
945 else if (curfractalspecific->tomandel != NOFRACTAL)
946 {
947 /* switch to corresponding Mandel set */
948 fractype = curfractalspecific->tomandel;
949 curfractalspecific = &fractalspecific[fractype];
950 if (*frommandel)
951 {
952 xxmin = jxxmin;
953 xxmax = jxxmax;
954 yymin = jyymin;
955 yymax = jyymax;
956 xx3rd = jxx3rd;
957 yy3rd = jyy3rd;
958 }
959 else
960 {
961 xxmin = xx3rd = curfractalspecific->xmin;
962 xxmax = curfractalspecific->xmax;
963 yymin = yy3rd = curfractalspecific->ymin;
964 yymax = curfractalspecific->ymax;
965 }
966 SaveC.x = param[0];
967 SaveC.y = param[1];
968 param[0] = 0;
969 param[1] = 0;
970 zoomoff = 1;
971 calc_status = 0;
972 *kbdmore = 0;
973 }
974 else
975 buzzer(2); /* can't switch */
976 } /* end of else for if == cellular */
977 break;
978 case 'j': /* inverse julia toggle */
979 /* if the inverse types proliferate, something more elegant will be
980 * needed */
981 if (fractype == JULIA || fractype == JULIAFP || fractype == INVERSEJULIA)
982 {
983 static int oldtype = -1;
984 if (fractype == JULIA || fractype == JULIAFP)
985 {
986 oldtype = fractype;
987 fractype = INVERSEJULIA;
988 }
989 else if (fractype == INVERSEJULIA)
990 {
991 if (oldtype != -1)
992 fractype = oldtype;
993 else
994 fractype = JULIA;
995 }
996 curfractalspecific = &fractalspecific[fractype];
997 zoomoff = 1;
998 calc_status = 0;
999 *kbdmore = 0;
1000 }
1001 #if 0
1007 #endif
1008 else
1009 buzzer(2);
1010 break;
1011 case '\\': /* return to prev image */
1012 case CTL_BACKSLASH:
1013 case 'h':
1014 case 8:
1015 if (name_stack_ptr >= 1)
1016 {
1017 /* go back one file if somewhere to go (ie. browsing) */
1018 name_stack_ptr--;
1019 while (file_name_stack[name_stack_ptr][0] == '\0'
1020 && name_stack_ptr >= 0)
1021 name_stack_ptr--;
1022 if (name_stack_ptr < 0) /* oops, must have deleted first one */
1023 break;
1024 strcpy(browsename, file_name_stack[name_stack_ptr]);
1025 /*
1026 splitpath(browsename, NULL, NULL, fname, ext);
1027 splitpath(readname, drive, dir, NULL, NULL);
1028 makepath(readname, drive, dir, fname, ext);
1029 */
1030 merge_pathnames(readname,browsename,2);
1031 browsing = TRUE;
1032 no_sub_images = FALSE;
1033 showfile = 0;
1034 if (askvideo)
1035 {
1036 stackscreen(); /* save graphics image */
1037 *stacked = 1;
1038 }
1039 return(RESTORESTART);
1040 }
1041 else if(maxhistory > 0 && bf_math == 0)
1042 {
1043 if(*kbdchar == '\\' || *kbdchar == 'h')
1044 if (--historyptr < 0)
1045 historyptr = maxhistory - 1;
1046 if(*kbdchar == CTL_BACKSLASH || *kbdchar == 8)
1047 if (++historyptr >= maxhistory)
1048 historyptr = 0;
1049 restore_history_info(historyptr);
1050 zoomoff = 1;
1051 initmode = adapter;
1052 if (curfractalspecific->isinteger != 0 &&
1053 curfractalspecific->tofloat != NOFRACTAL)
1054 usr_floatflag = 0;
1055 if (curfractalspecific->isinteger == 0 &&
1056 curfractalspecific->tofloat != NOFRACTAL)
1057 usr_floatflag = 1;
1058 historyflag = 1; /* avoid re-store parms due to rounding errs */
1059 return(IMAGESTART);
1060 }
1061 break;
1062 case 'd': /* shell to MS-DOS */
1063 #ifndef XFRACT
1064 stackscreen();
1065 if (75000L > fr_farfree()) {
1066 static FCODE dosmsg[] = {"Not enough memory to Shell-to-DOS"};
1067 unstackscreen();
1068 stopmsg(0, dosmsg);
1069 break;
1070 }
1071 if (axmode == 0 || axmode > 7)
1072 {
1073 static FCODE dosmsg[] =
1074 {"\
1075 Note: Your graphics image is still squirreled away in your video\n\
1076 adapter's memory. Switching video modes will clobber part of that\n\
1077 image. Sorry - it's the best we could do."};
1078 putstring(0, 0, 7, dosmsg);
1079 movecursor(6, 0);
1080 }
1081 shell_to_dos();
1082 unstackscreen();
1089 #endif
1090 /* calc_status = 0; */
1091 break;
1092 case 'c': /* switch to color cycling */
1093 case '+': /* rotate palette */
1094 case '-': /* rotate palette */
1095 clear_zoombox();
1096 memcpy(olddacbox, dacbox, 256 * 3);
1097 rotate((*kbdchar == 'c') ? 0 : ((*kbdchar == '+') ? 1 : -1));
1098 if (memcmp(olddacbox, dacbox, 256 * 3))
1099 {
1100 colorstate = 1;
1101 save_history_info();
1102 }
1103 return(CONTINUE);
1104 case 'e': /* switch to color editing */
1105 if (istruecolor && !initbatch) { /* don't enter palette editor */
1106 if (load_palette() >= 0) {
1107 *kbdmore = calc_status = 0;
1108 break;
1109 } else
1110 return(CONTINUE);
1111 }
1112 clear_zoombox();
1113 if (dacbox[0][0] != 255 && !reallyega && colors >= 16
1114 && dotmode != 11)
1115 {
1116 int oldhelpmode;
1117 oldhelpmode = helpmode;
1118 memcpy(olddacbox, dacbox, 256 * 3);
1119 helpmode = HELPXHAIR;
1120 EditPalette();
1121 helpmode = oldhelpmode;
1122 if (memcmp(olddacbox, dacbox, 256 * 3))
1123 {
1124 colorstate = 1;
1125 save_history_info();
1126 }
1127 }
1128 return(CONTINUE);
1129 case 's': /* save-to-disk */
1130 if (dotmode == 11 && disktarga == 1)
1131 return(CONTINUE); /* disk video and targa, nothing to save */
1132 diskisactive = 1; /* flag for disk-video routines */
1133 note_zoom();
1134 savetodisk(savename);
1135 restore_zoom();
1136 diskisactive = 0; /* flag for disk-video routines */
1137 return(CONTINUE);
1138 case '#': /* 3D overlay */
1139 #ifdef XFRACT
1140 case F3: /* 3D overlay */ 1141 #endif
1142 clear_zoombox();
1143 overlay3d = 1;
1144 case '3': /* restore-from (3d) */
1145 do_3d_transform:
1146 if (overlay3d)
1147 display3d = 2; /* for <b> command */
1148 else
1149 display3d = 1;
1150 case 'r': /* restore-from */
1151 comparegif = 0;
1152 *frommandel = 0;
1153 if (browsing)
1154 {
1155 browsing = FALSE;
1156 }
1157 if (*kbdchar == 'r')
1158 {
1159 if (debugflag == 50)
1160 {
1161 comparegif = overlay3d = 1;
1162 if (initbatch == 2)
1163 {
1164 stackscreen(); /* save graphics image */
1165 strcpy(readname, savename);
1166 showfile = 0;
1167 return(RESTORESTART);
1168 }
1169 }
1170 else
1171 comparegif = overlay3d = 0;
1172 display3d = 0;
1173 }
1174 stackscreen(); /* save graphics image */
1175 if (overlay3d)
1176 *stacked = 0;
1177 else
1178 *stacked = 1;
1179 if (resave_flag)
1180 {
1181 updatesavename(savename); /* do the pending increment */
1182 resave_flag = started_resaves = 0;
1183 }
1184 showfile = -1;
1185 return(RESTORESTART);
1186 case 'l':
1187 case 'L': /* Look for other files within this view */
1188 if ((zwidth == 0) && (!diskvideo))
1189 /* not zooming & no disk video */
1190 {
1191 int oldhelpmode;
1192 oldhelpmode = helpmode;
1193 helpmode = HELPBROWSE;
1194 switch (fgetwindow())
1195 {
1196 case ENTER:
1197 case ENTER_2:
1198 showfile = 0; /* trigger load */
1199 browsing = TRUE; /* but don't ask for the file name as it's
1200 * just been selected */
1201 if (name_stack_ptr == 15)
1202 { /* about to run off the end of the file
1203 * history stack so shift it all back one to
1204 * make room, lose the 1st one */
1205 int tmp;
1206 for (tmp = 1; tmp < 16; tmp++)
1207 strcpy(file_name_stack[tmp - 1], file_name_stack[tmp]);
1208 name_stack_ptr = 14;
1209 }
1210 name_stack_ptr++;
1211 strcpy(file_name_stack[name_stack_ptr], browsename);
1212 /*
1213 splitpath(browsename, NULL, NULL, fname, ext);
1214 splitpath(readname, drive, dir, NULL, NULL);
1215 makepath(readname, drive, dir, fname, ext);
1216 */
1217 merge_pathnames(readname,browsename,2);
1218 if (askvideo)
1219 {
1220 stackscreen(); /* save graphics image */
1221 *stacked = 1;
1222 }
1223 return(RESTORESTART); /* hop off and do it!! */
1224 case '\\':
1225 if (name_stack_ptr >= 1)
1226 {
1227 /* go back one file if somewhere to go (ie. browsing) */
1228 name_stack_ptr--;
1229 while (file_name_stack[name_stack_ptr][0] == '\0'
1230 && name_stack_ptr >= 0)
1231 name_stack_ptr--;
1232 if (name_stack_ptr < 0) /* oops, must have deleted first one */
1233 break;
1234 strcpy(browsename, file_name_stack[name_stack_ptr]);
1235 /*
1236 splitpath(browsename, NULL, NULL, fname, ext);
1237 splitpath(readname, drive, dir, NULL, NULL);
1238 makepath(readname, drive, dir, fname, ext);
1239 */
1240 merge_pathnames(readname,browsename,2);
1241 browsing = TRUE;
1242 showfile = 0;
1243 if (askvideo)
1244 {
1245 stackscreen();/* save graphics image */
1246 *stacked = 1;
1247 }
1248 return(RESTORESTART);
1249 } /* otherwise fall through and turn off
1250 * browsing */
1251 case ESC:
1252 case 'l': /* turn it off */
1253 case 'L':
1254 browsing = FALSE;
1255 helpmode = oldhelpmode;
1256 break;
1257 case 's':
1258 browsing = FALSE;
1259 helpmode = oldhelpmode;
1260 savetodisk(savename);
1261 break;
1262 default: /* or no files found, leave the state of
1263 * browsing */
1264 break; /* alone */
1265 }
1266 }
1267 else
1268 {
1269 browsing = FALSE;
1270 buzzer(2); /* can't browse if zooming or diskvideo */
1271 }
1272 break;
1273 case 'b': /* make batch file */
1274 make_batch_file();
1275 break;
1276 case 16: /* print current image */
1277 note_zoom();
1278 Print_Screen();
1279 restore_zoom();
1280 if (!keypressed())
1281 buzzer(0);
1282 else
1283 {
1284 buzzer(1);
1285 getakey();
1286 }
1287 return(CONTINUE);
1288 case ENTER: /* Enter */
1289 case ENTER_2: /* Numeric-Keypad Enter */
1290 #ifdef XFRACT
1292 #endif
1293 if (zwidth != 0.0)
1294 { /* do a zoom */
1295 init_pan_or_recalc(0);
1296 *kbdmore = 0;
1297 }
1298 if (calc_status != 4) /* don't restart if image complete */
1299 *kbdmore = 0;
1300 break;
1301 case CTL_ENTER: /* control-Enter */
1302 case CTL_ENTER_2: /* Control-Keypad Enter */
1303 init_pan_or_recalc(1);
1304 *kbdmore = 0;
1305 zoomout(); /* calc corners for zooming out */
1306 break;
1307 case INSERT: /* insert */
1308 setvideotext(); /* force text mode */
1309 return(RESTART);
1310 case LEFT_ARROW: /* cursor left */
1311 case RIGHT_ARROW: /* cursor right */
1312 case UP_ARROW: /* cursor up */
1313 case DOWN_ARROW: /* cursor down */
1314 move_zoombox(*kbdchar);
1315 break;
1316 case LEFT_ARROW_2: /* Ctrl-cursor left */
1317 case RIGHT_ARROW_2: /* Ctrl-cursor right */
1318 case UP_ARROW_2: /* Ctrl-cursor up */
1319 case DOWN_ARROW_2: /* Ctrl-cursor down */
1320 move_zoombox(*kbdchar);
1321 break;
1322 case CTL_HOME: /* Ctrl-home */
1323 if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
1324 {
1325 i = key_count(CTL_HOME);
1326 if ((zskew -= 0.02 * i) < -0.48)
1327 zskew = -0.48;
1328 }
1329 break;
1330 case CTL_END: /* Ctrl-end */
1331 if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
1332 {
1333 i = key_count(CTL_END);
1334 if ((zskew += 0.02 * i) > 0.48)
1335 zskew = 0.48;
1336 }
1337 break;
1338 case CTL_PAGE_UP: /* Ctrl-pgup */
1339 if (boxcount)
1340 chgboxi(0, -2 * key_count(CTL_PAGE_UP));
1341 break;
1342 case CTL_PAGE_DOWN: /* Ctrl-pgdn */
1343 if (boxcount)
1344 chgboxi(0, 2 * key_count(CTL_PAGE_DOWN));
1345 break;
1346
1347 case PAGE_UP: /* page up */
1348 if (zoomoff == 1)
1349 {
1350 if (zwidth == 0)
1351 { /* start zoombox */
1352 zwidth = zdepth = 1;
1353 zskew = zrotate = 0;
1354 zbx = zby = 0;
1355 find_special_colors();
1356 boxcolor = color_bright;
1357 px = py = gridsz/2;
1358 moveboxf(0.0,0.0); /* force scrolling */
1359 }
1360 else
1361 resizebox(0 - key_count(PAGE_UP));
1362 }
1363 break;
1364 case PAGE_DOWN: /* page down */
1365 if (boxcount)
1366 {
1367 if (zwidth >= .999 && zdepth >= 0.999) /* end zoombox */
1368 zwidth = 0;
1369 else
1370 resizebox(key_count(PAGE_DOWN));
1371 }
1372 break;
1373 case CTL_MINUS: /* Ctrl-kpad- */
1374 if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
1375 zrotate += key_count(CTL_MINUS);
1376 break;
1377 case CTL_PLUS: /* Ctrl-kpad+ */
1378 if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
1379 zrotate -= key_count(CTL_PLUS);
1380 break;
1381 case CTL_INSERT: /* Ctrl-ins */
1382 boxcolor += key_count(CTL_INSERT);
1383 break;
1384 case CTL_DEL: /* Ctrl-del */
1385 boxcolor -= key_count(CTL_DEL);
1386 break;
1387
1388 case 1120: /* alt + number keys set mutation level and start evolution engine */
1389 case 1121:
1390 case 1122:
1391 case 1123:
1392 case 1124:
1393 case 1125:
1394 case 1126:
1395 /*
1396 case 1127:
1397 case 1128:
1398 */
1399 viewwindow = evolving = 1;
1400 set_mutation_level(*kbdchar-1119);
1401 param_history(0); /* save parameter history */
1402 *kbdmore = calc_status = 0;
1403 break;
1404
1405 case DELETE: /* select video mode from list */
1406 {
1407 stackscreen();
1408 *kbdchar = select_video_mode(adapter);
1409 if (check_vidmode_key(0, *kbdchar) >= 0) /* picked a new mode? */
1410 discardscreen();
1411 else
1412 unstackscreen();
1413 /* fall through */
1414 }
1415 default: /* other (maybe a valid Fn key) */
1416 if ((k = check_vidmode_key(0, *kbdchar)) >= 0)
1417 {
1418 adapter = k;
1419 /* if (videotable[adapter].dotmode != 11 Took out so that */
1420 /* || videotable[adapter].colors != colors) DAC is not reset */
1421 /* savedac = 0; when changing video modes */
1422 if (videotable[adapter].colors != colors)
1423 savedac = 0;
1424 calc_status = 0;
1425 *kbdmore = 0;
1426 return(CONTINUE);
1427 }
1428 break;
1429 } /* end of the big switch */
1430 return(0);
1431 }
1432
1433 int evolver_menu_switch(int *kbdchar, int *frommandel, int *kbdmore, char *stacked)
1434 {
1435 int i,k;
1436
1437 switch (*kbdchar)
1438 {
1439 case 't': /* new fractal type */
1440 julibrot = 0;
1441 clear_zoombox();
1442 stackscreen();
1443 if ((i = get_fracttype()) >= 0)
1444 {
1445 discardscreen();
1446 savedac = 0;
1447 save_release = release;
1448 no_mag_calc = 0;
1449 use_old_period = 0;
1450 bad_outside = 0;
1451 ldcheck = 0;
1452 set_current_params();
1453 odpx=odpy=newodpx=newodpy=0;
1454 fiddlefactor = 1; /* reset param evolution stuff */
1455 set_orbit_corners = 0;
1456 param_history(0); /* save history */
1457 if (i == 0)
1458 {
1459 initmode = adapter;
1460 *frommandel = 0;
1461 }
1462 else if (initmode < 0) /* it is supposed to be... */
1463 setvideotext(); /* reset to text mode */
1464 return(IMAGESTART);
1465 }
1466 unstackscreen();
1467 break;
1468 case 'x': /* invoke options screen */
1469 case 'y':
1470 case 'p': /* passes options */
1471 case 'z': /* type specific parms */
1472 case 'g':
1473 case 5:
1474 case SPACE:
1475 clear_zoombox();
1476 if (fromtext_flag == 1)
1477 fromtext_flag = 0;
1478 else
1479 stackscreen();
1480 if (*kbdchar == 'x')
1481 i = get_toggles();
1482 else if (*kbdchar == 'y')
1483 i = get_toggles2();
1484 else if (*kbdchar == 'p')
1485 i = passes_options();
1486 else if (*kbdchar == 'z')
1487 i = get_fract_params(1);
1488 else if (*kbdchar == 5 || *kbdchar == SPACE)
1489 i = get_evolve_Parms();
1490 else
1491 i = get_cmd_string();
1492 unstackscreen();
1493 if (evolving && truecolor)
1494 truecolor = 0; /* truecolor doesn't play well with the evolver */
1495 if (i > 0) { /* time to redraw? */
1496 param_history(0); /* save history */
1497 *kbdmore = calc_status = 0;
1498 }
1499 break;
1500 case 'b': /* quick exit from evolve mode */
1501 evolving = viewwindow = 0;
1502 param_history(0); /* save history */
1503 *kbdmore = calc_status = 0;
1504 break;
1505
1506 case 'f': /* floating pt toggle */
1507 if (usr_floatflag == 0)
1508 usr_floatflag = 1;
1509 else if (stdcalcmode != 'o') /* don't go there */
1510 usr_floatflag = 0;
1511 initmode = adapter;
1512 return(IMAGESTART);
1513 case '\\': /* return to prev image */
1514 case CTL_BACKSLASH:
1515 case 'h':
1516 case 8:
1517 if(maxhistory > 0 && bf_math == 0)
1518 {
1519 if(*kbdchar == '\\' || *kbdchar == 'h')
1520 if (--historyptr < 0)
1521 historyptr = maxhistory - 1;
1522 if(*kbdchar == CTL_BACKSLASH || *kbdchar == 8)
1523 if (++historyptr >= maxhistory)
1524 historyptr = 0;
1525 restore_history_info(historyptr);
1526 zoomoff = 1;
1527 initmode = adapter;
1528 if (curfractalspecific->isinteger != 0 &&
1529 curfractalspecific->tofloat != NOFRACTAL)
1530 usr_floatflag = 0;
1531 if (curfractalspecific->isinteger == 0 &&
1532 curfractalspecific->tofloat != NOFRACTAL)
1533 usr_floatflag = 1;
1534 historyflag = 1; /* avoid re-store parms due to rounding errs */
1535 return(IMAGESTART);
1536 }
1537 break;
1538 case 'c': /* switch to color cycling */
1539 case '+': /* rotate palette */
1540 case '-': /* rotate palette */
1541 clear_zoombox();
1542 memcpy(olddacbox, dacbox, 256 * 3);
1543 rotate((*kbdchar == 'c') ? 0 : ((*kbdchar == '+') ? 1 : -1));
1544 if (memcmp(olddacbox, dacbox, 256 * 3))
1545 {
1546 colorstate = 1;
1547 save_history_info();
1548 }
1549 return(CONTINUE);
1550 case 'e': /* switch to color editing */
1551 if (istruecolor && !initbatch) { /* don't enter palette editor */
1552 if (load_palette() >= 0) {
1553 *kbdmore = calc_status = 0;
1554 break;
1555 } else
1556 return(CONTINUE);
1557 }
1558 clear_zoombox();
1559 if (dacbox[0][0] != 255 && !reallyega && colors >= 16
1560 && dotmode != 11)
1561 {
1562 int oldhelpmode;
1563 oldhelpmode = helpmode;
1564 memcpy(olddacbox, dacbox, 256 * 3);
1565 helpmode = HELPXHAIR;
1566 EditPalette();
1567 helpmode = oldhelpmode;
1568 if (memcmp(olddacbox, dacbox, 256 * 3))
1569 {
1570 colorstate = 1;
1571 save_history_info();
1572 }
1573 }
1574 return(CONTINUE);
1575 case 's': /* save-to-disk */
1576 { int oldsxoffs, oldsyoffs, oldxdots, oldydots, oldpx, oldpy;
1577 GENEBASE gene[NUMGENES];
1578
1579 if (dotmode == 11 && disktarga == 1)
1580 return(CONTINUE); /* disk video and targa, nothing to save */
1581 /* get the gene array from far memory */
1582 MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle);
1583 oldsxoffs = sxoffs;
1584 oldsyoffs = syoffs;
1585 oldxdots = xdots;
1586 oldydots = ydots;
1587 oldpx = px;
1588 oldpy = py;
1589 sxoffs = syoffs = 0;
1590 xdots = sxdots;
1591 ydots = sydots; /* for full screen save and pointer move stuff */
1592 px = py = gridsz / 2;
1593 diskisactive = 1; /* flag for disk-video routines */
1594 param_history(1); /* restore old history */
1595 fiddleparms(gene, 0);
1596 drawparmbox(1);
1597 savetodisk(savename);
1598 px = oldpx;
1599 py = oldpy;
1600 param_history(1); /* restore old history */
1601 fiddleparms(gene, unspiralmap());
1602 diskisactive = 0; /* flag for disk-video routines */
1603 sxoffs = oldsxoffs;
1604 syoffs = oldsyoffs;
1605 xdots = oldxdots;
1606 ydots = oldydots;
1607 MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle);
1608 }
1609 return(CONTINUE);
1610 case 'r': /* restore-from */
1611 comparegif = 0;
1612 *frommandel = 0;
1613 if (browsing)
1614 {
1615 browsing = FALSE;
1616 }
1617 if (*kbdchar == 'r')
1618 {
1619 if (debugflag == 50)
1620 {
1621 comparegif = overlay3d = 1;
1622 if (initbatch == 2)
1623 {
1624 stackscreen(); /* save graphics image */
1625 strcpy(readname, savename);
1626 showfile = 0;
1627 return(RESTORESTART);
1628 }
1629 }
1630 else
1631 comparegif = overlay3d = 0;
1632 display3d = 0;
1633 }
1634 stackscreen(); /* save graphics image */
1635 if (overlay3d)
1636 *stacked = 0;
1637 else
1638 *stacked = 1;
1639 if (resave_flag)
1640 {
1641 updatesavename(savename); /* do the pending increment */
1642 resave_flag = started_resaves = 0;
1643 }
1644 showfile = -1;
1645 return(RESTORESTART);
1646 case ENTER: /* Enter */
1647 case ENTER_2: /* Numeric-Keypad Enter */
1648 #ifdef XFRACT
1650 #endif
1651 if (zwidth != 0.0)
1652 { /* do a zoom */
1653 init_pan_or_recalc(0);
1654 *kbdmore = 0;
1655 }
1656 if (calc_status != 4) /* don't restart if image complete */
1657 *kbdmore = 0;
1658 break;
1659 case CTL_ENTER: /* control-Enter */
1660 case CTL_ENTER_2: /* Control-Keypad Enter */
1661 init_pan_or_recalc(1);
1662 *kbdmore = 0;
1663 zoomout(); /* calc corners for zooming out */
1664 break;
1665 case INSERT: /* insert */
1666 setvideotext(); /* force text mode */
1667 return(RESTART);
1668 case LEFT_ARROW: /* cursor left */
1669 case RIGHT_ARROW: /* cursor right */
1670 case UP_ARROW: /* cursor up */
1671 case DOWN_ARROW: /* cursor down */
1672 move_zoombox(*kbdchar);
1673 break;
1674 case LEFT_ARROW_2: /* Ctrl-cursor left */
1675 case RIGHT_ARROW_2: /* Ctrl-cursor right */
1676 case UP_ARROW_2: /* Ctrl-cursor up */
1677 case DOWN_ARROW_2: /* Ctrl-cursor down */
1678 /* borrow ctrl cursor keys for moving selection box */
1679 /* in evolver mode */
1680 if (boxcount) {
1681 int grout;
1682 GENEBASE gene[NUMGENES];
1683 /* get the gene array from far memory */
1684 MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle);
1685 if (evolving&1) {
1686 if (*kbdchar == LEFT_ARROW_2) {
1687 px--;
1688 }
1689 if (*kbdchar == RIGHT_ARROW_2) {
1690 px++;
1691 }
1692 if (*kbdchar == UP_ARROW_2) {
1693 py--;
1694 }
1695 if (*kbdchar == DOWN_ARROW_2) {
1696 py++;
1697 }
1698 if (px <0 ) px = gridsz-1;
1699 if (px >(gridsz-1)) px = 0;
1700 if (py <0) py = gridsz-1;
1701 if (py > (gridsz-1)) py = 0;
1702 grout = !((evolving & NOGROUT)/NOGROUT) ;
1703 sxoffs = px * (int)(dxsize+1+grout);
1704 syoffs = py * (int)(dysize+1+grout);
1705
1706 param_history(1); /* restore old history */
1707 fiddleparms(gene, unspiralmap()); /* change all parameters */
1708 /* to values appropriate to the image selected */
1709 set_evolve_ranges();
1710 chgboxi(0,0);
1711 drawparmbox(0);
1712 }
1713 /* now put the gene array back in far memory */
1714 MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle);
1715 }
1716 else /* if no zoombox, scroll by arrows */
1717 move_zoombox(*kbdchar);
1718 break;
1719 case CTL_HOME: /* Ctrl-home */
1720 if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
1721 {
1722 i = key_count(CTL_HOME);
1723 if ((zskew -= 0.02 * i) < -0.48)
1724 zskew = -0.48;
1725 }
1726 break;
1727 case CTL_END: /* Ctrl-end */
1728 if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
1729 {
1730 i = key_count(CTL_END);
1731 if ((zskew += 0.02 * i) > 0.48)
1732 zskew = 0.48;
1733 }
1734 break;
1735 case CTL_PAGE_UP:
1736 if(prmboxcount) {
1737 parmzoom -= 1.0;
1738 if(parmzoom<1.0) parmzoom=1.0;
1739 drawparmbox(0);
1740 set_evolve_ranges();
1741 }
1742 break;
1743 case CTL_PAGE_DOWN:
1744 if(prmboxcount) {
1745 parmzoom += 1.0;
1746 if(parmzoom>(double)gridsz/2.0) parmzoom=(double)gridsz/2.0;
1747 drawparmbox(0);
1748 set_evolve_ranges();
1749 }
1750 break;
1751
1752 case PAGE_UP: /* page up */
1753 if (zoomoff == 1)
1754 {
1755 if (zwidth == 0)
1756 { /* start zoombox */
1757 zwidth = zdepth = 1;
1758 zskew = zrotate = 0;
1759 zbx = zby = 0;
1760 find_special_colors();
1761 boxcolor = color_bright;
1762 /*rb*/ if (evolving&1) {
1763 /* set screen view params back (previously changed to allow
1764 full screen saves in viewwindow mode) */
1765 int grout = !((evolving & NOGROUT) / NOGROUT);
1766 sxoffs = px * (int)(dxsize+1+grout);
1767 syoffs = py * (int)(dysize+1+grout);
1768 SetupParamBox();
1769 drawparmbox(0);
1770 }
1771 moveboxf(0.0,0.0); /* force scrolling */
1772 }
1773 else
1774 resizebox(0 - key_count(PAGE_UP));
1775 }
1776 break;
1777 case PAGE_DOWN: /* page down */
1778 if (boxcount)
1779 {
1780 if (zwidth >= .999 && zdepth >= 0.999) { /* end zoombox */
1781 zwidth = 0;
1782 if (evolving&1) {
1783 drawparmbox(1); /* clear boxes off screen */
1784 ReleaseParamBox();
1785 }
1786 }
1787 else
1788 resizebox(key_count(PAGE_DOWN));
1789 }
1790 break;
1791 case CTL_MINUS: /* Ctrl-kpad- */
1792 if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
1793 zrotate += key_count(CTL_MINUS);
1794 break;
1795 case CTL_PLUS: /* Ctrl-kpad+ */
1796 if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
1797 zrotate -= key_count(CTL_PLUS);
1798 break;
1799 case CTL_INSERT: /* Ctrl-ins */
1800 boxcolor += key_count(CTL_INSERT);
1801 break;
1802 case CTL_DEL: /* Ctrl-del */
1803 boxcolor -= key_count(CTL_DEL);
1804 break;
1805
1806 /* grabbed a couple of video mode keys, user can change to these using
1807 delete and the menu if necessary */
1808
1809 case F2: /* halve mutation params and regen */
1810 fiddlefactor = fiddlefactor / 2;
1811 paramrangex = paramrangex / 2;
1812 newopx = opx + paramrangex / 2;
1813 paramrangey = paramrangey / 2;
1814 newopy = opy + paramrangey / 2;
1815 *kbdmore = calc_status = 0;
1816 break;
1817
1818 case F3: /*double mutation parameters and regenerate */
1819 {
1820 double centerx, centery;
1821 fiddlefactor = fiddlefactor * 2;
1822 centerx = opx + paramrangex / 2;
1823 paramrangex = paramrangex * 2;
1824 newopx = centerx - paramrangex / 2;
1825 centery = opy + paramrangey / 2;
1826 paramrangey = paramrangey * 2;
1827 newopy = centery - paramrangey / 2;
1828 *kbdmore = calc_status = 0;
1829 break;
1830 }
1831
1832 case F4: /*decrement gridsize and regen */
1833 if (gridsz > 3) {
1834 gridsz = gridsz - 2; /* gridsz must have odd value only */
1835 *kbdmore = calc_status = 0;
1836 }
1837 break;
1838
1839 case F5: /* increment gridsize and regen */
1840 if (gridsz < (sxdots / (MINPIXELS<<1))) {
1841 gridsz = gridsz + 2;
1842 *kbdmore = calc_status = 0;
1843 }
1844 break;
1845
1846 case F6: /* toggle all variables selected for random variation to
1847 center weighted variation and vice versa */
1848 {
1849 int i;
1850 GENEBASE gene[NUMGENES];
1851 /* get the gene array from far memory */
1852 MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle);
1853 for (i =0;i < NUMGENES; i++) {
1854 if (gene[i].mutate == 5) {
1855 gene[i].mutate = 6;
1856 continue;
1857 }
1858 if (gene[i].mutate == 6) gene[i].mutate = 5;
1859 }
1860 /* now put the gene array back in far memory */
1861 MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle);
1862 }
1863 *kbdmore = calc_status = 0;
1864 break;
1865
1866 case 1120: /* alt + number keys set mutation level */
1867 case 1121:
1868 case 1122:
1869 case 1123:
1870 case 1124:
1871 case 1125:
1872 case 1126:
1873 /*
1874 case 1127:
1875 case 1128:
1876 */
1877 set_mutation_level(*kbdchar-1119);
1878 param_history(1); /* restore old history */
1879 *kbdmore = calc_status = 0;
1880 break;
1881
1882 case '1':
1883 case '2':
1884 case '3':
1885 case '4':
1886 case '5':
1887 case '6':
1888 case '7':
1889 /* add these in when more parameters can be varied
1890 case '8':
1891 case '9':
1892 */
1893 set_mutation_level(*kbdchar-(int)'0');
1894 param_history(1); /* restore old history */
1895 *kbdmore = calc_status = 0;
1896 break;
1897 case '0': /* mutation level 0 == turn off evolving */
1898 evolving = viewwindow = 0;
1899 *kbdmore = calc_status = 0;
1900 break;
1901
1902 case DELETE: /* select video mode from list */
1903 stackscreen();
1904 *kbdchar = select_video_mode(adapter);
1905 if (check_vidmode_key(0, *kbdchar) >= 0) /* picked a new mode? */
1906 discardscreen();
1907 else
1908 unstackscreen();
1909 /* fall through */
1910 default: /* other (maybe valid Fn key */
1911 if ((k = check_vidmode_key(0, *kbdchar)) >= 0)
1912 {
1913 adapter = k;
1914 if (videotable[adapter].colors != colors)
1915 savedac = 0;
1916 calc_status = 0;
1917 *kbdmore = 0;
1918 return(CONTINUE);
1919 }
1920 break;
1921 } /* end of the big evolver switch */
1922 return(0);
1923 }
1924
1925 static int call_line3d(BYTE *pixels, int linelen)
1926 {
1927 /* this routine exists because line3d might be in an overlay */
1928 return(line3d(pixels,linelen));
1929 }
1930
1931 static void note_zoom()
1932 {
1933 if (boxcount) { /* save zoombox stuff in far mem before encode (mem reused) */
1934 if ((savezoom = (char far *)farmemalloc((long)(5*boxcount))) == NULL)
1935 clear_zoombox(); /* not enuf mem so clear the box */
1936 else {
1937 reset_zoom_corners(); /* reset these to overall image, not box */
1938 far_memcpy(savezoom,boxx,boxcount*2);
1939 far_memcpy(savezoom+boxcount*2,boxy,boxcount*2);
1940 far_memcpy(savezoom+boxcount*4,boxvalues,boxcount);
1941 }
1942 }
1943 }
1944
1945 static void restore_zoom()
1946 {
1947 if (boxcount) { /* restore zoombox arrays */
1948 far_memcpy(boxx,savezoom,boxcount*2);
1949 far_memcpy(boxy,savezoom+boxcount*2,boxcount*2);
1950 far_memcpy(boxvalues,savezoom+boxcount*4,boxcount);
1951 farmemfree(savezoom);
1952 drawbox(1); /* get the xxmin etc variables recalc'd by redisplaying */
1953 }
1954 }
1955
1956 /* do all pending movement at once for smooth mouse diagonal moves */
1957 static void move_zoombox(int keynum)
1958 { int vertical, horizontal, getmore;
1959 vertical = horizontal = 0;
1960 getmore = 1;
1961 while (getmore) {
1962 switch (keynum) {
1963 case LEFT_ARROW: /* cursor left */
1964 --horizontal;
1965 break;
1966 case RIGHT_ARROW: /* cursor right */
1967 ++horizontal;
1968 break;
1969 case UP_ARROW: /* cursor up */
1970 --vertical;
1971 break;
1972 case DOWN_ARROW: /* cursor down */
1973 ++vertical;
1974 break;
1975 case LEFT_ARROW_2: /* Ctrl-cursor left */
1976 horizontal -= 8;
1977 break;
1978 case RIGHT_ARROW_2: /* Ctrl-cursor right */
1979 horizontal += 8;
1980 break;
1981 case UP_ARROW_2: /* Ctrl-cursor up */
1982 vertical -= 8;
1983 break;
1984 case DOWN_ARROW_2: /* Ctrl-cursor down */
1985 vertical += 8;
1986 break; /* += 8 needed by VESA scrolling */
1987 default:
1988 getmore = 0;
1989 }
1990 if (getmore) {
1991 if (getmore == 2) /* eat last key used */
1992 getakey();
1993 getmore = 2;
1994 keynum = keypressed(); /* next pending key */
1995 }
1996 }
1997 if (boxcount) {
1998 /*
1999 if (horizontal != 0)
2000 moveboxf((double)horizontal/dxsize,0.0);
2001 if (vertical != 0)
2002 moveboxf(0.0,(double)vertical/dysize);
2003 */
2004 moveboxf((double)horizontal/dxsize,(double)vertical/dysize);
2005 }
2006 #ifndef XFRACT
2007 else /* if no zoombox, scroll by arrows */
2008 scroll_relative(horizontal,vertical);
2009 #endif
2010 }
2011
2012 /* displays differences between current image file and new image */
2013 static FILE *cmp_fp;
2014 static int errcount;
2015 int cmp_line(BYTE *pixels, int linelen)
2016 {
2017 int row,col;
2018 int oldcolor;
2019 if((row = rowcount++) == 0) {
2020 errcount = 0;
2021 cmp_fp = dir_fopen(workdir,"cmperr",(initbatch)?"a":"w");
2022 outln_cleanup = cmp_line_cleanup;
2023 }
2024 if(pot16bit) { /* 16 bit info, ignore odd numbered rows */
2025 if((row & 1) != 0) return(0);
2026 row >>= 1;
2027 }
2028 for(col=0;col<linelen;col++) {
2029 oldcolor=getcolor(col,row);
2030 if(oldcolor==(int)pixels[col])
2031 putcolor(col,row,0);
2032 else {
2033 if(oldcolor==0)
2034 putcolor(col,row,1);
2035 ++errcount;
2036 if(initbatch == 0)
2037 fprintf(cmp_fp,"#%5d col %3d row %3d old %3d new %3d\n",
2038 errcount,col,row,oldcolor,pixels[col]);
2039 }
2040 }
2041 return(0);
2042 }
2043
2044 static void cmp_line_cleanup(void)
2045 {
2046 char *timestring;
2047 time_t ltime;
2048 if(initbatch) {
2049 time(<ime);
2050 timestring = ctime(<ime);
2051 timestring[24] = 0; /*clobber newline in time string */
2052 fprintf(cmp_fp,"%s compare to %s has %5d errs\n",
2053 timestring,readname,errcount);
2054 }
2055 fclose(cmp_fp);
2056 }
2057
2058 void clear_zoombox()
2059 {
2060 zwidth = 0;
2061 drawbox(0);
2062 reset_zoom_corners();
2063 }
2064
2065 void reset_zoom_corners()
2066 {
2067 xxmin = sxmin;
2068 xxmax = sxmax;
2069 xx3rd = sx3rd;
2070 yymax = symax;
2071 yymin = symin;
2072 yy3rd = sy3rd;
2073 if(bf_math)
2074 {
2075 copy_bf(bfxmin,bfsxmin);
2076 copy_bf(bfxmax,bfsxmax);
2077 copy_bf(bfymin,bfsymin);
2078 copy_bf(bfymax,bfsymax);
2079 copy_bf(bfx3rd,bfsx3rd);
2080 copy_bf(bfy3rd,bfsy3rd);
2081 }
2082 }
2083
2084 /*
2085 Function setup287code is called by main() when a 287
2086 or better fpu is detected.
2087 */
2088 #define ORBPTR(x) fractalspecific[x].orbitcalc
2089 void setup287code()
2090 {
2091 ORBPTR(MANDELFP) = ORBPTR(JULIAFP) = FJuliafpFractal;
2092 ORBPTR(BARNSLEYM1FP) = ORBPTR(BARNSLEYJ1FP) = FBarnsley1FPFractal;
2093 ORBPTR(BARNSLEYM2FP) = ORBPTR(BARNSLEYJ2FP) = FBarnsley2FPFractal;
2094 ORBPTR(MANOWARFP) = ORBPTR(MANOWARJFP) = FManOWarfpFractal;
2095 ORBPTR(MANDELLAMBDAFP) = ORBPTR(LAMBDAFP) = FLambdaFPFractal;
2096 }
2097
2098 /* read keystrokes while = specified key, return 1+count; */
2099 /* used to catch up when moving zoombox is slower than keyboard */
2100 int key_count(int keynum)
2101 { int ctr;
2102 ctr = 1;
2103 while (keypressed() == keynum) {
2104 getakey();
2105 ++ctr;
2106 }
2107 return ctr;
2108 }
2109
2110 static void _fastcall save_history_info()
2111 {
2112 HISTORY current,last;
2113 if(maxhistory <= 0 || bf_math || history == 0)
2114 return;
2115 MoveFromMemory((BYTE far *)&last,(U16)sizeof(HISTORY),1L,(long)saveptr,history);
2116
2117 far_memset((void far *)¤t,0,sizeof(HISTORY));
2118 current.fractal_type = (short)fractype ;
2119 current.xmin = xxmin ;
2120 current.xmax = xxmax ;
2121 current.ymin = yymin ;
2122 current.ymax = yymax ;
2123 current.creal = param[0] ;
2124 current.cimag = param[1] ;
2125 current.dparm3 = param[2] ;
2126 current.dparm4 = param[3] ;
2127 current.dparm5 = param[4] ;
2128 current.dparm6 = param[5] ;
2129 current.dparm7 = param[6] ;
2130 current.dparm8 = param[7] ;
2131 current.dparm9 = param[8] ;
2132 current.dparm10 = param[9] ;
2133 current.fillcolor = (short)fillcolor ;
2134 current.potential[0] = potparam[0] ;
2135 current.potential[1] = potparam[1] ;
2136 current.potential[2] = potparam[2] ;
2137 current.rflag = (short)rflag ;
2138 current.rseed = (short)rseed ;
2139 current.inside = (short)inside ;
2140 current.logmap = LogFlag ;
2141 current.invert[0] = inversion[0] ;
2142 current.invert[1] = inversion[1] ;
2143 current.invert[2] = inversion[2] ;
2144 current.decomp = (short)decomp[0]; ;
2145 current.biomorph = (short)biomorph ;
2146 current.symmetry = (short)forcesymmetry ;
2147 current.init3d[0] = (short)init3d[0] ;
2148 current.init3d[1] = (short)init3d[1] ;
2149 current.init3d[2] = (short)init3d[2] ;
2150 current.init3d[3] = (short)init3d[3] ;
2151 current.init3d[4] = (short)init3d[4] ;
2152 current.init3d[5] = (short)init3d[5] ;
2153 current.init3d[6] = (short)init3d[6] ;
2154 current.init3d[7] = (short)init3d[7] ;
2155 current.init3d[8] = (short)init3d[8] ;
2156 current.init3d[9] = (short)init3d[9] ;
2157 current.init3d[10] = (short)init3d[10] ;
2158 current.init3d[11] = (short)init3d[12] ;
2159 current.init3d[12] = (short)init3d[13] ;
2160 current.init3d[13] = (short)init3d[14] ;
2161 current.init3d[14] = (short)init3d[15] ;
2162 current.init3d[15] = (short)init3d[16] ;
2163 current.previewfactor = (short)previewfactor ;
2164 current.xtrans = (short)xtrans ;
2165 current.ytrans = (short)ytrans ;
2166 current.red_crop_left = (short)red_crop_left ;
2167 current.red_crop_right = (short)red_crop_right ;
2168 current.blue_crop_left = (short)blue_crop_left ;
2169 current.blue_crop_right = (short)blue_crop_right ;
2170 current.red_bright = (short)red_bright ;
2171 current.blue_bright = (short)blue_bright ;
2172 current.xadjust = (short)xadjust ;
2173 current.yadjust = (short)yadjust ;
2174 current.eyeseparation = (short)eyeseparation ;
2175 current.glassestype = (short)glassestype ;
2176 current.outside = (short)outside ;
2177 current.x3rd = xx3rd ;
2178 current.y3rd = yy3rd ;
2179 current.stdcalcmode = usr_stdcalcmode ;
2180 current.three_pass = three_pass ;
2181 current.stoppass = (short)stoppass;
2182 current.distest = distest ;
2183 current.trigndx[0] = trigndx[0] ;
2184 current.trigndx[1] = trigndx[1] ;
2185 current.trigndx[2] = trigndx[2] ;
2186 current.trigndx[3] = trigndx[3] ;
2187 current.finattract = (short)finattract ;
2188 current.initorbit[0] = initorbit.x ;
2189 current.initorbit[1] = initorbit.y ;
2190 current.useinitorbit = useinitorbit ;
2191 current.periodicity = (short)periodicitycheck ;
2192 current.pot16bit = (short)disk16bit ;
2193 current.release = (short)release ;
2194 current.save_release = (short)save_release ;
2195 current.flag3d = (short)display3d ;
2196 current.ambient = (short)Ambient ;
2197 current.randomize = (short)RANDOMIZE ;
2198 current.haze = (short)haze ;
2199 current.transparent[0] = (short)transparent[0] ;
2200 current.transparent[1] = (short)transparent[1] ;
2201 current.rotate_lo = (short)rotate_lo ;
2202 current.rotate_hi = (short)rotate_hi ;
2203 current.distestwidth = (short)distestwidth ;
2204 current.mxmaxfp = mxmaxfp ;
2205 current.mxminfp = mxminfp ;
2206 current.mymaxfp = mymaxfp ;
2207 current.myminfp = myminfp ;
2208 current.zdots = (short)zdots ;
2209 current.originfp = originfp ;
2210 current.depthfp = depthfp ;
2211 current.heightfp = heightfp ;
2212 current.widthfp = widthfp ;
2213 current.distfp = distfp ;
2214 current.eyesfp = eyesfp ;
2215 current.orbittype = (short)neworbittype ;
2216 current.juli3Dmode = (short)juli3Dmode ;
2217 current.maxfn = maxfn ;
2218 current.major_method = (short)major_method ;
2219 current.minor_method = (short)minor_method ;
2220 current.bailout = bailout ;
2221 current.bailoutest = (short)bailoutest ;
2222 current.iterations = maxit ;
2223 current.old_demm_colors = (short)old_demm_colors;
2224 current.logcalc = (short)Log_Fly_Calc;
2225 current.ismand = (short)ismand;
2226 current.closeprox = closeprox;
2227 current.nobof = (short)nobof;
2228 current.orbit_delay = (short)orbit_delay;
2229 current.orbit_interval = orbit_interval;
2230 current.oxmin = oxmin;
2231 current.oxmax = oxmax;
2232 current.oymin = oymin;
2233 current.oymax = oymax;
2234 current.ox3rd = ox3rd;
2235 current.oy3rd = oy3rd;
2236 current.keep_scrn_coords= (short)keep_scrn_coords;
2237 current.drawmode = drawmode;
2238 far_memcpy(current.dac,dacbox,256*3);
2239 switch(fractype)
2240 {
2241 case FORMULA:
2242 case FFORMULA:
2243 far_strncpy(current.filename,FormFileName,FILE_MAX_PATH);
2244 far_strncpy(current.itemname,FormName,ITEMNAMELEN+1);
2245 break;
2246 case IFS:
2247 case IFS3D:
2248 far_strncpy(current.filename,IFSFileName,FILE_MAX_PATH);
2249 far_strncpy(current.itemname,IFSName,ITEMNAMELEN+1);
2250 break;
2251 case LSYSTEM:
2252 far_strncpy(current.filename,LFileName,FILE_MAX_PATH);
2253 far_strncpy(current.itemname,LName,ITEMNAMELEN+1);
2254 break;
2255 default:
2256 *(current.filename) = 0;
2257 *(current.itemname) = 0;
2258 break;
2259 }
2260 if (historyptr == -1) /* initialize the history file */
2261 {
2262 int i;
2263 for (i = 0; i < maxhistory; i++)
2264 MoveToMemory((BYTE far *)¤t,(U16)sizeof(HISTORY),1L,(long)i,history);
2265 historyflag = saveptr = historyptr = 0; /* initialize history ptr */
2266 }
2267 else if(historyflag == 1)
2268 historyflag = 0; /* coming from user history command, don't save */
2269 else if(far_memcmp(¤t,&last,sizeof(HISTORY)))
2270 {
2271 if(++saveptr >= maxhistory) /* back to beginning of circular buffer */
2272 saveptr = 0;
2273 if(++historyptr >= maxhistory) /* move user pointer in parallel */
2274 historyptr = 0;
2275 MoveToMemory((BYTE far *)¤t,(U16)sizeof(HISTORY),1L,(long)saveptr,history);
2276 }
2277 }
2278
2279 static void _fastcall restore_history_info(int i)
2280 {
2281 HISTORY last;
2282 if(maxhistory <= 0 || bf_math || history == 0)
2283 return;
2284 MoveFromMemory((BYTE far *)&last,(U16)sizeof(HISTORY),1L,(long)i,history);
2285 invert = 0;
2286 calc_status = 0;
2287 resuming = 0;
2288 fractype = last.fractal_type ;
2289 xxmin = last.xmin ;
2290 xxmax = last.xmax ;
2291 yymin = last.ymin ;
2292 yymax = last.ymax ;
2293 param[0] = last.creal ;
2294 param[1] = last.cimag ;
2295 param[2] = last.dparm3 ;
2296 param[3] = last.dparm4 ;
2297 param[4] = last.dparm5 ;
2298 param[5] = last.dparm6 ;
2299 param[6] = last.dparm7 ;
2300 param[7] = last.dparm8 ;
2301 param[8] = last.dparm9 ;
2302 param[9] = last.dparm10 ;
2303 fillcolor = last.fillcolor ;
2304 potparam[0] = last.potential[0] ;
2305 potparam[1] = last.potential[1] ;
2306 potparam[2] = last.potential[2] ;
2307 rflag = last.rflag ;
2308 rseed = last.rseed ;
2309 inside = last.inside ;
2310 LogFlag = last.logmap ;
2311 inversion[0] = last.invert[0] ;
2312 inversion[1] = last.invert[1] ;
2313 inversion[2] = last.invert[2] ;
2314 decomp[0] = last.decomp ;
2315 usr_biomorph = last.biomorph ;
2316 biomorph = last.biomorph ;
2317 forcesymmetry = last.symmetry ;
2318 init3d[0] = last.init3d[0] ;
2319 init3d[1] = last.init3d[1] ;
2320 init3d[2] = last.init3d[2] ;
2321 init3d[3] = last.init3d[3] ;
2322 init3d[4] = last.init3d[4] ;
2323 init3d[5] = last.init3d[5] ;
2324 init3d[6] = last.init3d[6] ;
2325 init3d[7] = last.init3d[7] ;
2326 init3d[8] = last.init3d[8] ;
2327 init3d[9] = last.init3d[9] ;
2328 init3d[10] = last.init3d[10] ;
2329 init3d[12] = last.init3d[11] ;
2330 init3d[13] = last.init3d[12] ;
2331 init3d[14] = last.init3d[13] ;
2332 init3d[15] = last.init3d[14] ;
2333 init3d[16] = last.init3d[15] ;
2334 previewfactor = last.previewfactor ;
2335 xtrans = last.xtrans ;
2336 ytrans = last.ytrans ;
2337 red_crop_left = last.red_crop_left ;
2338 red_crop_right = last.red_crop_right ;
2339 blue_crop_left = last.blue_crop_left ;
2340 blue_crop_right = last.blue_crop_right;
2341 red_bright = last.red_bright ;
2342 blue_bright = last.blue_bright ;
2343 xadjust = last.xadjust ;
2344 yadjust = last.yadjust ;
2345 eyeseparation = last.eyeseparation ;
2346 glassestype = last.glassestype ;
2347 outside = last.outside ;
2348 xx3rd = last.x3rd ;
2349 yy3rd = last.y3rd ;
2350 usr_stdcalcmode = last.stdcalcmode ;
2351 stdcalcmode = last.stdcalcmode ;
2352 three_pass = last.three_pass ;
2353 stoppass = last.stoppass ;
2354 distest = last.distest ;
2355 usr_distest = last.distest ;
2356 trigndx[0] = last.trigndx[0] ;
2357 trigndx[1] = last.trigndx[1] ;
2358 trigndx[2] = last.trigndx[2] ;
2359 trigndx[3] = last.trigndx[3] ;
2360 finattract = last.finattract ;
2361 initorbit.x = last.initorbit[0] ;
2362 initorbit.y = last.initorbit[1] ;
2363 useinitorbit = last.useinitorbit ;
2364 periodicitycheck = last.periodicity ;
2365 usr_periodicitycheck = last.periodicity ;
2366 disk16bit = last.pot16bit ;
2367 release = last.release ;
2368 save_release = last.save_release ;
2369 display3d = last.flag3d ;
2370 Ambient = last.ambient ;
2371 RANDOMIZE = last.randomize ;
2372 haze = last.haze ;
2373 transparent[0] = last.transparent[0] ;
2374 transparent[1] = last.transparent[1] ;
2375 rotate_lo = last.rotate_lo ;
2376 rotate_hi = last.rotate_hi ;
2377 distestwidth = last.distestwidth ;
2378 mxmaxfp = last.mxmaxfp ;
2379 mxminfp = last.mxminfp ;
2380 mymaxfp = last.mymaxfp ;
2381 myminfp = last.myminfp ;
2382 zdots = last.zdots ;
2383 originfp = last.originfp ;
2384 depthfp = last.depthfp ;
2385 heightfp = last.heightfp ;
2386 widthfp = last.widthfp ;
2387 distfp = last.distfp ;
2388 eyesfp = last.eyesfp ;
2389 neworbittype = last.orbittype ;
2390 juli3Dmode = last.juli3Dmode ;
2391 maxfn = last.maxfn ;
2392 major_method = (enum Major)last.major_method ;
2393 minor_method = (enum Minor)last.minor_method ;
2394 bailout = last.bailout ;
2395 bailoutest = (enum bailouts)last.bailoutest ;
2396 maxit = last.iterations ;
2397 old_demm_colors = last.old_demm_colors;
2398 curfractalspecific = &fractalspecific[fractype];
2399 potflag = (potparam[0] != 0.0);
2400 if (inversion[0] != 0.0)
2401 invert = 3;
2402 Log_Fly_Calc = last.logcalc;
2403 ismand = last.ismand;
2404 closeprox = last.closeprox;
2405 nobof = last.nobof;
2406 orbit_delay = last.orbit_delay;
2407 orbit_interval = last.orbit_interval;
2408 oxmin = last.oxmin;
2409 oxmax = last.oxmax;
2410 oymin = last.oymin;
2411 oymax = last.oymax;
2412 ox3rd = last.ox3rd;
2413 oy3rd = last.oy3rd;
2414 keep_scrn_coords = last.keep_scrn_coords;
2415 if (keep_scrn_coords) set_orbit_corners = 1;
2416 drawmode = last.drawmode;
2417 usr_floatflag = (char)((curfractalspecific->isinteger) ? 0 : 1);
2418 far_memcpy(dacbox,last.dac,256*3);
2419 far_memcpy(olddacbox,last.dac,256*3);
2420 if(mapdacbox)
2421 far_memcpy(mapdacbox,last.dac,256*3);
2422 spindac(0,1);
2423 if(fractype == JULIBROT || fractype == JULIBROTFP)
2424 savedac = 0;
2425 else
2426 savedac = 1;
2427 switch(fractype)
2428 {
2429 case FORMULA:
2430 case FFORMULA:
2431 far_strncpy(FormFileName,last.filename,FILE_MAX_PATH);
2432 far_strncpy(FormName, last.itemname,ITEMNAMELEN+1);
2433 break;
2434 case IFS:
2435 case IFS3D:
2436 far_strncpy(IFSFileName,last.filename,FILE_MAX_PATH);
2437 far_strncpy(IFSName ,last.itemname,ITEMNAMELEN+1);
2438 break;
2439 case LSYSTEM:
2440 far_strncpy(LFileName,last.filename,FILE_MAX_PATH);
2441 far_strncpy(LName ,last.itemname,ITEMNAMELEN+1);
2442 break;
2443 default:
2444 break;
2445 }
2446 }
2447
2448 void checkfreemem(int secondpass)
2449 {
2450 int oldmaxhistory;
2451 char far *tmp;
2452 static FCODE msg[] =
2453 {" I'm sorry, but you don't have enough free memory \n to run this program.\n\n"};
2454 static FCODE msg2[] = {"To save memory, reduced maxhistory to "};
2455 tmp = (char far *)farmemalloc(4096L);
2456 oldmaxhistory = maxhistory;
2457 if(secondpass && !history)
2458 {
2459 while(maxhistory > 0) /* decrease history if necessary */
2460 {
2461 history = MemoryAlloc((U16)sizeof(HISTORY),(long)maxhistory,EXPANDED);
2462 if(history)
2463 break;
2464 maxhistory--;
2465 }
2466 }
2467 if(extraseg == 0 || tmp == NULL)
2468 {
2469 buzzer(2);
2470 #ifndef XFRACT
2471 printf("%Fs",(char far *)msg);
2474 #endif
2475 exit(1);
2476 }
2477 farmemfree(tmp); /* was just to check for min space */
2478 if(secondpass && (maxhistory < oldmaxhistory || (history == 0 && oldmaxhistory != 0)))
2479 {
2480 #ifndef XFRACT
2481 printf("%Fs%d\n%Fs\n",(char far *)msg2,maxhistory,s_pressanykeytocontinue);
2484 #endif
2485 getakey();
2486 }
2487 }
2488
2489