home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / fractint / fras1611.zip / FRACTINT.C < prev    next >
Text File  |  1991-07-08  |  45KB  |  1,355 lines

  1. /*
  2.     FRACTINT - The Ultimate Fractal Generator
  3.             Main Routine
  4. */
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <time.h>
  10. #include <dos.h>
  11.  
  12. /* routines in this module    */
  13.  
  14. void main(int argc, char *argv[]);
  15. int  key_count(int);
  16. int  cmp_line(),pot_line();
  17. void reset_zoom_corners();
  18. static void cmp_line_cleanup();
  19. static void move_zoombox(int);
  20. static int  call_line3d();
  21. static void clear_zoombox();
  22. static void note_zoom();
  23. static void restore_zoom();
  24. static void setup287code();
  25.  
  26. #define PUTTHEMHERE 1        /* stuff common external arrays here */
  27.  
  28. #include "fractint.h"
  29. #include "mpmath.h"
  30. #include "fractype.h"
  31. #include "helpdefs.h"
  32.  
  33. int    adapter;        /* Video Adapter chosen from list in ...h */
  34.  
  35. extern char gifmask[];
  36. extern int TPlusErr;
  37.  
  38. extern int Transparent3D, far NewTPFractal, tpdepth;
  39. extern char far *TrueColorAutoDetect(void);
  40. extern int AntiAliasing, Shadowing;
  41. extern int pot16bit;        /* save 16 bit values for continuous potential */
  42. extern int disk16bit;        /* disk video up & running with 16 bit values */
  43. extern int video_type;        /* coded value indicating video adapter type */
  44. extern int tgaview();
  45. extern int gifview();
  46. extern void moveboxf(double,double);
  47. extern void chgboxi(int,int);
  48. extern int usr_biomorph;
  49. extern int forcesymmetry;
  50. extern    char    readname[];    /* name of fractal input file */
  51. extern    int    showfile;    /* zero if display of file is pending */
  52. #define MAXHISTORY    25    /* save this many historical rcds */
  53. struct historystruct {        /* history structure */
  54.     int fractype;        /* fractal type */
  55.     double param[2];    /* parameters */
  56.     double xxmin;        /* top left    */
  57.     double yymax;        /* top left    */
  58.     double xxmax;        /* bottom right */
  59.     double yymin;        /* bottom right */
  60.     double xx3rd;        /* bottom left    */
  61.     double yy3rd;        /* bottom left    */
  62.     } far *history;
  63.  
  64. #ifdef __TURBOC__
  65.  
  66. /* yes, I *know* it's supposed to be compatible with Microsoft C,
  67.    but some of the routines need to know if the "C" code
  68.    has been compiled with Turbo-C.  This flag is a 1 if FRACTINT.C
  69.    (and presumably the other routines as well) has been compiled
  70.    with Turbo-C. */
  71. int compiled_by_turboc = 1;
  72.  
  73. /* set size to be used for overlays, a bit bigger than largest (help) */
  74. unsigned _ovrbuffer = 50 * 64; /* that's 50k for overlays, counted in paragraphs */
  75.  
  76. #else
  77.  
  78. int compiled_by_turboc = 0;
  79.  
  80. #endif
  81.  
  82. extern char savename[];     /* save files using this name */
  83. extern char preview;        /* 3D preview mode flag */
  84. extern char temp1[];        /* temporary strings        */
  85. extern int  debugflag;        /* internal use only - you didn't see this */
  86.  
  87. /*
  88.    the following variables are out here only so
  89.    that the calcfract() and assembler routines can get at them easily
  90. */
  91.     int    active_system = 0;    /* 0 for DOS, WINFRAC for Windows */
  92.     int    dotmode;        /* video access method        */
  93.     int    textsafe2;        /* textsafe override from videotable */
  94.     int    oktoprint;        /* 0 if printf() won't work */
  95.     int    sxdots,sydots;        /* # of dots on the physical screen    */
  96.     int    sxoffs,syoffs;        /* physical top left of logical screen */
  97.     int    xdots, ydots;        /* # of dots on the logical screen     */
  98.     double    dxsize, dysize;     /* xdots-1, ydots-1        */
  99.     int    colors;         /* maximum colors available */
  100.     int    maxit;            /* try this many iterations */
  101.     int    boxcount;        /* 0 if no zoom-box yet     */
  102.     int    zrotate;        /* zoombox rotation        */
  103.     double    zbx,zby;        /* topleft of zoombox        */
  104.     double    zwidth,zdepth,zskew;    /* zoombox size & shape     */
  105.  
  106.     int    fractype;        /* if == 0, use Mandelbrot  */
  107.     char    stdcalcmode;        /* '1', '2', 'g', 'b'       */
  108.     long    creal, cimag;        /* real, imag'ry parts of C */
  109.     long    delx, dely;        /* screen pixel increments  */
  110.     long    delx2, dely2;        /* screen pixel increments  */
  111.     double    delxx, delyy;        /* screen pixel increments  */
  112.     double    delxx2, delyy2;     /* screen pixel increments  */
  113.     long    delmin;         /* for calcfrac/calcmand    */
  114.     double    ddelmin;        /* same as a double        */
  115.     double    param[4];        /* up to four parameters    */
  116.     double    potparam[3];        /* three potential parameters*/
  117.     long    fudge;            /* 2**fudgefactor        */
  118.     int    bitshift;        /* fudgefactor            */
  119.  
  120.     int    badconfig = 0;        /* 'fractint.cfg' ok?       */
  121.     int    diskisactive;        /* disk-video drivers flag  */
  122.     int    diskvideo;        /* disk-video access flag   */
  123.  
  124.     /* note that integer grid is set when integerfractal && !invert;    */
  125.     /* otherwise the floating point grid is set; never both at once     */
  126.     long    far *lx0, far *ly0;    /* x, y grid            */
  127.     long    far *lx1, far *ly1;    /* adjustment for rotate    */
  128.     /* note that lx1 & ly1 values can overflow into sign bit; since     */
  129.     /* they're used only to add to lx0/ly0, 2s comp straightens it out  */
  130.     double far *dx0, far *dy0;    /* floating pt equivs */
  131.     double far *dx1, far *dy1;
  132.     int    integerfractal;     /* TRUE if fractal uses integer math */
  133.  
  134.     /* usr_xxx is what the user wants, vs what we may be forced to do */
  135.     char    usr_stdcalcmode;
  136.     int    usr_periodicitycheck;
  137.     int    usr_distest;
  138.     char    usr_floatflag;
  139.  
  140.     int    viewwindow;        /* 0 for full screen, 1 for window */
  141.     float    viewreduction;        /* window auto-sizing */
  142.     int    viewcrop;        /* nonzero to crop default coords */
  143.     float    finalaspectratio;    /* for view shape and rotation */
  144.     int    viewxdots,viewydots;    /* explicit view sizing */
  145. extern    int    inside;         /* inside color: 1=blue     */
  146. extern    int    outside;        /* outside color, if set    */
  147. extern    int    cyclelimit;        /* color-rotator upper limit */
  148. extern    int    display3d;        /* 3D display flag: 0 = OFF */
  149. extern    int    overlay3d;        /* 3D overlay flag: 0 = OFF */
  150. extern    int    boxcolor;        /* zoom box color */
  151. extern    int    color_bright;        /* set by find_special_colors */
  152.  
  153. extern unsigned char dacbox[256][3];    /* Video-DAC (filled in by SETVIDEO) */
  154. extern unsigned char olddacbox[256][3]; /* backup copy of the Video-DAC */
  155. extern struct videoinfo far videotable[];
  156. extern unsigned char far *mapdacbox;    /* default dacbox when map= specified */
  157. extern int    daclearn, daccount;    /* used by the color-cyclers */
  158. extern int    extraseg;        /* used by Save-to-DISK routines */
  159. extern int    cpu;            /* cpu type            */
  160. extern int    fpu;            /* fpu type            */
  161. extern int    iit;            /* iit fpu?            */
  162. extern int    lookatmouse;        /* used to select mouse mode    */
  163. extern int    out_line();        /* called in decoder */
  164. extern int    outlin16();        /* called in decoder */
  165. extern int    line3d();        /* called in decoder */
  166. extern int    (*outln)();        /* called in decoder */
  167.        void    (*outln_cleanup)();
  168. extern int    filetype;        /* GIF or other */
  169.  
  170. /* variables defined by the command line/files processor */
  171. extern    double    inversion[];
  172. extern    int    invert;         /* non-zero if inversion active */
  173. extern    int    initbatch;        /* 1 if batch run (no kbd)  */
  174. extern    int    initmode;        /* initial video mode        */
  175. extern    int    goodmode;        /* video.asm sets nonzero if mode ok */
  176. extern    int    initcyclelimit;     /* initial cycle limit        */
  177. extern    int    LogFlag;        /* non-zero if logarithmic palettes */
  178. extern    int    reallyega;        /* == 0 if it's really an EGA */
  179.  
  180. extern char showbox;        /* flag to show box and vector in preview */
  181. extern unsigned initsavetime;    /* timed save interval */
  182.  
  183. int    comparegif=0;            /* compare two gif files flag */
  184. int    timedsave=0;            /* when doing a timed save */
  185. extern long saveticks, savebase;    /* timed save vars for general.asm */
  186. extern long readticker();        /* read bios ticker */
  187. extern int  finishrow;            /* for general.asm timed save */
  188. int    resave_flag=0;            /* tells encoder not to incr filename */
  189. int    started_resaves=0;        /* but incr on first resave */
  190. int    save_release,save_system;    /* from and for save files */
  191. int    tabmode = 1;            /* tab display enabled */
  192. extern    int release;            /* real current Fractint release */
  193. extern    int got_status;
  194. extern    int loaded3d;
  195. extern    int colorstate,colorpreloaded;    /* comments in cmdfiles */
  196.  
  197. /* for historical reasons (before rotation):         */
  198. /*    top    left  corner of screen is (xxmin,yymax) */
  199. /*    bottom left  corner of screen is (xx3rd,yy3rd) */
  200. /*    bottom right corner of screen is (xxmax,yymin) */
  201. double    xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners  */
  202. long    xmin, xmax, ymin, ymax, x3rd, y3rd;  /* integer equivs         */
  203. double    sxmin,sxmax,symin,symax,sx3rd,sy3rd; /* displayed screen corners */
  204. double    plotmx1,plotmx2,plotmy1,plotmy2;     /* real->screen multipliers */
  205.  
  206. int calc_status; /* -1 no fractal            */
  207.          /*  0 parms changed, recalc reqd   */
  208.          /*  1 actively calculating        */
  209.          /*  2 interrupted, resumable        */
  210.          /*  3 interrupted, not resumable   */
  211.          /*  4 completed            */
  212. long calctime;
  213.  
  214. int max_colors;                /* maximum palette size */
  215. extern int max_kbdcount;        /* governs keyboard-check speed */
  216.  
  217.  
  218. void main(int argc, char *argv[])
  219. {
  220.    double  jxxmin, jxxmax, jyymin, jyymax; /* "Julia mode" entry point */
  221.    double  jxx3rd, jyy3rd;
  222.    int       frommandel;            /* if julia entered from mandel */
  223.    int       axmode, bxmode, cxmode, dxmode; /* video mode (BIOS ##)    */
  224.    int       historyptr;            /* pointer into history tbl    */
  225.    int       historyflag;         /* are we backing off in history? */
  226.    int       zoomoff;            /* = 0 when zoom is disabled    */
  227.    int       kbdchar;            /* keyboard key-hit value    */
  228.    int       kbdmore;            /* continuation variable    */
  229.    int       i, k;            /* temporary loop counters    */
  230.    double  ftemp;            /* fp temp            */
  231.    int       savedac;            /* save-the-Video DAC flag    */
  232.  
  233.    initasmvars();            /* initialize ASM stuff */
  234.  
  235.    if (extraseg == 0        /* oops.  not enough memory */
  236.      || (history = (struct historystruct far * ) farmemalloc((unsigned long)
  237.               (MAXHISTORY * sizeof(*history)))) == NULL
  238.      || (ly0 = (long far *) farmemalloc(4096L)) == NULL) {
  239.       buzzer(2);
  240.       printf(" I'm sorry, but you don't have enough free memory \n");
  241.       printf(" to run this program.\n\n");
  242.       exit(1);
  243.       }
  244.    farmemfree((unsigned char far *)ly0); /* was just to check for min space */
  245.  
  246.    dx0 = MK_FP(extraseg,0);
  247.    dy1 = (dx1 = (dy0 = dx0 + MAXPIXELS) + MAXPIXELS) + MAXPIXELS;
  248.    lx0 = (long far *) dx0;
  249.    ly1 = (lx1 = (ly0 = lx0 + MAXPIXELS) + MAXPIXELS) + MAXPIXELS;
  250.  
  251.    historyptr = 0;            /* initialize history ptr */
  252.    historyflag = 0;
  253.    history[historyptr].fractype = -1;
  254.  
  255.    load_videotable(1); /* load fractint.cfg, no message yet if bad */
  256.    init_help();
  257.  
  258. restart:                /* insert key re-starts here */
  259.  
  260.    cmdfiles(argc,argv);         /* process the command-line */
  261.    memcpy(olddacbox,dacbox,256*3);    /* save in case colors= present */
  262.  
  263.    if (debugflag == 8088)         cpu =    86; /* for testing purposes */
  264.    if (debugflag == 2870 && fpu >= 287 ) fpu = 287; /* for testing purposes */
  265.    if (debugflag ==  870 && fpu >=  87 ) fpu =    87; /* for testing purposes */
  266.    if (debugflag ==   70)         fpu =     0; /* for testing purposes */
  267.    if (getenv("NO87")) fpu = 0;
  268.    if (fpu == 0)       iit = 0;
  269.    if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  270.       setup287code();
  271.  
  272.    /* IIT math coprocessor chip logic */
  273.    if(iit == 0 && fpu)
  274.       if(IITCoPro())
  275.          iit = 3;  /* detect iit chip */
  276.    if(iit < 0) iit = 0;  /* user wants chip turned off */
  277.    if(iit>0)
  278.    {
  279.       if(F4x4Check())
  280.          iit = 2;    /* semaphore TSR is installed */
  281.       else if(iit == 3)
  282.          iit = 0;    /* we detetct chip but no tsr - don't use */
  283.       /* else user forced iit == 1 */
  284.    }
  285.  
  286.    adapter_detect();            /* check what video is really present */
  287.    if (debugflag >= 9002 && debugflag <= 9100) /* for testing purposes */
  288.       if (video_type > (debugflag-9000)/2)     /* adjust the video value */
  289.      video_type = (debugflag-9000)/2;
  290.  
  291.    diskisactive = 0;            /* disk-video is inactive */
  292.    diskvideo = 0;            /* disk driver is not in use */
  293.    setvideotext();            /* switch to text mode */
  294.    calc_status = -1;            /* no active fractal image */
  295.    savedac = 0;             /* don't save the VGA DAC */
  296.  
  297.    if (debugflag == 10000)        /* check for free memory */
  298.       showfreemem();
  299.  
  300.    if (badconfig < 0)            /* fractint.cfg bad, no msg yet */
  301.       bad_fractint_cfg_msg();
  302.  
  303.    max_colors = 256;                    /* the Windows version is lower */
  304.    max_kbdcount=(cpu==386) ? 80 : 30;   /* check the keyboard this often */
  305.  
  306.    if (showfile && initmode < 0) {
  307.       intro();                /* display the credits screen */
  308.       if (keypressed() == 27) {
  309.      getakey();
  310.      goodbye();
  311.      }
  312.       }
  313.  
  314.    if (colorpreloaded)
  315.       memcpy(dacbox,olddacbox,256*3);    /* restore in case colors= present */
  316.  
  317. restorestart:
  318.  
  319.    lookatmouse = 0;            /* ignore mouse */
  320.  
  321.    while (showfile <= 0) {        /* image is to be loaded */
  322.       char *hdg;
  323.       tabmode = 0;
  324.       if (overlay3d) {
  325.      hdg = "Select File for 3D Overlay";
  326.      helpmode = HELP3DOVLY;
  327.      }
  328.       else if (display3d) {
  329.      hdg = "Select File for 3D Transform";
  330.      helpmode = HELP3D;
  331.      }
  332.       else {
  333.      hdg = "Select File to Restore";
  334.      helpmode = HELPSAVEREST;
  335.      }
  336.       if (showfile < 0 && getafilename(hdg,gifmask,readname) < 0) {
  337.      showfile = 1;             /* cancelled */
  338.      initmode = -1;
  339.      break;
  340.      }
  341.       showfile = 0;
  342.       helpmode = -1;
  343.       tabmode = 1;
  344.       if (read_overlay() == 0)         /* read hdr, get video mode */
  345.      break;              /* got it, exit */
  346.       showfile = -1;             /* retry */
  347.       }
  348.  
  349.    helpmode = HELPMENU;         /* now use this help mode */
  350.    tabmode = 1;
  351.    lookatmouse = 0;            /* ignore mouse */
  352.  
  353.    if (overlay3d && initmode < 0) {    /* overlay command failed */
  354.       unstackscreen();            /* restore the graphics screen */
  355.       overlay3d = 0;            /* forget overlays */
  356.       display3d = 0;            /* forget 3D */
  357.       if (calc_status > 0)
  358.      calc_status = 0;
  359.       goto resumeloop;            /* ooh, this is ugly */
  360.       }
  361.  
  362. imagestart:                /* calc/display a new image */
  363.  
  364.    savedac = 0;             /* don't save the VGA DAC */
  365.    got_status = -1;            /* for tab_display */
  366.  
  367.    if (showfile)
  368.       if (calc_status > 0)        /* goto imagestart implies re-calc */
  369.      calc_status = 0;
  370.  
  371.    if (initbatch == 0)
  372.       lookatmouse = -1073;        /* just mouse left button, == pgup */
  373.  
  374.    cyclelimit = initcyclelimit;     /* default cycle limit     */
  375.  
  376.    frommandel = 0;
  377.  
  378.    adapter = initmode;            /* set the video adapter up */
  379.    initmode = -1;            /* (once)            */
  380.  
  381.    while (adapter < 0) {        /* cycle through instructions */
  382.       if (initbatch)                /* batch, nothing to do */
  383.      goodbye();
  384.       kbdchar = main_menu(0);
  385.       if (kbdchar == INSERT) goto restart;    /* restart pgm on Insert Key */
  386.       if (kbdchar == DELETE)            /* select video mode list */
  387.      kbdchar = select_video_mode(-1);
  388.       if ((adapter = check_vidmode_key(0,kbdchar)) >= 0)
  389.      break;                 /* got a video mode now */
  390.       if ('A' <= kbdchar && kbdchar <= 'Z')
  391.      kbdchar = tolower(kbdchar);
  392.       if (kbdchar == 'd') {                     /* shell to DOS */
  393.      setclear();
  394.      printf("\n\nShelling to DOS - type 'exit' to return\n\n");
  395.      shell_to_dos();
  396.      goto imagestart;
  397.      }
  398.       if (kbdchar == '@') {                     /* execute commands */
  399.      if ((get_commands() & 4) == 0)
  400.         goto imagestart;
  401.      kbdchar = '3';                         /* 3d=y so fall thru '3' code */
  402.      }
  403.       if (kbdchar == 'r' || kbdchar == '3' || kbdchar == 'o') {
  404.      display3d = 0;
  405.      if (kbdchar == '3' || kbdchar == 'o')
  406.         display3d = 1;
  407.      setvideotext(); /* switch to text mode */
  408.      showfile = -1;
  409.      goto restorestart;
  410.      }
  411.       if (kbdchar == 't') {                     /* set fractal type */
  412.      get_fracttype();
  413.      goto imagestart;
  414.      }
  415.       if (kbdchar == 'x') {                     /* generic toggle switch */
  416.      get_toggles();
  417.      goto imagestart;
  418.      }
  419.       if (kbdchar == 'y') {                     /* generic toggle switch */
  420.      get_toggles2();
  421.      goto imagestart;
  422.      }
  423.       if (kbdchar == 'z') {                     /* type specific parms */
  424.      get_fract_params(1);
  425.      goto imagestart;
  426.      }
  427.       if (kbdchar == 'v') {                     /* view parameters */
  428.      get_view_params();
  429.      goto imagestart;
  430.      }
  431.       if (kbdchar == 'f') {                     /* floating pt toggle */
  432.      if (usr_floatflag == 0)
  433.         usr_floatflag = 1;
  434.      else
  435.         usr_floatflag = 0;
  436.      goto imagestart;
  437.      }
  438.       if (kbdchar == 'i') {                     /* set 3d fractal parms */
  439.      get_fract3d_params(); /* get the parameters */
  440.      goto imagestart;
  441.      }
  442.       /* buzzer(2); */                /* unrecognized key */
  443.       }
  444.  
  445.    zoomoff = 1;         /* zooming is enabled */
  446.    helpmode = HELPMAIN;     /* now use this help mode */
  447.  
  448.    while (1) {            /* eternal loop */
  449.  
  450.       if (calc_status != 2 || showfile == 0) {
  451.      far_memcpy((char far *)&videoentry,(char far *)&videotable[adapter],
  452.             sizeof(videoentry));
  453.      axmode  = videoentry.videomodeax; /* video mode (BIOS call)   */
  454.      bxmode  = videoentry.videomodebx; /* video mode (BIOS call)   */
  455.      cxmode  = videoentry.videomodecx; /* video mode (BIOS call)   */
  456.      dxmode  = videoentry.videomodedx; /* video mode (BIOS call)   */
  457.      dotmode = videoentry.dotmode;       /* assembler dot read/write */
  458.      xdots     = videoentry.xdots;       /* # dots across the screen */
  459.      ydots     = videoentry.ydots;       /* # dots down the screen   */
  460.      colors  = videoentry.colors;       /* # colors available */
  461.      textsafe2 = dotmode / 100;
  462.      dotmode  %= 100;
  463.      sxdots  = xdots;
  464.      sydots  = ydots;
  465.      sxoffs = syoffs = 0;
  466.  
  467.      diskvideo = 0;         /* set diskvideo flag */
  468.      if (dotmode == 11)        /* default assumption is disk */
  469.         diskvideo = 2;
  470.  
  471.      memcpy(olddacbox,dacbox,256*3); /* save the DAC */
  472.      diskisactive = 1;        /* flag for disk-video routines */
  473.  
  474.      if (overlay3d) {
  475.         unstackscreen();        /* restore old graphics image */
  476.         overlay3d = 0;
  477.         }
  478.  
  479.      else {
  480.         setvideomode(axmode,bxmode,cxmode,dxmode); /* switch video modes */
  481.         if (goodmode == 0) {
  482.            static char far msg[] = {"That video mode is not available with your adapter."};
  483.            static char far TPlusStr[] = "This video mode requires 'noninterlaced=yes'";
  484.  
  485.            if(TPlusErr) {
  486.           stopmsg(0, TPlusStr);
  487.           TPlusErr = 0;
  488.           }
  489.            else
  490.           stopmsg(0,msg);
  491.            initmode = -1;
  492.            setvideotext(); /* switch to text mode */
  493.            goto restorestart;
  494.            }
  495.  
  496.         if(Transparent3D && curfractalspecific->orbitcalc == Formula) {
  497.            char far *ErrMsg;
  498.            if((ErrMsg = TrueColorAutoDetect()) != ((char far*)0)) {
  499.           stopmsg(0, ErrMsg);
  500.           Transparent3D = 0;
  501.           }
  502.            else {
  503.           tpdepth = 0;
  504.           NewTPFractal = 1;
  505.           }
  506.            }
  507.         else if(AntiAliasing) {
  508.            if(dotmode != 11) {
  509.           static char far DiskVidError[] =
  510.             "Anti-aliasing resolution too high, try a lower value or lower\n\
  511. screen resolution.";
  512.           /* Ensure the absolute resolution is < 2048 */
  513.           if(AntiAliasing >= 8 ||
  514.              ((long)xdots << AntiAliasing) > 2048)
  515.              goto AntiAliasError;
  516.           if(!colors)
  517.              TrueColorAutoDetect();
  518.           if(SetupShadowVideo() != 0) {
  519. AntiAliasError:
  520.              stopmsg(0, DiskVidError);
  521.              initmode = -1;
  522.              setvideotext(); /* switch to text mode */
  523.              goto restorestart;
  524.              }
  525.           }
  526.            }
  527.         }
  528.  
  529.      diskisactive = 0;        /* flag for disk-video routines */
  530.      if (savedac || colorpreloaded) {
  531.         memcpy(dacbox,olddacbox,256*3); /* restore the DAC */
  532.         spindac(0,1);
  533.         colorpreloaded = 0;
  534.         }
  535.      else { /* reset DAC to defaults, which setvideomode has done for us */
  536.         if (mapdacbox) { /* but there's a map=, so load that */
  537.            far_memcpy((char far *)dacbox,mapdacbox,768);
  538.            spindac(0,1);
  539.            }
  540.         else if ((dotmode == 11 && colors == 256) || !colors) {
  541.            /* disk video, setvideomode via bios didn't get it right, so: */
  542.            ValidateLuts("default"); /* read the default palette file */
  543.            }
  544.         colorstate = 0;
  545.         }
  546.      if (viewwindow) {
  547.         ftemp = finalaspectratio
  548.             * (double)sydots / (double)sxdots / SCREENASPECT;
  549.         if ((xdots = viewxdots)) { /* xdots specified */
  550.            if ((ydots = viewydots) == 0) /* calc ydots? */
  551.           ydots = (double)xdots * ftemp + 0.5;
  552.            }
  553.         else
  554.            if (finalaspectratio <= SCREENASPECT) {
  555.           xdots = (double)sxdots / viewreduction + 0.5;
  556.           ydots = (double)xdots * ftemp + 0.5;
  557.           }
  558.            else {
  559.           ydots = (double)sydots / viewreduction + 0.5;
  560.           xdots = (double)ydots / ftemp + 0.5;
  561.           }
  562.         if (xdots > sxdots || ydots > sydots) {
  563.            static char far msg[] = {"View window too large; using full screen."};
  564.            stopmsg(0,msg);
  565.            xdots = sxdots;
  566.            ydots = sydots;
  567.            }
  568.         else if (xdots <= sxdots/20 || ydots <= sydots/20) { /* so ssg works */
  569.            static char far msg[] = {"View window too small; using full screen."};
  570.            stopmsg(0,msg);
  571.            xdots = sxdots;
  572.            ydots = sydots;
  573.            }
  574.         sxoffs = (sxdots - xdots) / 2;
  575.         syoffs = (sydots - ydots) / 3;
  576.         }
  577.      dxsize = xdots - 1;        /* convert just once now */
  578.      dysize = ydots - 1;
  579.      }
  580.  
  581.       savedac = 1;            /* assume we save next time */
  582.  
  583.       if (initbatch == 0)
  584.      lookatmouse = -1073;        /* mouse left button == pgup */
  585.  
  586.       if(showfile == 0) {        /* loading an image */
  587.      outln_cleanup = NULL;        /* outln routine can set this */
  588.      if (display3d)         /* set up 3D decoding */
  589.         outln = call_line3d;
  590.      else if(filetype >= 1)     /* old .tga format input file */
  591.         outln = outlin16;
  592.      else if(comparegif)        /* debug 50 */
  593.         outln = cmp_line;
  594.      else if(pot16bit) {        /* .pot format input file */
  595.         pot_startdisk();
  596.         outln = pot_line;
  597.         }
  598.      else                /* regular gif/fra input file */
  599.         outln = out_line;
  600.      if(filetype == 0)
  601.      {
  602.         if(iit == 2 && usr_floatflag != 0)
  603.            if(F4x4Lock()==0)
  604.               iit = -1;  /* semaphore not free - no iit */
  605.         if(debugflag==2224)
  606.          {
  607.             char buf[80];
  608.             sprintf(buf,"iit=%d floatflag=%d",iit,usr_floatflag);
  609.             stopmsg(4,(char far *)buf);
  610.          }
  611.  
  612.         i = funny_glasses_call(gifview);
  613.         if(iit == 2)
  614.            F4x4Free();      /* unlock semaphore */
  615.         else if(iit == -1)
  616.            iit = 2;         /* semaphore operating */
  617.      }
  618.      else
  619.         i = funny_glasses_call(tgaview);
  620.      if(outln_cleanup)        /* cleanup routine defined? */
  621.         (*outln_cleanup)();
  622.      if(i == 0)
  623.         buzzer(0);
  624.      else {
  625.         calc_status = -1;
  626.         if (keypressed()) {
  627.            buzzer(1);
  628.            while (keypressed()) getakey();
  629.            texttempmsg("*** load incomplete ***");
  630.            }
  631.         }
  632.      }
  633.  
  634.       zoomoff = 1;            /* zooming is enabled */
  635.       if (dotmode == 11 || (curfractalspecific->flags&NOZOOM) != 0)
  636.      zoomoff = 0;            /* for these cases disable zooming */
  637.  
  638.       calcfracinit();
  639.  
  640.       sxmin = xxmin; /* save 3 corners for zoom.c ref points */
  641.       sxmax = xxmax;
  642.       sx3rd = xx3rd;
  643.       symin = yymin;
  644.       symax = yymax;
  645.       sy3rd = yy3rd;
  646.  
  647.       if (history[0].fractype == -1)    /* initialize the history file */
  648.      for (i = 0; i < MAXHISTORY; i++) {
  649.         history[i].xxmax = xxmax;
  650.         history[i].xxmin = xxmin;
  651.         history[i].yymax = yymax;
  652.         history[i].yymin = yymin;
  653.         history[i].xx3rd = xx3rd;
  654.         history[i].yy3rd = yy3rd;
  655.         history[i].param[0] = param[0];
  656.         history[i].param[1] = param[1];
  657.         history[i].fractype = fractype;
  658.         }
  659.  
  660.       if ( history[historyptr].xxmax != xxmax  || /* save any (new) zoom data */
  661.        history[historyptr].xxmin != xxmin  ||
  662.        history[historyptr].yymax != yymax  ||
  663.        history[historyptr].yymin != yymin  ||
  664.        history[historyptr].xx3rd != xx3rd  ||
  665.        history[historyptr].yy3rd != yy3rd  ||
  666.        history[historyptr].param[0] != param[0] ||
  667.        history[historyptr].param[1] != param[1] ||
  668.        history[historyptr].fractype != fractype) {
  669.      if (historyflag == 0) /* if we're not backing off for <\> */
  670.         if (++historyptr == MAXHISTORY) historyptr = 0;
  671.      history[historyptr].xxmax = xxmax;
  672.      history[historyptr].xxmin = xxmin;
  673.      history[historyptr].yymax = yymax;
  674.      history[historyptr].yymin = yymin;
  675.      history[historyptr].xx3rd = xx3rd;
  676.      history[historyptr].yy3rd = yy3rd;
  677.      history[historyptr].param[0] = param[0];
  678.      history[historyptr].param[1] = param[1];
  679.      history[historyptr].fractype = fractype;
  680.      }
  681.       historyflag = 0;
  682.  
  683.       if (display3d || showfile) {    /* paranoia: these vars don't get set */
  684.      save_system  = active_system;    /*   unless really doing some work,   */
  685.      save_release = release;    /*   so simple <r> + <s> keeps number */
  686.      }
  687.  
  688.       if(showfile == 0) {        /* image has been loaded */
  689.      showfile = 1;
  690.      if (initbatch == 1 && calc_status == 2)
  691.         initbatch = -1; /* flag to finish calc before save */
  692.      if (loaded3d)        /* 'r' of image created with '3' */
  693.         display3d = 1;  /* so set flag for 'b' command */
  694.      }
  695.       else {                /* draw an image */
  696.      diskisactive = 1;        /* flag for disk-video routines */
  697.      if (initsavetime != 0        /* autosave and resumable? */
  698.        && (curfractalspecific->flags&NORESUME) == 0) {
  699.         savebase = readticker(); /* calc's start time */
  700.         saveticks = (long)initsavetime * 1092; /* bios ticks/minute */
  701.         if ((saveticks & 65535L) == 0)
  702.            ++saveticks; /* make low word nonzero */
  703.         finishrow = -1;
  704.         }
  705.  
  706.      if(Transparent3D && curfractalspecific->orbitcalc == Formula)
  707.         i = Transp3DFnct();
  708.      else {
  709.         i = calcfract();    /* draw the fractal using "C" */
  710.         if(AntiAliasing && i == 0)
  711.            AntiAliasPass();
  712.         }
  713.      if (i == 0)
  714.         buzzer(0); /* finished!! */
  715.  
  716.      saveticks = 0;         /* turn off autosave timer */
  717.      if (dotmode == 11 && i == 0) /* disk-video */
  718.         dvid_status(0,"Image has been completed");
  719.      diskisactive = 0;        /* flag for disk-video routines */
  720.      }
  721.  
  722.       boxcount = 0;            /* no zoom box yet  */
  723.       zwidth = 0;
  724.  
  725.       if (fractype == PLASMA && cpu > 88) {
  726.      cyclelimit = 256;        /* plasma clouds need quick spins */
  727.      daccount = 256;
  728.      daclearn = 1;
  729.      }
  730.  
  731. resumeloop:                /* return here on failed overlays */
  732.  
  733.       kbdmore = 1;
  734.       while (kbdmore == 1) {        /* loop through command keys */
  735.  
  736.      if (timedsave != 0) {
  737.         if (timedsave == 1) {    /* woke up for timed save */
  738.            getakey();     /* eat the dummy char */
  739.            kbdchar = 's'; /* do the save */
  740.            resave_flag = 1;
  741.            timedsave = 2;
  742.            }
  743.         else {            /* save done, resume */
  744.            timedsave = 0;
  745.            resave_flag = 2;
  746.            kbdchar = 13;
  747.            }
  748.         }
  749.      else if (initbatch == 0) {    /* not batch mode */
  750.         lookatmouse = (zwidth == 0) ? -1073 : 3;
  751.         if (calc_status == 2 && zwidth == 0 && !keypressed())
  752.            kbdchar = 13;        /* no visible reason to stop, continue */
  753.         else {            /* wait for a real keystroke */
  754.            while (!keypressed()) { }  /* enables help */
  755.            kbdchar = getakey();
  756.            if (kbdchar == 27 || kbdchar == 'm' || kbdchar == 'M') {
  757.           stackscreen();
  758.           kbdchar = main_menu(1);
  759.           if (kbdchar == '\\'
  760.             || check_vidmode_key(0,kbdchar) >= 0)
  761.              discardscreen();
  762.           else
  763.              unstackscreen();
  764.           }
  765.            }
  766.         }
  767.      else {             /* batch mode, fake next keystroke */
  768.         if (initbatch == -1) {    /* finish calc */
  769.            kbdchar = 13;
  770.            initbatch = 1;
  771.            }
  772.         else if (initbatch == 1) {    /* save-to-disk */
  773.            if (debugflag == 50)
  774.           kbdchar = 'r';
  775.            else
  776.           kbdchar = 's';
  777.            initbatch = 2;
  778.            }
  779.         else
  780.            goodbye();        /* done, exit */
  781.         }
  782.  
  783.      if ('A' <= kbdchar && kbdchar <= 'Z')
  784.         kbdchar = tolower(kbdchar);
  785.  
  786.      switch (kbdchar) {
  787.         case 't':                   /* new fractal type             */
  788.            clear_zoombox();
  789.            stackscreen();
  790.            if ((i = get_fracttype()) >= 0) {
  791.           discardscreen();
  792.           if (i == 0) {
  793.              initmode = adapter;
  794.              frommandel = 0;
  795.              }
  796.           else
  797.              if (initmode < 0)    /* it is supposed to be... */
  798.             setvideotext(); /* reset to text mode       */
  799.           goto imagestart;
  800.           }
  801.            unstackscreen();
  802.            break;
  803.         case 'x':                   /* invoke options screen        */
  804.         case 'y':
  805.         case 'z':                   /* type specific parms */
  806.            stackscreen();
  807.            if (kbdchar == 'x')
  808.           i = get_toggles();
  809.            else if (kbdchar == 'y')
  810.           i = get_toggles2();
  811.            else
  812.           i = get_fract_params(1);
  813.            if (i > 0) {        /* time to redraw? */
  814.           discardscreen();
  815.           kbdmore = calc_status = 0;
  816.           }
  817.            else
  818.           unstackscreen();
  819.            break;
  820.         case '@':                   /* execute commands */
  821.            stackscreen();
  822.            i = get_commands();
  823.            if (initmode != -1) {    /* video= was specified */
  824.           adapter = initmode;
  825.           initmode = -1;
  826.           i |= 1;
  827.           savedac = 0;
  828.           }
  829.            else if (colorpreloaded) { /* colors= was specified */
  830.           spindac(0,1);
  831.           colorpreloaded = 0;
  832.           }
  833.            else if ((i & 8))    /* reset was specified */
  834.           savedac = 0;
  835.            if ((i & 4)) {        /* 3d = was specified */
  836.           kbdchar = '3';
  837.           unstackscreen();
  838.           goto do_3d_transform; /* pretend '3' was keyed */
  839.           }
  840.            if ((i & 1)) {        /* fractal parameter changed */
  841.           discardscreen();
  842.           kbdmore = calc_status = 0;
  843.           }
  844.            else
  845.           unstackscreen();
  846.            break;
  847.         case 'v':                   /* invoke options screen        */
  848.            i = get_view_params();    /* get the parameters */
  849.            if (i > 0)        /* time to redraw? */
  850.           kbdmore = calc_status = 0;
  851.            break;
  852.         case 'f':                   /* floating pt toggle           */
  853.            if (usr_floatflag == 0)
  854.           usr_floatflag = 1;
  855.            else
  856.           usr_floatflag = 0;
  857.            initmode = adapter;
  858.            goto imagestart;
  859.         case 'i':                   /* 3d fractal parms */
  860.            if (get_fract3d_params() >= 0) /* get the parameters */
  861.           calc_status = kbdmore = 0;  /* time to redraw */
  862.            break;
  863.         case 'a':                  /* starfield parms               */
  864.            clear_zoombox();
  865.            if (get_starfield_params() >= 0) {
  866.           calc_status = 0;
  867.           continue;
  868.           }
  869.            break;
  870.         case 32:               /* spacebar, toggle mand/julia    */
  871.            if (curfractalspecific->tojulia != NOFRACTAL
  872.          && param[0] == 0.0 && param[1] == 0.0) {
  873.           /* switch to corresponding Julia set */
  874.           fractype = curfractalspecific->tojulia;
  875.           curfractalspecific = &fractalspecific[fractype];
  876.           param[0] = (xxmax + xxmin) / 2;
  877.           param[1] = (yymax + yymin) / 2;
  878.           jxxmin = sxmin; jxxmax = sxmax;
  879.           jyymax = symax; jyymin = symin;
  880.           jxx3rd = sx3rd; jyy3rd = sy3rd;
  881.           frommandel = 1;
  882.           xxmin = curfractalspecific->xmin;
  883.           xxmax = curfractalspecific->xmax;
  884.           yymin = curfractalspecific->ymin;
  885.           yymax = curfractalspecific->ymax;
  886.           xx3rd = xxmin;
  887.           yy3rd = yymin;
  888.           if (usr_distest == 0 && usr_biomorph != -1 && bitshift != 29) {
  889.              xxmin *= 3.0;
  890.              xxmax *= 3.0;
  891.              yymin *= 3.0;
  892.              yymax *= 3.0;
  893.              xx3rd *= 3.0;
  894.              yy3rd *= 3.0;
  895.              }
  896.           zoomoff = 1;
  897.           calc_status = 0;
  898.           kbdmore = 0;
  899.           }
  900.            else if (curfractalspecific->tomandel != NOFRACTAL) {
  901.           /* switch to corresponding Mandel set */
  902.           fractype = curfractalspecific->tomandel;
  903.           curfractalspecific = &fractalspecific[fractype];
  904.           if (frommandel) {
  905.              xxmin = jxxmin;  xxmax = jxxmax;
  906.              yymin = jyymin;  yymax = jyymax;
  907.              xx3rd = jxx3rd;  yy3rd = jyy3rd;
  908.              }
  909.           else {
  910.              double ccreal,ccimag;
  911.              ccreal = (curfractalspecific->xmax - curfractalspecific->xmin) / 2;
  912.              ccimag = (curfractalspecific->ymax - curfractalspecific->ymin) / 2;
  913.              xxmin = xx3rd = param[0] - ccreal;
  914.              xxmax = param[0] + ccreal;
  915.              yymin = yy3rd = param[1] - ccimag;
  916.              yymax = param[1] + ccimag;
  917.              }
  918.           param[0] = 0;
  919.           param[1] = 0;
  920.           zoomoff = 1;
  921.           calc_status = 0;
  922.           kbdmore = 0;
  923.           }
  924.            else
  925.           buzzer(2); /* can't switch */
  926.            break;
  927.         case '\\':                 /* return to prev image    */
  928.            if (--historyptr < 0)
  929.           historyptr = MAXHISTORY-1;
  930.            xxmax  = history[historyptr].xxmax;
  931.            xxmin  = history[historyptr].xxmin;
  932.            yymax  = history[historyptr].yymax;
  933.            yymin  = history[historyptr].yymin;
  934.            xx3rd  = history[historyptr].xx3rd;
  935.            yy3rd  = history[historyptr].yy3rd;
  936.            param[0] = history[historyptr].param[0];
  937.            param[1] = history[historyptr].param[1];
  938.            fractype = history[historyptr].fractype;
  939.            curfractalspecific = &fractalspecific[fractype];
  940.            zoomoff = 1;
  941.            initmode = adapter;
  942.            if (curfractalspecific->isinteger != 0 &&
  943.            curfractalspecific->tofloat != NOFRACTAL)
  944.           usr_floatflag = 0;
  945.            if (curfractalspecific->isinteger == 0 &&
  946.            curfractalspecific->tofloat != NOFRACTAL)
  947.           usr_floatflag = 1;
  948.            historyflag = 1; /* avoid re-store parms due to rounding errs */
  949.            goto imagestart;
  950.         case 'd':                   /* shell to MS-DOS              */
  951.            stackscreen();
  952.            if (axmode == 0 || axmode > 7) {
  953. static char far dosmsg[]={"\
  954. Note:  Your graphics image is still squirreled away in your video\n\
  955. adapter's memory.  Switching video modes (say, to get your cursor back)\n\
  956. will clobber part of that image.  Sorry - it's the best we could do."};
  957.           putstring(0,0,7,dosmsg);
  958.           movecursor(6,0);
  959.           }
  960.            shell_to_dos();
  961.            unstackscreen();
  962.            calc_status = 0;
  963.            break;
  964.         case 'c':                   /* switch to color cycling      */
  965.         case '+':                   /* rotate palette               */
  966.         case '-':                   /* rotate palette               */
  967.            clear_zoombox();
  968.            memcpy(olddacbox,dacbox,256*3);
  969.            rotate((kbdchar == 'c') ? 0 : ((kbdchar == '+') ? 1 : -1));
  970.            if (memcmp(olddacbox,dacbox,256*3))
  971.           colorstate = 1;
  972.            continue;
  973.         case 'e':                   /* switch to color editing      */
  974.            clear_zoombox();
  975.            if (dacbox[0][0] != 255 && !reallyega && colors >= 16
  976.          && dotmode != 11) {
  977.           int oldhelpmode;
  978.           oldhelpmode = helpmode;
  979.           memcpy(olddacbox,dacbox,256*3);
  980.           helpmode = HELPXHAIR;
  981.           EditPalette();
  982.           helpmode = oldhelpmode;
  983.           if (memcmp(olddacbox,dacbox,256*3))
  984.              colorstate = 1;
  985.           }
  986.            continue;
  987.         case 's':                   /* save-to-disk                 */
  988.            diskisactive = 1;    /* flag for disk-video routines */
  989.            note_zoom();
  990.            savetodisk(savename);
  991.            restore_zoom();
  992.            diskisactive = 0;    /* flag for disk-video routines */
  993.            continue;
  994.         case 'o':                   /* 3D overlay                   */
  995.            clear_zoombox();
  996.            overlay3d = 1;
  997.         case '3':                   /* restore-from (3d)            */
  998. do_3d_transform:
  999.            display3d = 1;
  1000.         case 'r':                   /* restore-from                 */
  1001.            comparegif = 0;
  1002.            frommandel = 0;
  1003.            if(kbdchar == 'r')  {
  1004.           if(debugflag == 50) {
  1005.              comparegif = overlay3d = 1;
  1006.              if (initbatch == 2) {
  1007.             stackscreen(); /* save graphics image */
  1008.             strcpy(readname,savename);
  1009.             showfile = 0;
  1010.             goto restorestart;
  1011.             }
  1012.              }
  1013.           else
  1014.              comparegif = overlay3d = 0;
  1015.           display3d = 0;
  1016.           }
  1017.            if (overlay3d)
  1018.            stackscreen(); /* save graphics image */
  1019.            else
  1020.            setvideotext(); /* switch to text mode */
  1021.            if (resave_flag) {
  1022.           updatesavename(savename); /* do the pending increment */
  1023.           resave_flag = started_resaves = 0;
  1024.           }
  1025.            showfile = -1;
  1026.            goto restorestart;
  1027.         case 'b':                   /* make batch file              */
  1028.            make_batch_file();
  1029.            break;
  1030.         case 'p':                   /* print current image          */
  1031.            note_zoom();
  1032.            Print_Screen();
  1033.            restore_zoom();
  1034.            if (!keypressed())
  1035.           buzzer(0);
  1036.            else {
  1037.           buzzer(1);
  1038.           getakey();
  1039.           }
  1040.            continue;
  1041.         case 13:            /* Enter            */
  1042.         case 1013:            /* Numeric-Keypad Enter     */
  1043.            if (zwidth != 0.0) {    /* do a zoom */
  1044.           init_pan_or_recalc(0);
  1045.           kbdmore = 0;
  1046.           }
  1047.            if (calc_status != 4)    /* don't restart if image complete */
  1048.           kbdmore = 0;
  1049.            break;
  1050.         case 10:            /* control-Enter        */
  1051.         case 1010:            /* Control-Keypad Enter     */
  1052.            init_pan_or_recalc(1);
  1053.            kbdmore = 0;
  1054.            zoomout(); /* calc corners for zooming out */
  1055.            break;
  1056.         case 1082:            /* insert            */
  1057.            setvideotext(); /* force text mode */
  1058.            goto restart;
  1059.         case 1075:            /* cursor left            */
  1060.         case 1077:            /* cursor right         */
  1061.         case 1072:            /* cursor up            */
  1062.         case 1080:            /* cursor down            */
  1063.         case 1115:            /* Ctrl-cursor left        */
  1064.         case 1116:            /* Ctrl-cursor right        */
  1065.         case 1141:            /* Ctrl-cursor up        */
  1066.         case 1145:            /* Ctrl-cursor down        */
  1067.            move_zoombox(kbdchar);
  1068.            break;
  1069.         case 1119:            /* Ctrl-home            */
  1070.            if (boxcount && (curfractalspecific->flags&NOROTATE) == 0) {
  1071.           i = key_count(1119);
  1072.           if ((zskew -= 0.02*i) < -0.48)
  1073.              zskew = -0.48;
  1074.           }
  1075.            break;
  1076.         case 1117:            /* Ctrl-end            */
  1077.            if (boxcount && (curfractalspecific->flags&NOROTATE) == 0) {
  1078.           i = key_count(1117);
  1079.           if ((zskew += 0.02*i) > 0.48)
  1080.              zskew = 0.48;
  1081.           }
  1082.            break;
  1083.         case 1132:            /* Ctrl-pgup            */
  1084.            if (boxcount)
  1085.           chgboxi(0,-2*key_count(1132));
  1086.            break;
  1087.         case 1118:            /* Ctrl-pgdn            */
  1088.            if (boxcount)
  1089.           chgboxi(0,2*key_count(1118));
  1090.            break;
  1091.         case 1073:            /* page up            */
  1092.            if (zoomoff == 1)
  1093.           if (zwidth == 0) { /* start zoombox */
  1094.              zwidth = zdepth = 1;
  1095.              zrotate = zskew = 0;
  1096.              zbx = zby = 0;
  1097.              find_special_colors();
  1098.              boxcolor = color_bright;
  1099.              }
  1100.           else
  1101.              resizebox(0-key_count(1073));
  1102.            break;
  1103.         case 1081:            /* page down            */
  1104.            if (boxcount) {
  1105.           if (zwidth >= .999 && zdepth >= 0.999) /* end zoombox */
  1106.              zwidth = 0;
  1107.           else
  1108.              resizebox(key_count(1081));
  1109.           }
  1110.            break;
  1111.         case 1142:            /* Ctrl-kpad-               */
  1112.            if (boxcount && (curfractalspecific->flags&NOROTATE) == 0)
  1113.           zrotate += key_count(1142);
  1114.            break;
  1115.         case 1144:            /* Ctrl-kpad+            */
  1116.            if (boxcount && (curfractalspecific->flags&NOROTATE) == 0)
  1117.           zrotate -= key_count(1144);
  1118.            break;
  1119.         case 1146:            /* Ctrl-ins            */
  1120.            boxcolor += key_count(1146);
  1121.            break;
  1122.         case 1147:            /* Ctrl-del            */
  1123.            boxcolor -= key_count(1147);
  1124.            break;
  1125.         case DELETE:        /* select video mode from list */
  1126.            stackscreen();
  1127.            kbdchar = select_video_mode(adapter);
  1128.            if (check_vidmode_key(0,kbdchar) >= 0) /* picked a new mode? */
  1129.           discardscreen();
  1130.            else
  1131.           unstackscreen();
  1132.            /* fall through */
  1133.         default:            /* other (maybe a valid Fn key) */
  1134.            if ((k = check_vidmode_key(0,kbdchar)) >= 0) {
  1135.           adapter = k;
  1136.           if (videotable[adapter].dotmode != 11
  1137.             || videotable[adapter].colors != colors)
  1138.              savedac = 0;
  1139.           calc_status = 0;
  1140.           kbdmore = 0;
  1141.           continue;
  1142.           }
  1143.            break;
  1144.         } /* end of the big switch */
  1145.  
  1146.      if (zoomoff == 1 && kbdmore == 1) /* draw/clear a zoom box? */
  1147.         drawbox(1);
  1148.      }
  1149.       }
  1150.  
  1151. }
  1152.  
  1153. /* read keystrokes while = specified key, return 1+count;    */
  1154. /* used to catch up when moving zoombox is slower than keyboard */
  1155. int key_count(int keynum)
  1156. {  int ctr;
  1157.    ctr = 1;
  1158.    while (keypressed() == keynum) {
  1159.       getakey();
  1160.       ++ctr;
  1161.       }
  1162.    return ctr;
  1163. }
  1164.  
  1165. /* do all pending movement at once for smooth mouse diagonal moves */
  1166. static void move_zoombox(int keynum)
  1167. {  int vertical, horizontal, getmore;
  1168.    if (boxcount == 0)
  1169.       return;
  1170.    vertical = horizontal = 0;
  1171.    getmore = 1;
  1172.    while (getmore) {
  1173.       switch (keynum) {
  1174.      case 1075:            /* cursor left */
  1175.         --horizontal;
  1176.         break;
  1177.      case 1077:            /* cursor right */
  1178.         ++horizontal;
  1179.         break;
  1180.      case 1072:            /* cursor up */
  1181.         --vertical;
  1182.         break;
  1183.      case 1080:            /* cursor down */
  1184.         ++vertical;
  1185.         break;
  1186.      case 1115:            /* Ctrl-cursor left */
  1187.         horizontal -= 5;
  1188.         break;
  1189.      case 1116:             /* Ctrl-cursor right */
  1190.         horizontal += 5;
  1191.         break;
  1192.      case 1141:            /* Ctrl-cursor up */
  1193.         vertical -= 5;
  1194.         break;
  1195.      case 1145:            /* Ctrl-cursor down */
  1196.         vertical += 5;
  1197.         break;
  1198.      default:
  1199.         getmore = 0;
  1200.      }
  1201.       if (getmore) {
  1202.      if (getmore == 2)        /* eat last key used */
  1203.         getakey();
  1204.      getmore = 2;
  1205.      keynum = keypressed();     /* next pending key */
  1206.      }
  1207.       }
  1208.    if (horizontal!=0)
  1209.       moveboxf((double)horizontal/dxsize,0.0);
  1210.    if (vertical!=0)
  1211.       moveboxf(0.0,(double)vertical/dysize);
  1212. }
  1213.  
  1214. /* displays differences between current image file and new image */
  1215. static FILE *cmp_fp;
  1216. static errcount;
  1217. int cmp_line(unsigned char *pixels, int linelen)
  1218. {
  1219.    extern int rowcount;
  1220.    int row,col;
  1221.    int oldcolor;
  1222.    if((row = rowcount++) == 0) {
  1223.       errcount = 0;
  1224.       cmp_fp = fopen("cmperr",(initbatch)?"a":"w");
  1225.       outln_cleanup = cmp_line_cleanup;
  1226.       }
  1227.    if(pot16bit) { /* 16 bit info, ignore odd numbered rows */
  1228.       if((row & 1) != 0) return(0);
  1229.       row >>= 1;
  1230.       }
  1231.    for(col=0;col<linelen;col++) {
  1232.       oldcolor=getcolor(col,row);
  1233.       if(oldcolor==pixels[col])
  1234.      putcolor(col,row,0);
  1235.       else {
  1236.      if(oldcolor==0)
  1237.         putcolor(col,row,1);
  1238.      ++errcount;
  1239.      if(initbatch == 0)
  1240.         fprintf(cmp_fp,"#%5d col %3d row %3d old %3d new %3d\n",
  1241.            errcount,col,row,oldcolor,pixels[col]);
  1242.      }
  1243.       }
  1244.    return(0);
  1245. }
  1246.  
  1247. static void cmp_line_cleanup()
  1248. {
  1249.    char *timestring;
  1250.    time_t ltime;
  1251.    if(initbatch) {
  1252.       time(<ime);
  1253.       timestring = ctime(<ime);
  1254.       timestring[24] = 0; /*clobber newline in time string */
  1255.       fprintf(cmp_fp,"%s compare to %s has %5d errs\n",
  1256.              timestring,readname,errcount);
  1257.       }
  1258.    fclose(cmp_fp);
  1259. }
  1260.  
  1261. int pot_line(unsigned char *pixels, int linelen)
  1262. {
  1263.    extern int rowcount;
  1264.    int row,col,saverowcount;
  1265.    if (rowcount == 0)
  1266.       pot_startdisk();
  1267.    saverowcount = rowcount;
  1268.    row = (rowcount >>= 1);
  1269.    if ((saverowcount & 1) != 0) /* odd line */
  1270.       row += ydots;
  1271.    else             /* even line */
  1272.       if (dotmode != 11) /* display the line too */
  1273.      out_line(pixels,linelen);
  1274.    for (col = 0; col < xdots; ++col)
  1275.       writedisk(col+sxoffs,row+syoffs,*(pixels+col));
  1276.    rowcount = saverowcount + 1;
  1277.    return(0);
  1278. }
  1279.  
  1280. static int call_line3d(unsigned char *pixels, int linelen)
  1281. {
  1282.    /* this routine exists because line3d might be in an overlay */
  1283.    return(line3d(pixels,linelen));
  1284. }
  1285.  
  1286.  
  1287. static void clear_zoombox()
  1288. {
  1289.    zwidth = 0;
  1290.    drawbox(0);
  1291.    reset_zoom_corners();
  1292. }
  1293.  
  1294. void reset_zoom_corners()
  1295. {
  1296.    xxmin = sxmin;
  1297.    xxmax = sxmax;
  1298.    xx3rd = sx3rd;
  1299.    yymax = symax;
  1300.    yymin = symin;
  1301.    yy3rd = sy3rd;
  1302. }
  1303.  
  1304. static char far *savezoom;
  1305. extern int boxcount;
  1306. extern char boxx[],boxy[];
  1307. extern char boxvalues[];
  1308.  
  1309. static void note_zoom()
  1310. {
  1311.    if (boxcount) { /* save zoombox stuff in far mem before encode (mem reused) */
  1312.       if ((savezoom = farmemalloc((long)(5*boxcount))) == NULL)
  1313.      clear_zoombox(); /* not enuf mem so clear the box */
  1314.       else {
  1315.      reset_zoom_corners(); /* reset these to overall image, not box */
  1316.      far_memcpy(savezoom,boxx,boxcount*2);
  1317.      far_memcpy(savezoom+boxcount*2,boxy,boxcount*2);
  1318.      far_memcpy(savezoom+boxcount*4,boxvalues,boxcount);
  1319.      }
  1320.       }
  1321. }
  1322.  
  1323. static void restore_zoom()
  1324. {
  1325.    if (boxcount) { /* restore zoombox arrays */
  1326.       far_memcpy(boxx,savezoom,boxcount*2);
  1327.       far_memcpy(boxy,savezoom+boxcount*2,boxcount*2);
  1328.       far_memcpy(boxvalues,savezoom+boxcount*4,boxcount);
  1329.       farmemfree(savezoom);
  1330.       drawbox(1); /* get the xxmin etc variables recalc'd by redisplaying */
  1331.       }
  1332. }
  1333.  
  1334.  
  1335. /*
  1336.    Function setup287code is called by main() when a 287
  1337.    or better fpu is detected.
  1338. */
  1339. #define ORBPTR(x) fractalspecific[x].orbitcalc
  1340. extern FJuliafpFractal();
  1341. extern FBarnsley1FPFractal();
  1342. extern FBarnsley2FPFractal();
  1343. extern FManOWarfpFractal();
  1344. extern FLambdaFPFractal();
  1345. static void setup287code()
  1346. {
  1347.    ORBPTR(MANDELFP)      = ORBPTR(JULIAFP)     = FJuliafpFractal;
  1348.    ORBPTR(BARNSLEYM1FP)   = ORBPTR(BARNSLEYJ1FP) = FBarnsley1FPFractal;
  1349.    ORBPTR(BARNSLEYM2FP)   = ORBPTR(BARNSLEYJ2FP) = FBarnsley2FPFractal;
  1350.    ORBPTR(MANOWARFP)      = ORBPTR(MANOWARJFP)     = FManOWarfpFractal;
  1351.    ORBPTR(MANDELLAMBDAFP) = ORBPTR(LAMBDAFP)     = FLambdaFPFractal;
  1352. }
  1353.  
  1354.  
  1355.