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