home *** CD-ROM | disk | FTP | other *** search
/ Fractal Creations (Second Edition) / FRACTALS_2E.iso / frasrc.exe / MISCOVL.C < prev    next >
C/C++ Source or Header  |  1993-08-21  |  58KB  |  1,870 lines

  1. /*
  2.     Overlayed odds and ends that don't fit anywhere else.
  3. */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #ifndef XFRACT
  9. #include <process.h>
  10. #include <dos.h>
  11. #include <stdarg.h>
  12. #include <io.h>
  13. #else
  14. #include <varargs.h>
  15. #endif
  16. #include "fractint.h"
  17. #include "fractype.h"
  18. #include "helpdefs.h"
  19. #include "prototyp.h"
  20.  
  21. /* routines in this module    */
  22.  
  23. static void write_batch_parms(FILE *,char *,int);
  24. #ifndef XFRACT
  25. static void put_parm(char *parm,...);
  26. #else
  27. static void put_parm();
  28. #endif
  29.  
  30. static void put_parm_line(void);
  31. static int getprec(double,double,double);
  32. static void put_float(int,double,int);
  33. static void put_filename(char *keyword,char *fname);
  34. static void format_item(int choice,char *buf);
  35. static int check_modekey(int curkey,int choice);
  36. static int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2);
  37. static void update_fractint_cfg(void);
  38. extern int  debugflag;
  39. extern int  xdots,ydots;
  40. extern int  cpu;        /* cpu type            */
  41. extern int  fpu;        /* fpu type            */
  42. extern int  iit;        /* iit fpu?            */
  43. extern int  video_type;
  44. extern int  askvideo;
  45. extern char overwrite;        /* 1 means ok to overwrite */
  46. extern int  fillcolor;        /* fill color: -1 = normal*/
  47. extern int  inside;        /* inside color: 1=blue     */
  48. extern int  outside;        /* outside color, if set    */
  49. extern double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners */
  50. extern double sxmin, sxmax, sx3rd, symin, symax, sy3rd; /* zoom box corners */
  51. extern double param[];       /* up to four parameters    */
  52. extern int  finattract;     /* finite attractor option  */
  53. extern int  forcesymmetry;
  54. extern int  LogFlag;        /* non-zero if logarithmic palettes */
  55. extern int  rflag, rseed;
  56. extern int  periodicitycheck;
  57. extern int  potflag;        /* continuous potential flag */
  58. extern int  pot16bit;        /* save 16 bit values for continuous potential */
  59. extern double potparam[3];    /* three potential parameters*/
  60. extern int  fractype;        /* if == 0, use Mandelbrot  */
  61. extern BYTE usemag;
  62. extern long delmin;
  63. extern int  maxit;        /* try this many iterations */
  64. extern int  invert;        /* non-zero if inversion active */
  65. extern double inversion[];
  66. extern int  decomp[];
  67. extern int  distest;        /* non-zero if distance estimator   */
  68. extern int  distestwidth;
  69. extern int  init3d[20];     /* '3d=nn/nn/nn/...' values */
  70. extern char floatflag;        /* floating-point fractals? */
  71. extern int  usr_biomorph;
  72. extern char FormFileName[];    /* file to find (type=)formulas in */
  73. extern char FormName[];     /* Name of the Formula (if not null) */
  74. extern char LFileName[];
  75. extern char LName[];
  76. extern char IFSFileName[];
  77. extern char IFSName[];
  78. extern int  bailout;        /* user input bailout value */
  79. extern char useinitorbit;
  80. extern _CMPLX initorbit;
  81. extern int  display3d;        /* 3D display flag: 0 = OFF */
  82. extern int  overlay3d;        /* 3D overlay flag: 0 = OFF */
  83. extern int  loaded3d;
  84. extern char readname[];     /* name of fractal input file */
  85. extern int  showfile;        /* has file been displayed yet? */
  86. extern int  transparent[];
  87. extern char preview;        /* 3D preview mode flag */
  88. extern char showbox;        /* flag to show box and vector in preview */
  89. extern int  RANDOMIZE;        /* Color randomizing factor */
  90. extern int  Targa_Out;  /* Selects full color with light source fills */
  91. extern int  Ambient;        /* Darkness of shadows in light source */
  92. extern int  haze;        /* Amount of haze to factor in in full color */
  93. extern char light_name[];    /* Name of full color .TGA file */
  94. extern int previewfactor;
  95. extern int BRIEF;
  96. extern int RAY;
  97. extern int xtrans;
  98. extern int ytrans;
  99. extern int red_crop_left;
  100. extern int red_crop_right;
  101. extern int blue_crop_left;
  102. extern int blue_crop_right;
  103. extern int red_bright;
  104. extern int blue_bright;
  105. extern int xadjust;
  106. extern int eyeseparation;
  107. extern int glassestype;
  108. extern BYTE trigndx[];
  109. extern int rotate_lo,rotate_hi;
  110. extern int far *ranges;
  111. extern int rangeslen;
  112. extern char CommandFile[80];
  113. extern char CommandName[ITEMNAMELEN+1];
  114. extern char far CommandComment1[57];
  115. extern char far CommandComment2[57];
  116. extern char far CommandComment3[57];
  117. extern char far CommandComment4[57];
  118. extern char usr_stdcalcmode;
  119.  
  120. extern int calc_status;
  121. extern double    sxmin,sxmax,symin,symax,sx3rd,sy3rd;
  122.  
  123. /* Julibrot variables TIW 1/24/93 */
  124. extern double mxmaxfp, mxminfp, mymaxfp, myminfp, originfp;
  125. extern double depthfp, heightfp, widthfp, distfp, eyesfp;
  126.  
  127. extern int zdots; 
  128. extern int lastorbittype, neworbittype;
  129. extern char *juli3Doptions[];
  130. extern int juli3Dmode;
  131.  
  132. /* viewwindows parameters */
  133. extern int   viewwindow;
  134. extern float viewreduction;
  135. extern int   viewcrop;
  136. extern float finalaspectratio;
  137. extern int   viewxdots,viewydots;
  138.  
  139. extern int  colorstate;     /* comments in cmdfiles */
  140. extern int  colors;
  141. extern int  gotrealdac;
  142. extern int  reallyega;
  143. extern char colorfile[];
  144. extern int  mapset;
  145. extern char MAP_name[];
  146. extern BYTE dacbox[256][3];
  147. extern char far *mapdacbox;
  148. extern int save_release;
  149.  
  150. extern char tstack[4096];
  151. extern char s_cantopen[];
  152. extern char s_cantwrite[];
  153. extern char s_cantcreate[];
  154. extern char s_cantunderstand[];
  155. extern char s_cantfind[];
  156. extern int calc_status;
  157.  
  158. extern struct videoinfo far videotable[];
  159.  
  160. /* fullscreen_choice options */
  161. #define CHOICERETURNKEY 1
  162. #define CHOICEMENU    2
  163. #define CHOICEHELP    4
  164. void miscovl_overlay() { }    /* for restore_active_ovly */
  165.  
  166. extern char s_real[];
  167. extern char s_imag[];
  168. extern char s_mult[];
  169. extern char s_sum[];
  170. extern char s_zmag[];
  171. extern char s_bof60[];
  172. extern char s_bof61[];
  173. extern char s_maxiter[];
  174. extern char s_epscross[];
  175. extern char s_startrail[];
  176. extern char s_normal[];
  177. extern char s_period[];
  178.  
  179. char *major[] = {"breadth","depth","walk","run"};
  180. char *minor[] = {"left","right"};
  181.  
  182. static FILE *parmfile;
  183.  
  184. #define PAR_KEY(x)  ( x < 10 ? '0' + x : 'a' - 10 + x)
  185.  
  186. #ifdef C6
  187. #pragma optimize("e",off)  /* MSC 6.00A messes up next rtn with "e" on */
  188. #endif
  189. void make_batch_file()
  190. {
  191.    static char far hdg[]={"Save Current Parameters"};
  192.    /** added for pieces feature **/
  193.    double pdelx;
  194.    double pdely;
  195.    double pdelx2;
  196.    double pdely2;
  197.    unsigned int j, pxdots, pydots, xm, ym;
  198.    double pxxmin, pxxmax, pyymin, pyymax, pxx3rd, pyy3rd;
  199.    char vidmde[4];
  200.    int promptnum;
  201.    int piecespromts;
  202.    int have3rd;
  203.    /****/
  204.  
  205.    int i;
  206.    char inpcommandfile[80], inpcommandname[ITEMNAMELEN + 1];
  207.    char inpcomment1[57], inpcomment2[57], inpcomment3[57], inpcomment4[57];
  208.    struct fullscreenvalues paramvalues[18];
  209.    char far *choices[18];
  210.    int gotinfile;
  211.    char outname[81], buf[256], buf2[128];
  212.    FILE *infile;
  213.    FILE *fpbat=NULL;
  214.    char colorspec[14];
  215.    int maxcolor;
  216.    int maxcolorindex;
  217.    char *sptr, *sptr2;
  218.    int oldhelpmode;
  219.  
  220.    ENTER_OVLY(OVLY_MISCOVL);
  221.    stackscreen();
  222.    oldhelpmode = helpmode;
  223.    helpmode = HELPPARMFILE;
  224.  
  225.    strcpy(colorspec, "n");
  226.    maxcolor = colors;
  227.    if (gotrealdac && !reallyega)
  228.    {
  229.       --maxcolor;
  230. /*    if (maxit < maxcolor)  remove 2 lines */
  231. /*       maxcolor = maxit;   so that whole palette is always saved */
  232.       if (inside > 0 && inside > maxcolor)
  233.          maxcolor = inside;
  234.       if (outside > 0 && outside > maxcolor)
  235.          maxcolor = outside;
  236.       if (distest < 0 && 0 - distest > maxcolor)
  237.          maxcolor = 0 - distest;
  238.       if (decomp[0] > maxcolor)
  239.          maxcolor = decomp[0] - 1;
  240.       if (potflag && potparam[0] >= maxcolor)
  241.          maxcolor = potparam[0];
  242.       if (++maxcolor > 256)
  243.          maxcolor = 256;
  244.       if (colorstate == 0)
  245.       {                         /* default colors */
  246.          if (mapdacbox)
  247.          {
  248.             colorspec[0] = '@';
  249.             sptr = MAP_name;
  250.          }
  251.       }
  252.       else
  253.       if (colorstate == 2)
  254.       {                         /* colors match colorfile */
  255.          colorspec[0] = '@';
  256.          sptr = colorfile;
  257.       }
  258.       else                      /* colors match no .map that we know of */
  259.          colorspec[0] = 'y';
  260.       if (colorspec[0] == '@')
  261.       {
  262.          if ((sptr2 = strrchr(sptr, SLASHC)))
  263.             sptr = sptr2 + 1;
  264.          if ((sptr2 = strrchr(sptr, ':')))
  265.             sptr = sptr2 + 1;
  266.          strncpy(&colorspec[1], sptr, 12);
  267.          colorspec[13] = 0;
  268.       }
  269.    }
  270.    strcpy(inpcommandfile, CommandFile);
  271.    strcpy(inpcommandname, CommandName);
  272.    far_strcpy(inpcomment1, CommandComment1);
  273.    far_strcpy(inpcomment2, CommandComment2);
  274.    far_strcpy(inpcomment3, CommandComment3);
  275.    far_strcpy(inpcomment4, CommandComment4);
  276.    if (CommandName[0] == 0)
  277.       strcpy(inpcommandname, "test");
  278.       /* TW added these  - and Bert moved them */
  279.       pxdots = xdots;
  280.       pydots = ydots;
  281.       vidmode_keyname(videoentry.keynum, vidmde);
  282.  
  283.       xm = ym = 1;
  284.  
  285.    while (1)
  286.    {
  287. prompt_user:
  288.       promptnum = 0;
  289.       {
  290.          static char far tmp[] = {"Parameter file"};
  291.          choices[promptnum] = tmp;
  292.       }
  293.       paramvalues[promptnum].type = 0x100 + 56;
  294.       paramvalues[promptnum++].uval.sbuf = inpcommandfile;
  295.       {
  296.          static char far tmp[] = {"Name"};
  297.          choices[promptnum] = tmp;
  298.       }
  299.       paramvalues[promptnum].type = 0x100 + ITEMNAMELEN;
  300.       paramvalues[promptnum++].uval.sbuf = inpcommandname;
  301.       {
  302.          static char far tmp[] = {"Main comment"};
  303.          choices[promptnum] = tmp;
  304.       }
  305.       paramvalues[promptnum].type = 0x100 + 56;
  306.       paramvalues[promptnum++].uval.sbuf = inpcomment1;
  307.       {
  308.          static char far tmp[] = {"Second comment"};
  309.          choices[promptnum] = tmp;
  310.       }
  311.       paramvalues[promptnum].type = 0x100 + 56;;
  312.       paramvalues[promptnum++].uval.sbuf = inpcomment2;
  313.       {
  314.          static char far tmp[] = {"Third comment"};
  315.          choices[promptnum] = tmp;
  316.       }
  317.       paramvalues[promptnum].type = 0x100 + 56;;
  318.       paramvalues[promptnum++].uval.sbuf = inpcomment3;
  319.       {
  320.          static char far tmp[] = {"Fourth comment"};
  321.          choices[promptnum] = tmp;
  322.       }
  323.       paramvalues[promptnum].type = 0x100 + 56;;
  324.       paramvalues[promptnum++].uval.sbuf = inpcomment4;
  325.       if (gotrealdac && !reallyega)
  326.       {
  327.          {
  328.             static char far tmp[] = {"Record colors?"};
  329.             choices[promptnum] = tmp;
  330.          }
  331.          paramvalues[promptnum].type = 0x100 + 13;
  332.          paramvalues[promptnum++].uval.sbuf = colorspec;
  333.          {
  334.             static char far tmp[] = {"    (no | yes for full info | @filename to point to a map file)"};
  335.             choices[promptnum] = tmp;
  336.          }
  337.          paramvalues[promptnum++].type = '*';
  338.          {
  339.             static char far tmp[] = {"# of colors"};
  340.             choices[promptnum] = tmp;
  341.          }
  342.          maxcolorindex = promptnum;
  343.          paramvalues[promptnum].type = 'i';
  344.          paramvalues[promptnum++].uval.ival = maxcolor;
  345.          {
  346.             static char far tmp[] = {"    (if recording full color info)"};
  347.             choices[promptnum] = tmp;
  348.          }
  349.          paramvalues[promptnum++].type = '*';
  350.       }
  351.       {
  352.          static char tmp[] = {""};
  353.          choices[promptnum] = tmp;
  354.       }
  355.       paramvalues[promptnum++].type = '*';
  356.  
  357.       {
  358.          static char far tmp[] = {"    **** The following is for generating images in pieces ****"};
  359.          choices[promptnum] = tmp;
  360.       }
  361.       paramvalues[promptnum++].type = '*';
  362.       {
  363.          static char far tmp[] = {"X Multiples"};
  364.          choices[promptnum] = tmp;
  365.       }
  366.       piecespromts = promptnum;
  367.       paramvalues[promptnum].type = 'i';
  368.       paramvalues[promptnum++].uval.ival = xm;
  369.  
  370.       {
  371.          static char far tmp[] = {"Y Multiples"};
  372.          choices[promptnum] = tmp;
  373.       }
  374.       paramvalues[promptnum].type = 'i';
  375.       paramvalues[promptnum++].uval.ival = ym;
  376.  
  377. #ifndef XFRACT
  378.       {
  379.          static char far tmp[] = {"Video mode"};
  380.          choices[promptnum] = tmp;
  381.       }
  382.       paramvalues[promptnum].type = 0x100 + 4;
  383.       paramvalues[promptnum++].uval.sbuf = vidmde;
  384. #endif
  385.  
  386.       if (fullscreen_prompt(hdg,promptnum, choices, paramvalues, 0, 0, NULL) < 0)
  387.          break;
  388.  
  389.       strcpy(CommandFile, inpcommandfile);
  390.       if (strchr(CommandFile, '.') == NULL)
  391.          strcat(CommandFile, ".par");   /* default extension .par */
  392.       strcpy(CommandName, inpcommandname);
  393.       far_strcpy(CommandComment1, inpcomment1);
  394.       far_strcpy(CommandComment2, inpcomment2);
  395.       far_strcpy(CommandComment3, inpcomment3);
  396.       far_strcpy(CommandComment4, inpcomment4);
  397.       if (gotrealdac && !reallyega)
  398.          if (paramvalues[maxcolorindex].uval.ival > 0 &&
  399.              paramvalues[maxcolorindex].uval.ival <= 256)
  400.             maxcolor = paramvalues[maxcolorindex].uval.ival;
  401.  
  402.       promptnum = piecespromts;
  403.       xm = paramvalues[promptnum++].uval.ival;
  404.  
  405.       ym = paramvalues[promptnum++].uval.ival;
  406.  
  407.       /* sanity checks */
  408.       {
  409.       int i;
  410.       long xtotal, ytotal;
  411.  
  412.       /* get resolution from the video name (which must be valid) */
  413. #ifndef XFRACT
  414.       pxdots = pydots = 0;
  415.       if ((i = check_vidmode_keyname(vidmde)) > 0)
  416.           if ((i = check_vidmode_key(0, i)) >= 0) {
  417.               /* get the resolution of this video mode */
  418.               pxdots = videotable[i].xdots;
  419.               pydots = videotable[i].ydots;
  420.               }
  421.       if (pxdots == 0 ) {
  422.           /* no corresponding video mode! */
  423.           static char far msg[] = {"Invalid video mode entry!"};
  424.           stopmsg(0,msg);
  425.           goto prompt_user;
  426.           }
  427. #endif
  428.  
  429.       /* bounds range on xm, ym */
  430.       if (xm < 1 || xm > 36 || ym < 1 || ym > 36) {
  431.           static char far msg[] = {"X and Y components must be 1 to 36"};
  432.           stopmsg(0,msg);
  433.           goto prompt_user;
  434.           }
  435.  
  436.       /* another sanity check: total resolution cannot exceed 65535 */
  437.       xtotal = xm;  ytotal = ym;
  438.       xtotal *= pxdots;  ytotal *= pydots;
  439.       if (xtotal > 65535L || ytotal > 65535L) {
  440.       static char far msg[] = {"Total resolution (X or Y) cannot exceed 65535"};
  441.           stopmsg(0,msg);
  442.           goto prompt_user;
  443.           }
  444.       }
  445.  
  446.       strcpy(outname, CommandFile);
  447.       gotinfile = 0;
  448.       if (access(CommandFile, 0) == 0)
  449.       {                         /* file exists */
  450.          gotinfile = 1;
  451.          if (access(CommandFile, 6))
  452.          {
  453.             sprintf(buf, s_cantwrite, CommandFile);
  454.             stopmsg(0, buf);
  455.             continue;
  456.          }
  457.          i = strlen(outname);
  458.          while (--i >= 0 && outname[i] != SLASHC)
  459.             outname[i] = 0;
  460.          strcat(outname, "fractint.tmp");
  461.          infile = fopen(CommandFile, "rt");
  462. #ifndef XFRACT
  463.          setvbuf(infile, tstack, _IOFBF, 4096); /* improves speed */
  464. #endif
  465.       }
  466.       if ((parmfile = fopen(outname, "wt")) == NULL)
  467.       {
  468.          sprintf(buf, s_cantcreate, outname);
  469.          stopmsg(0, buf);
  470.          if (gotinfile)
  471.             fclose(infile);
  472.          continue;
  473.       }
  474.  
  475.       if (gotinfile)
  476.       {
  477.          while (file_gets(buf, 255, infile) >= 0)
  478.          {
  479.             if (strchr(buf, '{')/* entry heading? */
  480.                 && sscanf(buf, " %40[^ \t({]", buf2)
  481.                 && stricmp(buf2, CommandName) == 0)
  482.             {                   /* entry with same name */
  483.                sprintf(buf2, "File already has an entry named %s\n\
  484. Continue to replace it, Cancel to back out", CommandName);
  485.                if (stopmsg(18, buf2) < 0)
  486.                {                /* cancel */
  487.                   fclose(infile);
  488.                   fclose(parmfile);
  489.                   unlink(outname);
  490.                   goto prompt_user;
  491.                }
  492.                while (strchr(buf, '}') == NULL
  493.                       && file_gets(buf, 255, infile) > 0)
  494.                {
  495.                }                /* skip to end of set */
  496.                break;
  497.             }
  498.             fputs(buf, parmfile);
  499.             fputc('\n', parmfile);
  500.          }
  501.       }
  502. /***** start here*/
  503.       if (xm > 1 || ym > 1)
  504.       {
  505.          if (xxmin != xx3rd || yymin != yy3rd)
  506.             have3rd = 1;
  507.          else
  508.             have3rd = 0;
  509.          if ((fpbat = fopen("makemig.bat", "w")) == NULL)
  510.             xm = ym = 0;
  511.          pdelx  = (xxmax - xx3rd) / (xm * pxdots - 1);   /* calculate stepsizes */
  512.          pdely  = (yymax - yy3rd) / (ym * pydots - 1);
  513.          pdelx2 = (xx3rd - xxmin) / (ym * pydots - 1);
  514.          pdely2 = (yy3rd - yymin) / (xm * pxdots - 1);
  515.  
  516.          /* save corners */
  517.          pxxmin = xxmin;
  518.          pxxmax = xxmax;
  519.          pyymin = yymin;
  520.          pyymax = yymax;
  521.       }
  522.       for (i = 0; i < xm; i++)  /* columns */
  523.       for (j = 0; j < ym; j++)  /* rows    */
  524.       {
  525.          if (xm > 1 || ym > 1)
  526.          {
  527.             int w;
  528.             char c;
  529.             char PCommandName[80];
  530.             w=0;
  531.             while(w < strlen(CommandName))
  532.             {
  533.                c = CommandName[w];
  534.                if(isspace(c) || c == 0)
  535.                   break;
  536.                PCommandName[w] = c;
  537.                w++;
  538.             }
  539.             PCommandName[w] = 0;
  540.             {
  541.                char buf[20];
  542.                sprintf(buf,"_%c%c",PAR_KEY(i),PAR_KEY(j));
  543.                strcat(PCommandName,buf);
  544.             }
  545.             fprintf(parmfile, "%-19s{",PCommandName);
  546.             xxmin = pxxmin + pdelx*(i*pxdots) + pdelx2*(j*pydots);
  547.             xxmax = pxxmin + pdelx*((i+1)*pxdots - 1) + pdelx2*((j+1)*pydots - 1);
  548.             yymin = pyymax - pdely*((j+1)*pydots - 1) - pdely2*((i+1)*pxdots - 1);
  549.             yymax = pyymax - pdely*(j*pydots) - pdely2*(i*pxdots);
  550.             if (have3rd)
  551.             {
  552.                xx3rd = pxxmin + pdelx*(i*pxdots) + pdelx2*((j+1)*pydots - 1);
  553.                yy3rd = pyymax - pdely*((j+1)*pydots - 1) - pdely2*(i*pxdots);
  554.             }
  555.             else
  556.             {
  557.                xx3rd = xxmin;
  558.                yy3rd = yymin;
  559.             }
  560.             fprintf(fpbat,"Fractint batch=yes overwrite=yes @%s/%s\n",CommandFile,PCommandName);
  561.             fprintf(fpbat,"If Errorlevel 2 goto oops\n");
  562.          }
  563.          else
  564.             fprintf(parmfile, "%-19s{", CommandName);
  565.          if (CommandComment1[0])
  566.             fprintf(parmfile, " ; %Fs", CommandComment1);
  567.          fputc('\n', parmfile);
  568.          {
  569.             char buf[25];
  570.             memset(buf, ' ', 23);
  571.             buf[23] = 0;
  572.             buf[21] = ';';
  573.             if (CommandComment2[0])
  574.                fprintf(parmfile, "%s%Fs\n", buf, CommandComment2);
  575.             if (CommandComment3[0])
  576.                fprintf(parmfile, "%s%Fs\n", buf, CommandComment3);
  577.             if (CommandComment4[0])
  578.                fprintf(parmfile, "%s%Fs\n", buf, CommandComment4);
  579.          }
  580.          write_batch_parms(parmfile, colorspec, maxcolor);   /* write the parameters */
  581.          if(xm > 1 || ym > 1)
  582.          {
  583.             fprintf(parmfile,"  video=%s", vidmde);
  584.             fprintf(parmfile," savename=frmig_%c%c\n", PAR_KEY(i), PAR_KEY(j));
  585.          }
  586.          fprintf(parmfile, "  }\n\n");
  587.       }
  588.       if(xm > 1 || ym > 1)
  589.          {
  590.          fprintf(fpbat,"Fractint makemig=%d/%d\n",xm,ym);
  591.          fprintf(fpbat,"Rem Simplgif fractmig.gif simplgif.gif  in case you need it\n");
  592.          fprintf(fpbat,":oops\n");
  593.          fclose(fpbat);
  594.          }
  595. /*******end here */
  596.  
  597.       if (gotinfile)
  598.       {                         /* copy the rest of the file */
  599.          while ((i = file_gets(buf, 255, infile)) == 0)
  600.          {
  601.          }                      /* skip blanks */
  602.          while (i >= 0)
  603.          {
  604.             fputs(buf, parmfile);
  605.             fputc('\n', parmfile);
  606.             i = file_gets(buf, 255, infile);
  607.          }
  608.          fclose(infile);
  609.       }
  610.       fclose(parmfile);
  611.       if (gotinfile)
  612.       {                         /* replace the original file with the new */
  613.          unlink(CommandFile);   /* success assumed on these lines       */
  614.          rename(outname, CommandFile);  /* since we checked earlier with
  615.                                          * access */
  616.       }
  617.       break;
  618.    }
  619.    helpmode = oldhelpmode;
  620.    unstackscreen();
  621.    EXIT_OVLY;
  622. }
  623. #ifdef C6
  624. #pragma optimize("e",on)  /* back to normal */
  625. #endif
  626.  
  627. static struct write_batch_data { /* buffer for parms to break lines nicely */
  628.    int len;
  629.    char buf[513];
  630.    } *wbdata;
  631.  
  632. static void write_batch_parms(FILE *batch,char *colorinf,int maxcolor)
  633. {
  634.    int i,j,k;
  635.    double Xctr, Yctr, Magnification;
  636.    struct write_batch_data wb_data;
  637.    char *sptr;
  638.    char buf[81];
  639.  
  640.    wbdata = &wb_data;
  641.    wb_data.len = 0; /* force first parm to start on new line */
  642.  
  643.    if (display3d <= 0) { /* a fractal was generated */
  644.  
  645.       /****** fractal only parameters in this section *******/
  646.       put_parm(" reset");
  647.       if (save_release!=0) put_parm("=%d",save_release);
  648.  
  649.       if (*(sptr = curfractalspecific->name) == '*') ++sptr;
  650.       put_parm( " type=%s",sptr);
  651.  
  652.       if (fractype == JULIBROT || fractype == JULIBROTFP)
  653.       {
  654.            put_parm(" julibrotfromto=%.15g/%.15g/%.15g/%.15g",
  655.                mxmaxfp,mxminfp,mymaxfp,myminfp);
  656.          /* these rarely change */
  657.          if(originfp != 8 || heightfp != 7 || widthfp != 10 || distfp != 24
  658.                           || depthfp != 8 || zdots != 128)
  659.             put_parm(" julibrot3d=%d/%g/%g/%g/%g/%g",
  660.                 zdots, originfp, depthfp, heightfp, widthfp,distfp);
  661.          if(eyesfp != 0)
  662.             put_parm(" julibroteyes=%g",eyesfp);
  663.          if(neworbittype != JULIA)
  664.          {
  665.             char *name;
  666.             name = fractalspecific[neworbittype].name;
  667.             if(*name=='*')
  668.                name++;
  669.             put_parm(" orbitname=%s",name);
  670.          }
  671.          if(juli3Dmode !=0)
  672.             put_parm(" 3Dmode=%s",juli3Doptions[juli3Dmode]);
  673.       }
  674.       if (fractype == FORMULA || fractype == FFORMULA)
  675.      put_parm( " formulafile=%s formulaname=%s",extract_filename(FormFileName),FormName);
  676.       if (fractype == LSYSTEM)
  677.      put_parm( " lfile=%s lname=%s",extract_filename(LFileName),LName);
  678.       if (fractype == IFS || fractype == IFS3D)
  679.      put_parm( " ifsfile=%s ifs=%s",extract_filename(IFSFileName),IFSName);
  680.       if (fractype == INVERSEJULIA || fractype == INVERSEJULIAFP)
  681.       {
  682.      extern int major_method, minor_method;
  683.      put_parm( " miim=%s/%s", major[major_method], minor[minor_method]);
  684.       }
  685.  
  686.       showtrig(buf); /* this function is in miscres.c */
  687.       if (buf[0])
  688.      put_parm(buf);
  689.  
  690.       if (usr_stdcalcmode != 'g')
  691.      put_parm(" passes=%c",usr_stdcalcmode);
  692.  
  693.       if (usemag && cvtcentermag(&Xctr, &Yctr, &Magnification)) {
  694.      put_parm(" center-mag=");
  695.      put_parm((delmin > 1000) ? "%g/%g/%g"
  696.                   : "%+20.17lf/%+20.17lf/%+20.17lf",
  697.           Xctr,Yctr,Magnification);
  698.      }
  699.       else {
  700.      int xdigits,ydigits;
  701.      put_parm( " corners=");
  702.      xdigits = getprec(xxmin,xxmax,xx3rd);
  703.      ydigits = getprec(yymin,yymax,yy3rd);
  704.      put_float(0,xxmin,xdigits);
  705.      put_float(1,xxmax,xdigits);
  706.      put_float(1,yymin,ydigits);
  707.      put_float(1,yymax,ydigits);
  708.      if (xx3rd != xxmin || yy3rd != yymin) {
  709.         put_float(1,xx3rd,xdigits);
  710.         put_float(1,yy3rd,ydigits);
  711.         }
  712.      }
  713.  
  714.       for (i = (MAXPARAMS-1); i >= 0; --i)
  715.      if (param[i] != 0.0) break;
  716.       if (i >= 0) {
  717.         if (fractype == CELLULAR)
  718.           put_parm(" params=%.1f",param[0]);
  719.         else
  720. #ifndef XFRACT
  721.      put_parm(" params=%.17Lg",(long double)param[0]);
  722. #else
  723.        put_parm(" params=%.17g",(double)param[0]);
  724. #endif
  725.      for (j = 1; j <= i; ++j)
  726.         if (fractype == CELLULAR)
  727.           put_parm("/%.1f",param[j]);
  728.         else
  729. #ifndef XFRACT
  730.         put_parm("/%.17Lg",(long double)param[j]);
  731. #else
  732.           put_parm("/%.17g",(double)param[j]);
  733. #endif
  734.      }
  735.  
  736.       if(useinitorbit == 2)
  737.      put_parm( " initorbit=pixel");
  738.       else if(useinitorbit == 1)
  739.      put_parm( " initorbit=%.15g/%.15g",initorbit.x,initorbit.y);
  740.  
  741.       if (floatflag)
  742.      put_parm( " float=y");
  743.  
  744.       if (maxit != 150)
  745.      put_parm(" maxiter=%d",maxit);
  746.  
  747.       if(bailout && (potflag == 0 || potparam[2] == 0.0))
  748.      put_parm( " bailout=%d",bailout);
  749.       if(fillcolor != -1) {
  750.        put_parm(" fillcolor=");
  751.     put_parm( "%d",fillcolor);
  752.       }
  753.       if (inside != 1) {
  754.      put_parm(" inside=");
  755.      if (inside == -1)
  756.         put_parm( s_maxiter);
  757.      else if (inside == -59)
  758.         put_parm(s_zmag);
  759.      else if (inside == -60)
  760.         put_parm(s_bof60);
  761.      else if (inside == -61)
  762.         put_parm(s_bof61);
  763.      else if (inside == -100)
  764.         put_parm(s_epscross);
  765.      else if (inside == -101)
  766.         put_parm(s_startrail);
  767.      else if (inside == -102)
  768.         put_parm(s_period);
  769.      else
  770.         put_parm( "%d",inside);
  771.      }
  772.       if (outside != -1)
  773.       {
  774.      put_parm(" outside=");
  775.      if (outside == -2)
  776.         put_parm(s_real);
  777.      else if (outside == -3)
  778.         put_parm(s_imag);
  779.      else if (outside == -4)
  780.         put_parm(s_mult);
  781.      else if (outside == -5)
  782.         put_parm(s_sum);
  783.      else
  784.         put_parm( "%d",outside);
  785.       }
  786.  
  787.       if(LogFlag) {
  788.      put_parm( " logmap=");
  789.      if(LogFlag == -1)
  790.         put_parm( "old");
  791.      else if(LogFlag == 1)
  792.         put_parm( "yes");
  793.      else
  794.         put_parm( "%d", LogFlag);
  795.      }
  796.  
  797.       if (potflag) {
  798.        put_parm( " potential=%d/%g/%d",
  799.            (int)potparam[0],potparam[1],(int)potparam[2]);
  800.        if(pot16bit)
  801.         put_parm( "/16bit");
  802.      }
  803.       if (invert)
  804.      put_parm( " invert=%g/%g/%g",
  805.          inversion[0], inversion[1], inversion[2]);
  806.       if (decomp[0])
  807.      put_parm( " decomp=%d", decomp[0]);
  808.       if (distest)
  809.      put_parm( " distest=%d/%d", distest, distestwidth);
  810.       if (usr_biomorph != -1)
  811.      put_parm( " biomorph=%d", usr_biomorph);
  812.       if (finattract)
  813.      put_parm(" finattract=y");
  814.  
  815.       if (forcesymmetry != 999) {
  816.          static char far msg[] = 
  817.             {"Regenerate before <b> to get correct symmetry"};
  818.          if(forcesymmetry == 1000)
  819.             stopmsg(0,msg);
  820.      put_parm( " symmetry=");
  821.      if (forcesymmetry==XAXIS)
  822.         put_parm("xaxis");
  823.      else if(forcesymmetry==YAXIS)
  824.         put_parm("yaxis");
  825.      else if(forcesymmetry==XYAXIS)
  826.         put_parm("xyaxis");
  827.      else if(forcesymmetry==ORIGIN)
  828.         put_parm("origin");
  829.      else if(forcesymmetry==PI_SYM)
  830.         put_parm("pi");
  831.      else
  832.         put_parm("none");
  833.      }
  834.  
  835.       if (periodicitycheck != 1)
  836.      put_parm( " periodicity=%d",periodicitycheck);
  837.  
  838.       if (rflag)
  839.      put_parm( " rseed=%d",rseed);
  840.  
  841.       if (rangeslen) {
  842.      put_parm(" ranges=");
  843.      i = 0;
  844.      while (i < rangeslen) {
  845.         if (i)
  846.            put_parm("/");
  847.         if (ranges[i] == -1) {
  848.            put_parm("-%d/",ranges[++i]);
  849.            ++i;
  850.            }
  851.         put_parm("%d",ranges[i++]);
  852.         }
  853.      }
  854.       }
  855.  
  856.    if (display3d >= 1) {
  857.       /***** 3d transform only parameters in this section *****/
  858.       if(display3d == 2)
  859.          put_parm( " 3d=overlay");
  860.       else
  861.       put_parm( " 3d=yes");
  862.       if (loaded3d == 0)
  863.      put_filename("filename",readname);
  864.       if (SPHERE) {
  865.      put_parm( " sphere=y");
  866.      put_parm( " latitude=%d/%d", THETA1, THETA2);
  867.      put_parm( " longitude=%d/%d", PHI1, PHI2);
  868.      put_parm( " radius=%d", RADIUS);
  869.      }
  870.       put_parm( " scalexyz=%d/%d", XSCALE, YSCALE);
  871.       put_parm( " roughness=%d", ROUGH);
  872.       put_parm( " waterline=%d", WATERLINE);
  873.       if (FILLTYPE)
  874.      put_parm( " filltype=%d", FILLTYPE);
  875.       if (transparent[0] || transparent[1])
  876.      put_parm( " transparent=%d/%d", transparent[0],transparent[1]);
  877.       if (preview) {
  878.      put_parm( " preview=y");
  879.      if (showbox)
  880.         put_parm( " showbox=y");
  881.      put_parm( " coarse=%d",previewfactor);
  882.      }
  883.       if (RAY) {
  884.      put_parm( " ray=%d",RAY);
  885.      if (BRIEF)
  886.         put_parm(" brief=y");
  887.      }
  888.       if (FILLTYPE > 4) {
  889.      put_parm( " lightsource=%d/%d/%d", XLIGHT, YLIGHT, ZLIGHT);
  890.      if (LIGHTAVG)
  891.         put_parm( " smoothing=%d", LIGHTAVG);
  892.      }
  893.       if (RANDOMIZE)
  894.      put_parm( " randomize=%d",RANDOMIZE);
  895.  
  896.       if (Targa_Out)
  897.      put_parm( " fullcolor=y");
  898.       if (Ambient)
  899.      put_parm( " ambient=%d",Ambient);
  900.       if (haze)
  901.      put_parm( " haze=%d",haze);
  902.       }
  903.  
  904.    if (display3d) {        /* universal 3d */
  905.       /***** common (fractal & transform) 3d parameters in this section *****/
  906.       if (!SPHERE || display3d < 0)
  907.      put_parm( " rotation=%d/%d/%d", XROT, YROT, ZROT);
  908.       put_parm( " perspective=%d", ZVIEWER);
  909.       put_parm( " xyshift=%d/%d", XSHIFT, YSHIFT);
  910.       if(xtrans || ytrans)
  911.      put_parm( " xyadjust=%d/%d",xtrans,ytrans);
  912.       if(glassestype) {
  913.      put_parm( " stereo=%d",glassestype);
  914.      put_parm( " interocular=%d",eyeseparation);
  915.      put_parm( " converge=%d",xadjust);
  916.      put_parm( " crop=%d/%d/%d/%d",
  917.          red_crop_left,red_crop_right,blue_crop_left,blue_crop_right);
  918.      put_parm( " bright=%d/%d",
  919.          red_bright,blue_bright);
  920.      }
  921.       }
  922.  
  923.    /***** universal parameters in this section *****/
  924.  
  925.    if(viewwindow == 1)
  926.    {
  927.       put_parm(" viewwindows=%g/%g",viewreduction,finalaspectratio);
  928.       if(viewcrop)
  929.          put_parm("/yes");
  930.       else
  931.          put_parm("/no");
  932.       put_parm("/%d/%d",viewxdots,viewydots);
  933.    }
  934.    if (*colorinf != 'n') {
  935.       put_parm(" colors=");
  936.       if (*colorinf == '@')
  937.      put_parm(colorinf);
  938.       else {
  939.      int curc,scanc,force,diffmag;
  940.      int delta,diff1[4][3],diff2[4][3];
  941.      curc = force = 0;
  942.      while (1) {
  943.         /* emit color in rgb 3 char encoded form */
  944.         for (j = 0; j < 3; ++j) {
  945.            if ((k = dacbox[curc][j]) < 10) k += '0';
  946.            else if (k < 36)            k += ('A' - 10);
  947.            else                   k += ('_' - 36);
  948.            buf[j] = k;
  949.            }
  950.         buf[3] = 0;
  951.         put_parm(buf);
  952.         if (++curc >= maxcolor)     /* quit if done last color */
  953.            break;
  954.         /* Next a P Branderhorst special, a tricky scan for smooth-shaded
  955.            ranges which can be written as <nn> to compress .par file entry.
  956.            Method used is to check net change in each color value over
  957.            spans of 2 to 5 color numbers.  First time for each span size
  958.            the value change is noted.  After first time the change is
  959.            checked against noted change.  First time it differs, a
  960.            a difference of 1 is tolerated and noted as an alternate
  961.            acceptable change.  When change is not one of the tolerated
  962.            values, loop exits. */
  963.         if (force) {
  964.            --force;
  965.            continue;
  966.            }
  967.         scanc = curc;
  968.         while (scanc < maxcolor) {     /* scan while same diff to next */
  969.            if ((i = scanc - curc) > 3) /* check spans up to 4 steps */
  970.           i = 3;
  971.            for (k = 0; k <= i; ++k) {
  972.           for (j = 0; j < 3; ++j) { /* check pattern of chg per color */
  973.              delta = (int)dacbox[scanc][j] - (int)dacbox[scanc-k-1][j];
  974.              if (k == scanc - curc)
  975.             diff1[k][j] = diff2[k][j] = delta;
  976.              else
  977.             if (delta != diff1[k][j] && delta != diff2[k][j]) {
  978.                diffmag = abs(delta - diff1[k][j]);
  979.                if (diff1[k][j] != diff2[k][j] || diffmag != 1)
  980.                   break;
  981.                diff2[k][j] = delta;
  982.                }
  983.              }
  984.           if (j < 3) break; /* must've exited from inner loop above */
  985.           }
  986.            if (k <= i) break;   /* must've exited from inner loop above */
  987.            ++scanc;
  988.            }
  989.         /* now scanc-1 is next color which must be written explicitly */
  990.         if (scanc - curc > 2) { /* good, we have a shaded range */
  991.            if (scanc != maxcolor) {
  992.           if (diffmag < 3) {  /* not a sharp slope change? */
  993.              force = 2;       /* force more between ranges, to stop  */
  994.              --scanc;          /* "drift" when load/store/load/store/ */
  995.              }
  996.           if (k) {          /* more of the same             */
  997.              force += k;
  998.              --scanc;
  999.              }
  1000.           }
  1001.            if (--scanc - curc > 1) {
  1002.           put_parm("<%d>",scanc-curc);
  1003.           curc = scanc;
  1004.           }
  1005.            else           /* changed our mind */
  1006.           force = 0;
  1007.            }
  1008.         }
  1009.      }
  1010.       }
  1011.  
  1012.    if (rotate_lo != 1 || rotate_hi != 255)
  1013.       put_parm( " cyclerange=%d/%d",rotate_lo,rotate_hi);
  1014.  
  1015.    while (wbdata->len) /* flush the buffer */
  1016.       put_parm_line();
  1017. }
  1018.  
  1019. static void put_filename(char *keyword,char *fname)
  1020. {
  1021.    char *p;
  1022.    if (*fname && !endswithslash(fname)) {
  1023.       if ((p = strrchr(fname, SLASHC)))
  1024.      if (*(fname = p+1) == 0) return;
  1025.       put_parm(" %s=%s",keyword,fname);
  1026.       }
  1027. }
  1028.  
  1029. #ifndef XFRACT
  1030. static void put_parm(char *parm,...)
  1031. #else
  1032. static void put_parm(va_alist)
  1033. va_dcl
  1034. #endif
  1035. {
  1036.    char *bufptr;
  1037.    va_list args;
  1038.  
  1039. #ifndef XFRACT
  1040.    va_start(args,parm);
  1041. #else
  1042.    char * parm;
  1043.  
  1044.    va_start(args);
  1045.    parm = va_arg(args,char *);
  1046. #endif
  1047.    if (*parm == ' '             /* starting a new parm */
  1048.      && wbdata->len == 0)    /* skip leading space */
  1049.       ++parm;
  1050.    bufptr = wbdata->buf + wbdata->len;
  1051.    vsprintf(bufptr,parm,args);
  1052.    while (*(bufptr++))
  1053.       ++wbdata->len;
  1054.    while (wbdata->len > 200)
  1055.       put_parm_line();
  1056. }
  1057.  
  1058. #define NICELINELEN 68
  1059. #define MAXLINELEN  72
  1060.  
  1061. static void put_parm_line()
  1062. {
  1063.    int len,c;
  1064.    if ((len = wbdata->len) > NICELINELEN) {
  1065.       len = NICELINELEN+1;
  1066.       while (--len != 0 && wbdata->buf[len] != ' ') { }
  1067.       if (len == 0) {
  1068.      len = NICELINELEN-1;
  1069.      while (++len < MAXLINELEN
  1070.        && wbdata->buf[len] && wbdata->buf[len] != ' ') { }
  1071.      }
  1072.       }
  1073.    c = wbdata->buf[len];
  1074.    wbdata->buf[len] = 0;
  1075.    fputs("  ",parmfile);
  1076.    fputs(wbdata->buf,parmfile);
  1077.    if (c && c != ' ')
  1078.       fputc('\\',parmfile);
  1079.    fputc('\n',parmfile);
  1080.    if ((wbdata->buf[len] = c) == ' ')
  1081.       ++len;
  1082.    wbdata->len -= len;
  1083.    strcpy(wbdata->buf,wbdata->buf+len);
  1084. }
  1085.  
  1086. static int getprec(double a,double b,double c)
  1087. {
  1088.    double diff,temp;
  1089.    int digits;
  1090.    double highv = 1.0E20;
  1091.    if ((diff = fabs(a - b)) == 0.0) diff = highv;
  1092.    if ((temp = fabs(a - c)) == 0.0) temp = highv;
  1093.    if (temp < diff) diff = temp;
  1094.    if ((temp = fabs(b - c)) == 0.0) temp = highv;
  1095.    if (temp < diff) diff = temp;
  1096.    digits = 7;
  1097.    if(debugflag >= 700 && debugflag < 720 )
  1098.       digits =  debugflag - 700;
  1099.    while (diff < 1.0 && digits < 17) {
  1100.       diff *= 10;
  1101.       ++digits;
  1102.       }
  1103.    return(digits);
  1104. }
  1105.  
  1106. static void put_float(int slash,double fnum,int prec)
  1107. {  char buf[40];
  1108.    char *bptr, *dptr;
  1109.    bptr = buf;
  1110.    if (slash)
  1111.       *(bptr++) = '/';
  1112. /*   sprintf(bptr,"%1.*f",prec,fnum); */
  1113. #ifndef XFRACT
  1114.      sprintf(bptr,"%1.*Lg",prec,(long double)fnum);
  1115. #else
  1116.      sprintf(bptr,"%1.*g",prec,(double)fnum);
  1117. #endif
  1118.  
  1119.    if ((dptr = strchr(bptr,'.'))) {
  1120.       ++dptr;
  1121.       bptr = buf + strlen(buf);
  1122.       while (--bptr > dptr && *bptr == '0')
  1123.      *bptr = 0;
  1124.       }
  1125.    put_parm(buf);
  1126. }
  1127.  
  1128. #ifndef XFRACT
  1129. void shell_to_dos()
  1130. {
  1131.    char *comspec;
  1132.    /* from fractint.c & calls no ovlys, doesn't need ENTER_OVLY */
  1133.    if ((comspec = getenv("COMSPEC")) == NULL)
  1134.       printf("Cannot find COMMAND.COM.\n");
  1135.    else {
  1136.       putenv("PROMPT='EXIT' returns to FRACTINT.$_$p$g");
  1137.       spawnl(P_WAIT, comspec, NULL);
  1138.       }
  1139. }
  1140. #endif
  1141.  
  1142.  
  1143. void showfreemem()
  1144. {
  1145. #ifndef XFRACT
  1146.    extern int num_adapters;
  1147.    extern char *adapters[];
  1148.    char *tempptr;
  1149.    BYTE huge *fartempptr;
  1150.    unsigned i,i2;
  1151.    long j,j2;
  1152.  
  1153.    extern char supervga_list;    /* from the list in VIDEO.ASM */
  1154.    char adapter_name[8];      /* entry lenth from VIDEO.ASM */
  1155.    char *adapter_ptr;
  1156.  
  1157.    ENTER_OVLY(OVLY_MISCOVL);
  1158.    printf("\n CPU type: %d  FPU type: %d  IIT FPU: %d  Video: %d",
  1159.       cpu, fpu, iit, video_type);
  1160.          
  1161.    adapter_ptr = &supervga_list;
  1162.    
  1163.    for(i = 0 ; ; i++) {        /* find the SuperVGA entry */
  1164.        int j;
  1165.        memcpy(adapter_name , adapter_ptr, 8);
  1166.        adapter_ptr += 8;
  1167.        if (adapter_name[0] == ' ') break;    /* end-of-the-list */
  1168.        if (adapter_name[6] == 0) continue;    /* not our adapter */
  1169.        adapter_name[6] = ' ';
  1170.        for (j = 0; j < 8; j++)
  1171.            if(adapter_name[j] == ' ')
  1172.                adapter_name[j] = 0;
  1173.        printf("  Video chip: %d (%s)",i+1,adapter_name);
  1174.        }
  1175.    printf("\n\n");
  1176.  
  1177.    i = j = 0;
  1178.    i2 = 0x8000;
  1179.    while ((i2 >>= 1) != 0)
  1180.       if ((tempptr = malloc(i+i2)) != NULL) {
  1181.      free(tempptr);
  1182.      i += i2;
  1183.      }
  1184.    printf(" %d NEAR bytes free \n", i);
  1185.    j2 = 0x80000;
  1186.    while ((j2 >>= 1) != 0)
  1187.       if ((fartempptr = (BYTE huge *)farmemalloc(j+j2)) != NULL) {
  1188.      farmemfree((void far*)fartempptr);
  1189.      j += j2;
  1190.      }
  1191.    printf(" %ld FAR bytes free \n\n press any key to continue...\n", j);
  1192.    getakey();
  1193.    EXIT_OVLY;
  1194. #endif
  1195. }
  1196.  
  1197.  
  1198. edit_text_colors()
  1199. {
  1200.    extern int debugflag;
  1201.    extern int lookatmouse;
  1202.    int save_debugflag,save_lookatmouse;
  1203.    int row,col,bkgrd;
  1204.    int rowf,colf,rowt,colt;
  1205.    char far *vidmem;
  1206.    char far *savescreen;
  1207.    char far *farp1; char far *farp2;
  1208.    int i,j,k;
  1209.    ENTER_OVLY(OVLY_MISCOVL);
  1210.    save_debugflag = debugflag;
  1211.    save_lookatmouse = lookatmouse;
  1212.    debugflag = 0;   /* don't get called recursively */
  1213.    lookatmouse = 2; /* text mouse sensitivity */
  1214.    row = col = bkgrd = rowt = rowf = colt = colf = 0;
  1215.    vidmem = MK_FP(0xB800,0);
  1216.    while (1) {
  1217.       if (row < 0)  row = 0;
  1218.       if (row > 24) row = 24;
  1219.       if (col < 0)  col = 0;
  1220.       if (col > 79) col = 79;
  1221.       movecursor(row,col);
  1222.       i = getakey();
  1223.       if (i >= 'a' && i <= 'z') i -= 32; /* uppercase */
  1224.       switch (i) {
  1225.      case 27: /* esc */
  1226.         debugflag = save_debugflag;
  1227.         lookatmouse = save_lookatmouse;
  1228.         movecursor(25,80);
  1229.         EXIT_OVLY;
  1230.         return 0;
  1231.      case '/':
  1232.         farp1 = savescreen = farmemalloc(4000L);
  1233.         farp2 = vidmem;
  1234.         for (i = 0; i < 4000; ++i) { /* save and blank */
  1235.            *(farp1++) = *farp2;
  1236.            *(farp2++) = 0;
  1237.            }
  1238.         for (i = 0; i < 8; ++i)      /* 8 bkgrd attrs */
  1239.            for (j = 0; j < 16; ++j) { /* 16 fgrd attrs */
  1240.           k = i*16 + j;
  1241.           farp1 = vidmem + i*320 + j*10;
  1242.           *(farp1++) = ' '; *(farp1++) = k;
  1243.           *(farp1++) = i+'0'; *(farp1++) = k;
  1244.           *(farp1++) = (j < 10) ? j+'0' : j+'A'-10; *(farp1++) = k;
  1245.           *(farp1++) = ' '; *(farp1++) = k;
  1246.           }
  1247.         getakey();
  1248.         farp1 = vidmem;
  1249.         farp2 = savescreen;
  1250.         for (i = 0; i < 4000; ++i) /* restore */
  1251.            *(farp1++) = *(farp2++);
  1252.         farmemfree(savescreen);
  1253.         break;
  1254.      case ',':
  1255.         rowf = row; colf = col; break;
  1256.      case '.':
  1257.         rowt = row; colt = col; break;
  1258.      case ' ': /* next color is background */
  1259.         bkgrd = 1; break;
  1260.      case 1075: /* cursor left  */
  1261.         --col; break;
  1262.      case 1077: /* cursor right */
  1263.         ++col; break;
  1264.      case 1072: /* cursor up    */
  1265.         --row; break;
  1266.      case 1080: /* cursor down  */
  1267.         ++row; break;
  1268.      case 13:   /* enter */
  1269.         *(vidmem + row*160 + col*2) = getakey();
  1270.         break;
  1271.      default:
  1272.         if (i >= '0' && i <= '9')      i -= '0';
  1273.         else if (i >= 'A' && i <= 'F') i -= 'A'-10;
  1274.         else break;
  1275.         for (j = rowf; j <= rowt; ++j)
  1276.            for (k = colf; k <= colt; ++k) {
  1277.           farp1 = vidmem + j*160 + k*2 + 1;
  1278.           if (bkgrd) *farp1 = (*farp1 & 15) + i * 16;
  1279.           else         *farp1 = (*farp1 & 0xf0) + i;
  1280.           }
  1281.         bkgrd = 0;
  1282.      }
  1283.       }
  1284. }
  1285.  
  1286.  
  1287. extern int badconfig;
  1288. extern struct videoinfo far videotable[];
  1289. extern struct videoinfo far *vidtbl;
  1290. extern int vidtbllen;
  1291. extern int tabmode;
  1292. extern int adapter;
  1293. static int *entsptr;
  1294. static int modes_changed;
  1295. extern int mode7text;
  1296.  
  1297. int select_video_mode(int curmode)
  1298. {
  1299.    static char far hdg2[]={"key...name......................xdot.ydot.colr.comment.................."};
  1300.    static char far hdg1[]={"Select Video Mode"};
  1301.    int entnums[MAXVIDEOMODES];
  1302.    int attributes[MAXVIDEOMODES];
  1303.    int i,j,k,ret;
  1304.    int oldtabmode,oldhelpmode;
  1305.  
  1306.    ENTER_OVLY(OVLY_MISCOVL);
  1307.  
  1308.    load_fractint_cfg(0);    /* load fractint.cfg to extraseg */
  1309.  
  1310.    for (i = 0; i < vidtbllen; ++i) { /* init tables */
  1311.       entnums[i] = i;
  1312.       attributes[i] = 1;
  1313.       }
  1314.    entsptr = entnums;        /* for indirectly called subroutines */
  1315.  
  1316.    qsort(entnums,vidtbllen,sizeof(entnums[0]),entcompare); /* sort modes */
  1317.  
  1318.    /* pick default mode */
  1319.    if (curmode < 0) {
  1320.       switch (video_type) { /* set up a reasonable default (we hope) */
  1321.      case 1:  videoentry.videomodeax = 8;    /* hgc */
  1322.           videoentry.colors = 2;
  1323.           break;
  1324.      case 2:  videoentry.videomodeax = 4;    /* cga */
  1325.           videoentry.colors = 4;
  1326.           break;
  1327.      case 3:  videoentry.videomodeax = 16;    /* ega */
  1328.           videoentry.colors = 16;
  1329.           if (mode7text) {        /* egamono */
  1330.              videoentry.videomodeax = 15;
  1331.              videoentry.colors = 2;
  1332.              }
  1333.           break;
  1334.      default: videoentry.videomodeax = 19;    /* mcga/vga? */
  1335.           videoentry.colors = 256;
  1336.           break;
  1337.      }
  1338.       }
  1339.    else
  1340.       far_memcpy((char far *)&videoentry,(char far *)&videotable[curmode],
  1341.          sizeof(videoentry));
  1342. #ifndef XFRACT
  1343.    for (i = 0; i < vidtbllen; ++i) { /* find default mode */
  1344.       if ( videoentry.videomodeax == vidtbl[entnums[i]].videomodeax
  1345.     && videoentry.colors      == vidtbl[entnums[i]].colors
  1346.     && (curmode < 0
  1347.         || far_memcmp((char far *)&videoentry,(char far *)&vidtbl[entnums[i]],
  1348.               sizeof(videoentry)) == 0))
  1349.      break;
  1350.       }
  1351.    if (i >= vidtbllen) /* no match, default to first entry */
  1352.       i = 0;
  1353.  
  1354.    oldtabmode = tabmode;
  1355.    oldhelpmode = helpmode;
  1356.    modes_changed = 0;
  1357.    tabmode = 0;
  1358.    helpmode = HELPVIDSEL;
  1359.    i = fullscreen_choice(CHOICEHELP,hdg1,hdg2,NULL,vidtbllen,NULL,attributes,
  1360.                          1,16,72,i,format_item,NULL,NULL,check_modekey);
  1361.    tabmode = oldtabmode;
  1362.    helpmode = oldhelpmode;
  1363.    if (i == -1) {
  1364.    static char far msg[]={"Save new function key assignments or cancel changes?"};
  1365.       if (modes_changed /* update fractint.cfg for new key assignments */
  1366.     && badconfig == 0
  1367.     && stopmsg(22,msg) == 0)
  1368.      update_fractint_cfg();
  1369.       EXIT_OVLY;
  1370.       return(-1);
  1371.       }
  1372.    if (i < 0)    /* picked by function key */
  1373.       i = -1 - i;
  1374.    else     /* picked by Enter key */
  1375.       i = entnums[i];
  1376. #endif
  1377.    far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i],
  1378.           sizeof(videoentry));  /* the selected entry now in videoentry */
  1379.  
  1380. #ifndef XFRACT
  1381.    /* copy fractint.cfg table to resident table, note selected entry */
  1382.    j = k = 0;
  1383.    far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE);
  1384.    for (i = 0; i < vidtbllen; ++i) {
  1385.       if (vidtbl[i].keynum > 0) {
  1386.      far_memcpy((char far *)&videotable[j],(char far *)&vidtbl[i],
  1387.             sizeof(*vidtbl));
  1388.      if (far_memcmp((char far *)&videoentry,(char far *)&vidtbl[i],
  1389.             sizeof(videoentry)) == 0)
  1390.         k = vidtbl[i].keynum;
  1391.      if (++j >= MAXVIDEOTABLE-1)
  1392.         break;
  1393.      }
  1394.       }
  1395. #else
  1396.     k = vidtbl[0].keynum;
  1397. #endif
  1398.    if ((ret = k) == 0) { /* selected entry not a copied (assigned to key) one */
  1399.       far_memcpy((char far *)&videotable[MAXVIDEOTABLE-1],
  1400.          (char far *)&videoentry,sizeof(*vidtbl));
  1401.       ret = 1400; /* special value for check_vidmode_key */
  1402.       }
  1403.  
  1404.    if (modes_changed /* update fractint.cfg for new key assignments */
  1405.      && badconfig == 0)
  1406.       update_fractint_cfg();
  1407.  
  1408.    EXIT_OVLY;
  1409.    return(ret);
  1410. }
  1411.  
  1412. static void format_item(int choice,char *buf)
  1413. {
  1414.    char kname[5];
  1415.    char biosflag;
  1416.    far_memcpy((char far *)&videoentry,(char far *)&vidtbl[entsptr[choice]],
  1417.           sizeof(videoentry));
  1418.    vidmode_keyname(videoentry.keynum,kname);
  1419.    biosflag = (videoentry.dotmode % 100 == 1) ? 'B' : ' ';
  1420.    sprintf(buf,"%-5s %-25s %4d %4d %3d%c %-25s",  /* 72 chars */
  1421.        kname, videoentry.name, videoentry.xdots, videoentry.ydots,
  1422.        videoentry.colors, biosflag, videoentry.comment);
  1423. }
  1424.  
  1425. static int check_modekey(int curkey,int choice)
  1426. {
  1427.    int i,j,k,ret;
  1428.    if ((i = check_vidmode_key(1,curkey)) >= 0)
  1429.       return(-1-i);
  1430.    i = entsptr[choice];
  1431.    ret = 0;
  1432.    if ( (curkey == '-' || curkey == '+')
  1433.      && (vidtbl[i].keynum == 0 || vidtbl[i].keynum >= 1084)) {
  1434.       static char far msg[]={"Missing or bad FRACTINT.CFG file. Can't reassign keys."};
  1435.       if (badconfig)
  1436.      stopmsg(0,msg);
  1437.       else {
  1438.      if (curkey == '-') {                   /* deassign key? */
  1439.         if (vidtbl[i].keynum >= 1084) {
  1440.            vidtbl[i].keynum = 0;
  1441.            modes_changed = 1;
  1442.            }
  1443.         }
  1444.      else {                 /* assign key? */
  1445.         j = getakeynohelp();
  1446.         if (j >= 1084 && j <= 1113) {
  1447.            for (k = 0; k < vidtbllen; ++k) {
  1448.           if (vidtbl[k].keynum == j) {
  1449.              vidtbl[k].keynum = 0;
  1450.              ret = -1; /* force redisplay */
  1451.              }
  1452.           }
  1453.            vidtbl[i].keynum = j;
  1454.            modes_changed = 1;
  1455.            }
  1456.         }
  1457.      }
  1458.       }
  1459.    return(ret);
  1460. }
  1461.  
  1462. static int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2)
  1463. {
  1464.    int i,j;
  1465.    if ((i = vidtbl[*((int *)p1)].keynum) == 0) i = 9999;
  1466.    if ((j = vidtbl[*((int *)p2)].keynum) == 0) j = 9999;
  1467.    if (i < j || (i == j && *((int *)p1) < *((int *)p2)))
  1468.       return(-1);
  1469.    return(1);
  1470. }
  1471.  
  1472. static void update_fractint_cfg()
  1473. {
  1474. #ifndef XFRACT
  1475.    char cfgname[100],outname[100],buf[121],kname[5];
  1476.    FILE *cfgfile,*outfile;
  1477.    int far *cfglinenums;
  1478.    int i,j,linenum,nextlinenum,nextmode;
  1479.    struct videoinfo vident;
  1480.  
  1481.    findpath("fractint.cfg",cfgname);
  1482.  
  1483.    if (access(cfgname,6)) {
  1484.       sprintf(buf,s_cantwrite,cfgname);
  1485.       stopmsg(0,buf);
  1486.       return;
  1487.       }
  1488.    strcpy(outname,cfgname);
  1489.    i = strlen(outname);
  1490.    while (--i >= 0 && outname[i] != SLASHC)
  1491.    outname[i] = 0;
  1492.    strcat(outname,"fractint.tmp");
  1493.    if ((outfile = fopen(outname,"w")) == NULL) {
  1494.       sprintf(buf,s_cantcreate,outname);
  1495.       stopmsg(0,buf);
  1496.       return;
  1497.       }
  1498.    cfgfile = fopen(cfgname,"r");
  1499.  
  1500.    cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]);
  1501.    linenum = nextmode = 0;
  1502.    nextlinenum = cfglinenums[0];
  1503.    while (fgets(buf,120,cfgfile)) {
  1504.       ++linenum;
  1505.       if (linenum == nextlinenum) { /* replace this line */
  1506.      far_memcpy((char far *)&vident,(char far *)&vidtbl[nextmode],
  1507.             sizeof(videoentry));
  1508.      vidmode_keyname(vident.keynum,kname);
  1509.      strcpy(buf,vident.name);
  1510.      i = strlen(buf);
  1511.      while (i && buf[i-1] == ' ') /* strip trailing spaces to compress */
  1512.         --i;
  1513.      j = i + 5;
  1514.      while (j < 32) {        /* tab to column 33 */
  1515.         buf[i++] = '\t';
  1516.         j += 8;
  1517.         }
  1518.      buf[i] = 0;
  1519.      fprintf(outfile,"%-4s,%s,%4x,%4x,%4x,%4x,%4d,%4d,%4d,%3d,%s\n",
  1520.         kname,
  1521.         buf,
  1522.         vident.videomodeax,
  1523.         vident.videomodebx,
  1524.         vident.videomodecx,
  1525.         vident.videomodedx,
  1526.         vident.dotmode,
  1527.         vident.xdots,
  1528.         vident.ydots,
  1529.         vident.colors,
  1530.         vident.comment);
  1531.      if (++nextmode >= vidtbllen)
  1532.         nextlinenum = 32767;
  1533.      else
  1534.         nextlinenum = cfglinenums[nextmode];
  1535.      }
  1536.       else
  1537.      fputs(buf,outfile);
  1538.       }
  1539.  
  1540.    fclose(cfgfile);
  1541.    fclose(outfile);
  1542.    unlink(cfgname);        /* success assumed on these lines        */
  1543.    rename(outname,cfgname); /* since we checked earlier with access */
  1544. #endif
  1545. }
  1546.  
  1547. extern unsigned char olddacbox[256][3];
  1548. extern int gif87a_flag;
  1549.  
  1550. /* make_mig() takes a collection of individual GIF images (all
  1551.    presumably the same resolution and all presumably generated
  1552.    by Fractint and its "divide and conquer" algorithm) and builds
  1553.    a single multiple-image GIF out of them.  This routine is
  1554.    invoked by the "batch=stitchmode/x/y" option, and is called
  1555.    with the 'x' and 'y' parameters
  1556. */
  1557.  
  1558. make_mig(unsigned int xmult, unsigned int ymult)
  1559. {
  1560. unsigned int xstep, ystep;
  1561. unsigned int xres, yres;
  1562. unsigned int allxres, allyres, xtot, ytot;
  1563. unsigned int xloc, yloc;
  1564. unsigned int x, y;
  1565. unsigned char ichar;
  1566. unsigned int allitbl, itbl;
  1567. unsigned int i, j, k;
  1568. char gifin[15], gifout[15];
  1569. int errorflag, inputerrorflag;
  1570. unsigned char *temp;
  1571. FILE *out, *in;
  1572. char msgbuf[81];
  1573.  
  1574. errorflag = 0;                /* no errors so far */
  1575.  
  1576. strcpy(gifout,"fractmig.gif");
  1577.  
  1578. temp= &olddacbox[0][0];            /* a safe place for our temp data */
  1579.  
  1580. gif87a_flag = 1;            /* for now, force this */
  1581.  
  1582. /* process each input image, one at a time */
  1583. for (ystep = 0; ystep < ymult; ystep++) {
  1584.     for (xstep = 0; xstep < xmult; xstep++) {
  1585.  
  1586. if (xstep == 0 && ystep == 0) {        /* first time through? */
  1587.     static char far msg1[] = "Cannot create output file %s!\n";
  1588.     static char far msg2[] = " \n Generating multi-image GIF file %s using";
  1589.     static char far msg3[] = " %d X and %d Y components\n\n";
  1590.     _fstrcpy(msgbuf, msg2);
  1591.     printf(msgbuf, gifout);
  1592.     _fstrcpy(msgbuf, msg3);
  1593.     printf(msgbuf, xmult, ymult);
  1594.     /* attempt to create the output file */
  1595.     if ((out = fopen(gifout,"wb")) == NULL) {
  1596.         _fstrcpy(msgbuf, msg1);
  1597.         printf(msgbuf, gifout);
  1598.         exit(1);
  1599.         }
  1600.     }
  1601.  
  1602.         sprintf(gifin, "frmig_%c%c.gif", PAR_KEY(xstep), PAR_KEY(ystep));
  1603.  
  1604.         if ((in = fopen(gifin,"rb")) == NULL) {
  1605.             static char far msg1[] = "Can't open file %s!\n";
  1606.             _fstrcpy(msgbuf, msg1);
  1607.             printf(msgbuf, gifin);
  1608.             exit(1);
  1609.             }
  1610.  
  1611.         inputerrorflag = 0;
  1612.  
  1613.         /* (read, but only copy this if it's the first time through) */
  1614.         if (fread(temp,13,1,in) != 1)    /* read the header and LDS */
  1615.             inputerrorflag = 1;
  1616.         memcpy(&xres, &temp[6], 2);    /* X-resolution */
  1617.         memcpy(&yres, &temp[8], 2);    /* Y-resolution */
  1618.  
  1619.         if (xstep == 0 && ystep == 0) {    /* first time through? */
  1620.             allxres = xres;        /* save the "master" resolution */
  1621.             allyres = yres;
  1622.             xtot = xres * xmult;    /* adjust the image size */
  1623.             ytot = yres * ymult;
  1624.             memcpy(&temp[6], &xtot, 2);
  1625.             memcpy(&temp[8], &ytot, 2);
  1626.             if (gif87a_flag) {
  1627.                 temp[3] = '8';
  1628.                 temp[4] = '7';
  1629.                 temp[5] = 'a';
  1630.                 }
  1631.             if (fwrite(temp,13,1,out) != 1)    /* write out the header */
  1632.                 errorflag = 1;
  1633.             }                /* end of first-time-through */
  1634.  
  1635.  
  1636.         ichar = temp[10] & 0x07;    /* find the color table size */
  1637.         itbl = 1 << (++ichar);
  1638.         ichar = temp[10] & 0x80;    /* is there a global color table? */
  1639.         if (xstep == 0 && ystep == 0)    /* first time through? */
  1640.             allitbl = itbl;        /* save the color table size */
  1641.         if (ichar != 0) {        /* yup */
  1642.             /* (read, but only copy this if it's the first time through) */
  1643.             if(fread(temp,3*itbl,1,in) != 1)    /* read the global color table */
  1644.                 inputerrorflag = 2;
  1645.             if (xstep == 0 && ystep == 0)    /* first time through? */
  1646.                 if (fwrite(temp,3*itbl,1,out) != 1)    /* write out the GCT */
  1647.                     errorflag = 2;
  1648.             }
  1649.  
  1650.         if (xres != allxres || yres != allyres || itbl != allitbl) {
  1651.             /* Oops - our pieces don't match */
  1652.             static char far msg1[] = "File %s doesn't have the same resolution as its predecessors!\n";
  1653.             _fstrcpy(msgbuf, msg1);
  1654.             printf(msgbuf, gifin);
  1655.             exit(1);
  1656.             }
  1657.  
  1658.         for (;;) {            /* process each information block */
  1659.         if (fread(temp,1,1,in) != 1)    /* read the block identifier */
  1660.             inputerrorflag = 3;
  1661.  
  1662.         if (temp[0] == 0x2c) {        /* image descriptor block */
  1663.             if (fread(&temp[1],9,1,in) != 1)    /* read the Image Descriptor */
  1664.                 inputerrorflag = 4;
  1665.             memcpy(&xloc, &temp[1], 2);    /* X-location */
  1666.             memcpy(&yloc, &temp[3], 2);    /* Y-location */
  1667.             xloc += (xstep * xres);    /* adjust the locations */
  1668.             yloc += (ystep * yres);
  1669.             memcpy(&temp[1], &xloc, 2);
  1670.             memcpy(&temp[3], &yloc, 2);
  1671.             if (fwrite(temp,10,1,out) != 1)    /* write out the Image Descriptor */
  1672.                 errorflag = 4;
  1673.  
  1674.             ichar = temp[9] & 0x80;    /* is there a local color table? */
  1675.             if (ichar != 0) {        /* yup */
  1676.                 if (fread(temp,3*itbl,1,in) != 1)    /* read the local color table */
  1677.                     inputerrorflag = 5;
  1678.                 if (fwrite(temp,3*itbl,1,out) != 1)    /* write out the LCT */
  1679.                     errorflag = 5;
  1680.                 }
  1681.  
  1682.             if (fread(temp,1,1,in) != 1)    /* LZH table size */
  1683.                 inputerrorflag = 6;
  1684.             if (fwrite(temp,1,1,out) != 1)
  1685.                 errorflag = 6;
  1686.             while (1) {
  1687.                 if (errorflag != 0 || inputerrorflag != 0)    /* oops - did something go wrong? */
  1688.                     break;
  1689.                 if (fread(temp,1,1,in) != 1)    /* block size */
  1690.                     inputerrorflag = 7;
  1691.                 if (fwrite(temp,1,1,out) != 1)
  1692.                     errorflag = 7;
  1693.                 if ((i = temp[0]) == 0)
  1694.                     break;
  1695.                 if (fread(temp,i,1,in) != 1)    /* LZH data block */
  1696.                     inputerrorflag = 8;
  1697.                 if (fwrite(temp,i,1,out) != 1)
  1698.                     errorflag = 8;
  1699.                 }
  1700.             }
  1701.  
  1702.         if (temp[0] == 0x21) {        /* extension block */
  1703.             /* (read, but only copy this if it's the last time through) */
  1704.             if (fread(&temp[2],1,1,in) != 1)    /* read the block type */
  1705.                 inputerrorflag = 9;
  1706.             if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1)
  1707.                 if (fwrite(temp,2,1,out) != 1)
  1708.                     errorflag = 9;
  1709.             while (1) {
  1710.                 if (errorflag != 0 || inputerrorflag != 0)    /* oops - did something go wrong? */
  1711.                     break;
  1712.                 if (fread(temp,1,1,in) != 1)    /* block size */
  1713.                     inputerrorflag = 10;
  1714.                 if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1)
  1715.                     if (fwrite(temp,1,1,out) != 1)
  1716.                         errorflag = 10;
  1717.                 if ((i = temp[0]) == 0)
  1718.                     break;
  1719.                 if (fread(temp,i,1,in) != 1)    /* data block */
  1720.                     inputerrorflag = 11;
  1721.                 if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1)
  1722.                     if (fwrite(temp,i,1,out) != 1)
  1723.                         errorflag = 11;
  1724.                 }
  1725.             }
  1726.  
  1727.         if (temp[0] == 0x3b) {        /* end-of-stream indicator */
  1728.             break;            /* done with this file */
  1729.             }
  1730.  
  1731.         if (errorflag != 0 || inputerrorflag != 0)    /* oops - did something go wrong? */
  1732.             break;
  1733.  
  1734.         }
  1735.         fclose(in);            /* done with an input GIF */
  1736.  
  1737.         if (errorflag != 0 || inputerrorflag != 0)    /* oops - did something go wrong? */
  1738.             break;
  1739.         }
  1740.  
  1741.     if (errorflag != 0 || inputerrorflag != 0)    /* oops - did something go wrong? */
  1742.         break;
  1743.     }
  1744.  
  1745. temp[0] = 0x3b;            /* end-of-stream indicator */
  1746. if (fwrite(temp,1,1,out) != 1)
  1747.     errorflag = 12;
  1748. fclose(out);            /* done with the output GIF */
  1749.  
  1750. if (inputerrorflag != 0) {    /* uh-oh - something failed */
  1751.     static char far msg1[] = "\007 Process failed = early EOF on input file %s\n";
  1752.     _fstrcpy(msgbuf, msg1);
  1753.     printf(msgbuf, gifin);
  1754. /* following line was for debugging
  1755.     printf("inputerrorflag = %d\n", inputerrorflag);
  1756. */
  1757.     }
  1758.  
  1759. if (errorflag != 0) {        /* uh-oh - something failed */
  1760.     static char far msg1[] = "\007 Process failed = out of disk space?\n";
  1761.     _fstrcpy(msgbuf, msg1);
  1762.     printf(msgbuf);
  1763. /* following line was for debugging
  1764.     printf("errorflag = %d\n", errorflag);
  1765. */
  1766.     }
  1767.  
  1768. /* now delete each input image, one at a time */
  1769. if (errorflag == 0 && inputerrorflag == 0)
  1770.   for (ystep = 0; ystep < ymult; ystep++) {
  1771.     for (xstep = 0; xstep < xmult; xstep++) {
  1772.         sprintf(gifin, "frmig_%c%c.gif", PAR_KEY(xstep), PAR_KEY(ystep));
  1773.         remove(gifin);
  1774.         }
  1775.     }
  1776.  
  1777. /* tell the world we're done */
  1778. if (errorflag == 0 && inputerrorflag == 0) {
  1779.     static char far msg1[] = "File %s has been created (and its component files deleted)\n";
  1780.     _fstrcpy(msgbuf, msg1);
  1781.     printf(msgbuf, gifout);
  1782.     }
  1783. }
  1784.  
  1785. /* This routine copies the current screen to by flipping x-axis, y-axis,
  1786.    or both. Refuses to work if calculation in progress or if fractal
  1787.    non-resumable. Clears zoombox if any. Resets corners so resulting fractal
  1788.    is still valid. */
  1789. void flip_image(int key)
  1790. {
  1791.    int i, j, ix, iy, ixhalf, iyhalf, tempdot;
  1792.  
  1793.    ENTER_OVLY(OVLY_MISCOVL);
  1794.    /* fractal must be rotate-able and be finished */
  1795.    if ((curfractalspecific->flags&NOROTATE) > 0 
  1796.        || calc_status == 1   
  1797.        || calc_status == 2)  
  1798.       return;
  1799.    clear_zoombox(); /* clear, don't copy, the zoombox */
  1800.    ixhalf = xdots / 2;  
  1801.    iyhalf = ydots / 2;
  1802.    switch(key)
  1803.    {
  1804.    case 24:            /* control-X - reverse X-axis */
  1805.       for (i = 0; i < ixhalf; i++) 
  1806.       {
  1807.          if(keypressed())
  1808.             break;
  1809.          for (j = 0; j < ydots; j++) 
  1810.          {
  1811.             tempdot=getcolor(i,j);
  1812.             putcolor(i, j, getcolor(xdots-1-i,j));
  1813.             putcolor(xdots-1-i, j, tempdot);
  1814.          }
  1815.       }
  1816.       sxmin = xxmax + xxmin - xx3rd;
  1817.       symax = yymax + yymin - yy3rd;
  1818.       sxmax = xx3rd;
  1819.       symin = yy3rd;
  1820.       sx3rd = xxmax;
  1821.       sy3rd = yymin;
  1822.       reset_zoom_corners();
  1823.       calc_status = 0;
  1824.       break;
  1825.    case 25:            /* control-Y - reverse Y-aXis */
  1826.       for (j = 0; j < iyhalf; j++)
  1827.       {
  1828.          if(keypressed())
  1829.             break;
  1830.          for (i = 0; i < xdots; i++) 
  1831.          {
  1832.             tempdot=getcolor(i,j);
  1833.             putcolor(i, j, getcolor(i,ydots-1-j));
  1834.             putcolor(i,ydots-1-j, tempdot);
  1835.          }
  1836.       }
  1837.       sxmin = xx3rd;
  1838.       symax = yy3rd;
  1839.       sxmax = xxmax + xxmin - xx3rd;
  1840.       symin = yymax + yymin - yy3rd;
  1841.       sx3rd = xxmin;
  1842.       sy3rd = yymax;
  1843.       calc_status = 0;
  1844.       break;
  1845.    case 26:            /* control-Z - reverse X and Y aXis */
  1846.       for (i = 0; i < ixhalf; i++) 
  1847.       {
  1848.          if(keypressed())
  1849.             break;
  1850.          for (j = 0; j < ydots; j++) 
  1851.          {
  1852.             tempdot=getcolor(i,j);
  1853.             putcolor(i, j, getcolor(xdots-1-i,ydots-1-j));
  1854.             putcolor(xdots-1-i, ydots-1-j, tempdot);
  1855.          }
  1856.       }
  1857.       sxmin = xxmax;
  1858.       symax = yymin;
  1859.       sxmax = xxmin;
  1860.       symin = yymax;
  1861.       sx3rd = xxmax + xxmin - xx3rd;
  1862.       sy3rd = yymax + yymin - yy3rd;
  1863.       break;
  1864.    }
  1865.    reset_zoom_corners();
  1866.    calc_status = 0;
  1867.    EXIT_OVLY;
  1868. }
  1869.  
  1870.