home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / FORTH / FRASRC11.ZIP / FRACTINT.C < prev    next >
C/C++ Source or Header  |  1989-12-21  |  59KB  |  1,737 lines

  1.  
  2. /*
  3.     FRACTINT - The Ultimate Fractal Generator
  4.             Main Routine
  5. */
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <dos.h>
  11.  
  12. #ifndef __TURBOC__
  13. #include <malloc.h>
  14. #endif
  15.  
  16. #define PUTTHEMHERE 1            /* stuff common external arrays here */
  17.  
  18. #include "fractint.h"
  19.  
  20. int    adapter;        /* Video Adapter chosen from list in ...h */
  21.  
  22. struct fractal_info save_info, read_info; /*  for saving data in file */
  23. extern int biomorph;
  24. extern int askvideo;
  25. extern int forcesymmetry;
  26. extern    char    readname[];     /* name of fractal input file */
  27. extern    int     showfile;        /* has file been displayed yet? */
  28. #define    FUDGEFACTOR    29        /* fudge all values up by 2**this */
  29. #define FUDGEFACTOR2    24        /* (or maybe this)          */
  30.  
  31. #ifndef __TURBOC__
  32. #define MAXHISTORY    50        /* save this many historical rcds */
  33. long    far history[MAXHISTORY][7];    /* for historical (HOME Key) purposes */
  34. #else
  35. #define MAXHISTORY    10        /* save this many historical rcds */
  36. long    history[MAXHISTORY][7];        /* for historical (HOME Key) purposes */
  37. #endif
  38.  
  39. /* yes, I *know* it's supposed to be compatible with Microsoft C,
  40.    but some of the routines need to know if the "C" code
  41.    has been compiled with Turbo-C.  This flag is a 1 if FRACTINT.C 
  42.    (and presumably the other routines as well) has been compiled
  43.    with Turbo-C. */
  44.  
  45. int compiled_by_turboc;
  46.  
  47. extern    char    savename[];        /* save files using this name */
  48.  
  49. extern  char preview;    /* 3D preview mode flag */
  50.  
  51. extern char floatflag;            /* floating-point fractals? */
  52.  
  53. extern    char    temp1[];            /* temporary strings        */
  54.  
  55. extern    int    debugflag;        /* internal use only - you didn't see this */
  56. /*
  57.    the following variables are out here only so
  58.    that the calcfract() and assembler routines can get at them easily
  59. */
  60.     int    dotmode;            /* video access method      */
  61.     int    oktoprint;            /* 0 if printf() won't work */
  62.     int    xdots, ydots;            /* # of dots on the screen  */
  63.     int    colors;                /* maximum colors available */
  64.     int    maxit;                /* try this many iterations */
  65.     int    ixmin, ixmax, iymin, iymax;    /* corners of the zoom box  */
  66.     int    boxcount;            /* 0 if no zoom-box yet     */
  67.  
  68.     int    fractype;            /* if == 0, use Mandelbrot  */
  69.     int    numpasses;            /* 0 if single-pass, else 1 */
  70.     int    solidguessing;            /* 0 if disabled, else 1    */
  71.     long    creal, cimag;            /* real, imag'ry parts of C */
  72.     long    delx, dely;            /* screen pixel increments */
  73.     double    param[4];            /* up to four parameters    */
  74.     double    potparam[3];        /* three potential parameters*/
  75.     long    fudge;                /* 2**fudgefactor    */
  76.     int    bitshift;            /* fudgefactor        */
  77.  
  78.     int    hasconfig;            /* = 0 if 'fractint.cfg'    */
  79.     int    diskisactive;            /* disk-video drivers flag  */
  80.     int    diskvideo;            /* disk-video access flag   */
  81.     int    diskprintfs;            /* disk-video access flag   */
  82.  
  83. extern    long    lx0[MAXPIXELS], ly0[MAXPIXELS];    /* x, y grid                */
  84.  
  85. extern    int    inside;                /* inside color: 1=blue     */
  86. extern    int    cyclelimit;            /* color-rotator upper limit */
  87. extern    int    display3d;            /* 3D display flag: 0 = OFF */
  88. extern    int    overlay3d;            /* 3D overlay flag: 0 = OFF */
  89. extern    int    init3d[20];            /* '3d=nn/nn/nn/...' values */
  90.  
  91. extern unsigned char dacbox[256][3];    /* Video-DAC (filled in by SETVIDEO) */
  92. extern unsigned char olddacbox[256][3]; /* backup copy of the Video-DAC */
  93. extern int    daclearn, daccount;    /* used by the color-cyclers */
  94. extern int    extraseg;        /* used by Save-to-DISK routines */
  95. extern int    cpu;            /* cpu type            */
  96. extern int    fpu;            /* fpu type            */
  97. extern int    lookatmouse;        /* used to activate non-button mouse movement */
  98. extern int    out_line();        /* called in decoder */
  99. extern    int    outlin16();        /* called in decoder */
  100. extern int    line3d();        /* called in decoder */
  101. extern int    (*outln)();        /* called in decoder */
  102. extern    int    filetype;        /* GIF or other */
  103.  
  104. /* variables defined by the command line/files processor */
  105. extern    double    inversion[];
  106. extern    int    invert;            /* non-zero if inversion active */
  107. extern    int    initbatch;        /* 1 if batch run (no kbd)  */
  108. extern    int    initmode;        /* initial video mode       */
  109. extern    int    inititer;        /* initial value of maxiter */
  110. extern    int    initincr;        /* initial maxiter incrmnt  */
  111. extern    int    initpass;        /* initial pass mode        */
  112. extern    int    initsolidguessing;    /* initial solid-guessing md*/
  113. extern    int    initfractype;        /* initial type set flag    */
  114. extern    int    initcyclelimit;        /* initial cycle limit      */
  115. extern    int    initcorners;        /* initial flag: corners set*/
  116. extern    double    initxmin,initxmax;    /* initial corner values    */
  117. extern    double    initymin,initymax;    /* initial corner values    */
  118. extern    double    initparam[4];        /* initial parameters       */
  119. extern    int    LogFlag;        /* non-zero if logarithmic palettes */
  120. extern int transparent[];
  121. extern int decomp[];
  122.  
  123. extern int rflag, rseed;
  124.  
  125. void main(argc,argv)
  126. int argc;
  127. char *argv[];
  128. {
  129.     long    jxmin, jxmax, jymin, jymax;    /* "Julia mode" entry point */
  130.     long    xmin, xmax, ymin, ymax;        /* screen corner values */
  131.     double    atof(), ftemp;            /* floating point stuff    */
  132.     double    ccreal,ccimag;            /* Julia Set Parameters    */
  133.     double    xxmin,xxmax,yymin,yymax;    /* (printf) screen corners */
  134.     int    xstep, ystep;            /* zoom-box increment values */
  135.     int    axmode, bxmode, cxmode, dxmode;    /* video mode (BIOS ##) */
  136.     int    historyptr;            /* pointer into history tbl */
  137.     int    zoomoff;            /* = 0 when zoom is disabled */
  138.     int    kbdchar;            /* keyboard key-hit value */
  139.     int    more, kbdmore;            /* continuation variables */
  140.     int    i, j, k, l;            /* temporary loop counters */
  141.     int    displaypage;            /* signon display page      */
  142.     int    savedac;            /* save-the-Video DAC flag  */
  143.     int    olddotmode;            /* temp copy of dotmode        */
  144.     long    huge *xxxalloc;            /* Quick-C klooge (extraseg) */
  145.  
  146.     char accessmethod[2];            /* "B" if through the BIOS */
  147.  
  148. initasmvars();                    /* initialize ASM stuff */
  149.  
  150. hasconfig = readconfig();            /* read fractint.cfg, if any */
  151.  
  152. maxvideomode = initvideotable();        /* get the size of video table */
  153. if ( maxvideomode >= MAXVIDEOMODES)        /* that's all the Fn keys we got! */
  154.     maxvideomode = MAXVIDEOMODES;
  155.     
  156. cmdfiles(argc,argv);                /* process the command-line */
  157.  
  158. if (debugflag == 8088)                cpu = 8088;/* for testing purposes */
  159. if (debugflag == 2870 && fpu >= 287 ) fpu = 287; /* for testing purposes */
  160. if (debugflag ==  870 && fpu >=  87 ) fpu =  87; /* for testing purposes */
  161. if (debugflag ==   70 && fpu >=   0 ) fpu =   0; /* for testing purposes */
  162.  
  163. #ifdef __TURBOC__
  164.    compiled_by_turboc = 1;
  165. #else
  166.    compiled_by_turboc = 0;
  167. #endif
  168.  
  169. /*
  170.    This code is used for emergency purposes when we just *have* to
  171.    get CodeView working and we don't *care* about the fact that any
  172.    attempt to do something tricky like using help mode or a hi-rez
  173.    video mode will require "extraseg" memory that we just don't have.
  174.    
  175.    Note: unless and until you can get CodeView to reside *entirely* in
  176.    extended/expanded memory, run "codeview /s /e fractint debug=10000"
  177.    and don't use help or any hi-rez video modes (they require the full
  178.    92K of memory allocated to 'extraseg').
  179.  
  180.    Hopefully this code will go away when Microsoft C 6.0 is released
  181.    with a version of CodeView that resides entirely in extended/expanded
  182.    memory.
  183. */
  184.  
  185. #ifndef __TURBOC__
  186. if (debugflag == 10000 && extraseg == 0) { 
  187.     xxxalloc = (long huge *)halloc(16384L,4);  /* try for 64K */
  188.     extraseg = FP_SEG(xxxalloc);
  189.     if (extraseg == 0) {
  190.         xxxalloc = (long huge *)halloc(8192L,4); /* try for 32K */ 
  191.         extraseg = FP_SEG(xxxalloc);
  192.         }
  193.     }
  194. #endif
  195.  
  196. if (extraseg == 0) {            /* oops.  not enough memory     */
  197.     buzzer(2);
  198.     printf(" I'm sorry, but you don't have enough free memory \n");
  199.     printf(" to run this program.\n\n");
  200.     exit(1);
  201.     }
  202.  
  203. savedac = 0;                /* don't save the VGA DAC */
  204. diskisactive = 0;            /* disk-video is inactive */
  205. diskvideo = 0;                /* disk driver is not in use */
  206. diskprintfs = 1;            /* disk-video should display status */
  207. setvideomode(3,0,0,0);            /* switch to text mode */
  208.  
  209. if (debugflag == 10000) {        /* check for free memory */
  210.     char *tempptr;
  211.     printf("\n CPU type is %d \n\n FPU type is %d \n", cpu, fpu);
  212.     printf("\n checking for free memory ...\n\n");
  213.     for (i = 100;(tempptr = malloc(i)) != NULL; i+=100)
  214.         free(tempptr) ;
  215.     printf(" %d bytes free .. press any key to continue...\n", i-100);
  216.     getakey();
  217.     }
  218.  
  219. restorestart:
  220.  
  221. if(*readname){  /* This is why readname initialized to null string */
  222.     if (!overlay3d)            /* overlays use the existing mode */
  223.         initmode = -1;        /* no viewing mode set yet */
  224.     else
  225.         initmode = adapter;    /* use previous adapter mode for overlays */
  226.     if(find_fractal_info(readname,&read_info)==0){
  227.               inititer   = read_info.iterations;
  228.               initfractype  = read_info.fractal_type;
  229.               initxmin   = read_info.xmin;
  230.               initxmax   = read_info.xmax;
  231.               initymin   = read_info.ymin;
  232.               initymax   = read_info.ymax;
  233.               initparam[0]   = read_info.creal;
  234.               initparam[1]   = read_info.cimag;
  235.               
  236.               if(read_info.version > 0)
  237.             {
  238.                   initparam[2]  = read_info.parm3;
  239.                   initparam[3]  = read_info.parm4;
  240.                 potparam[0]   = read_info.potential[0];     
  241.                 potparam[1]   = read_info.potential[1];     
  242.                 potparam[2]   = read_info.potential[2];     
  243.                 rflag         = read_info.rflag;
  244.                 rseed         = read_info.rseed;
  245.                 inside        = read_info.inside;
  246.                 LogFlag       = read_info.logmap;
  247.                 inversion[0]  = read_info.invert[0];
  248.                 inversion[1]  = read_info.invert[1];
  249.                 inversion[2]  = read_info.invert[2];
  250.                 decomp[0]     = read_info.decomp[0];
  251.                 decomp[1]     = read_info.decomp[1];
  252.                 biomorph      = read_info.biomorph;
  253.                 forcesymmetry = read_info.symmetry;
  254.             }
  255.  
  256.          showfile = 0;
  257.     if (!overlay3d) {        /* don't worry about the video if overlay */
  258.         if ((hasconfig || askvideo) && read_info.info_id[0] == 'G') {
  259.             buzzer(2);
  260.             printf("You have selected an unknown (non-fractal) GIF image\n");
  261.             printf("I am treating this image as a PLASMA CLOUD of unknown video type\n");
  262.             }
  263.         if (read_info.dotmode == 11 && ! initbatch) {
  264.             buzzer(2);
  265.             printf("You have selected a fractal image generated in 'no-video' mode\n");
  266.             }
  267.         if (((hasconfig || askvideo) && read_info.info_id[0] == 'G') ||
  268.             (read_info.dotmode == 11 && ! initbatch)) {
  269.             printf("with resolution %d x %d x %d\n",
  270.                 read_info.xdots, read_info.ydots, read_info.colors);
  271.             }
  272.         if ((!(hasconfig || askvideo) || read_info.info_id[0] != 'G') && 
  273.             (read_info.dotmode != 11 || initbatch))
  274.              initmode = getGIFmode(&read_info);
  275.         if (initmode >= maxvideomode) initmode = -1;
  276.         if (/* read_info.info_id[0] != 'G' &&*/ read_info.dotmode != 11
  277.             && initmode >= 0
  278.             && (hasconfig || askvideo) && ! initbatch ){
  279.                         char c;
  280.             fromvideotable(initmode);
  281.             strcpy(accessmethod," ");
  282.             if (videoentry.dotmode == 1)
  283.                 accessmethod[0] = 'B';
  284.                     printf("fractal file contains following mode:\n\n");
  285. #ifdef __TURBOC__
  286.             printf("%-6.6s %-25.25s%5d x%4d%5d %1.1s  %-25.25s\n",
  287. #else
  288.             printf("%-6s %-25s%5d x%4d%5d %1s  %-25s\n",
  289. #endif
  290.                     fkeys[initmode],
  291.                 videoentry.name,
  292.                 videoentry.xdots,
  293.                 videoentry.ydots,
  294.                 videoentry.colors,
  295.                 accessmethod,
  296.                 videoentry.comment);
  297.                         printf("Legal for this machine? ([Y] or N) --> ");
  298.                     while((c=getch())!='y' && c!='Y' && c!='n' && c!='N' && c!=13);
  299.                     if( c == 'n' || c == 'N')
  300.                         initmode = -1;
  301.             }
  302.         else     {
  303.             /* initmode bad */
  304.             if (initmode == -1 && initbatch) 
  305.                            showfile = 1; /* pretend already displayed */
  306.                            }
  307.         if (initmode == -1 && ! initbatch) {
  308.             printf("\nPlease select a video mode with which to view this image by\n");
  309.             printf("pressing the appropriate function key (or press the ENTER)\n");
  310.             printf("key to bail out without displaying this image).  You can also press\n");
  311.             printf("the 'h' or '?' keys to get help on the available video modes)\n");
  312.             helpmode = HELPVIDEO;
  313.             while (!keypressed());
  314.             kbdchar = getakey();
  315.             for (initmode = 0; initmode < maxvideomode; initmode++)
  316.                 if (kbdchar == kbdkeys[initmode]) break;
  317.             if (initmode == maxvideomode) {
  318.                 *readname = NULL; /* failed ... zap filename */
  319.                         initmode = -1;
  320.                            showfile = 1; /* pretend already displayed */
  321.                 }
  322.         }
  323.             if (initmode >= 0) fromvideotable(initmode);
  324.             if (initmode >= 0 && (
  325.                 read_info.xdots != videoentry.xdots ||
  326.                  read_info.ydots != videoentry.ydots)) {
  327.                     initxmax = initxmin +
  328.                         ((initxmax-initxmin)*videoentry.xdots)/
  329.                         read_info.xdots;
  330.                     initymin = initymax -
  331.                         ((initymax-initymin)*videoentry.ydots)/
  332.                         read_info.ydots;
  333.                     if ((initfractype == MANDEL || initfractype == JULIA) &&
  334.                         ((initxmax-initxmin) > 4.0 || (initymax-initymin) > 4.0)) {
  335.                         initfractype = PLASMA;
  336.                         initparam[0] = 0;
  337.                         }
  338.                     }
  339.                 }
  340.  
  341.         if (initmode >= 0 && display3d) {
  342.             initfractype = PLASMA;
  343.             initparam[0] = 0;
  344.             }
  345.         if (initmode >= 0 && display3d && ! initbatch) {
  346.             printf("\n\n");
  347.             if(preview)
  348.                strcpy(temp1,"yes");
  349.             else
  350.                strcpy(temp1,"no");
  351.             printf("Preview Mode? (y or n) (if not %3s) ",temp1);
  352.             gets(temp1);
  353.             if(*temp1 == 'y' || *temp1 == 'Y') {
  354.                            preview = 1;
  355.                            temp1[0] = 0;
  356.                            }
  357.                         else {
  358.                            if (*temp1 != 0)
  359.                               preview = 0;                  
  360.                            }
  361.             if(SPHERE)
  362.                strcpy(temp1,"yes");
  363.             else
  364.                strcpy(temp1,"no");
  365.             printf("\n\nSphere Projection? (y or n) (if not %3s) ",temp1);
  366.             gets(temp1);
  367.             if((*temp1 == 'y' || *temp1 == 'Y') && !SPHERE)
  368.                     {
  369.                /* reset sphere defaults */
  370.                SPHERE    = TRUE;    
  371.                PHI1      =  180;    
  372.                PHI2      =  0;   
  373.                THETA1    =  -90;   
  374.                THETA2    =  90;   
  375.                RADIUS    =  100;   
  376.                ROUGH     =  30;   
  377.                WATERLINE = 0;
  378.                FILLTYPE  = 2;
  379.                ZVIEWER   = 0;
  380.                XSHIFT    = 0;
  381.                YSHIFT    = 0;
  382.                XLIGHT    = 0;
  383.                YLIGHT    = 0;
  384.                ZLIGHT    = 1;
  385.                LIGHTAVG  = 1;
  386.             }   
  387.             else if((*temp1 == 'n' || *temp1 == 'N') && SPHERE)
  388.             {
  389.                SPHERE    = FALSE;    
  390.                XROT      = 60;
  391.                YROT      = 30;
  392.                ZROT      = 0;
  393.                XSCALE    = 90;
  394.                YSCALE    = 90;
  395.                ROUGH     = 30;   
  396.                WATERLINE = 0;
  397.                FILLTYPE  = 0;
  398.                ZVIEWER   = 0;
  399.                XSHIFT    = 0;
  400.                YSHIFT    = 0;
  401.                XLIGHT    = 0;
  402.                YLIGHT    = 0;
  403.                ZLIGHT    = 1;
  404.                LIGHTAVG  = 1;
  405.             }   
  406.             if(SPHERE){
  407.  
  408.             /* BEGIN Sphere-specific parameters */
  409.             printf("\n\nSphere is on its side; North pole to right\n");
  410.             printf("180 degrees longitude is top; 0 degrees bottom\n");
  411.             printf("-90 degrees latitude is left; 90 degrees right\n");
  412.             printf("Longitude start (degrees) (if not %3d) ",PHI1);
  413.             gets(temp1);
  414.             k = atoi(temp1);
  415.             if (temp1[0] >19) PHI1 = k;
  416.             printf("Longitude stop  (degrees) (if not %3d) ",PHI2);
  417.             gets(temp1);
  418.             k = atoi(temp1);
  419.             if (temp1[0] >19) PHI2 = k;
  420.             printf("Latitude start  (degrees) (if not %3d) ",THETA1);
  421.             gets(temp1);
  422.             k = atoi(temp1);
  423.             if (temp1[0] >19) THETA1 = k;
  424.             printf("Latitude stop   (degrees) (if not %3d) ",THETA2);
  425.             gets(temp1);
  426.             k = atoi(temp1);
  427.             if (temp1[0] >19) THETA2 = k;
  428.             printf("Radius scaling factor in pct  (if not %3d)  ",RADIUS);
  429.             gets(temp1);
  430.             k = atoi(temp1);
  431.             if (temp1[0] >19) RADIUS = k;
  432.             }else{
  433.             /* BEGIN Regular-3D-specific parameters */
  434.             printf("X-axis rotation in degrees (if not %3d) ",XROT);
  435.             gets(temp1);
  436.             k = atoi(temp1);
  437.             if (temp1[0] >19) XROT = k;
  438.             printf("Y-axis rotation in degrees (if not %3d) ",YROT);
  439.             gets(temp1);
  440.             k = atoi(temp1);
  441.             if (temp1[0] >19) YROT = k;
  442.             printf("Z-axis rotation in degrees (if not %3d)  ",ZROT);
  443.             gets(temp1);
  444.             k = atoi(temp1);
  445.             if (temp1[0] >19) ZROT = k;
  446.             printf("X-axis scaling factor in pct  (if not %3d)  ",XSCALE);
  447.             gets(temp1);
  448.             k = atoi(temp1);
  449.             if (temp1[0] >19) XSCALE = k;
  450.             printf("Y-axis scaling factor in pct  (if not %3d)  ",YSCALE);
  451.             gets(temp1);
  452.             k = atoi(temp1);
  453.             if (temp1[0] >19) YSCALE = k;
  454.             }
  455.             /* Begin Common Parameters */
  456.             printf("Surface Roughness scaling factor in pct  (if not %3d)  ",ROUGH);
  457.             gets(temp1);
  458.             k = atoi(temp1);
  459.             if (temp1[0] >19) ROUGH = k;
  460.             printf("'Water Level' (minimum color value)  (if not %3d)  ",WATERLINE);
  461.             gets(temp1);
  462.             k = atoi(temp1);
  463.             if (temp1[0] >19) WATERLINE = k;
  464.             printf("Line-Fill options are 0 - just draw the dots, 1 - connected dots (wire frame),\n");
  465.             printf("  2 - surface-fill, 3 - surface fill (no interpolation), 4 - solid fill,\n");
  466.             printf("  5 - light source before transformation, 6 - light source after transformation\n");
  467.             printf("  Enter the Fill option  (if not %3d)  ",FILLTYPE);
  468.             gets(temp1);
  469.             k = atoi(temp1);
  470.             if (k > 6) k = 6;
  471.             if (k <= 0) k = 0;
  472.             if (temp1[0] >19) FILLTYPE = k;
  473.             printf("Perspective 'height' [1 - 999, 0 for no perspective] (if not %3d) ",ZVIEWER);
  474.             gets(temp1);
  475.             k = atoi(temp1);
  476.             if (temp1[0] >19) ZVIEWER = k;
  477.             printf("X shift (positive = right)(if not %3d) ",XSHIFT);
  478.             gets(temp1);
  479.             k = atoi(temp1);
  480.             if (temp1[0] >19) XSHIFT = k;
  481.             printf("Y shift (positive = up    )(if not %3d) ",YSHIFT);
  482.             gets(temp1);
  483.             k = atoi(temp1);
  484.             if (temp1[0] >19) YSHIFT = k;
  485.             if(ILLUMINE)
  486.             {
  487.             printf("X value light vector  )(if not %3d) ",XLIGHT);
  488.             gets(temp1);
  489.             k = atoi(temp1);
  490.             if (temp1[0] >19) XLIGHT = k;
  491.             printf("Y value light vector  )(if not %3d) ",YLIGHT);
  492.             gets(temp1);
  493.             k = atoi(temp1);
  494.             if (temp1[0] >19) YLIGHT = k;
  495.             printf("Z value light vector  )(if not %3d) ",ZLIGHT);
  496.             gets(temp1);
  497.             k = atoi(temp1);
  498.             if (temp1[0] >19) ZLIGHT = k;
  499.             printf("Light Source Smoothing Factor )(if not %3d) ",LIGHTAVG);
  500.             gets(temp1);
  501.             k = atoi(temp1);
  502.             if (temp1[0] >19) LIGHTAVG = k;
  503.             }
  504.                         printf("First transparent color (if not %3d) ",transparent[0]);
  505.                         gets(temp1);
  506.                         k = atoi(temp1);
  507.                         if (k > 0) transparent[0] = k;
  508.                         printf("Last transparent color (if not %3d) ",transparent[1]);
  509.                         gets(temp1);
  510.                         k = atoi(temp1);
  511.                         if (k > 0) transparent[1] = k;
  512.             }
  513.         initcorners = 1;
  514.               }
  515.     else    {
  516.         buzzer(2);
  517.         initmode = -1;
  518.         *readname = NULL;
  519.         }
  520.     }
  521.  
  522. if (overlay3d && initmode < 0) {    /* overlay command failed */
  523.     setforgraphics();        /* restore the graphics screen */
  524.     overlay3d = 0;            /* forget overlays */
  525.     display3d = 0;            /* forget 3D */
  526.     goto resumeloop;        /* ooh, this is ugly */
  527.     }
  528.  
  529.  
  530. restart:                                /* insert key re-starts here */
  531.  
  532. savedac = 0;                /* don't save the VGA DAC */
  533.  
  534. lookatmouse = 0;            /* de-activate full mouse-checking */
  535.  
  536. maxit = inititer;                /* max iterations */
  537. numpasses = initpass-1;                /* single/dual-pass mode */
  538. solidguessing = initsolidguessing;        /* solid-guessing mode */
  539.  
  540. fractype = initfractype;            /* use the default set   */
  541.  
  542. if (floatflag) {                /* adjust for floating pt */
  543.     if (fractalspecific[fractype].isinteger != 0 &&
  544.         fractalspecific[fractype].tofloat != NOFRACTAL) 
  545.         fractype = fractalspecific[fractype].tofloat;
  546.     }
  547. else    {
  548.     if (fractalspecific[fractype].isinteger == 0 &&
  549.         fractalspecific[fractype].tofloat != NOFRACTAL) 
  550.         fractype = fractalspecific[fractype].tofloat;
  551.     }
  552.  
  553. cyclelimit = initcyclelimit;            /* default cycle limit     */
  554. for (i = 0; i < 4; i++) param[i] = initparam[i];/* use the default params*/
  555. ccreal = param[0]; ccimag = param[1];        /* default C-values      */
  556. xxmin = initxmin; xxmax = initxmax;        /* default corner values */
  557. yymin = initymin; yymax = initymax;        /* default corner values */
  558.  
  559. if (xxmin > xxmax) { ftemp = xxmax; xxmax = xxmin; xxmin = ftemp; }
  560. if (yymin > yymax) { ftemp = yymax; yymax = yymin; yymin = ftemp; }
  561.  
  562. /* set some reasonable limits on the numbers (or the algorithms will fail) */
  563.  
  564. if(fractalspecific[fractype].isinteger > 1)
  565.    bitshift = fractalspecific[fractype].isinteger;
  566. else
  567.    bitshift = FUDGEFACTOR2;                     /* shift bits by this much */
  568. if (fractype == MANDEL || fractype == JULIA) {  /* adust shift bits if.. */
  569.    if (fabs(potparam[0]) < .0001                /* not using potential */
  570.        && (fractype != MANDEL ||                /* and not an int mandel */
  571.        (ccreal == 0.0 && ccimag == 0.0))        /*  w/ "fudged" parameters */
  572.        && ! invert                              /* and not inverting */
  573.        && biomorph == -1                        /* and not biomorphing */
  574.        && debugflag != 1234)                    /* and not debugging */
  575.        bitshift = FUDGEFACTOR;
  576.    if (ccreal < -1.99 || ccreal > 1.99) ccreal = 1.99;
  577.    if (ccimag < -1.99 || ccimag > 1.99) ccimag = 1.99;
  578.    }
  579.  
  580. ftemp = 32767.99;                               /* avoid corners overflow */
  581. if (bitshift >= 24) ftemp = 31.99;
  582. if (bitshift >= 29) ftemp = 3.99;
  583. if (xxmax - xxmin > ftemp) xxmax = xxmin + ftemp;
  584. if (yymax - yymin > ftemp) yymax = yymin + ftemp;
  585.  
  586. fudge = 1; fudge = fudge << bitshift;          /* fudged value for printfs */
  587.  
  588. ccreal = ccreal * fudge; creal = ccreal;
  589. ccimag = ccimag * fudge; cimag = ccimag;
  590. xxmin = xxmin * fudge; xmin = xxmin;
  591. xxmax = xxmax * fudge; xmax = xxmax;
  592. yymin = yymin * fudge; ymin = yymin;
  593. yymax = yymax * fudge; ymax = yymax;
  594.  
  595. jxmin = xmin;  jxmax = xmax;
  596. jymin = ymin;  jymax = ymax;
  597.  
  598. adapter = initmode;            /* set the video adapter up    */
  599. initmode = -1;                /* (once)            */
  600.  
  601. helpmode = HELPAUTHORS;            /* use this help mode */
  602. if (adapter < 0)
  603.     help();                /* display the credits screen    */
  604. helpmode = HELPMENU;            /* now use this help mode */
  605.  
  606. while (adapter < 0) {            /* cycle through instructions    */
  607.  
  608.     if (initbatch == 0) {            /* online-mode only, please */
  609.         while (!keypressed()) ;        /* enable help */
  610.         kbdchar = getakey();
  611.         }
  612.     else
  613.         kbdchar = 27;
  614.         if (kbdchar == 32) continue;        /* spacebar stops scrolling */
  615.     while (kbdchar == 13 || kbdchar == 1013) { /* ENTER calls help, here */
  616.         kbdchar = help();
  617.         }
  618.     adapter = -1;                /* no video adapter yet */
  619.     for (k = 0; k < maxvideomode; k++)    /* search for an adapter */
  620.         if (kbdchar == kbdkeys[k])
  621.             adapter = k;        /* use this adapter */
  622.     if (adapter >= 0) break;        /* bail out if we found one */
  623.     if (kbdchar == 1082) goto restart;    /* restart pgm on Insert Key */
  624.     if (kbdchar == 1000) goodbye();        /* Control-C */
  625.     if (kbdchar == 27) goodbye();        /* exit to DOS on Escape Key */
  626.     if (kbdchar == 1083) goodbye();        /* exit to DOS on Delete Key */
  627.         if (kbdchar == 'd' || kbdchar == 'D') { /* shell to DOS */
  628.             clscr();
  629.         printf("\n\nShelling to DOS - type 'exit' to return\n\n");
  630.             system("command.com");
  631.             goto restart;
  632.             }
  633.     if (kbdchar == '1' || kbdchar == '2') {    /* select single or dual-pass */
  634.         numpasses = kbdchar - '1';
  635.         solidguessing = 0;
  636.         continue;
  637.         }
  638.     if (kbdchar == 'g' || kbdchar == 'G') {    /* solid-guessing */
  639.         numpasses = 1;
  640.         solidguessing = 1;
  641.         continue;
  642.         }
  643.     if (kbdchar == 'n' || kbdchar == 'N') { /* normal palette */
  644.         LogFlag = 0;
  645.         ChkLogFlag();
  646.         continue;
  647.         }
  648.     if (kbdchar == 'l' || kbdchar == 'L') { /* logarithmic palette */
  649.         LogFlag = 1;
  650.         continue;
  651.         }
  652.     if (kbdchar == 'r' || kbdchar == 'R' ||    kbdchar == '3'
  653.         || kbdchar == 'o' || kbdchar == 'O') {    /* restore old image    */
  654.         display3d = 0;
  655.         if (kbdchar == '3' || kbdchar == 'o' ||
  656.             kbdchar == 'O') display3d = 1;
  657.         setvideomode(3,0,0,0);    /* switch to text mode */
  658.             printf("\n Restart from what file? ");
  659.             gets(readname);
  660.             goto restorestart;
  661.             }
  662.     if (kbdchar == 't' || kbdchar == 'T') {    /* set fractal type */
  663.         olddotmode = dotmode;    /* save the old dotmode */
  664.         dotmode = 1;        /* force a disable of any 8514/A */
  665.         if ((j = getfracttype(initfractype)) < 0) goto restart;
  666.         initfractype = j;
  667.         invert = 0;
  668.         inversion[0] = inversion[1] = inversion[2] = 0;
  669.         for ( i = 0; i < 4; i++)
  670.             initparam[i] = 0.0;
  671.         for ( i = 0; i < 3; i++)
  672.             potparam[i] = 0.0;
  673.         for (i = 0; i < 4; i++) {
  674.             if (fractalspecific[initfractype].param[i][0] == 0) break;
  675.               if (i == 0) {
  676.                   printf("\n\n Select your options for fractal type %s",
  677.                       fractalspecific[initfractype].name[0] != '*' ?
  678.                       fractalspecific[initfractype].name           :
  679.                       &fractalspecific[initfractype].name[1]       );
  680.                    printf("\n\n Please enter any parameters that apply (an empty response bails out) \n\n");
  681.                 }
  682.             printf(" %s => ", fractalspecific[initfractype].param[i]);
  683.             temp1[0] = 0;
  684.             gets(temp1);
  685.             initparam[i] = atof(temp1);
  686.             if (temp1[0] == 0) i = 99;
  687.             }
  688.         initcorners = 1;
  689.         initxmin = fractalspecific[initfractype].xmin;
  690.         initxmax = fractalspecific[initfractype].xmax;
  691.         initymin = fractalspecific[initfractype].ymin;
  692.         initymax = fractalspecific[initfractype].ymax;
  693.         dotmode = olddotmode;
  694.         goto restart;
  695.         }
  696.     if (kbdchar == 'f' || kbdchar == 'F') {    /* floating pt toggle */
  697.         if (floatflag == 0)
  698.             floatflag = 1;
  699.         else
  700.             floatflag = 0;
  701.         goto restart;
  702.         }
  703.     if (kbdchar == 'e' || kbdchar == 'E') {    /* set IFS fractal parms */
  704.         clscr();
  705.         ifsgetparams();        /* get the parameters */
  706.         goto restart;
  707.         }
  708.     else 
  709.         buzzer(2);
  710.     }
  711.  
  712. historyptr = 0;                    /* initialize history ptr */
  713. history[0][0] = -1;
  714. zoomoff = 1;                    /* zooming is enabled */
  715.  
  716. helpmode = HELPMAIN;                /* switch help modes */
  717.  
  718.  
  719. more = 1;
  720. while (more) {                    /* eternal loop */
  721.  
  722.                         /* collect adapter info */
  723.     fromvideotable(adapter);
  724.     axmode  = videoentry.videomodeax;     /* video mode (BIOS call) */
  725.     bxmode  = videoentry.videomodebx;     /* video mode (BIOS call) */
  726.     cxmode  = videoentry.videomodecx;     /* video mode (BIOS call) */
  727.     dxmode  = videoentry.videomodedx;     /* video mode (BIOS call) */
  728.     dotmode = videoentry.dotmode;        /* assembler dot read/write */
  729.     xdots   = videoentry.xdots;        /* # dots across the screen */
  730.     ydots   = videoentry.ydots;        /* # dots down the screen   */
  731.     colors  = videoentry.colors;        /* # colors available */
  732.  
  733.     diskvideo = 0;                /* set diskvideo flag */
  734.     if (dotmode == 11)            /* default assumption is disk */
  735.         diskvideo = 2;
  736.  
  737.     memcpy(olddacbox,dacbox,256*3);        /* save the DAC */
  738.     diskisactive = 1;        /* flag for disk-video routines */
  739.     if (overlay3d) {
  740.         setforgraphics();    /* restore old graphics image */
  741.         overlay3d = 0;
  742.         }
  743.     else
  744.             setvideomode(axmode,bxmode,cxmode,dxmode); /* switch video modes */
  745.     diskisactive = 0;        /* flag for disk-video routines */
  746.     if (savedac) {
  747.         memcpy(dacbox,olddacbox,256*3);        /* restore the DAC */
  748.         spindac(0,1);
  749.         }
  750.     savedac = 1;                /* assume we save next time */
  751.  
  752.     if(*readname && showfile==0) {
  753.         /*
  754.         only requirements for gifview: take file name in global
  755.         variable "readname" - link to frasmint's video (I used putcolor),
  756.         and should NOT set video mode (that's done here)
  757.         */
  758.  
  759.         if (display3d)            /* set up 3D decoding */
  760.             outln = line3d;
  761.         else if(filetype >= 1)
  762.             outln = outlin16;
  763.         else
  764.             outln = out_line;
  765.         {
  766.            extern int filetype;    
  767.            if(filetype == 0)
  768.               gifview();
  769.            else
  770.               tgaview();
  771.         }
  772.         display3d = 0;            /* turn off 3D retrievals */
  773.          }
  774.  
  775.     xstep   = xdots / 40;            /* zoom-box increment: across */
  776.     ystep   = ydots / 40;            /* zoom-box increment: down */
  777.     if (xdots == 640 && ydots == 350)    /* zoom-box adjust:  640x350 */
  778.         { xstep = 16; ystep =  9; }
  779.     if (xdots == 720 && ydots == 348)    /* zoom-box adjust:  720x348 */
  780.         { xstep = 18; ystep =  9; }
  781.     if (xdots == 632 && ydots == 474)    /* zoom-box adjust:  632x474 */
  782.         { xstep = 16; ystep = 12; }
  783.     if (xdots == 720 && ydots == 512)    /* zoom-box adjust:  720x512 */
  784.         { xstep = 20; ystep = 15; }
  785.     if (xdots * 3 == ydots * 4)        /* zoom-box adjust:  VGA Tweaks */
  786.         { xstep = 16; ystep = 12; }
  787.     if (xdots == 1024 && ydots == 768)    /* zoom-box adjust: 1024x768 */
  788.         { xstep = 32; ystep = 24; }
  789.     if (xdots == 1016 && ydots == 762)    /* zoom-box adjust: 1018x762 */
  790.         { xstep = 32; ystep = 24; }
  791.     if (xdots == 720 && ydots == 348)    /* zoom-box adjust:  720x348 */
  792.         { xstep = 18; ystep =  9; }
  793.  
  794.     delx = ((xmax - xmin) / (xdots - 1));    /* calculate the stepsizes */
  795.     dely = ((ymax - ymin) / (ydots - 1));
  796.  
  797.     zoomoff = 1;                /* zooming is enabled */
  798.     if (delx <= 1 || dely <= 1) {    /* oops.  zoomed too far */
  799.         zoomoff = 0;
  800.         dely = 1;
  801.         delx = 1;
  802.         }
  803.     if (dotmode == 11 || fractype == PLASMA)
  804.         zoomoff = 0;        /* disable zooming */
  805.  
  806.     lx0[0] = xmin;                /* fill up the x, y grids */
  807.     ly0[0] = ymax;
  808.     for (i = 1; i < xdots; i++ )
  809.         lx0[i] = lx0[i-1] + delx;
  810.     for (i = 1; i < ydots; i++ )
  811.         ly0[i] = ly0[i-1] - dely;
  812.  
  813.     if (zoomoff == 0) {
  814.         xmax = lx0[xdots-1];        /* re-set xmax and ymax */
  815.         ymin = ly0[ydots-1];
  816.         }
  817.  
  818.          if ((fractype == MANDEL || fractype == JULIA) && bitshift == 29)
  819.             decomp[1] = 0;      /* make the world safe for decomposition */
  820.  
  821.     if (history[0][0] == -1)            /* initialize the history file */
  822.         for (i = 0; i < MAXHISTORY; i++) {
  823.             history[i][0] = xmax;
  824.             history[i][1] = xmin;
  825.             history[i][2] = ymax;
  826.             history[i][3] = ymin;
  827.             history[i][4] = creal;
  828.             history[i][5] = cimag;
  829.             history[i][6] = fractype;
  830.         }
  831.  
  832.     if (history[historyptr][0] != xmax  ||    /* save any (new) zoom data */
  833.         history[historyptr][1] != xmin  ||
  834.         history[historyptr][2] != ymax  ||
  835.         history[historyptr][3] != ymin  ||
  836.         history[historyptr][4] != creal ||
  837.         history[historyptr][5] != cimag ||
  838.         history[historyptr][6] != fractype) {
  839.         if (++historyptr == MAXHISTORY) historyptr = 0;
  840.         history[historyptr][0] = xmax;
  841.         history[historyptr][1] = xmin;
  842.         history[historyptr][2] = ymax;
  843.         history[historyptr][3] = ymin;
  844.         history[historyptr][4] = creal;
  845.         history[historyptr][5] = cimag;
  846.         history[historyptr][6] = fractype;
  847.         }
  848.  
  849.     if (diskvideo) {        /* disk-file video klooges */
  850.         numpasses = 0;        /* single-pass mode */
  851.         solidguessing = 0;    /* no solid-guessing */
  852.         }
  853.  
  854.     if(*readname && showfile==0)
  855.         showfile = 1;
  856.     else    {
  857.         diskisactive = 1;    /* flag for disk-video routines */
  858.         /* TW 07/21/89 - see below */
  859.         /* set save parameters in save structure */
  860.         strcpy(save_info.info_id, INFO_ID);
  861.         save_info.iterations   = maxit;
  862.         save_info.fractal_type = fractype;
  863.         save_info.xmin         = xxmin;
  864.         save_info.xmax         = xxmax;
  865.         save_info.ymin         = yymin;
  866.         save_info.ymax         = yymax;
  867.         save_info.creal        = param[0];
  868.         save_info.cimag        = param[1];
  869.         save_info.videomodeax  = videoentry.videomodeax;
  870.         save_info.videomodebx  = videoentry.videomodebx;
  871.         save_info.videomodecx  = videoentry.videomodecx;
  872.         save_info.videomodedx  = videoentry.videomodedx;
  873.         save_info.dotmode    = videoentry.dotmode;
  874.         save_info.xdots        = videoentry.xdots;
  875.         save_info.ydots        = videoentry.ydots;
  876.         save_info.colors    = videoentry.colors;
  877.         save_info.version = 1;
  878.           save_info.parm3          = param[2]; 
  879.           save_info.parm4          = param[3]; 
  880.         save_info.potential[0]   = potparam[0];
  881.         save_info.potential[1]   = potparam[1];
  882.         save_info.potential[2]   = potparam[2];
  883.         save_info.rflag          = rflag;
  884.         save_info.rseed          = rseed;
  885.         save_info.inside         = inside;
  886.         save_info.logmap         = LogFlag;
  887.         save_info.invert[0]      = inversion[0];
  888.         save_info.invert[1]      = inversion[1];
  889.         save_info.invert[2]      = inversion[2]; 
  890.         save_info.decomp[0]      = decomp[0];
  891.         save_info.decomp[1]      = decomp[1];
  892.         save_info.biomorph       = biomorph;
  893.         save_info.symmetry       = forcesymmetry;
  894.  
  895.         for (i = 0; i < sizeof(save_info.future)/sizeof(int); i++)
  896.                save_info.future[i] = 0;
  897.  
  898.         if (calcfract() == 0)        /* draw the fractal using "C" */
  899.             buzzer(0);        /* finished!! */
  900.         if( dotmode == 9 || dotmode == 11 ) {    /* if TARGA or disk-video */
  901.             if( dotmode == 11 )    /* TARGA already has some text up */
  902.                 home();
  903.             else
  904.                 EndTGA();    /* make sure TARGA is OFF */
  905.             printf("Image has been completed");
  906.         }
  907.         diskisactive = 0;    /* flag for disk-video routines */
  908.         }
  909.  
  910.     ixmin = 0;  ixmax = xdots-1;        /* initial zoom box */
  911.     iymin = 0;  iymax = ydots-1;
  912.     boxcount = 0;                /* no zoom box yet  */
  913.  
  914.     if (fractype == PLASMA && cpu > 88) {
  915.         cyclelimit = 256;        /* plasma clouds need quick spins */
  916.         daccount = 256;
  917.         daclearn = 1;
  918.         }
  919.  
  920. resumeloop:                    /* return here on failed overlays */
  921.  
  922.     kbdmore = 1;
  923.     while (kbdmore == 1) {            /* loop through cursor keys */
  924.         if (initbatch == 0) {        /* online only, please */
  925.             lookatmouse = 1;    /* activate full mouse-checking */
  926.             while (!keypressed());    /* enables help */
  927.             kbdchar = getakey();
  928.             lookatmouse = 0;    /* de-activate full mouse-checking */
  929.             }
  930.         else {                /* batch mode special  */
  931.             if (initbatch == 1) {    /* first, save-to-disk */
  932.                 kbdchar = 's';
  933.                 initbatch = 2;
  934.                 }
  935.             else
  936.                 kbdchar = 27;    /* then, exit          */
  937.             }
  938.         switch (kbdchar) {
  939.             case 't':            /* new fractal type */
  940.             case 'T':
  941.                 olddotmode = dotmode;    /* save the old dotmode */
  942.                 dotmode = 1;        /* force a disable of any 8514/A */
  943.                 if ((j = getfracttype(fractype)) < 0) goto restart;
  944.                 initfractype = j;
  945.                 invert = 0;
  946.                 inversion[0] = inversion[1] = inversion[2] = 0;
  947.                 initfractype = j;
  948.                 savedac = 0;
  949.                 for ( i = 0; i < 4; i++)
  950.                     initparam[i] = 0.0;
  951.                 for (i = 0; i < 4; i++) {
  952.                     if (fractalspecific[initfractype].param[i][0] == 0) break;
  953.                       if (i == 0) {
  954.                           printf("\n\n Select your options for fractal type %s",
  955.                               fractalspecific[initfractype].name[0] != '*' ?
  956.                               fractalspecific[initfractype].name           :
  957.                               &fractalspecific[initfractype].name[1]       );
  958.                            printf("\n\n Please enter any parameters that apply (an empty response bails out) \n\n");
  959.                         }
  960.                     printf(" %s => ", fractalspecific[initfractype].param[i]);
  961.                     temp1[0] = 0;
  962.                     gets(temp1);
  963.                     initparam[i] = atof(temp1);
  964.                     if (temp1[0] == 0) i = 99;
  965.                     }
  966.                 initcorners = 1;
  967.                 initxmin = fractalspecific[initfractype].xmin;
  968.                 initxmax = fractalspecific[initfractype].xmax;
  969.                 initymin = fractalspecific[initfractype].ymin;
  970.                 initymax = fractalspecific[initfractype].ymax;
  971.                 initmode = adapter;
  972.                 dotmode = olddotmode;
  973.                 goto restart;
  974.                 break;
  975.             case 'f':            /* floating pt toggle */
  976.             case 'F':
  977.                 if (floatflag == 0)
  978.                     floatflag = 1;
  979.                 else
  980.                     floatflag = 0;
  981.                 initfractype = fractype;
  982.                 initmode = adapter;
  983.                 initxmin = xmin; initxmin /= fudge;
  984.                 initxmax = xmax; initxmax /= fudge;
  985.                 initymin = ymin; initymin /= fudge;
  986.                 initymax = ymax; initymax /= fudge;
  987.                 for (i = 0; i < 4; i++)
  988.                     initparam[i] = param[i];
  989.                 goto restart;
  990.             case 'e':            /* new IFS parms    */
  991.             case 'E':
  992.                 setfortext();        /* switch to text mode */
  993.                 ifsgetparams();        /* get the parameters */
  994.                 setforgraphics();    /* back to graphics */
  995.                 kbdmore = 0;
  996.                 break;
  997.             case 'i':            /* inversion parms    */
  998.             case 'I':
  999.                 setfortext();        /* switch to text mode */
  1000.                 get_invert_params();    /* get the parameters */
  1001.                 setforgraphics();    /* back to graphics */
  1002.                 kbdmore = 0;
  1003.                 break;
  1004.             case 'q':            /* decomposition parms    */
  1005.             case 'Q':
  1006.                 setfortext();        /* switch to text mode */
  1007.                 get_decomp_params();    /* get the parameters */
  1008.                 setforgraphics();    /* back to graphics */
  1009.                 kbdmore = 0;
  1010.                 break;
  1011.             case 32:            /* spacebar */
  1012.                 if (fractalspecific[fractype].tojulia != NOFRACTAL
  1013.                     && creal == 0 && cimag == 0) { 
  1014.                      /* switch to corresponding Julia set */
  1015.                     fractype = fractalspecific[fractype].tojulia;
  1016.                     creal = (xmax + xmin) / 2;
  1017.                     cimag = (ymax + ymin) / 2;
  1018.                     param[0] = creal; param[0] /= fudge;
  1019.                     param[1] = cimag; param[1] /= fudge;
  1020.                     jxmin = lx0[0]; jxmax = lx0[xdots-1];
  1021.                     jymax = ly0[0]; jymin = ly0[ydots-1];
  1022.  
  1023.                     xxmin = fractalspecific[fractype].xmin;
  1024.                     xxmax = fractalspecific[fractype].xmax;
  1025.                     yymin = fractalspecific[fractype].ymin;
  1026.                     yymax = fractalspecific[fractype].ymax;
  1027.  
  1028.                     if(biomorph != -1 && bitshift != 29)
  1029.                     {
  1030.                        xxmin *= 3.0;
  1031.                        xxmax *= 3.0;
  1032.                        yymin *= 3.0;
  1033.                        yymax *= 3.0;
  1034.                     }
  1035.  
  1036.                     xxmin = xxmin * fudge; xmin = xxmin;
  1037.                     xxmax = xxmax * fudge; xmax = xxmax - 100;
  1038.                     yymin = yymin * fudge; ymin = yymin + 100;
  1039.                     yymax = yymax * fudge; ymax = yymax;
  1040.                     zoomoff = 1;
  1041.                     }
  1042.                 else if (fractalspecific[fractype].tomandel != NOFRACTAL) { 
  1043.                      /* switch to corresponding Mandel set */
  1044.                     fractype = fractalspecific[fractype].tomandel;
  1045.                     creal = 0;
  1046.                     cimag = 0;
  1047.                     param[0] = 0;
  1048.                     param[1] = 0;
  1049.                     xmin = jxmin;  xmax = jxmax;
  1050.                     ymin = jymin;  ymax = jymax;
  1051.                     zoomoff = 1;
  1052.                     }
  1053.                 else buzzer(2);        /* no switch */
  1054.                 kbdmore = 0;
  1055.                 break;
  1056.             case 1071:            /* home */
  1057.                 if (--historyptr < 0)
  1058.                     historyptr = MAXHISTORY-1;
  1059.                 xmax  = history[historyptr][0];
  1060.                 xmin  = history[historyptr][1];
  1061.                 ymax  = history[historyptr][2];
  1062.                 ymin  = history[historyptr][3];
  1063.                 creal = history[historyptr][4];
  1064.                 cimag = history[historyptr][5];
  1065.                 fractype = history[historyptr][6];
  1066.                 param[0] = creal; param[0] /= fudge;
  1067.                 param[1] = cimag; param[1] /= fudge;
  1068.                 zoomoff = 1;
  1069.                 kbdmore = 0;
  1070.                 break;
  1071.             case 9:                /* tab */
  1072.                 xxmax = xmax; xxmax = xxmax / fudge;
  1073.                 xxmin = xmin; xxmin = xxmin / fudge;
  1074.                 yymax = ymax; yymax = yymax / fudge;
  1075.                 yymin = ymin; yymin = yymin / fudge;
  1076.                 setfortext();
  1077.                 printf("\n\nCurrent Fractal Type is: %-7s \n\n", 
  1078.                         fractalspecific[fractype].name[0] == '*' ?
  1079.                         &fractalspecific[fractype].name[1] :
  1080.                         fractalspecific[fractype].name);
  1081.                 for(i=0;i<4;i++)
  1082.                 printf("   Param%1d = %12.9f \n",i+1,param[i]);
  1083.                 printf("\nCurrent Screen Corners are: \n\n");
  1084.                 printf("     Xmin = %12.9f \n",xxmin);
  1085.                 printf("     Xmax = %12.9f \n",xxmax);
  1086.                 printf("     Ymin = %12.9f \n",yymin);
  1087.                 printf("     Ymax = %12.9f \n",yymax);
  1088.                 printf("\nCurrent Iteration Maximum = %d\n",maxit);
  1089.                 if (fractype == PLASMA)
  1090.                   printf("\nCurrent 'rseed=' value is %d\n",rseed);
  1091.                 if(invert) {
  1092.                     extern double f_radius,f_xcenter,f_ycenter;
  1093.                     printf("\nCurrent Inversion parameters are: \n\n");
  1094.                     printf("   radius = %12.9f \n",f_radius);
  1095.                     printf("  xcenter = %12.9f \n",f_xcenter);
  1096.                     printf("  ycenter = %12.9f \n",f_ycenter);
  1097.                     }
  1098.                 if (floatflag)
  1099.                   printf("\nFloating-point flag is activated\n");
  1100.                 printf("\nPress any key to continue...");
  1101.                 getakey();
  1102.                 setforgraphics();
  1103.                 continue;    
  1104.             break;
  1105.             case 'd':            /* shell to MS-DOS */
  1106.             case 'D':
  1107.                 setfortext();
  1108.                 printf("\n\nShelling to DOS - type 'exit' to return\n\n");
  1109.                 if (axmode == 0 || axmode > 7) {
  1110.                     printf("Note:  Your graphics image is still squirreled away in your video\n");
  1111.                     printf("adapter's memory.  Switching video modes (say, to get your cursor back)\n");
  1112.                     printf("will clobber part of that image.  Sorry - it's the best we could do.\n\n");
  1113.                     }
  1114.                 system("command.com");
  1115.                 setforgraphics();
  1116.                 break;
  1117.             case '<':            /* lower iter maximum */
  1118.             case ',':
  1119.                 if (maxit >= 10+initincr) maxit -= initincr;
  1120.                 maxit -= initincr;    /* for fall-thru */
  1121.             case '>':            /* raise iter maximum */
  1122.             case '.':
  1123.                 if (maxit <= 32000-initincr) maxit += initincr;
  1124.                 if (LogFlag) {        /* log palettes? */
  1125.                     LogFlag = 0;    /* clear them out */
  1126.                     ChkLogFlag();
  1127.                     LogFlag = 1;    /* and re-calculate */
  1128.                     }
  1129.                 continue;
  1130.                 break;
  1131.             case 'c':            /* switch to cycling */
  1132.             case 'C':
  1133.                 rotate(0);
  1134.                 continue;
  1135.                 break;
  1136.             case '+':            /* rotate palette */
  1137.                 rotate(+1);
  1138.                 continue;
  1139.                 break;
  1140.             case '-':            /* rotate palette */
  1141.                 rotate(-1);
  1142.                 continue;
  1143.                 break;
  1144.                         case 's':                       /* save-to-disk */
  1145.                         case 'S':
  1146.                 drawbox(0);        /* clobber zoom-box */
  1147.                 ixmin = 0;  ixmax = xdots-1;
  1148.                 iymin = 0;  iymax = ydots-1;
  1149.                 xmin = lx0[0];
  1150.                 xmax = lx0[xdots-1];    /* re-set xmax and ymax */
  1151.                 ymin = ly0[ydots-1];
  1152.                 ymax = ly0[0];
  1153.  
  1154.                             /* convert parameters back to doubles */
  1155.                                 xxmax = xmax; xxmax = xxmax / fudge;
  1156.                                 xxmin = xmin; xxmin = xxmin / fudge;
  1157.                                 yymax = ymax; yymax = yymax / fudge;
  1158.                                 yymin = ymin; yymin = yymin / fudge;
  1159.  
  1160.                             /* set save parameters in save structure */
  1161.                 strcpy(save_info.info_id, INFO_ID);
  1162.                         save_info.iterations   = maxit;
  1163.                         save_info.fractal_type = fractype;
  1164.                         save_info.xmin         = xxmin;
  1165.                         save_info.xmax         = xxmax;
  1166.                         save_info.ymin         = yymin;
  1167.                         save_info.ymax         = yymax;
  1168.                         save_info.creal        = param[0];
  1169.                         save_info.cimag        = param[1];
  1170.                         save_info.videomodeax  = videoentry.videomodeax;
  1171.                         save_info.videomodebx  = videoentry.videomodebx;
  1172.                         save_info.videomodecx  = videoentry.videomodecx;
  1173.                         save_info.videomodedx  = videoentry.videomodedx;
  1174.                         save_info.dotmode       = videoentry.dotmode;
  1175.                         save_info.xdots           = videoentry.xdots;
  1176.                         save_info.ydots           = videoentry.ydots;
  1177.                         save_info.colors       = videoentry.colors;
  1178.                         save_info.version      = 1;     /* structure version number */
  1179.                            save_info.parm3          = param[2]; 
  1180.                            save_info.parm4          = param[3]; 
  1181.                         save_info.potential[0]   = potparam[0];
  1182.                         save_info.potential[1]   = potparam[1];
  1183.                         save_info.potential[2]   = potparam[2];
  1184.                         save_info.rflag          = rflag;
  1185.                         save_info.rseed          = rseed;
  1186.                         save_info.inside         = inside;
  1187.                         save_info.logmap         = LogFlag;
  1188.                         save_info.invert[0]      = inversion[0];
  1189.                         save_info.invert[1]      = inversion[1];
  1190.                         save_info.invert[2]      = inversion[2]; 
  1191.                        
  1192.                         for (i = 0; i < sizeof(save_info.future)/sizeof(int); i++)
  1193.                            save_info.future[i] = 0;
  1194.  
  1195.                 diskisactive = 1;    /* flag for disk-video routines */
  1196.                                 savetodisk(savename);
  1197.                 diskisactive = 0;    /* flag for disk-video routines */
  1198.                 continue;
  1199.                                 break;
  1200.             case 'o':            /* 3D overlay */
  1201.             case 'O':
  1202.                 overlay3d = 1;
  1203.             case '3':            /* restore-from (3d) */
  1204.                 display3d = 1;
  1205.             case 'r':            /* restore-from */
  1206.             case 'R':
  1207.                 if (overlay3d) {
  1208.                     setfortext();    /* save graphics image */
  1209.                     printf("\n Overlay from");
  1210.                     }
  1211.                 else    {
  1212.                     olddotmode = dotmode;    /* save the old dotmode */
  1213.                     dotmode = 1;        /* in case of an 8514/A mode */
  1214.                     setvideomode(3,0,0,0);    /* switch to text mode */
  1215.                     printf("\n Restart from");
  1216.                     }
  1217.                 if (*readname)
  1218.                     printf(" what file (if not %s)? ",
  1219.                         readname);
  1220.                 else
  1221.                     printf(" what file? ");
  1222.                 temp1[0] = 0;
  1223.                 gets(temp1);
  1224.                 if (temp1[0] != 0)
  1225.                     strcpy(readname,temp1);
  1226.                 dotmode = olddotmode;
  1227.                 goto restorestart;
  1228.                 break;
  1229.             case '1':            /* single-pass mode */
  1230.             case '2':            /* dual-pass mode */
  1231.                 numpasses = kbdchar - '1';
  1232.                 solidguessing = 0;
  1233.                 kbdmore = 0;
  1234.                 break;
  1235.             case 'g':            /* solid-guessing */
  1236.             case 'G':
  1237.                 numpasses = 1;
  1238.                 solidguessing = 1;
  1239.                 kbdmore = 0;    
  1240.                 break;
  1241.             case 'n':            /* normal palette */
  1242.             case 'N':
  1243.                 LogFlag = 0;
  1244.                 ChkLogFlag();
  1245.                 kbdmore = 0;
  1246.                 break;
  1247.             case 'l':            /* log palette */
  1248.             case 'L':
  1249.                 LogFlag = 1;
  1250.                 kbdmore = 0;
  1251.                 break;
  1252.             case 'b':            /* make batch file */
  1253.             case 'B':
  1254.                 {
  1255.                 FILE *batch;
  1256.                 xxmax = xmax; xxmax = xxmax / fudge;
  1257.                 xxmin = xmin; xxmin = xxmin / fudge;
  1258.                 yymax = ymax; yymax = yymax / fudge;
  1259.                 yymin = ymin; yymin = yymin / fudge;
  1260.                 batch=fopen("frabatch.bat","a");
  1261.                 fprintf(batch,"fractint type=%s",
  1262.                         fractalspecific[fractype].name);
  1263.                 if (delx > 1000 && dely > 1000)
  1264.                 fprintf(batch," corners=%g/%g/%g/%g",
  1265.                     xxmin, xxmax, yymin, yymax);
  1266.                 else
  1267.                 fprintf(batch," corners=%+12.9f/%+12.9f/%+12.9f/%+12.9f",
  1268.                     xxmin, xxmax, yymin, yymax);
  1269.                 if (param[0] != 0.0 || param[1] != 0.0)
  1270.                     fprintf(batch," params=%g/%g", param[0], param[1]);
  1271.                 if (maxit != 150)
  1272.                     fprintf(batch," maxiter=%d", maxit);
  1273.                 if (initincr != 50)
  1274.                     fprintf(batch," iterincr=%d", initincr);
  1275.                 if (inside != 1)
  1276.                     fprintf(batch," inside=%d", inside);
  1277.                 if (invert) 
  1278.                     fprintf(batch," invert=%g/%g/%g",
  1279.                         inversion[0], inversion[1], inversion[2]);
  1280.                 if (decomp[0]) 
  1281.                     fprintf(batch," decomp=%d/%d",
  1282.                         decomp[0], decomp[1]);
  1283.                 if (floatflag) 
  1284.                     fprintf(batch," float=yes");
  1285.                 if (biomorph!=-1)
  1286.                     fprintf(batch," biomorph=%d", biomorph);
  1287.                             
  1288.                 fprintf(batch,"\n");
  1289.                 if(batch != NULL) fclose(batch);
  1290.                 }
  1291.                 break;
  1292.                                 /*  vvvvv  MDS 7/1/89  vvvvv  */
  1293.                         case 'p':
  1294.                         case 'P':
  1295.                                 Print_Screen();
  1296.                                 if (!keypressed()) buzzer(0);
  1297.                                  else {
  1298.                                         buzzer(1);
  1299.                                         getakey();
  1300.                                  }
  1301.                                 continue;
  1302.                                 /*  ^^^^^  MDS 7/1/89  ^^^^^  */
  1303.             case 13:            /* Enter */
  1304.             case 1013:            /* Numeric-Keypad Enter */
  1305.             case 1079:            /* end */
  1306.                 kbdmore = 0;
  1307.                 break;
  1308.             case 10:            /* control-Enter */
  1309.             case 1010:            /* Control-Keypad Enter */
  1310.                 ftemp = 1.0 * delx;
  1311.                 ftemp = (ftemp * xdots) / (ixmax-ixmin+1);
  1312.                 xxmin = lx0[0] - (ftemp * ixmin);
  1313.                 xxmax = xxmin  + (ftemp * (xdots-1));
  1314.                 ftemp = 1.0 * dely;
  1315.                 ftemp = (ftemp * ydots) / (iymax-iymin+1);
  1316.                 yymax = ly0[0] + (ftemp * iymin);
  1317.                 yymin = yymax  - (ftemp * (ydots-1));
  1318.                 if (xxmin < -2.147e9 || xxmax > 2.147e9 ||
  1319.                   yymin < -2.147e9 || yymax > 2.147e9 ||
  1320.                   (xxmax-xxmin) > 2.147e9 ||
  1321.                   (yymax-yymin) > 2.147e9) {
  1322.                     buzzer(2);
  1323.                     break;
  1324.                     }
  1325.                 xmin = xxmin; xmax = xxmax;
  1326.                 ymin = yymin; ymax = yymax;
  1327.                 kbdmore = 0;
  1328.                 break;
  1329.             case 1082:            /* insert */
  1330.                 dotmode = 1;
  1331.                 setvideomode(3,0,0,0);     /* force text mode */
  1332.                 goto restart;
  1333.                 break;
  1334.             case 1000:            /* Control-C */
  1335.             case 27:            /* Escape */
  1336.             case 1083:            /* delete */
  1337.                 more = 0; kbdmore = 0;
  1338.                 break;
  1339.             case 1075:            /* cursor left */
  1340.                 if (zoomoff == 1 && ixmin >= 1) {
  1341.                     ixmin -= 1;
  1342.                     ixmax -= 1;
  1343.                     }
  1344.                 break;
  1345.             case 1077:            /* cursor right */
  1346.                 if (zoomoff == 1 && ixmax < xdots - 1) {
  1347.                     ixmin += 1;
  1348.                     ixmax += 1;
  1349.                     }
  1350.                 break;
  1351.             case 1072:            /* cursor up */
  1352.                 if (zoomoff == 1 && iymin >= 1) {
  1353.                     iymin -= 1;
  1354.                     iymax -= 1;
  1355.                     }
  1356.                 break;
  1357.             case 1080:            /* cursor down */
  1358.                 if (zoomoff == 1 && iymax < ydots - 1) {
  1359.                     iymin += 1;
  1360.                     iymax += 1;
  1361.                     }
  1362.                 break;
  1363.             case 1115:            /* Ctrl-cursor left */
  1364.                 if (zoomoff == 1 && ixmin >= 5) {
  1365.                     ixmin -= 5;
  1366.                     ixmax -= 5;
  1367.                     }
  1368.                 break;
  1369.             case 1116:            /* Ctrl-cursor right */
  1370.                 if (zoomoff == 1 && ixmax < xdots - 5) {
  1371.                     ixmin += 5;
  1372.                     ixmax += 5;
  1373.                     }
  1374.                 break;
  1375.             case 1141:            /* Ctrl-cursor up */
  1376.                 if (zoomoff == 1 && iymin >= 5) {
  1377.                     iymin -= 5;
  1378.                     iymax -= 5;
  1379.                     }
  1380.                 break;
  1381.             case 1145:            /* Ctrl-cursor down */
  1382.                 if (zoomoff == 1 && iymax < ydots - 5) {
  1383.                     iymin += 5;
  1384.                     iymax += 5;
  1385.                     }
  1386.                 break;
  1387.             case 1073:            /* page up */
  1388.                 if (zoomoff == 1 
  1389.                   && ixmax - ixmin > 3 * xstep
  1390.                   && iymax - iymin > 3 * ystep) {
  1391.                     /* 640x350 Zoom-In Klooge:  Adjust the
  1392.                        Zoom-Box on the initial Zoom-In */
  1393.                     if (xdots == 640 && ydots == 350
  1394.                       && iymin == 0  && iymax == ydots-1) {
  1395.                         iymin -= 5;
  1396.                         iymax += 5;
  1397.                         }
  1398.                     /* 720x348 Zoom-In Klooge:  Adjust the
  1399.                        Zoom-Box on the initial Zoom-In */
  1400.                     if (xdots == 720 && ydots == 348
  1401.                       && iymin == 0  && iymax == ydots-1) {
  1402.                         iymin -= 6;
  1403.                         iymax += 6;
  1404.                         }
  1405.                     /* 720x512 Zoom-In Klooge:  Adjust the
  1406.                        Zoom-Box on the initial Zoom-In */
  1407.                     if (xdots == 720 && ydots == 512
  1408.                       && iymin == 0  && iymax == ydots-1) {
  1409.                         iymin -= 14;
  1410.                         iymax += 14;
  1411.                         }
  1412.                     ixmin += xstep;    ixmax -= xstep;
  1413.                     iymin += ystep;    iymax -= ystep;
  1414.                     }
  1415.                 break;
  1416.             case 1081:            /* page down */
  1417.                 if (zoomoff == 1
  1418.                  && ixmin >= xstep && ixmax < xdots - xstep
  1419.                  && iymin >= ystep && iymax < ydots - ystep) {
  1420.                     ixmin -= xstep;    ixmax += xstep;
  1421.                     iymin -= ystep;    iymax += ystep;
  1422.                     }
  1423.                 break;
  1424.             default:        /* other (maybe a valid Fn key) */
  1425.                 for (k = 0; k < maxvideomode; k++)
  1426.                     if (kbdchar == kbdkeys[k]) {
  1427.                         adapter = k;
  1428.                         kbdmore = 0;
  1429.                         savedac = 0;
  1430.                         }
  1431.                 if (kbdmore != 0)
  1432.                     continue;
  1433.                 break;
  1434.             }
  1435.  
  1436.         if (zoomoff == 1 && kbdmore == 1) {    /* draw a zoom box? */
  1437.             xmin = lx0[ixmin];
  1438.             xmax = lx0[ixmax];
  1439.             ymin = ly0[iymax];
  1440.             ymax = ly0[iymin];
  1441.             if (ixmin > 0 || ixmax < xdots-1 
  1442.                 || iymin > 0 || iymax < ydots-1)
  1443.                 drawbox(1);
  1444.             else
  1445.                 drawbox(0);
  1446.             }
  1447.         }
  1448.  
  1449.     }
  1450.     dotmode = 0;        /* no need to reinit TARGA 2 April 89 j mclain */
  1451.     goodbye();                /* we done. */
  1452.  
  1453. }
  1454.  
  1455. /* compare for sort of type table */
  1456. compare(unsigned char *i, unsigned char *j)
  1457. {
  1458.    return(strcmp(fractalspecific[(int)*i].name,fractalspecific[(int)*j].name));
  1459. }
  1460.  
  1461. /* Define command keys */
  1462.  
  1463. #define   PAGE_UP        1073
  1464. #define   PAGE_DOWN      1081
  1465. #define   LEFT_ARROW     1075
  1466. #define   RIGHT_ARROW    1077
  1467. #define   UP_ARROW       1072
  1468. #define   DOWN_ARROW     1080
  1469. #define   LEFT_ARROW_2   1115
  1470. #define   RIGHT_ARROW_2  1116
  1471. #define   UP_ARROW_2     1141
  1472. #define   DOWN_ARROW_2   1145
  1473. #define   HOME           1071
  1474. #define   END            1079
  1475. #define   ENTER          13
  1476. #define   ENTER_2        1013
  1477. #define   ESC            27
  1478.  
  1479. unsigned video_seg;                /* Current video display segment */
  1480. int crtrows, crtcols;              /* Lines per page, columns/row */
  1481.  
  1482. getfracttype(int t)
  1483. {
  1484.    char *s;
  1485.    int oldhelpmode;
  1486.    int done;
  1487.    int numtypes;                 /* length of list    */
  1488.    int numcols;                  /* number of columns */
  1489.    int colwidth;                 /* width of a column */
  1490.    int startrow, startcol;       /* upper left corner of list */
  1491.    int c;
  1492.    int  video_mode;              /* current video mode */
  1493.    unsigned char far *lowptr;    /* Low memory pointer */
  1494.    int crow, ccol, i, j, k, k1;
  1495.    int attribute;
  1496.    
  1497.    unsigned char onthelist[256];    /* list of REAL name locations */
  1498.  
  1499.    setvideomode(3,0,0,0);        /* switch to text mode */
  1500.    
  1501.    /* setup stuff for video */
  1502. #ifdef __TURBOC__
  1503.    lowptr = MK_FP(0, 0x449);        /* Set for low memory */
  1504. #else
  1505.    FP_SEG(lowptr) = 0;                     /* Set for low memory */
  1506.    FP_OFF(lowptr) = 0x449;                 /* Get video mode */
  1507. #endif
  1508.    if ((video_mode = *lowptr) >= 0 && video_mode < 4) 
  1509.       video_seg = 0xB800; /* Define video segment */
  1510.    else if (video_mode == 7)               /* If monochrome */
  1511.       video_seg = 0xB000;
  1512.    else 
  1513.    { 
  1514.       printf("%d is a bad Video mode", video_mode);
  1515.       exit(0);
  1516.    }
  1517.    
  1518. #ifdef __TURBOC__
  1519.    lowptr = MK_FP(0, 0x484);           /* get screen rows -1 */
  1520. #else
  1521.    FP_SEG(lowptr) = 0;
  1522.    FP_OFF(lowptr) = 0x484;
  1523. #endif
  1524.    crtrows = (int)(*lowptr);
  1525.    
  1526. #ifdef __TURBOC__
  1527.    lowptr = MK_FP(0, 0x44a);           /* get cols/row */
  1528. #else
  1529.    FP_SEG(lowptr) = 0;
  1530.    FP_OFF(lowptr) = 0x44a;
  1531. #endif
  1532.    crtcols = (int)(*lowptr);
  1533.  
  1534.    if (video_mode == 7) 
  1535.    { 
  1536.       crtrows = 24; /* Since some mono adapters don't update lower RAM */
  1537.       crtcols = 80; 
  1538.    } 
  1539.    /* end setup stuff for video */
  1540.    
  1541.    /* setup context sensitive help */
  1542.    oldhelpmode = helpmode;
  1543.    helpmode = HELPFRACTALS;
  1544.  
  1545.    /* set up details of how type list is displayed on the screen */
  1546.    numcols  =  5;                 /* number of columns */
  1547.    colwidth = 16;                 /* width of a column */
  1548.    startrow =  5;                 /* upper left corner of list */
  1549.    startcol =  1;                 /* upper left corner of list */
  1550.  
  1551.    i = -1;
  1552.    j = -1;
  1553.    k = 0;
  1554.    while(fractalspecific[++i].name)
  1555.    {
  1556.       if (fractalspecific[i].name[0] == '*')
  1557.          continue;
  1558.       onthelist[++j] = i;    /* remember where the real item is */
  1559.       if (strcmp(fractalspecific[onthelist[j]].name,
  1560.                  fractalspecific[t].name) == 0 ||
  1561.           (fractalspecific[t].name[0] == '*' &&
  1562.           strcmp(fractalspecific[onthelist[j]].name,
  1563.                  fractalspecific[fractalspecific[t].tofloat].name) == 0))
  1564.           k = j;
  1565.    }
  1566.    k1 = onthelist[k]; /* remember index of current type */
  1567.    numtypes = j;
  1568.    
  1569.    qsort(onthelist,1+numtypes,1,compare); /* sort type list */
  1570.    
  1571.    putstring(2,(crtcols-50)/2,7,
  1572.       "Select one of the available fractal types below",
  1573.       0);
  1574.  
  1575.    /* display the list */
  1576.    for(i=0;i<=numtypes;i++)
  1577.    {
  1578.       if(onthelist[i] == k1)
  1579.          k = i;  /* this is the current type */
  1580.       ccol  = startcol + (i%numcols)*colwidth;
  1581.       crow  = startrow + i/(numcols);
  1582.       putstring(crow,ccol,7,fractalspecific[onthelist[i]].name,0);
  1583.    }   
  1584.    movecursor(25,81); /* kill cursor */
  1585.  
  1586.    putstring(22,(crtcols-66)/2,7,
  1587.       "Use your cursor keypad, HOME, and END to move to your chosen item",
  1588.       0);
  1589.    putstring(23,(crtcols-66)/2,7,
  1590.       "(or press the 'h' key for a short description of each fractal type)",
  1591.       0);
  1592.    putstring(24,(crtcols-66)/2,7,
  1593.       "Press <ENTER> to select or <ESC> to return to the previous screen",
  1594.       0);
  1595.    
  1596.    i = k;    /* start with current type highlighted */
  1597.    ccol  = startcol + (i%numcols)*colwidth;
  1598.    crow  = startrow + i/(numcols);
  1599.    done = 0;
  1600.    while(!done)
  1601.    {
  1602.       /* write type in reverse video */
  1603.       putstring(crow,ccol,112,fractalspecific[onthelist[i]].name,0);
  1604.       while (! keypressed());
  1605.       c = getakey();
  1606.       
  1607.       /* write type back to normal video */
  1608.       putstring(crow,ccol, 7,fractalspecific[onthelist[i]].name,0);
  1609.       
  1610.       switch(c)
  1611.       {
  1612.       case DOWN_ARROW:
  1613.       case DOWN_ARROW_2:
  1614.          i += numcols;
  1615.          if(i > numtypes)
  1616.             i = i%numcols; 
  1617.          break;
  1618.       case UP_ARROW:
  1619.       case UP_ARROW_2:
  1620.          i -= numcols;
  1621.          if(i < 0)
  1622.             i = (numtypes/numcols)*numcols+i%numcols;
  1623.          break;
  1624.       case HOME:
  1625.          i=0;
  1626.          break;
  1627.       case END:
  1628.          i=numtypes;
  1629.          break;
  1630.       case RIGHT_ARROW:
  1631.       case RIGHT_ARROW_2:
  1632.          i ++;
  1633.          if(i > numtypes)
  1634.             i = 0;
  1635.          break;    
  1636.       case LEFT_ARROW:
  1637.       case LEFT_ARROW_2:
  1638.          i --;
  1639.          if(i < 0)
  1640.             i = numtypes;
  1641.          break;    
  1642.       case ENTER:
  1643.       case ENTER_2:
  1644.          done = 1;
  1645.          break;
  1646.       case ESC:
  1647.          done = -1;
  1648.          break;
  1649.       default:
  1650.          continue; 
  1651.       }
  1652.       ccol = startcol + (i%numcols)*colwidth;
  1653.       crow = startrow + i/(numcols);
  1654.    }
  1655.    clscr();
  1656.    helpmode = oldhelpmode;
  1657.    if (done >= 0)
  1658.       return(onthelist[i]);
  1659.    return(-1);
  1660. }
  1661.  
  1662. get_decomp_params()
  1663. {
  1664.    decomp[0] = decomp[1] = 0;
  1665.    printf("\n\nPlease enter your Decomposition Parameters:\n");
  1666.    printf("\nNumber of colors (2,4,8,16,32,64,128,256 or <ENTER> to disable) : ");
  1667.    gets(temp1);
  1668.    if (temp1[0] == 0) return;
  1669.    decomp[0] = atoi(temp1);
  1670.    if (decomp[0] == 0) return;
  1671.    printf("\nPlease enter your new Bailout value (or <ENTER> to use the default) : ");
  1672.    gets(temp1);
  1673.    decomp[1] = atoi(temp1);   
  1674. }
  1675.  
  1676. get_invert_params()
  1677. {
  1678.    extern int StandardFractal();
  1679.    extern int calcmand();
  1680.    invert = 0;
  1681.    inversion[0] = inversion[1] = inversion[2] = 0;
  1682.    if(fractalspecific[initfractype].calctype != StandardFractal &&
  1683.       fractalspecific[initfractype].calctype != calcmand) 
  1684.       return(0);
  1685.    printf("\n\n Please enter inversion parameters that apply (an empty response\n");
  1686.    printf("  bails out).  Also, note that the inversion option requires a fixed\n");
  1687.    printf("  radius and center for zooming to make sense - if you want to zoom,\n");
  1688.    printf("  do not use default values, but specify radius and center\n");
  1689.    printf("Radius of inversion (-1 for auto calculate) => "); 
  1690.    temp1[0] = 0;
  1691.    gets(temp1);
  1692.    if(temp1[0] != 0)
  1693.    {
  1694.       inversion[0] = atof(temp1);
  1695.       invert++;
  1696.       printf("X Center inversion (<enter for auto calc) => "); 
  1697.       temp1[0] = 0;
  1698.       gets(temp1);
  1699.       if(temp1[0] != 0)
  1700.       {
  1701.          inversion[1] = atof(temp1);
  1702.          invert++;
  1703.          printf("Y Center inversion (<enter> for auto calculate) => "); 
  1704.          temp1[0] = 0;
  1705.          gets(temp1);
  1706.          if(temp1[0] != 0)
  1707.          {
  1708.             inversion[2] = atof(temp1);
  1709.             invert++;
  1710.          }   
  1711.       }
  1712.    }
  1713. }
  1714.  
  1715. extern char far argerrormessage[];
  1716.  
  1717. argerror(badarg)            /* oops.   couldn't decode this */
  1718. char *badarg;
  1719. {
  1720.  
  1721. buzzer(2);
  1722. printf("\nOops.   I couldn't understand the argument '%s'\n\n",badarg);
  1723. helpmessage(argerrormessage);
  1724. exit(1);
  1725.  
  1726. }
  1727.  
  1728. extern char far goodbyemessage[];
  1729.  
  1730. goodbye()
  1731. {
  1732. setvideomode(3,0,0,0);
  1733. helpmessage(goodbyemessage);
  1734. exit(0);
  1735. }
  1736.  
  1737.