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