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