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