1 /*
2         Overlayed odds and ends that don't fit anywhere else.
3 */
4 
5 #include <string.h>
6 #include <ctype.h>
7 #include <time.h>
8 
9 #ifndef XFRACT
10 #include <malloc.h>
11 #include <process.h>
12 #include <io.h>
13 #endif
14 
15 #ifndef USE_VARARGS
16 #include <stdarg.h>
17 #else
18 #include <varargs.h>
19 #endif
20 
21   /* see Fractint.c for a description of the "include"  hierarchy */
22 #include "port.h"
23 #include "prototyp.h"
24 #include "fractype.h"
25 #include "helpdefs.h"
26 
27 /* routines in this module      */
28 
29 void write_batch_parms(char *colorinf,int colorsonly, int maxcolor,int i, int j);
30 void expand_comments(char far *target, char far *source);
31 
32 #ifndef USE_VARARGS
33 static void put_parm(char *parm,...);
34 #else
35 static void put_parm();
36 #endif
37 
38 static void put_parm_line(void);
39 static int getprec(double,double,double);
40 int getprecbf(int);
41 static void put_float(int,double,int);
42 static void put_bf(int slash,bf_t r, int prec);
43 static void put_filename(char *keyword,char *fname);
44 #ifndef XFRACT
45 static int check_modekey(int curkey,int choice);
46 #endif
47 static int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2);
48 static void update_fractint_cfg(void);
49 static void strip_zeros(char *buf);
50 
51 /* fullscreen_choice options */
52 #define CHOICERETURNKEY 1
53 #define CHOICEMENU      2
54 #define CHOICEHELP      4
55 
56 char far par_comment[4][MAXCMT];
57 
58 char s_yes[]      = "yes";
59 char s_no[]       = "no";
60 char s_seqs[]     = " %s=%s";
61 char s_seqd[]     = " %s=%d";
62 char s_seqdd[]    = " %s=%d/%d";
63 char s_seqddd[]   = " %s=%d/%d/%d";
64 char s_seqldddd[]  = " %s=%ld/%d/%d/%d";
65 char s_seqd12[]   = " %s=%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d";
66 char s_seqy[]     = " %s=y";
67 char s_x[]        = "x";
68 char s_y[]        = "y";
69 char s_z[]        = "z";
70 
71 /* JIIM */
72 
73 FILE *parmfile;
74 
75 #define PAR_KEY(x)  ( x < 10 ? '0' + x : 'a' - 10 + x)
76 
77 #ifdef _MSC_VER
78 #pragma optimize("e",off)  /* MSC 6.00A messes up next rtn with "e" on */
79 #endif
80 
81 #define LOADBATCHPROMPTS(X)     {\
82    static FCODE tmp[] = { X };\
83    far_strcpy(ptr,tmp);\
84    choices[promptnum]= ptr;\
85    ptr += sizeof(tmp);\
86    }
87 
make_batch_file()88 void make_batch_file()
89 {
90 #define MAXPROMPTS 18
91    int colorsonly = 0;
92    static char far hdg[]={"Save Current Parameters"};
93    /** added for pieces feature **/
94    double pdelx = 0.0;
95    double pdely = 0.0;
96    double pdelx2 = 0.0;
97    double pdely2 = 0.0;
98    unsigned int pxdots, pydots, xm, ym;
99    double pxxmin = 0.0, pyymax = 0.0;
100    char vidmde[5];
101    int promptnum;
102    int piecespromts;
103    int have3rd = 0;
104    /****/
105 
106    int i,j;
107    char far *inpcommandfile, far *inpcommandname;
108    char far *inpcomment[4];
109    struct fullscreenvalues paramvalues[18];
110    char far * choices[MAXPROMPTS];
111    char far *ptr;
112    int gotinfile;
113    char outname[FILE_MAX_PATH+1], buf[256], buf2[128];
114    FILE *infile = NULL;
115    FILE *fpbat = NULL;
116    char colorspec[MAX_NAME+1];
117    int maxcolor;
118    int maxcolorindex = 0;
119    char *sptr = NULL, *sptr2;
120    int oldhelpmode;
121 
122    if(s_makepar[1] == 0) /* makepar map case */
123       colorsonly = 1;
124 
125    /* put comment storage in extraseg */
126    inpcommandfile = MK_FP(extraseg,0);
127    inpcommandname = inpcommandfile+80;
128    inpcomment[0]    = inpcommandname+(ITEMNAMELEN + 1);
129    inpcomment[1]    = inpcomment[0] + MAXCMT;
130    inpcomment[2]    = inpcomment[1] + MAXCMT;
131    inpcomment[3]    = inpcomment[2] + MAXCMT;
132 
133    /* steal existing array for "choices" */
134    ptr = (char far *)(inpcomment[3] + MAXCMT);
135    stackscreen();
136    oldhelpmode = helpmode;
137    helpmode = HELPPARMFILE;
138 
139    maxcolor = colors;
140    strcpy(colorspec,"y");
141 #ifndef XFRACT
142    if ((gotrealdac && !reallyega) || (istruecolor && !truemode))
143 #else
144    if ((gotrealdac && !reallyega) || (istruecolor && !truemode) || fake_lut)
145 #endif
146    {
147       --maxcolor;
148 /*    if (maxit < maxcolor)  remove 2 lines */
149 /*       maxcolor = maxit;   so that whole palette is always saved */
150       if (inside > 0 && inside > maxcolor)
151          maxcolor = inside;
152       if (outside > 0 && outside > maxcolor)
153          maxcolor = outside;
154       if (distest < 0 && 0 - distest > maxcolor)
155          maxcolor = (int)(0 - distest);
156       if (decomp[0] > maxcolor)
157          maxcolor = decomp[0] - 1;
158       if (potflag && potparam[0] >= maxcolor)
159          maxcolor = (int)potparam[0];
160       if (++maxcolor > 256)
161          maxcolor = 256;
162       if (colorstate == 0)
163       {                         /* default colors */
164          if (mapdacbox)
165          {
166             colorspec[0] = '@';
167             sptr = MAP_name;
168          }
169       }
170       else if (colorstate == 2 || (colorstate == 3 && recordcolors == 'c'))
171       {  /* colors match colorfile or only rotated and we want map name */
172          colorspec[0] = '@';
173          sptr = colorfile;
174       }
175       else                      /* colors match no .map that we know of */
176          strcpy (colorspec,"y");
177 
178       if (colorspec[0] == '@')
179       {
180          if ((sptr2 = strrchr(sptr, SLASHC)) != NULL)
181             sptr = sptr2 + 1;
182          if ((sptr2 = strrchr(sptr, ':')) != NULL)
183             sptr = sptr2 + 1;
184          strncpy(&colorspec[1], sptr, MAX_NAME-1);
185          colorspec[MAX_NAME] = 0;
186       }
187    }
188    far_strcpy(inpcommandfile, CommandFile);
189    far_strcpy(inpcommandname, CommandName);
190    for(i=0;i<4;i++)
191    {
192       expand_comments(CommandComment[i], par_comment[i]);
193       far_strcpy(inpcomment[i], CommandComment[i]);
194    }
195 
196    if (CommandName[0] == 0)
197       far_strcpy(inpcommandname, "test");
198    /* TW added these  - and Bert moved them */
199    pxdots = xdots;
200    pydots = ydots;
201    xm = ym = 1;
202    if(*s_makepar == 0)
203       goto skip_UI;
204 
205    vidmode_keyname(videoentry.keynum, vidmde);
206    for(;;)
207    {
208 prompt_user:
209       promptnum = 0;
210       LOADBATCHPROMPTS("Parameter file");
211       paramvalues[promptnum].type = 0x100 + MAXCMT - 1;
212       paramvalues[promptnum++].uval.sbuf = inpcommandfile;
213       LOADBATCHPROMPTS("Name");
214       paramvalues[promptnum].type = 0x100 + ITEMNAMELEN;
215       paramvalues[promptnum++].uval.sbuf = inpcommandname;
216       LOADBATCHPROMPTS("Main comment");
217       paramvalues[promptnum].type = 0x100 + MAXCMT - 1;
218       paramvalues[promptnum++].uval.sbuf = inpcomment[0];
219       LOADBATCHPROMPTS("Second comment");
220       paramvalues[promptnum].type = 0x100 + MAXCMT - 1;
221       paramvalues[promptnum++].uval.sbuf = inpcomment[1];
222       LOADBATCHPROMPTS("Third comment");
223       paramvalues[promptnum].type = 0x100 + MAXCMT - 1;
224       paramvalues[promptnum++].uval.sbuf = inpcomment[2];
225       LOADBATCHPROMPTS("Fourth comment");
226       paramvalues[promptnum].type = 0x100 + MAXCMT - 1;
227       paramvalues[promptnum++].uval.sbuf = inpcomment[3];
228 #ifndef XFRACT
229       if ((gotrealdac && !reallyega) || (istruecolor && !truemode))
230 #else
231       if ((gotrealdac && !reallyega) || (istruecolor && !truemode) || fake_lut)
232 #endif
233       {
234          LOADBATCHPROMPTS("Record colors?");
235          paramvalues[promptnum].type = 0x100 + 13;
236          paramvalues[promptnum++].uval.sbuf = colorspec;
237          LOADBATCHPROMPTS("    (no | yes | only for full info | @filename to point to a map file)");
238          paramvalues[promptnum++].type = '*';
239          LOADBATCHPROMPTS("# of colors");
240          maxcolorindex = promptnum;
241          paramvalues[promptnum].type = 'i';
242          paramvalues[promptnum++].uval.ival = maxcolor;
243          LOADBATCHPROMPTS("    (if recording full color info)");
244          paramvalues[promptnum++].type = '*';
245       }
246       LOADBATCHPROMPTS("Maximum line length");
247       paramvalues[promptnum].type = 'i';
248       paramvalues[promptnum++].uval.ival = maxlinelength;
249       LOADBATCHPROMPTS("");
250       paramvalues[promptnum++].type = '*';
251       LOADBATCHPROMPTS("    **** The following is for generating images in pieces ****");
252       paramvalues[promptnum++].type = '*';
253       LOADBATCHPROMPTS("X Multiples");
254       piecespromts = promptnum;
255       paramvalues[promptnum].type = 'i';
256       paramvalues[promptnum++].uval.ival = xm;
257       LOADBATCHPROMPTS("Y Multiples");
258       paramvalues[promptnum].type = 'i';
259       paramvalues[promptnum++].uval.ival = ym;
260 #ifndef XFRACT
261       LOADBATCHPROMPTS("Video mode");
262       paramvalues[promptnum].type = 0x100 + 4;
263       paramvalues[promptnum++].uval.sbuf = vidmde;
264 #endif
265 
266       if (fullscreen_prompt(hdg,promptnum, choices, paramvalues, 0, NULL) < 0)
267          break;
268 
269       if(*colorspec == 'o' || s_makepar[1] == 0)
270       {
271          strcpy(colorspec,"y");
272          colorsonly = 1;
273       }
274 
275       far_strcpy(CommandFile, inpcommandfile);
276       if (has_ext(CommandFile) == NULL)
277          strcat(CommandFile, ".par");   /* default extension .par */
278       far_strcpy(CommandName, inpcommandname);
279       for(i=0;i<4;i++)
280          far_strncpy(CommandComment[i], inpcomment[i], MAXCMT);
281 #ifndef XFRACT
282       if ((gotrealdac && !reallyega) || (istruecolor && !truemode))
283 #else
284       if ((gotrealdac && !reallyega) || (istruecolor && !truemode) || fake_lut)
285 #endif
286          if (paramvalues[maxcolorindex].uval.ival > 0 &&
287              paramvalues[maxcolorindex].uval.ival <= 256)
288             maxcolor = paramvalues[maxcolorindex].uval.ival;
289       promptnum = piecespromts;
290       {
291          int newmaxlinelength;
292          newmaxlinelength = paramvalues[promptnum-3].uval.ival;
293          if(maxlinelength != newmaxlinelength &&
294               newmaxlinelength >= MINMAXLINELENGTH &&
295               newmaxlinelength <= MAXMAXLINELENGTH)
296             maxlinelength = newmaxlinelength;
297       }
298       xm = paramvalues[promptnum++].uval.ival;
299 
300       ym = paramvalues[promptnum++].uval.ival;
301 
302       /* sanity checks */
303       {
304       long xtotal, ytotal;
305 #ifndef XFRACT
306       int i;
307 
308       /* get resolution from the video name (which must be valid) */
309       pxdots = pydots = 0;
310       if ((i = check_vidmode_keyname(vidmde)) > 0)
311           if ((i = check_vidmode_key(0, i)) >= 0) {
312               /* get the resolution of this video mode */
313               pxdots = videotable[i].xdots;
314               pydots = videotable[i].ydots;
315               }
316       if (pxdots == 0 && (xm > 1 || ym > 1)) {
317           /* no corresponding video mode! */
318           static FCODE msg[] = {"Invalid video mode entry!"};
319           stopmsg(0,msg);
320           goto prompt_user;
321           }
322 #endif
323 
324       /* bounds range on xm, ym */
325       if (xm < 1 || xm > 36 || ym < 1 || ym > 36) {
326           static FCODE msg[] = {"X and Y components must be 1 to 36"};
327           stopmsg(0,msg);
328           goto prompt_user;
329           }
330 
331       /* another sanity check: total resolution cannot exceed 65535 */
332       xtotal = xm;  ytotal = ym;
333       xtotal *= pxdots;  ytotal *= pydots;
334       if (xtotal > 65535L || ytotal > 65535L) {
335       static FCODE msg[] = {"Total resolution (X or Y) cannot exceed 65535"};
336           stopmsg(0,msg);
337           goto prompt_user;
338           }
339       }
340 skip_UI:
341       if(*s_makepar == 0)
342       {
343          if(filecolors > 0)
344             strcpy(colorspec, "y");
345          else
346             strcpy(colorspec, "n");
347          if(s_makepar[1] == 0)
348             maxcolor = 256;
349          else
350             maxcolor = filecolors;
351       }
352       strcpy(outname, CommandFile);
353       gotinfile = 0;
354       if (access(CommandFile, 0) == 0)
355       {                         /* file exists */
356          gotinfile = 1;
357          if (access(CommandFile, 6))
358          {
359             sprintf(buf, s_cantwrite, CommandFile);
360             stopmsg(0, buf);
361             continue;
362          }
363          i = strlen(outname);
364          while (--i >= 0 && outname[i] != SLASHC)
365             outname[i] = 0;
366          strcat(outname, "fractint.tmp");
367          infile = fopen(CommandFile, "rt");
368 #ifndef XFRACT
369          setvbuf(infile, tstack, _IOFBF, 4096); /* improves speed */
370 #endif
371       }
372       if ((parmfile = fopen(outname, "wt")) == NULL)
373       {
374          sprintf(buf, s_cantcreate, outname);
375          stopmsg(0, buf);
376          if (gotinfile)
377             fclose(infile);
378          continue;
379       }
380 
381       if (gotinfile)
382       {
383          while (file_gets(buf, 255, infile) >= 0)
384          {
385             if (strchr(buf, '{')/* entry heading? */
386                 && sscanf(buf, " %40[^ \t({]", buf2)
387                 && stricmp(buf2, CommandName) == 0)
388             {                   /* entry with same name */
389                static FCODE s1[] = {"File already has an entry named "};
390                static FCODE s2[] = {"\n\
391 Continue to replace it, Cancel to back out"};
392                static FCODE s2a[] = {"... Replacing ..."};
393                far_strcpy(buf2,s1);
394                far_strcat(buf2,CommandName);
395                if(*s_makepar == 0)
396                    far_strcat(buf2,s2a);
397                else
398                    far_strcat(buf2,s2);
399                if (stopmsg(18, buf2) < 0)
400                {                /* cancel */
401                   fclose(infile);
402                   fclose(parmfile);
403                   unlink(outname);
404                   goto prompt_user;
405                }
406                while (strchr(buf, '}') == NULL
407                       && file_gets(buf, 255, infile) > 0)
408                   ; /* skip to end of set */
409                break;
410             }
411             fputs(buf, parmfile);
412             fputc('\n', parmfile);
413          }
414       }
415 /***** start here*/
416       if (xm > 1 || ym > 1)
417       {
418          if (xxmin != xx3rd || yymin != yy3rd)
419             have3rd = 1;
420          else
421             have3rd = 0;
422          if ((fpbat = dir_fopen(workdir,"makemig.bat", "w")) == NULL)
423             xm = ym = 0;
424          pdelx  = (xxmax - xx3rd) / (xm * pxdots - 1);   /* calculate stepsizes */
425          pdely  = (yymax - yy3rd) / (ym * pydots - 1);
426          pdelx2 = (xx3rd - xxmin) / (ym * pydots - 1);
427          pdely2 = (yy3rd - yymin) / (xm * pxdots - 1);
428 
429          /* save corners */
430          pxxmin = xxmin;
431          pyymax = yymax;
432       }
433       for (i = 0; i < (int)xm; i++)  /* columns */
434       for (j = 0; j < (int)ym; j++)  /* rows    */
435       {
436          if (xm > 1 || ym > 1)
437          {
438             int w;
439             char c;
440             char PCommandName[80];
441             w=0;
442             while(w < (int)strlen(CommandName))
443             {
444                c = CommandName[w];
445                if(isspace(c) || c == 0)
446                   break;
447                PCommandName[w] = c;
448                w++;
449             }
450             PCommandName[w] = 0;
451             {
452                char buf[20];
453                sprintf(buf,"_%c%c",PAR_KEY(i),PAR_KEY(j));
454                strcat(PCommandName,buf);
455             }
456             fprintf(parmfile, "%-19s{",PCommandName);
457             xxmin = pxxmin + pdelx*(i*pxdots) + pdelx2*(j*pydots);
458             xxmax = pxxmin + pdelx*((i+1)*pxdots - 1) + pdelx2*((j+1)*pydots - 1);
459             yymin = pyymax - pdely*((j+1)*pydots - 1) - pdely2*((i+1)*pxdots - 1);
460             yymax = pyymax - pdely*(j*pydots) - pdely2*(i*pxdots);
461             if (have3rd)
462             {
463                xx3rd = pxxmin + pdelx*(i*pxdots) + pdelx2*((j+1)*pydots - 1);
464                yy3rd = pyymax - pdely*((j+1)*pydots - 1) - pdely2*(i*pxdots);
465             }
466             else
467             {
468                xx3rd = xxmin;
469                yy3rd = yymin;
470             }
471             fprintf(fpbat,"Fractint batch=yes overwrite=yes @%s/%s\n",CommandFile,PCommandName);
472             fprintf(fpbat,"If Errorlevel 2 goto oops\n");
473          }
474          else
475             fprintf(parmfile, "%-19s{", CommandName);
476          {
477             /* guarantee that there are no blank comments above the last
478                non-blank par_comment */
479             int i, last;
480             for(last=-1,i=0;i<4;i++)
481                if(*par_comment[i])
482                   last=i;
483             for(i=0;i<last;i++)
484                if(*CommandComment[i]=='\0')
485                   far_strcpy(CommandComment[i],";");
486          }
487          if (CommandComment[0][0])
488             fprintf(parmfile, " ; %s", CommandComment[0]);
489          fputc('\n', parmfile);
490          {
491             int k;
492             char buf[25];
493             memset(buf, ' ', 23);
494             buf[23] = 0;
495             buf[21] = ';';
496             for(k=1;k<4;k++)
497                if (CommandComment[k][0])
498                   fprintf(parmfile, "%s%s\n", buf, CommandComment[k]);
499             if (debugflag != 0 && colorsonly == 0)
500                fprintf(parmfile, "%s %s Version %d Patchlevel %d\n", buf,
501                   Fractint, release, patchlevel);
502          }
503          write_batch_parms(colorspec, colorsonly, maxcolor, i, j);
504          if(xm > 1 || ym > 1)
505          {
506             fprintf(parmfile,"  video=%s", vidmde);
507             fprintf(parmfile," savename=frmig_%c%c\n", PAR_KEY(i), PAR_KEY(j));
508          }
509          fprintf(parmfile, "  }\n\n");
510       }
511       if(xm > 1 || ym > 1)
512          {
513          fprintf(fpbat,"Fractint makemig=%d/%d\n",xm,ym);
514          fprintf(fpbat,"Rem Simplgif fractmig.gif simplgif.gif  in case you need it\n");
515          fprintf(fpbat,":oops\n");
516          fclose(fpbat);
517          }
518 /*******end here */
519 
520       if (gotinfile)
521       {                         /* copy the rest of the file */
522          while ((i = file_gets(buf, 255, infile)) == 0)
523             ; /* skip blanks */
524          while (i >= 0)
525          {
526             fputs(buf, parmfile);
527             fputc('\n', parmfile);
528             i = file_gets(buf, 255, infile);
529          }
530          fclose(infile);
531       }
532       fclose(parmfile);
533       if (gotinfile)
534       {                         /* replace the original file with the new */
535          unlink(CommandFile);   /* success assumed on these lines       */
536          rename(outname, CommandFile);  /* since we checked earlier with
537                                          * access */
538       }
539       break;
540    }
541    helpmode = oldhelpmode;
542    unstackscreen();
543 }
544 
545 #ifdef C6
546 #pragma optimize("e",on)  /* back to normal */
547 #endif
548 
549 static struct write_batch_data { /* buffer for parms to break lines nicely */
550    int len;
551    char *buf;
552    } *wbdata;
553 
write_batch_parms(char * colorinf,int colorsonly,int maxcolor,int ii,int jj)554 void write_batch_parms(char *colorinf, int colorsonly, int maxcolor, int ii, int jj)
555 {
556    char far *saveshared;
557    int i,j,k;
558    double Xctr, Yctr;
559    LDBL Magnification;
560    double Xmagfactor, Rotation, Skew;
561    struct write_batch_data wb_data;
562    char *sptr;
563    char buf[81];
564    bf_t bfXctr=NULL, bfYctr=NULL;
565    int saved;
566    saved = save_stack();
567    if(bf_math)
568    {
569       bfXctr = alloc_stack(bflength+2);
570       bfYctr = alloc_stack(bflength+2);
571    }
572    wbdata = &wb_data;
573    wb_data.len = 0; /* force first parm to start on new line */
574 
575    /* Using near string boxx for buffer after saving to extraseg */
576 
577    saveshared = MK_FP(extraseg,0);
578    far_memcpy(saveshared,boxx,10000);
579    far_memset(boxx,0,10000);
580    wb_data.buf = (char *)boxx;
581    if(colorsonly)
582       goto docolors;
583    if (display3d <= 0) { /* a fractal was generated */
584 
585       /****** fractal only parameters in this section *******/
586       put_parm(" reset");
587       if (check_back())
588         put_parm("=%d",min(save_release,release));
589       else
590         put_parm("=%d",release);
591 
592       if (*(sptr = curfractalspecific->name) == '*') ++sptr;
593       put_parm( s_seqs,s_type,sptr);
594 
595       if (fractype == JULIBROT || fractype == JULIBROTFP)
596       {
597          put_parm(" %s=%.15g/%.15g/%.15g/%.15g",
598              s_julibrotfromto,mxmaxfp,mxminfp,mymaxfp,myminfp);
599          /* these rarely change */
600          if(originfp != 8 || heightfp != 7 || widthfp != 10 || distfp != 24
601                           || depthfp != 8 || zdots != 128)
602             put_parm(" %s=%d/%g/%g/%g/%g/%g",s_julibrot3d,
603                 zdots, originfp, depthfp, heightfp, widthfp,distfp);
604          if(eyesfp != 0)
605             put_parm(" %s=%g",s_julibroteyes,eyesfp);
606          if(neworbittype != JULIA)
607          {
608             char *name;
609             name = fractalspecific[neworbittype].name;
610             if(*name=='*')
611                name++;
612             put_parm(s_seqs,s_orbitname,name);
613          }
614          if(juli3Dmode != 0)
615             put_parm(s_seqs,s_3dmode,juli3Doptions[juli3Dmode]);
616       }
617       if (fractype == FORMULA || fractype == FFORMULA)
618       {
619          put_filename(s_formulafile,FormFileName);
620          put_parm( s_seqs,s_formulaname,FormName);
621          if (uses_ismand)
622             put_parm(" %s=%c",s_ismand,ismand?'y':'n');
623       }
624       if (fractype == LSYSTEM)
625       {
626          put_filename(s_lfile,LFileName);
627          put_parm( s_seqs,s_lname,LName);
628       }
629       if (fractype == IFS || fractype == IFS3D)
630       {
631          put_filename(s_ifsfile,IFSFileName);
632          put_parm( s_seqs,s_ifs,IFSName);
633       }
634       if (fractype == INVERSEJULIA || fractype == INVERSEJULIAFP)
635          put_parm( " %s=%s/%s",s_miim,JIIMmethod[major_method], JIIMleftright[minor_method]);
636 
637       showtrig(buf); /* this function is in miscres.c */
638       if (buf[0])
639          put_parm(buf);
640 
641       if (usr_stdcalcmode != 'g')
642          put_parm(" %s=%c",s_passes,usr_stdcalcmode);
643 
644 
645       if (stoppass != 0)
646          put_parm(" %s=%c%c",s_passes,usr_stdcalcmode,(char)stoppass + '0');
647 
648       if (usemag)
649       {
650          if (bf_math)
651          {
652             int digits;
653             cvtcentermagbf(bfXctr, bfYctr, &Magnification, &Xmagfactor, &Rotation, &Skew);
654             digits = getprecbf(MAXREZ);
655             put_parm(" %s=",s_centermag);
656             put_bf(0,bfXctr,digits);
657             put_bf(1,bfYctr,digits);
658          }
659          else /* !bf_math */
660          {
661             cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew);
662             put_parm(" %s=",s_centermag);
663 /*          convert 1000 fudged long to double, 1000/1<<24 = 6e-5 */
664             put_parm(ddelmin > 6e-5 ? "%g/%g" : "%+20.17lf/%+20.17lf", Xctr, Yctr);
665          }
666 #ifdef USE_LONG_DOUBLE
667          put_parm("/%.7Lg",Magnification); /* precision of magnification not critical, but magnitude is */
668 #else
669          put_parm("/%.7lg",Magnification); /* precision of magnification not critical, but magnitude is */
670 #endif
671          /* Round to avoid ugly decimals, precision here is not critical */
672          /* Don't round Xmagfactor if it's small */
673          if (fabs(Xmagfactor) > 0.5) /* or so, exact value isn't important */
674             Xmagfactor = (sign(Xmagfactor) * (long)(fabs(Xmagfactor) * 1e4 + 0.5)) / 1e4;
675          /* Just truncate these angles.  Who cares about 1/1000 of a degree */
676          /* Somebody does.  Some rotated and/or skewed images are slightly */
677          /* off when recreated from a PAR using 1/1000. */
678          /* JCO 08052001 */
679 #if 0
680          Rotation   = (long)(Rotation   * 1e3)/1e3;
681          Skew       = (long)(Skew       * 1e3)/1e3;
682 #endif
683          if (Xmagfactor != 1 || Rotation != 0 || Skew != 0)
684          { /* Only put what is necessary */
685             /* The difference with Xmagfactor is that it is normally */
686             /* near 1 while the others are normally near 0 */
687             if (fabs(Xmagfactor) >= 1)
688                put_float(1,Xmagfactor,5); /* put_float() uses %g */
689             else /* abs(Xmagfactor) is < 1 */
690                put_float(1,Xmagfactor,4); /* put_float() uses %g */
691             if (Rotation != 0 || Skew != 0)
692             {
693                /* Use precision=6 here.  These angle have already been rounded        */
694                /* to 3 decimal places, but angles like 123.456 degrees need 6         */
695                /* sig figs to get 3 decimal places.  Trailing 0's are dropped anyway. */
696                /* Changed to 18 to address rotated and skewed problem w/ PARs */
697                /* JCO 08052001 */
698                put_float(1,Rotation,18);
699                if (Skew != 0)
700                {
701                   put_float(1,Skew,18);
702                }
703             }
704          }
705       }
706       else /* not usemag */
707       {
708          put_parm( " %s=",s_corners);
709          if(bf_math)
710          {
711             int digits;
712             digits = getprecbf(MAXREZ);
713             put_bf(0,bfxmin,digits);
714             put_bf(1,bfxmax,digits);
715             put_bf(1,bfymin,digits);
716             put_bf(1,bfymax,digits);
717             if (cmp_bf(bfx3rd,bfxmin) || cmp_bf(bfy3rd,bfymin))
718             {
719                put_bf(1,bfx3rd,digits);
720                put_bf(1,bfy3rd,digits);
721             }
722          }
723          else
724          {
725             int xdigits,ydigits;
726             xdigits = getprec(xxmin,xxmax,xx3rd);
727             ydigits = getprec(yymin,yymax,yy3rd);
728             put_float(0,xxmin,xdigits);
729             put_float(1,xxmax,xdigits);
730             put_float(1,yymin,ydigits);
731             put_float(1,yymax,ydigits);
732             if (xx3rd != xxmin || yy3rd != yymin)
733             {
734                put_float(1,xx3rd,xdigits);
735                put_float(1,yy3rd,ydigits);
736             }
737          }
738       }
739 
740       for(i = (MAXPARAMS-1); i >= 0; --i)
741           if(typehasparm((fractype==JULIBROT || fractype==JULIBROTFP)
742                           ?neworbittype:fractype,i,NULL)) break;
743 
744       if (i >= 0) {
745         if (fractype == CELLULAR || fractype == ANT)
746           put_parm(" %s=%.1f",s_params,param[0]);
747         else
748         {
749 #ifdef USE_LONG_DOUBLE
750           if(debugflag == 750)
751              put_parm(" %s=%.17Lg",s_params,(long double)param[0]);
752           else
753 #endif
754           put_parm(" %s=%.17g",s_params,param[0]);
755         }
756         for (j = 1; j <= i; ++j)
757         if (fractype == CELLULAR || fractype == ANT)
758           put_parm("/%.1f",param[j]);
759         else
760         {
761 #ifdef USE_LONG_DOUBLE
762           if(debugflag == 750)
763              put_parm("/%.17Lg",(long double)param[j]);
764           else
765 #endif
766           put_parm("/%.17g",param[j]);
767         }
768       }
769 
770       if(useinitorbit == 2)
771          put_parm( " %s=pixel",s_initorbit);
772       else if(useinitorbit == 1)
773          put_parm( " %s=%.15g/%.15g",s_initorbit,initorbit.x,initorbit.y);
774 
775       if (floatflag)
776          put_parm( s_seqy,s_float);
777 
778       if (maxit != 150)
779          put_parm(" %s=%ld",s_maxiter,maxit);
780 
781       if(bailout && (potflag == 0 || potparam[2] == 0.0))
782          put_parm(" %s=%ld",s_bailout,bailout);
783 
784       if(bailoutest != Mod) {
785          put_parm(" %s=",s_bailoutest);
786          if (bailoutest == Real)
787             put_parm( s_real);
788          else if (bailoutest == Imag)
789             put_parm(s_imag);
790          else if (bailoutest == Or)
791             put_parm(s_or);
792          else if (bailoutest == And)
793             put_parm(s_and);
794          else if (bailoutest == Manh)
795             put_parm(s_manh);
796          else if (bailoutest == Manr)
797             put_parm(s_manr);
798          else
799             put_parm(s_mod); /* default, just in case */
800       }
801       if(fillcolor != -1) {
802          put_parm(" %s=",s_fillcolor);
803         put_parm( "%d",fillcolor);
804       }
805       if (inside != 1) {
806          put_parm(" %s=",s_inside);
807          if (inside == -1)
808             put_parm( s_maxiter);
809          else if (inside == ZMAG)
810             put_parm(s_zmag);
811          else if (inside == BOF60)
812             put_parm(s_bof60);
813          else if (inside == BOF61)
814             put_parm(s_bof61);
815          else if (inside == EPSCROSS)
816             put_parm(s_epscross);
817          else if (inside == STARTRAIL)
818             put_parm(s_startrail);
819          else if (inside == PERIOD)
820             put_parm(s_period);
821          else if (inside == FMODI)
822             put_parm(s_fmod);
823          else if (inside == ATANI)
824             put_parm(s_atan);
825          else
826             put_parm( "%d",inside);
827          }
828       if (closeprox != 0.01 && (inside == EPSCROSS || inside == FMODI
829           || outside==FMOD) ) {
830          put_parm(" %s=%.15g",s_prox,closeprox);
831          }
832       if (outside != -1)
833       {
834          put_parm(" %s=",s_outside);
835          if (outside == REAL)
836             put_parm(s_real);
837          else if (outside == IMAG)
838             put_parm(s_imag);
839          else if (outside == MULT)
840             put_parm(s_mult);
841          else if (outside == SUM)
842             put_parm(s_sum);
843          else if (outside == ATAN)
844             put_parm(s_atan);
845          else if (outside == FMOD)
846             put_parm(s_fmod);
847          else if (outside == TDIS)
848             put_parm(s_tdis);
849          else
850             put_parm( "%d",outside);
851           }
852 
853       if(LogFlag && !rangeslen) {
854          put_parm( " %s=",s_logmap);
855          if(LogFlag == -1)
856             put_parm( "old");
857          else if(LogFlag == 1)
858             put_parm( s_yes);
859          else
860             put_parm( "%ld", LogFlag);
861          }
862 
863       if(Log_Fly_Calc && LogFlag && !rangeslen) {
864          put_parm( " %s=",s_logmode);
865          if(Log_Fly_Calc == 1)
866             put_parm( "fly");
867          else if(Log_Fly_Calc == 2)
868             put_parm( "table");
869          }
870 
871       if (potflag) {
872        put_parm( " %s=%d/%g/%d",s_potential,
873            (int)potparam[0],potparam[1],(int)potparam[2]);
874        if(pot16bit)
875             put_parm( "/%s",s_16bit);
876          }
877       if (invert)
878          put_parm( " %s=%-1.15lg/%-1.15lg/%-1.15lg",s_invert,
879              inversion[0], inversion[1], inversion[2]);
880       if (decomp[0])
881          put_parm( s_seqd,s_decomp, decomp[0]);
882       if (distest) {
883          put_parm( s_seqldddd,s_distest, distest, distestwidth,
884                      pseudox?pseudox:xdots,pseudoy?pseudoy:ydots);
885       }
886       if (old_demm_colors)
887          put_parm( s_seqy,s_olddemmcolors);
888       if (usr_biomorph != -1)
889          put_parm( s_seqd,s_biomorph, usr_biomorph);
890       if (finattract)
891          put_parm(s_seqy,s_finattract);
892 
893       if (forcesymmetry != 999) {
894          static FCODE msg[] =
895             {"Regenerate before <b> to get correct symmetry"};
896          if(forcesymmetry == 1000 && ii == 1 && jj == 1)
897             stopmsg(0,msg);
898          put_parm( " %s=",s_symmetry);
899          if (forcesymmetry==XAXIS)
900             put_parm(s_xaxis);
901          else if(forcesymmetry==YAXIS)
902             put_parm(s_yaxis);
903          else if(forcesymmetry==XYAXIS)
904             put_parm(s_xyaxis);
905          else if(forcesymmetry==ORIGIN)
906             put_parm(s_origin);
907          else if(forcesymmetry==PI_SYM)
908             put_parm(s_pi);
909          else
910             put_parm(s_none);
911          }
912 
913       if (periodicitycheck != 1)
914          put_parm( s_seqd,s_periodicity,periodicitycheck);
915 
916       if (rflag)
917          put_parm( s_seqd,s_rseed,rseed);
918 
919       if (rangeslen) {
920          put_parm(" %s=",s_ranges);
921          i = 0;
922          while (i < rangeslen) {
923             if (i)
924                put_parm("/");
925             if (ranges[i] == -1) {
926                put_parm("-%d/",ranges[++i]);
927                ++i;
928                }
929             put_parm("%d",ranges[i++]);
930             }
931          }
932       }
933 
934    if (display3d >= 1) {
935       /***** 3d transform only parameters in this section *****/
936       if(display3d == 2)
937          put_parm( s_seqs,s_3d,s_overlay);
938       else
939       put_parm( s_seqs,s_3d,s_yes);
940       if (loaded3d == 0)
941          put_filename(s_filename,readname);
942       if (SPHERE) {
943          put_parm( s_seqy,s_sphere);
944          put_parm( s_seqdd,s_latitude, THETA1, THETA2);
945          put_parm( s_seqdd,s_longitude, PHI1, PHI2);
946          put_parm( s_seqd,s_radius, RADIUS);
947          }
948       put_parm( s_seqdd,s_scalexyz, XSCALE, YSCALE);
949       put_parm( s_seqd,s_roughness, ROUGH);
950       put_parm( s_seqd,s_waterline, WATERLINE);
951       if (FILLTYPE)
952          put_parm( s_seqd,s_filltype, FILLTYPE);
953       if (transparent[0] || transparent[1])
954          put_parm( s_seqdd,s_transparent, transparent[0],transparent[1]);
955       if (preview) {
956          put_parm( s_seqs,s_preview,s_yes);
957          if (showbox)
958             put_parm( s_seqs,s_showbox,s_yes);
959          put_parm( s_seqd,s_coarse,previewfactor);
960          }
961       if (RAY) {
962          put_parm( s_seqd,s_ray,RAY);
963          if (BRIEF)
964             put_parm(s_seqy,s_brief);
965          }
966       if (FILLTYPE > 4) {
967          put_parm( s_seqddd,s_lightsource, XLIGHT, YLIGHT, ZLIGHT);
968          if (LIGHTAVG)
969             put_parm(s_seqd,s_smoothing, LIGHTAVG);
970          }
971       if (RANDOMIZE)
972          put_parm( s_seqd,s_randomize,RANDOMIZE);
973       if (Targa_Out)
974          put_parm( s_seqy,s_fullcolor);
975       if (grayflag)
976          put_parm( s_seqy,s_usegrayscale);
977       if (Ambient)
978          put_parm( s_seqd,s_ambient,Ambient);
979       if (haze)
980          put_parm( s_seqd,s_haze,haze);
981       if (back_color[0] != 51 || back_color[1] != 153 || back_color[2] != 200)
982          put_parm( s_seqddd,s_background,back_color[0],back_color[1],
983                    back_color[2]);
984       }
985 
986    if (display3d) {             /* universal 3d */
987       /***** common (fractal & transform) 3d parameters in this section *****/
988       if (!SPHERE || display3d < 0)
989          put_parm( s_seqddd,s_rotation, XROT, YROT, ZROT);
990       put_parm( s_seqd,s_perspective, ZVIEWER);
991       put_parm( s_seqdd,s_xyshift, XSHIFT, YSHIFT);
992       if(xtrans || ytrans)
993          put_parm( s_seqdd,s_xyadjust,xtrans,ytrans);
994       if(glassestype) {
995          put_parm( s_seqd,s_stereo,glassestype);
996          put_parm( s_seqd,s_interocular,eyeseparation);
997          put_parm( s_seqd,s_converge,xadjust);
998          put_parm( " %s=%d/%d/%d/%d",s_crop,
999              red_crop_left,red_crop_right,blue_crop_left,blue_crop_right);
1000          put_parm( s_seqdd,s_bright,
1001              red_bright,blue_bright);
1002          }
1003       }
1004 
1005    /***** universal parameters in this section *****/
1006 
1007    if(viewwindow == 1)
1008    {
1009       put_parm(" %s=%g/%g",s_viewwindows,viewreduction,finalaspectratio);
1010       if(viewcrop)
1011          put_parm("/%s",s_yes);
1012       else
1013          put_parm("/%s",s_no);
1014       put_parm("/%d/%d",viewxdots,viewydots);
1015    }
1016 
1017    if(colorsonly == 0)
1018    {
1019    if (rotate_lo != 1 || rotate_hi != 255)
1020       put_parm( s_seqdd,s_cyclerange,rotate_lo,rotate_hi);
1021 
1022    if(basehertz != 440)
1023       put_parm(s_seqd,s_hertz,basehertz);
1024 
1025 #ifndef XFRACT
1026    if(fm_vol != 63)
1027      put_parm(s_seqd,s_volume,fm_vol);
1028 
1029    if(hi_atten != 0) {
1030      if(hi_atten == 1)
1031         put_parm(s_seqs,s_atten,s_low);
1032      else if(hi_atten == 2)
1033         put_parm(s_seqs,s_atten,s_mid);
1034      else if(hi_atten == 3)
1035         put_parm(s_seqs,s_atten,s_high);
1036      else   /* just in case */
1037         put_parm(s_seqs,s_atten,s_none);
1038    }
1039 
1040    if(polyphony != 0)
1041      put_parm(s_seqd,s_polyphony,polyphony+1);
1042 
1043    if(fm_wavetype !=0)
1044      put_parm(s_seqd,s_wavetype,fm_wavetype);
1045 
1046    if(fm_attack != 5)
1047       put_parm(s_seqd,s_attack,fm_attack);
1048 
1049    if(fm_decay != 10)
1050       put_parm(s_seqd,s_decay,fm_decay);
1051 
1052    if(fm_sustain != 13)
1053       put_parm(s_seqd,s_sustain,fm_sustain);
1054 
1055    if(fm_release != 5)
1056       put_parm(s_seqd,s_srelease,fm_release);
1057 
1058    if(soundflag&64) { /* quantize turned on */
1059       for(i=0;i<=11;i++) if(scale_map[i] != i+1) i=15;
1060       if(i>12){
1061          put_parm(" %s=",s_scalemap);
1062          for(i=0;i<=10;i++){
1063             if (scale_map[i] == -1)
1064                put_parm("%s/", s_pause);
1065             else
1066                put_parm("%d/", scale_map[i]);
1067          }
1068          if (scale_map[11] == -1)
1069             put_parm("%s", s_pause);
1070          else
1071             put_parm("%d", scale_map[11]);
1072       }
1073    }
1074 
1075   if(soundflag != 9) {
1076    if((soundflag&7) == 0)
1077       put_parm(s_seqs,s_sound,s_off);
1078    else if((soundflag&7) == 1)
1079       put_parm(s_seqs,s_sound,s_beep);
1080    else if((soundflag&7) == 2)
1081       put_parm(s_seqs,s_sound,s_x);
1082    else if((soundflag&7) == 3)
1083       put_parm(s_seqs,s_sound,s_y);
1084    else if((soundflag&7) == 4)
1085       put_parm(s_seqs,s_sound,s_z);
1086 #ifndef XFRACT
1087    if((soundflag&7) && (soundflag&7) <=4) {
1088       if(soundflag&8)
1089          put_parm("/pc");
1090       if(soundflag&16)
1091          put_parm("/fm");
1092       if(soundflag&32)
1093          put_parm("/midi");
1094       if(soundflag&64)
1095          put_parm("/quant");
1096    }
1097 #endif
1098   }
1099 
1100 #endif
1101 
1102    if(nobof > 0)
1103       put_parm(s_seqs,s_nobof,s_yes);
1104 
1105    if(orbit_delay > 0)
1106       put_parm(s_seqd,s_orbitdelay,orbit_delay);
1107 
1108    if(orbit_interval != 1)
1109       put_parm(s_seqd,s_orbitinterval,orbit_interval);
1110 
1111    if(start_showorbit > 0)
1112       put_parm(s_seqs,s_showorbit,s_yes);
1113 
1114    if (keep_scrn_coords)
1115       put_parm(s_seqs,s_screencoords,s_yes);
1116 
1117    if (usr_stdcalcmode == 'o' && set_orbit_corners && keep_scrn_coords)
1118       {
1119          int xdigits,ydigits;
1120          put_parm( " %s=",s_orbitcorners);
1121          xdigits = getprec(oxmin,oxmax,ox3rd);
1122          ydigits = getprec(oymin,oymax,oy3rd);
1123          put_float(0,oxmin,xdigits);
1124          put_float(1,oxmax,xdigits);
1125          put_float(1,oymin,ydigits);
1126          put_float(1,oymax,ydigits);
1127          if (ox3rd != oxmin || oy3rd != oymin)
1128          {
1129             put_float(1,ox3rd,xdigits);
1130             put_float(1,oy3rd,ydigits);
1131          }
1132       }
1133 
1134    if (drawmode != 'r')
1135       put_parm(" %s=%c",s_orbitdrawmode, drawmode);
1136 
1137    if (math_tol[0] != 0.05 || math_tol[1] != 0.05)
1138       put_parm(" %s=%g/%g",s_mathtolerance,math_tol[0],math_tol[1]);
1139 
1140    }
1141 
1142    if (*colorinf != 'n')
1143    {
1144       if(recordcolors=='c' && *colorinf == '@')
1145       {
1146          put_parm_line();
1147          put_parm(" %s=",s_colors);
1148          put_parm(colorinf);
1149          put_parm_line();
1150       }
1151 docolors:
1152       put_parm(" %s=",s_colors);
1153       if (recordcolors !='c' && recordcolors != 'y' && *colorinf == '@')
1154          put_parm(colorinf);
1155       else {
1156          int curc,scanc,force,diffmag = -1;
1157          int delta,diff1[4][3],diff2[4][3];
1158          curc = force = 0;
1159 #ifdef XFRACT
1160          if (fake_lut && !truemode) loaddac(); /* stupid kludge JCO 6/23/2001 */
1161 #endif
1162          for(;;) {
1163             /* emit color in rgb 3 char encoded form */
1164             for (j = 0; j < 3; ++j) {
1165                if ((k = dacbox[curc][j]) < 10) k += '0';
1166                else if (k < 36)                k += ('A' - 10);
1167                else                            k += ('_' - 36);
1168                buf[j] = (char)k;
1169                }
1170             buf[3] = 0;
1171             put_parm(buf);
1172             if (++curc >= maxcolor)      /* quit if done last color */
1173                break;
1174             if(debugflag == 920)  /* lossless compression */
1175                continue;
1176             /* Next a P Branderhorst special, a tricky scan for smooth-shaded
1177                ranges which can be written as <nn> to compress .par file entry.
1178                Method used is to check net change in each color value over
1179                spans of 2 to 5 color numbers.  First time for each span size
1180                the value change is noted.  After first time the change is
1181                checked against noted change.  First time it differs, a
1182                a difference of 1 is tolerated and noted as an alternate
1183                acceptable change.  When change is not one of the tolerated
1184                values, loop exits. */
1185             if (force) {
1186                --force;
1187                continue;
1188                }
1189             scanc = curc;
1190             while (scanc < maxcolor) {   /* scan while same diff to next */
1191                if ((i = scanc - curc) > 3) /* check spans up to 4 steps */
1192                   i = 3;
1193                for (k = 0; k <= i; ++k) {
1194                   for (j = 0; j < 3; ++j) { /* check pattern of chg per color */
1195                      /* Sylvie Gallet's fix */
1196                      if (debugflag != 910 && scanc > (curc+4) && scanc < maxcolor-5)
1197                         if (abs(2*dacbox[scanc][j] - dacbox[scanc-5][j]
1198                                 - dacbox[scanc+5][j]) >= 2)
1199                            break;
1200                      /* end Sylvie's fix */
1201                      delta = (int)dacbox[scanc][j] - (int)dacbox[scanc-k-1][j];
1202                      if (k == scanc - curc)
1203                         diff1[k][j] = diff2[k][j] = delta;
1204                      else
1205                         if (delta != diff1[k][j] && delta != diff2[k][j]) {
1206                            diffmag = abs(delta - diff1[k][j]);
1207                            if (diff1[k][j] != diff2[k][j] || diffmag != 1)
1208                               break;
1209                            diff2[k][j] = delta;
1210                            }
1211                      }
1212                   if (j < 3) break; /* must've exited from inner loop above */
1213                   }
1214                if (k <= i) break;   /* must've exited from inner loop above */
1215                ++scanc;
1216                }
1217             /* now scanc-1 is next color which must be written explicitly */
1218             if (scanc - curc > 2) { /* good, we have a shaded range */
1219                if (scanc != maxcolor) {
1220                   if (diffmag < 3) {  /* not a sharp slope change? */
1221                      force = 2;       /* force more between ranges, to stop  */
1222                      --scanc;         /* "drift" when load/store/load/store/ */
1223                      }
1224                   if (k) {            /* more of the same                    */
1225                      force += k;
1226                      --scanc;
1227                      }
1228                   }
1229                if (--scanc - curc > 1) {
1230                   put_parm("<%d>",scanc-curc);
1231                   curc = scanc;
1232                   }
1233                else                /* changed our mind */
1234                   force = 0;
1235                }
1236             }
1237          }
1238       }
1239 
1240    while (wbdata->len) /* flush the buffer */
1241       put_parm_line();
1242    /* restore previous boxx data from extraseg */
1243    far_memcpy(boxx, saveshared, 10000);
1244    restore_stack(saved);
1245 }
1246 
put_filename(char * keyword,char * fname)1247 static void put_filename(char *keyword,char *fname)
1248 {
1249    char *p;
1250    if (*fname && !endswithslash(fname)) {
1251       if ((p = strrchr(fname, SLASHC)) != NULL)
1252          if (*(fname = p+1) == 0) return;
1253       put_parm(s_seqs,keyword,fname);
1254       }
1255 }
1256 
1257 #ifndef USE_VARARGS
put_parm(char * parm,...)1258 static void put_parm(char *parm,...)
1259 #else
1260 static void put_parm(va_alist)
1261 va_dcl
1262 #endif
1263 {
1264    char *bufptr;
1265    va_list args;
1266 
1267 #ifndef USE_VARARGS
1268    va_start(args,parm);
1269 #else
1270    char * parm;
1271 
1272    va_start(args);
1273    parm = va_arg(args,char *);
1274 #endif
1275    if (*parm == ' '             /* starting a new parm */
1276      && wbdata->len == 0)       /* skip leading space */
1277       ++parm;
1278    bufptr = wbdata->buf + wbdata->len;
1279    vsprintf(bufptr,parm,args);
1280    while (*(bufptr++))
1281       ++wbdata->len;
1282    while (wbdata->len > 200)
1283       put_parm_line();
1284 }
1285 
1286 int maxlinelength=72;
1287 #define MAXLINELEN  maxlinelength
1288 #define NICELINELEN (MAXLINELEN-4)
1289 
put_parm_line()1290 static void put_parm_line()
1291 {
1292    int len,c;
1293    if ((len = wbdata->len) > NICELINELEN) {
1294       len = NICELINELEN+1;
1295       while (--len != 0 && wbdata->buf[len] != ' ') { }
1296       if (len == 0) {
1297          len = NICELINELEN-1;
1298          while (++len < MAXLINELEN
1299            && wbdata->buf[len] && wbdata->buf[len] != ' ') { }
1300          }
1301       }
1302    c = wbdata->buf[len];
1303    wbdata->buf[len] = 0;
1304    fputs("  ",parmfile);
1305    fputs(wbdata->buf,parmfile);
1306    if (c && c != ' ')
1307       fputc('\\',parmfile);
1308    fputc('\n',parmfile);
1309    if ((wbdata->buf[len] = (char)c) == ' ')
1310       ++len;
1311    wbdata->len -= len;
1312    strcpy(wbdata->buf,wbdata->buf+len);
1313 }
1314 
getprecbf_mag()1315 int getprecbf_mag()
1316 {
1317    double Xmagfactor, Rotation, Skew;
1318    LDBL Magnification;
1319    bf_t bXctr, bYctr;
1320    int saved,dec;
1321 
1322    saved = save_stack();
1323    bXctr            = alloc_stack(bflength+2);
1324    bYctr            = alloc_stack(bflength+2);
1325    /* this is just to find Magnification */
1326    cvtcentermagbf(bXctr, bYctr, &Magnification, &Xmagfactor, &Rotation, &Skew);
1327    restore_stack(saved);
1328 
1329    /* I don't know if this is portable, but something needs to */
1330    /* be used in case compiler's LDBL_MAX is not big enough    */
1331    if (Magnification > LDBL_MAX || Magnification < -LDBL_MAX)
1332       return(-1);
1333 
1334    dec = getpower10(Magnification) + 4; /* 4 digits of padding sounds good */
1335    return(dec);
1336 }
1337 
getprec(double a,double b,double c)1338 static int getprec(double a,double b,double c)
1339 {
1340    double diff,temp;
1341    int digits;
1342    double highv = 1.0E20;
1343    if ((diff = fabs(a - b)) == 0.0) diff = highv;
1344    if ((temp = fabs(a - c)) == 0.0) temp = highv;
1345    if (temp < diff) diff = temp;
1346    if ((temp = fabs(b - c)) == 0.0) temp = highv;
1347    if (temp < diff) diff = temp;
1348    digits = 7;
1349    if(debugflag >= 700 && debugflag < 720 )
1350       digits =  debugflag - 700;
1351    while (diff < 1.0 && digits <= DBL_DIG+1) {
1352       diff *= 10;
1353       ++digits;
1354       }
1355    return(digits);
1356 }
1357 
1358 /* This function calculates the precision needed to distiguish adjacent
1359    pixels at Fractint's maximum resolution of MAXPIXELS by MAXPIXELS
1360    (if rez==MAXREZ) or at current resolution (if rez==CURRENTREZ)    */
getprecbf(int rezflag)1361 int getprecbf(int rezflag)
1362 {
1363    bf_t del1,del2, one, bfxxdel, bfxxdel2, bfyydel, bfyydel2;
1364    int digits,dec;
1365    int saved;
1366    int rez;
1367    saved    = save_stack();
1368    del1     = alloc_stack(bflength+2);
1369    del2     = alloc_stack(bflength+2);
1370    one      = alloc_stack(bflength+2);
1371    bfxxdel   = alloc_stack(bflength+2);
1372    bfxxdel2  = alloc_stack(bflength+2);
1373    bfyydel   = alloc_stack(bflength+2);
1374    bfyydel2  = alloc_stack(bflength+2);
1375    floattobf(one,1.0);
1376    if(rezflag == MAXREZ)
1377       rez = OLDMAXPIXELS -1;
1378    else
1379       rez = xdots-1;
1380 
1381    /* bfxxdel = (bfxmax - bfx3rd)/(xdots-1) */
1382    sub_bf(bfxxdel, bfxmax, bfx3rd);
1383    div_a_bf_int(bfxxdel, (U16)rez);
1384 
1385    /* bfyydel2 = (bfy3rd - bfymin)/(xdots-1) */
1386    sub_bf(bfyydel2, bfy3rd, bfymin);
1387    div_a_bf_int(bfyydel2, (U16)rez);
1388 
1389    if(rezflag == CURRENTREZ)
1390       rez = ydots-1;
1391 
1392    /* bfyydel = (bfymax - bfy3rd)/(ydots-1) */
1393    sub_bf(bfyydel, bfymax, bfy3rd);
1394    div_a_bf_int(bfyydel, (U16)rez);
1395 
1396    /* bfxxdel2 = (bfx3rd - bfxmin)/(ydots-1) */
1397    sub_bf(bfxxdel2, bfx3rd, bfxmin);
1398    div_a_bf_int(bfxxdel2, (U16)rez);
1399 
1400    abs_a_bf(add_bf(del1,bfxxdel,bfxxdel2));
1401    abs_a_bf(add_bf(del2,bfyydel,bfyydel2));
1402    if(cmp_bf(del2,del1) < 0)
1403        copy_bf(del1, del2);
1404    if(cmp_bf(del1,clear_bf(del2)) == 0)
1405    {
1406       restore_stack(saved);
1407       return(-1);
1408    }
1409    digits = 1;
1410    while(cmp_bf(del1,one) < 0)
1411    {
1412       digits++;
1413       mult_a_bf_int(del1,10);
1414    }
1415    digits = max(digits,3);
1416    restore_stack(saved);
1417    dec = getprecbf_mag();
1418    return(max(digits,dec));
1419 }
1420 
1421 #ifdef _MSC_VER
1422 #pragma optimize("e",off)  /* MSC 7.00 messes up next with "e" on */
1423 #endif
1424 
1425 /* This function calculates the precision needed to distiguish adjacent
1426    pixels at Fractint's maximum resolution of MAXPIXELS by MAXPIXELS
1427    (if rez==MAXREZ) or at current resolution (if rez==CURRENTREZ)    */
getprecdbl(int rezflag)1428 int getprecdbl(int rezflag)
1429 {
1430    LDBL del1,del2, xdel, xdel2, ydel, ydel2;
1431    int digits;
1432    LDBL rez;
1433    if(rezflag == MAXREZ)
1434       rez = OLDMAXPIXELS -1;
1435    else
1436       rez = xdots-1;
1437 
1438    xdel =  ((LDBL)xxmax - (LDBL)xx3rd)/rez;
1439    ydel2 = ((LDBL)yy3rd - (LDBL)yymin)/rez;
1440 
1441    if(rezflag == CURRENTREZ)
1442       rez = ydots-1;
1443 
1444    ydel = ((LDBL)yymax - (LDBL)yy3rd)/rez;
1445    xdel2 = ((LDBL)xx3rd - (LDBL)xxmin)/rez;
1446 
1447    del1 = fabsl(xdel) + fabsl(xdel2);
1448    del2 = fabsl(ydel) + fabsl(ydel2);
1449    if(del2 < del1)
1450        del1 = del2;
1451    if(del1 == 0)
1452    {
1453 #ifdef DEBUG
1454       showcornersdbl("getprecdbl");
1455 #endif
1456       return(-1);
1457    }
1458    digits = 1;
1459    while(del1 < 1.0)
1460    {
1461       digits++;
1462       del1 *= 10;
1463    }
1464    digits = max(digits,3);
1465    return(digits);
1466 }
1467 
1468 #ifdef _MSC_VER
1469 #pragma optimize("e",on)
1470 #endif
1471 
1472 /*
1473    Strips zeros from the non-exponent part of a number. This logic
1474    was originally in put_bf(), but is split into this routine so it can be
1475    shared with put_float(), which had a bug in Fractint 19.2 (used to strip
1476    zeros from the exponent as well.)
1477 */
1478 
strip_zeros(char * buf)1479 static void strip_zeros(char *buf)
1480 {
1481    char *dptr, *bptr, *exptr;
1482    strlwr(buf);
1483    if ((dptr = strchr(buf,'.')) != 0) {
1484       ++dptr;
1485       if ((exptr = strchr(buf,'e')) !=0)  /* scientific notation with 'e'? */
1486          bptr = exptr;
1487       else
1488          bptr = buf + strlen(buf);
1489       while (--bptr > dptr && *bptr == '0')
1490          *bptr = 0;
1491       if(exptr && bptr < exptr -1)
1492         strcat(buf,exptr);
1493    }
1494 }
1495 
put_float(int slash,double fnum,int prec)1496 static void put_float(int slash,double fnum,int prec)
1497 {  char buf[40];
1498    char *bptr;
1499    bptr = buf;
1500    if (slash)
1501       *(bptr++) = '/';
1502 /*   sprintf(bptr,"%1.*f",prec,fnum); */
1503 #ifdef USE_LONG_DOUBLE
1504    /* Idea of long double cast is to squeeze out another digit or two
1505       which might be needed (we have found cases where this digit makes
1506       a difference.) But lets not do this at lower precision */
1507    if(prec > 15)
1508       sprintf(bptr,"%1.*Lg",prec,(long double)fnum);
1509    else
1510 #endif
1511       sprintf(bptr,"%1.*g",prec,(double)fnum);
1512    strip_zeros(bptr);
1513    put_parm(buf);
1514 }
1515 
put_bf(int slash,bf_t r,int prec)1516 static void put_bf(int slash,bf_t r, int prec)
1517 {
1518    char *buf; /* "/-1.xxxxxxE-1234" */
1519    char *bptr;
1520    /* buf = malloc(decimals+11); */
1521    buf = wbdata->buf+5000;  /* end of use suffix buffer, 5000 bytes safe */
1522    bptr = buf;
1523    if (slash)
1524       *(bptr++) = '/';
1525    bftostr(bptr, prec, r);
1526    strip_zeros(bptr);
1527    put_parm(buf);
1528 }
1529 
1530 #ifndef XFRACT
1531 #include <direct.h>
shell_to_dos()1532 void shell_to_dos()
1533 {
1534    int drv;
1535    char *comspec;
1536    char curdir[FILE_MAX_DIR],*s;
1537    if ((comspec = getenv("COMSPEC")) == NULL)
1538       printf("Cannot find COMMAND.COM.\n");
1539    else {
1540       putenv("PROMPT='EXIT' returns to FRACTINT.$_$p$g");
1541       s = getcwd(curdir,100);
1542       drv = _getdrive();
1543       spawnl(P_WAIT, comspec, NULL);
1544       if(drv)
1545          _chdrive(drv);
1546       if(s)
1547          chdir(s);
1548       }
1549 }
1550 
showstack(void)1551 size_t showstack(void)
1552 {
1553    return(stackavail());
1554 }
1555 
fr_farfree(void)1556 long fr_farfree(void)
1557 {
1558    long j,j2;
1559    BYTE huge *fartempptr;
1560    j = 0;
1561    j2 = 0x80000L;
1562    while ((j2 >>= 1) != 0)
1563       if ((fartempptr = (BYTE huge *)farmemalloc(j+j2)) != NULL) {
1564          farmemfree((void far*)fartempptr);
1565          j += j2;
1566          }
1567    return(j);
1568 }
1569 
showfreemem(void)1570 void showfreemem(void)
1571 {
1572    char *tempptr;
1573    unsigned i,i2;
1574 
1575    char adapter_name[8];        /* entry lenth from VIDEO.ASM */
1576    char *adapter_ptr;
1577 
1578    printf("\n CPU type: %d  FPU type: %d  Video: %d",
1579           cpu, fpu, video_type);
1580 
1581    adapter_ptr = &supervga_list;
1582 
1583    for(i = 0 ; ; i++) {         /* find the SuperVGA entry */
1584        int j;
1585        memcpy(adapter_name , adapter_ptr, 8);
1586        adapter_ptr += 8;
1587        if (adapter_name[0] == ' ') break;       /* end-of-the-list */
1588        if (adapter_name[6] == 0) continue;      /* not our adapter */
1589        adapter_name[6] = ' ';
1590        for (j = 0; j < 8; j++)
1591            if(adapter_name[j] == ' ')
1592                adapter_name[j] = 0;
1593        printf("  Video chip: %d (%s)",i+1,adapter_name);
1594        }
1595    printf("\n\n");
1596 
1597    i = 0;
1598    i2 = 0x8000;
1599    while ((i2 >>= 1) != 0)
1600       if ((tempptr = malloc(i+i2)) != NULL) {
1601          free(tempptr);
1602          i += i2;
1603          }
1604    printf(" %d NEAR bytes free \n", i);
1605 
1606    printf(" %ld FAR bytes free ", fr_farfree());
1607    {
1608       size_t stack;
1609       stack = showstack();
1610 /*      if(stack >= 0) */ /* stack is unsigned */
1611          printf("\n %u STACK bytes free",stack);
1612    }
1613    printf("\n %ld used by HISTORY structure",
1614       sizeof(HISTORY)*(unsigned long)maxhistory);
1615    printf("\n %d video table used",showvidlength());
1616    printf("\n\n %Fs...\n",s_pressanykeytocontinue);
1617    getakey();
1618 }
1619 #endif
1620 
edit_text_colors()1621 int edit_text_colors()
1622 {
1623    int save_debugflag,save_lookatmouse;
1624    int row,col,bkgrd;
1625    int rowf,colf,rowt,colt;
1626    char far *vidmem;
1627    char far *savescreen;
1628    char far *farp1; char far *farp2;
1629    int i,j,k;
1630    save_debugflag = debugflag;
1631    save_lookatmouse = lookatmouse;
1632    debugflag = 0;   /* don't get called recursively */
1633    lookatmouse = 2; /* text mouse sensitivity */
1634    row = col = bkgrd = rowt = rowf = colt = colf = 0;
1635    vidmem = MK_FP(0xB800,0);
1636    for(;;) {
1637       if (row < 0)  row = 0;
1638       if (row > 24) row = 24;
1639       if (col < 0)  col = 0;
1640       if (col > 79) col = 79;
1641       movecursor(row,col);
1642       i = getakey();
1643       if (i >= 'a' && i <= 'z') i -= 32; /* uppercase */
1644       switch (i) {
1645          case 27: /* esc */
1646             debugflag = save_debugflag;
1647             lookatmouse = save_lookatmouse;
1648             movecursor(25,80);
1649             return 0;
1650          case '/':
1651             farp1 = savescreen = (char far *)farmemalloc(4000L);
1652             farp2 = vidmem;
1653             for (i = 0; i < 4000; ++i) { /* save and blank */
1654                *(farp1++) = *farp2;
1655                *(farp2++) = 0;
1656                }
1657             for (i = 0; i < 8; ++i)       /* 8 bkgrd attrs */
1658                for (j = 0; j < 16; ++j) { /* 16 fgrd attrs */
1659                   k = i*16 + j;
1660                   farp1 = vidmem + i*320 + j*10;
1661                   *(farp1++) = ' '; *(farp1++) = (char)k;
1662                   *(farp1++) = (char)(i+'0'); *(farp1++) = (char)k;
1663                   *(farp1++) = (char)((j < 10) ? j+'0' : j+'A'-10); *(farp1++) = (char)k;
1664                   *(farp1++) = ' '; *(farp1++) = (char)k;
1665                   }
1666             getakey();
1667             farp1 = vidmem;
1668             farp2 = savescreen;
1669             for (i = 0; i < 4000; ++i) /* restore */
1670                *(farp1++) = *(farp2++);
1671             farmemfree(savescreen);
1672             break;
1673          case ',':
1674             rowf = row; colf = col; break;
1675          case '.':
1676             rowt = row; colt = col; break;
1677          case ' ': /* next color is background */
1678             bkgrd = 1; break;
1679          case 1075: /* cursor left  */
1680             --col; break;
1681          case 1077: /* cursor right */
1682             ++col; break;
1683          case 1072: /* cursor up    */
1684             --row; break;
1685          case 1080: /* cursor down  */
1686             ++row; break;
1687          case 13:   /* enter */
1688             *(vidmem + row*160 + col*2) = (char)getakey();
1689             break;
1690          default:
1691             if (i >= '0' && i <= '9')      i -= '0';
1692             else if (i >= 'A' && i <= 'F') i -= 'A'-10;
1693             else break;
1694             for (j = rowf; j <= rowt; ++j)
1695                for (k = colf; k <= colt; ++k) {
1696                   farp1 = vidmem + j*160 + k*2 + 1;
1697                   if (bkgrd) *farp1 = (char)((*farp1 & 15) + i * 16);
1698                   else       *farp1 = (char)((*farp1 & 0xf0) + i);
1699                   }
1700             bkgrd = 0;
1701          }
1702       }
1703 }
1704 
1705 static int *entsptr;
1706 static int modes_changed;
1707 
select_video_mode(int curmode)1708 int select_video_mode(int curmode)
1709 {
1710    static FCODE o_hdg2[]={"key...name.......................xdot..ydot.colr.comment.................."};
1711    static FCODE o_hdg1[]={"Select Video Mode"};
1712    char hdg2[sizeof(o_hdg2)];
1713    char hdg1[sizeof(o_hdg1)];
1714 
1715    int entnums[MAXVIDEOMODES];
1716    int attributes[MAXVIDEOMODES];
1717    int i,k,ret;
1718 #ifndef XFRACT
1719    int j;
1720    int oldtabmode,oldhelpmode;
1721 #endif
1722 
1723    load_fractint_cfg(0);        /* load fractint.cfg to extraseg */
1724 
1725    far_strcpy(hdg1,o_hdg1);
1726    far_strcpy(hdg2,o_hdg2);
1727 
1728    for (i = 0; i < vidtbllen; ++i) { /* init tables */
1729       entnums[i] = i;
1730       attributes[i] = 1;
1731       }
1732    entsptr = entnums;           /* for indirectly called subroutines */
1733 
1734    qsort(entnums,vidtbllen,sizeof(entnums[0]),entcompare); /* sort modes */
1735 
1736    /* pick default mode */
1737    if (curmode < 0) {
1738       switch (video_type) { /* set up a reasonable default (we hope) */
1739          case 1:  videoentry.videomodeax = 8;   /* hgc */
1740                   videoentry.colors = 2;
1741                   break;
1742          case 2:  videoentry.videomodeax = 4;   /* cga */
1743                   videoentry.colors = 4;
1744                   break;
1745          case 3:  videoentry.videomodeax = 16;  /* ega */
1746                   videoentry.colors = 16;
1747                   if (mode7text) {              /* egamono */
1748                      videoentry.videomodeax = 15;
1749                      videoentry.colors = 2;
1750                      }
1751                   break;
1752          default: videoentry.videomodeax = 19;  /* mcga/vga? */
1753                   videoentry.colors = 256;
1754                   break;
1755          }
1756       }
1757    else
1758       far_memcpy((char far *)&videoentry,(char far *)&videotable[curmode],
1759                  sizeof(videoentry));
1760 #ifndef XFRACT
1761    for (i = 0; i < vidtbllen; ++i) { /* find default mode */
1762       if ( videoentry.videomodeax == vidtbl[entnums[i]].videomodeax
1763         && videoentry.colors      == vidtbl[entnums[i]].colors
1764         && (curmode < 0
1765             || far_memcmp((char far *)&videoentry,(char far *)&vidtbl[entnums[i]],
1766                           sizeof(videoentry)) == 0))
1767          break;
1768       }
1769    if (i >= vidtbllen) /* no match, default to first entry */
1770       i = 0;
1771 
1772    oldtabmode = tabmode;
1773    oldhelpmode = helpmode;
1774    modes_changed = 0;
1775    tabmode = 0;
1776    helpmode = HELPVIDSEL;
1777    i = fullscreen_choice(CHOICEHELP,hdg1,hdg2,NULL,vidtbllen,NULL,attributes,
1778                          1,16,74,i,format_vid_table,NULL,NULL,check_modekey);
1779    tabmode = oldtabmode;
1780    helpmode = oldhelpmode;
1781    if (i == -1) {
1782    static FCODE msg[]={"Save new function key assignments or cancel changes?"};
1783       if (modes_changed /* update fractint.cfg for new key assignments */
1784         && badconfig == 0
1785         && stopmsg(22,msg) == 0)
1786          update_fractint_cfg();
1787       return(-1);
1788       }
1789    if (i < 0)   /* picked by function key */
1790       i = -1 - i;
1791    else         /* picked by Enter key */
1792       i = entnums[i];
1793 #endif
1794    far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i],
1795               sizeof(videoentry));  /* the selected entry now in videoentry */
1796 
1797 #ifndef XFRACT
1798    /* copy fractint.cfg table to resident table, note selected entry */
1799    j = k = 0;
1800    far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE);
1801    for (i = 0; i < vidtbllen; ++i) {
1802       if (vidtbl[i].keynum > 0) {
1803          far_memcpy((char far *)&videotable[j],(char far *)&vidtbl[i],
1804                     sizeof(*vidtbl));
1805          if (far_memcmp((char far *)&videoentry,(char far *)&vidtbl[i],
1806                         sizeof(videoentry)) == 0)
1807             k = vidtbl[i].keynum;
1808          if (++j >= MAXVIDEOTABLE-1)
1809             break;
1810          }
1811       }
1812 #else
1813     k = vidtbl[0].keynum;
1814 #endif
1815    if ((ret = k) == 0) { /* selected entry not a copied (assigned to key) one */
1816       far_memcpy((char far *)&videotable[MAXVIDEOTABLE-1],
1817                  (char far *)&videoentry,sizeof(*vidtbl));
1818       ret = 1400; /* special value for check_vidmode_key */
1819       }
1820 
1821    if (modes_changed /* update fractint.cfg for new key assignments */
1822      && badconfig == 0)
1823       update_fractint_cfg();
1824 
1825    return(ret);
1826 }
1827 
format_vid_table(int choice,char * buf)1828 void format_vid_table(int choice,char *buf)
1829 {
1830    char local_buf[81];
1831    char kname[5];
1832    char biosflag;
1833    int truecolorbits;
1834    far_memcpy((char far *)&videoentry,(char far *)&vidtbl[entsptr[choice]],
1835               sizeof(videoentry));
1836    vidmode_keyname(videoentry.keynum,kname);
1837    biosflag = (char)((videoentry.dotmode % 100 == 1) ? 'B' : ' ');
1838    sprintf(buf,"%-5s %-25s %5d %5d ",  /* 44 chars */
1839            kname, videoentry.name, videoentry.xdots, videoentry.ydots);
1840    if((truecolorbits = videoentry.dotmode/1000) == 0)
1841       sprintf(local_buf,"%s%3d",  /* 47 chars */
1842            buf, videoentry.colors);
1843    else
1844       sprintf(local_buf,"%s%3s",  /* 47 chars */
1845            buf, (truecolorbits == 4)?" 4g":
1846                 (truecolorbits == 3)?"16m":
1847                 (truecolorbits == 2)?"64k":
1848                 (truecolorbits == 1)?"32k":"???");
1849    sprintf(buf,"%s%c %-25s",  /* 74 chars */
1850            local_buf, biosflag, videoentry.comment);
1851 }
1852 
1853 #ifndef XFRACT
check_modekey(int curkey,int choice)1854 static int check_modekey(int curkey,int choice)
1855 {
1856    int i,j,k,ret;
1857    if ((i = check_vidmode_key(1,curkey)) >= 0)
1858       return(-1-i);
1859    i = entsptr[choice];
1860    ret = 0;
1861    if ( (curkey == '-' || curkey == '+')
1862      && (vidtbl[i].keynum == 0 || vidtbl[i].keynum >= 1084)) {
1863       static FCODE msg[]={"Missing or bad FRACTINT.CFG file. Can't reassign keys."};
1864       if (badconfig)
1865          stopmsg(0,msg);
1866       else {
1867          if (curkey == '-') {                   /* deassign key? */
1868             if (vidtbl[i].keynum >= 1084) {
1869                vidtbl[i].keynum = 0;
1870                modes_changed = 1;
1871                }
1872             }
1873          else {                                 /* assign key? */
1874             j = getakeynohelp();
1875             if (j >= 1084 && j <= 1113) {
1876                for (k = 0; k < vidtbllen; ++k) {
1877                   if (vidtbl[k].keynum == j) {
1878                      vidtbl[k].keynum = 0;
1879                      ret = -1; /* force redisplay */
1880                      }
1881                   }
1882                vidtbl[i].keynum = j;
1883                modes_changed = 1;
1884                }
1885             }
1886          }
1887       }
1888    return(ret);
1889 }
1890 #endif
1891 
entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2)1892 static int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2)
1893 {
1894    int i,j;
1895    if ((i = vidtbl[*((int *)p1)].keynum) == 0) i = 9999;
1896    if ((j = vidtbl[*((int *)p2)].keynum) == 0) j = 9999;
1897    if (i < j || (i == j && *((int *)p1) < *((int *)p2)))
1898       return(-1);
1899    return(1);
1900 }
1901 
update_fractint_cfg()1902 static void update_fractint_cfg()
1903 {
1904 #ifndef XFRACT
1905    char cfgname[100],outname[100],buf[121],kname[5];
1906    FILE *cfgfile,*outfile;
1907    int far *cfglinenums;
1908    int i,j,linenum,nextlinenum,nextmode;
1909    struct videoinfo vident;
1910 
1911    findpath("fractint.cfg",cfgname);
1912 
1913    if (access(cfgname,6)) {
1914       sprintf(buf,s_cantwrite,cfgname);
1915       stopmsg(0,buf);
1916       return;
1917       }
1918    strcpy(outname,cfgname);
1919    i = strlen(outname);
1920    while (--i >= 0 && outname[i] != SLASHC)
1921    outname[i] = 0;
1922    strcat(outname,"fractint.tmp");
1923    if ((outfile = fopen(outname,"w")) == NULL) {
1924       sprintf(buf,s_cantcreate,outname);
1925       stopmsg(0,buf);
1926       return;
1927       }
1928    cfgfile = fopen(cfgname,"r");
1929 
1930    cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]);
1931    linenum = nextmode = 0;
1932    nextlinenum = cfglinenums[0];
1933    while (fgets(buf,120,cfgfile)) {
1934       int truecolorbits;
1935       char colorsbuf[10];
1936       ++linenum;
1937       if (linenum == nextlinenum) { /* replace this line */
1938          far_memcpy((char far *)&vident,(char far *)&vidtbl[nextmode],
1939                     sizeof(videoentry));
1940          vidmode_keyname(vident.keynum,kname);
1941          strcpy(buf,vident.name);
1942          i = strlen(buf);
1943          while (i && buf[i-1] == ' ') /* strip trailing spaces to compress */
1944             --i;
1945          j = i + 5;
1946          while (j < 32) {               /* tab to column 33 */
1947             buf[i++] = '\t';
1948             j += 8;
1949             }
1950          buf[i] = 0;
1951          if((truecolorbits = vident.dotmode/1000) == 0)
1952             sprintf(colorsbuf,"%3d",vident.colors);
1953          else
1954             sprintf(colorsbuf,"%3s",
1955                     (truecolorbits == 4)?" 4g":
1956                     (truecolorbits == 3)?"16m":
1957                     (truecolorbits == 2)?"64k":
1958                     (truecolorbits == 1)?"32k":"???");
1959          fprintf(outfile,"%-4s,%s,%4x,%4x,%4x,%4x,%4d,%5d,%5d,%s,%s\n",
1960                 kname,
1961                 buf,
1962                 vident.videomodeax,
1963                 vident.videomodebx,
1964                 vident.videomodecx,
1965                 vident.videomodedx,
1966                 vident.dotmode%1000, /* remove true-color flag, keep textsafe */
1967                 vident.xdots,
1968                 vident.ydots,
1969                 colorsbuf,
1970                 vident.comment);
1971          if (++nextmode >= vidtbllen)
1972             nextlinenum = 32767;
1973          else
1974             nextlinenum = cfglinenums[nextmode];
1975          }
1976       else
1977          fputs(buf,outfile);
1978       }
1979 
1980    fclose(cfgfile);
1981    fclose(outfile);
1982    unlink(cfgname);         /* success assumed on these lines       */
1983    rename(outname,cfgname); /* since we checked earlier with access */
1984 #endif
1985 }
1986 
1987 /* make_mig() takes a collection of individual GIF images (all
1988    presumably the same resolution and all presumably generated
1989    by Fractint and its "divide and conquer" algorithm) and builds
1990    a single multiple-image GIF out of them.  This routine is
1991    invoked by the "batch=stitchmode/x/y" option, and is called
1992    with the 'x' and 'y' parameters
1993 */
1994 
make_mig(unsigned int xmult,unsigned int ymult)1995 void make_mig(unsigned int xmult, unsigned int ymult)
1996 {
1997 unsigned int xstep, ystep;
1998 unsigned int xres, yres;
1999 unsigned int allxres, allyres, xtot, ytot;
2000 unsigned int xloc, yloc;
2001 unsigned char ichar;
2002 unsigned int allitbl, itbl;
2003 unsigned int i;
2004 char gifin[15], gifout[15];
2005 int errorflag, inputerrorflag;
2006 unsigned char *temp;
2007 FILE *out, *in;
2008 char msgbuf[81];
2009 
2010 errorflag = 0;                          /* no errors so far */
2011 inputerrorflag = 0;
2012 allxres = allyres = allitbl = 0;
2013 out = in = NULL;
2014 
2015 strcpy(gifout,"fractmig.gif");
2016 
2017 temp= &olddacbox[0][0];                 /* a safe place for our temp data */
2018 
2019 gif87a_flag = 1;                        /* for now, force this */
2020 
2021 /* process each input image, one at a time */
2022 for (ystep = 0; ystep < ymult; ystep++) {
2023     for (xstep = 0; xstep < xmult; xstep++) {
2024 
2025 if (xstep == 0 && ystep == 0) {         /* first time through? */
2026     static FCODE msg1[] = "Cannot create output file %s!\n";
2027     static FCODE msg2[] = " \n Generating multi-image GIF file %s using";
2028     static FCODE msg3[] = " %d X and %d Y components\n\n";
2029     far_strcpy(msgbuf, msg2);
2030     printf(msgbuf, gifout);
2031     far_strcpy(msgbuf, msg3);
2032     printf(msgbuf, xmult, ymult);
2033     /* attempt to create the output file */
2034     if ((out = fopen(gifout,"wb")) == NULL) {
2035         far_strcpy(msgbuf, msg1);
2036         printf(msgbuf, gifout);
2037         exit(1);
2038         }
2039     }
2040 
2041         sprintf(gifin, "frmig_%c%c.gif", PAR_KEY(xstep), PAR_KEY(ystep));
2042 
2043         if ((in = fopen(gifin,"rb")) == NULL) {
2044             static FCODE msg1[] = "Can't open file %s!\n";
2045             far_strcpy(msgbuf, msg1);
2046             printf(msgbuf, gifin);
2047             exit(1);
2048             }
2049 
2050         /* (read, but only copy this if it's the first time through) */
2051         if (fread(temp,13,1,in) != 1)   /* read the header and LDS */
2052             inputerrorflag = 1;
2053         memcpy(&xres, &temp[6], 2);     /* X-resolution */
2054         memcpy(&yres, &temp[8], 2);     /* Y-resolution */
2055 
2056         if (xstep == 0 && ystep == 0) { /* first time through? */
2057             allxres = xres;             /* save the "master" resolution */
2058             allyres = yres;
2059             xtot = xres * xmult;        /* adjust the image size */
2060             ytot = yres * ymult;
2061             memcpy(&temp[6], &xtot, 2);
2062             memcpy(&temp[8], &ytot, 2);
2063             if (gif87a_flag) {
2064                 temp[3] = '8';
2065                 temp[4] = '7';
2066                 temp[5] = 'a';
2067                 }
2068             temp[12] = 0; /* reserved */
2069             if (fwrite(temp,13,1,out) != 1)     /* write out the header */
2070                 errorflag = 1;
2071             }                           /* end of first-time-through */
2072 
2073 
2074         ichar = (char)(temp[10] & 0x07);        /* find the color table size */
2075         itbl = 1 << (++ichar);
2076         ichar = (char)(temp[10] & 0x80);        /* is there a global color table? */
2077         if (xstep == 0 && ystep == 0)   /* first time through? */
2078             allitbl = itbl;             /* save the color table size */
2079         if (ichar != 0) {               /* yup */
2080             /* (read, but only copy this if it's the first time through) */
2081             if(fread(temp,3*itbl,1,in) != 1)    /* read the global color table */
2082                 inputerrorflag = 2;
2083             if (xstep == 0 && ystep == 0)       /* first time through? */
2084                 if (fwrite(temp,3*itbl,1,out) != 1)     /* write out the GCT */
2085                     errorflag = 2;
2086             }
2087 
2088         if (xres != allxres || yres != allyres || itbl != allitbl) {
2089             /* Oops - our pieces don't match */
2090             static FCODE msg1[] = "File %s doesn't have the same resolution as its predecessors!\n";
2091             far_strcpy(msgbuf, msg1);
2092             printf(msgbuf, gifin);
2093             exit(1);
2094             }
2095 
2096         for (;;) {                      /* process each information block */
2097         memset(temp,0,10);
2098         if (fread(temp,1,1,in) != 1)    /* read the block identifier */
2099             inputerrorflag = 3;
2100 
2101         if (temp[0] == 0x2c) {          /* image descriptor block */
2102             if (fread(&temp[1],9,1,in) != 1)    /* read the Image Descriptor */
2103                 inputerrorflag = 4;
2104             memcpy(&xloc, &temp[1], 2); /* X-location */
2105             memcpy(&yloc, &temp[3], 2); /* Y-location */
2106             xloc += (xstep * xres);     /* adjust the locations */
2107             yloc += (ystep * yres);
2108             memcpy(&temp[1], &xloc, 2);
2109             memcpy(&temp[3], &yloc, 2);
2110             if (fwrite(temp,10,1,out) != 1)     /* write out the Image Descriptor */
2111                 errorflag = 4;
2112 
2113             ichar = (char)(temp[9] & 0x80);     /* is there a local color table? */
2114             if (ichar != 0) {           /* yup */
2115                 if (fread(temp,3*itbl,1,in) != 1)       /* read the local color table */
2116                     inputerrorflag = 5;
2117                 if (fwrite(temp,3*itbl,1,out) != 1)     /* write out the LCT */
2118                     errorflag = 5;
2119                 }
2120 
2121             if (fread(temp,1,1,in) != 1)        /* LZH table size */
2122                 inputerrorflag = 6;
2123             if (fwrite(temp,1,1,out) != 1)
2124                 errorflag = 6;
2125             for(;;) {
2126                 if (errorflag != 0 || inputerrorflag != 0)      /* oops - did something go wrong? */
2127                     break;
2128                 if (fread(temp,1,1,in) != 1)    /* block size */
2129                     inputerrorflag = 7;
2130                 if (fwrite(temp,1,1,out) != 1)
2131                     errorflag = 7;
2132                 if ((i = temp[0]) == 0)
2133                     break;
2134                 if (fread(temp,i,1,in) != 1)    /* LZH data block */
2135                     inputerrorflag = 8;
2136                 if (fwrite(temp,i,1,out) != 1)
2137                     errorflag = 8;
2138                 }
2139             }
2140 
2141         if (temp[0] == 0x21) {          /* extension block */
2142             /* (read, but only copy this if it's the last time through) */
2143             if (fread(&temp[2],1,1,in) != 1)    /* read the block type */
2144                 inputerrorflag = 9;
2145             if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1)
2146                 if (fwrite(temp,2,1,out) != 1)
2147                     errorflag = 9;
2148             for(;;) {
2149                 if (errorflag != 0 || inputerrorflag != 0)      /* oops - did something go wrong? */
2150                     break;
2151                 if (fread(temp,1,1,in) != 1)    /* block size */
2152                     inputerrorflag = 10;
2153                 if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1)
2154                     if (fwrite(temp,1,1,out) != 1)
2155                         errorflag = 10;
2156                 if ((i = temp[0]) == 0)
2157                     break;
2158                 if (fread(temp,i,1,in) != 1)    /* data block */
2159                     inputerrorflag = 11;
2160                 if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1)
2161                     if (fwrite(temp,i,1,out) != 1)
2162                         errorflag = 11;
2163                 }
2164             }
2165 
2166         if (temp[0] == 0x3b) {          /* end-of-stream indicator */
2167             break;                      /* done with this file */
2168             }
2169 
2170         if (errorflag != 0 || inputerrorflag != 0)      /* oops - did something go wrong? */
2171             break;
2172 
2173         }
2174         fclose(in);                     /* done with an input GIF */
2175 
2176         if (errorflag != 0 || inputerrorflag != 0)      /* oops - did something go wrong? */
2177             break;
2178         }
2179 
2180     if (errorflag != 0 || inputerrorflag != 0)  /* oops - did something go wrong? */
2181         break;
2182     }
2183 
2184 temp[0] = 0x3b;                 /* end-of-stream indicator */
2185 if (fwrite(temp,1,1,out) != 1)
2186     errorflag = 12;
2187 fclose(out);                    /* done with the output GIF */
2188 
2189 if (inputerrorflag != 0) {      /* uh-oh - something failed */
2190     static FCODE msg1[] = "\007 Process failed = early EOF on input file %s\n";
2191     far_strcpy(msgbuf, msg1);
2192     printf(msgbuf, gifin);
2193 /* following line was for debugging
2194     printf("inputerrorflag = %d\n", inputerrorflag);
2195 */
2196     }
2197 
2198 if (errorflag != 0) {           /* uh-oh - something failed */
2199     static FCODE msg1[] = "\007 Process failed = out of disk space?\n";
2200     far_strcpy(msgbuf, msg1);
2201     printf(msgbuf);
2202 /* following line was for debugging
2203     printf("errorflag = %d\n", errorflag);
2204 */
2205     }
2206 
2207 /* now delete each input image, one at a time */
2208 if (errorflag == 0 && inputerrorflag == 0)
2209   for (ystep = 0; ystep < ymult; ystep++) {
2210     for (xstep = 0; xstep < xmult; xstep++) {
2211         sprintf(gifin, "frmig_%c%c.gif", PAR_KEY(xstep), PAR_KEY(ystep));
2212         remove(gifin);
2213         }
2214     }
2215 
2216 /* tell the world we're done */
2217 if (errorflag == 0 && inputerrorflag == 0) {
2218     static FCODE msg1[] = "File %s has been created (and its component files deleted)\n";
2219     far_strcpy(msgbuf, msg1);
2220     printf(msgbuf, gifout);
2221     }
2222 }
2223 
2224 /* This routine copies the current screen to by flipping x-axis, y-axis,
2225    or both. Refuses to work if calculation in progress or if fractal
2226    non-resumable. Clears zoombox if any. Resets corners so resulting fractal
2227    is still valid. */
flip_image(int key)2228 void flip_image(int key)
2229 {
2230    int i, j, ixhalf, iyhalf, tempdot;
2231 
2232    /* fractal must be rotate-able and be finished */
2233    if ((curfractalspecific->flags&NOROTATE) != 0
2234        || calc_status == 1
2235        || calc_status == 2)
2236       return;
2237    if(bf_math)
2238        clear_zoombox(); /* clear, don't copy, the zoombox */
2239    ixhalf = xdots / 2;
2240    iyhalf = ydots / 2;
2241    switch(key)
2242    {
2243    case 24:            /* control-X - reverse X-axis */
2244       for (i = 0; i < ixhalf; i++)
2245       {
2246          if(keypressed())
2247             break;
2248          for (j = 0; j < ydots; j++)
2249          {
2250             tempdot=getcolor(i,j);
2251             putcolor(i, j, getcolor(xdots-1-i,j));
2252             putcolor(xdots-1-i, j, tempdot);
2253          }
2254       }
2255       sxmin = xxmax + xxmin - xx3rd;
2256       symax = yymax + yymin - yy3rd;
2257       sxmax = xx3rd;
2258       symin = yy3rd;
2259       sx3rd = xxmax;
2260       sy3rd = yymin;
2261       if(bf_math)
2262       {
2263          add_bf(bfsxmin, bfxmax, bfxmin); /* sxmin = xxmax + xxmin - xx3rd; */
2264          sub_a_bf(bfsxmin, bfx3rd);
2265          add_bf(bfsymax, bfymax, bfymin); /* symax = yymax + yymin - yy3rd; */
2266          sub_a_bf(bfsymax, bfy3rd);
2267          copy_bf(bfsxmax, bfx3rd);        /* sxmax = xx3rd; */
2268          copy_bf(bfsymin, bfy3rd);        /* symin = yy3rd; */
2269          copy_bf(bfsx3rd, bfxmax);        /* sx3rd = xxmax; */
2270          copy_bf(bfsy3rd, bfymin);        /* sy3rd = yymin; */
2271       }
2272       break;
2273    case 25:            /* control-Y - reverse Y-aXis */
2274       for (j = 0; j < iyhalf; j++)
2275       {
2276          if(keypressed())
2277             break;
2278          for (i = 0; i < xdots; i++)
2279          {
2280             tempdot=getcolor(i,j);
2281             putcolor(i, j, getcolor(i,ydots-1-j));
2282             putcolor(i,ydots-1-j, tempdot);
2283          }
2284       }
2285       sxmin = xx3rd;
2286       symax = yy3rd;
2287       sxmax = xxmax + xxmin - xx3rd;
2288       symin = yymax + yymin - yy3rd;
2289       sx3rd = xxmin;
2290       sy3rd = yymax;
2291       if(bf_math)
2292       {
2293          copy_bf(bfsxmin, bfx3rd);        /* sxmin = xx3rd; */
2294          copy_bf(bfsymax, bfy3rd);        /* symax = yy3rd; */
2295          add_bf(bfsxmax, bfxmax, bfxmin); /* sxmax = xxmax + xxmin - xx3rd; */
2296          sub_a_bf(bfsxmax, bfx3rd);
2297          add_bf(bfsymin, bfymax, bfymin); /* symin = yymax + yymin - yy3rd; */
2298          sub_a_bf(bfsymin, bfy3rd);
2299          copy_bf(bfsx3rd, bfxmin);        /* sx3rd = xxmin; */
2300          copy_bf(bfsy3rd, bfymax);        /* sy3rd = yymax; */
2301       }
2302       break;
2303    case 26:            /* control-Z - reverse X and Y aXis */
2304       for (i = 0; i < ixhalf; i++)
2305       {
2306          if(keypressed())
2307             break;
2308          for (j = 0; j < ydots; j++)
2309          {
2310             tempdot=getcolor(i,j);
2311             putcolor(i, j, getcolor(xdots-1-i,ydots-1-j));
2312             putcolor(xdots-1-i, ydots-1-j, tempdot);
2313          }
2314       }
2315       sxmin = xxmax;
2316       symax = yymin;
2317       sxmax = xxmin;
2318       symin = yymax;
2319       sx3rd = xxmax + xxmin - xx3rd;
2320       sy3rd = yymax + yymin - yy3rd;
2321       if(bf_math)
2322       {
2323          copy_bf(bfsxmin, bfxmax);        /* sxmin = xxmax; */
2324          copy_bf(bfsymax, bfymin);        /* symax = yymin; */
2325          copy_bf(bfsxmax, bfxmin);        /* sxmax = xxmin; */
2326          copy_bf(bfsymin, bfymax);        /* symin = yymax; */
2327          add_bf(bfsx3rd, bfxmax, bfxmin); /* sx3rd = xxmax + xxmin - xx3rd; */
2328          sub_a_bf(bfsx3rd, bfx3rd);
2329          add_bf(bfsy3rd, bfymax, bfymin); /* sy3rd = yymax + yymin - yy3rd; */
2330          sub_a_bf(bfsy3rd, bfy3rd);
2331       }
2332       break;
2333    }
2334    reset_zoom_corners();
2335    calc_status = 0;
2336 }
expand_var(char * var,char * buf)2337 static char *expand_var(char *var, char *buf)
2338 {
2339    static FCODE s_year    [] = {"year"    };
2340    static FCODE s_month   [] = {"month"   };
2341    static FCODE s_day     [] = {"day"     };
2342    static FCODE s_hour    [] = {"hour"    };
2343    static FCODE s_min     [] = {"min"     };
2344    static FCODE s_sec     [] = {"sec"     };
2345    static FCODE s_time    [] = {"time"    };
2346    static FCODE s_date    [] = {"date"    };
2347    static FCODE s_calctime[] = {"calctime"};
2348    static FCODE s_version [] = {"version" };
2349    static FCODE s_patch   [] = {"patch"   };
2350    static FCODE s_xdots   [] = {"xdots"   };
2351    static FCODE s_ydots   [] = {"ydots"   };
2352    static FCODE s_vidkey  [] = {"vidkey"  };
2353 
2354    time_t ltime;
2355    char *str, *out;
2356 
2357    time( &ltime );
2358    str = ctime(&ltime);
2359 
2360    /* ctime format             */
2361    /* Sat Aug 17 21:34:14 1996 */
2362    /* 012345678901234567890123 */
2363    /*           1         2    */
2364    if(far_strcmp(var,s_year) == 0)       /* 4 chars */
2365    {
2366       str[24] = '\0';
2367       out = &str[20];
2368    }
2369    else if(far_strcmp(var,s_month) == 0) /* 3 chars */
2370    {
2371       str[7] = '\0';
2372       out = &str[4];
2373    }
2374    else if(far_strcmp(var,s_day) == 0)   /* 2 chars */
2375    {
2376       str[10] = '\0';
2377       out = &str[8];
2378    }
2379    else if(far_strcmp(var,s_hour) == 0)  /* 2 chars */
2380    {
2381       str[13] = '\0';
2382       out = &str[11];
2383    }
2384    else if(far_strcmp(var,s_min) == 0)   /* 2 chars */
2385    {
2386       str[16] = '\0';
2387       out = &str[14];
2388    }
2389    else if(far_strcmp(var,s_sec) == 0)   /* 2 chars */
2390    {
2391       str[19] = '\0';
2392       out = &str[17];
2393    }
2394    else if(far_strcmp(var,s_time) == 0)  /* 8 chars */
2395    {
2396       str[19] = '\0';
2397       out = &str[11];
2398    }
2399    else if(far_strcmp(var,s_date) == 0)
2400    {
2401       str[10] = '\0';
2402       str[24] = '\0';
2403       out = &str[4];
2404       strcat(out,", ");
2405       strcat(out,&str[20]);
2406    }
2407    else if(far_strcmp(var,s_calctime) == 0)
2408    {
2409       get_calculation_time(buf,calctime);
2410       out = buf;
2411    }
2412    else if(far_strcmp(var,s_version) == 0)  /* 4 chars */
2413    {
2414       sprintf(buf,"%d",release);
2415       out = buf;
2416    }
2417    else if(far_strcmp(var,s_patch) == 0)   /* 1 or 2 chars */
2418    {
2419       sprintf(buf,"%d",patchlevel);
2420       out = buf;
2421    }
2422    else if(far_strcmp(var,s_xdots) == 0)   /* 2 to 4 chars */
2423    {
2424       sprintf(buf,"%d",xdots);
2425       out = buf;
2426    }
2427    else if(far_strcmp(var,s_ydots) == 0)   /* 2 to 4 chars */
2428    {
2429       sprintf(buf,"%d",ydots);
2430       out = buf;
2431    }
2432    else if(far_strcmp(var,s_vidkey) == 0)   /* 2 to 3 chars */
2433    {
2434       char vidmde[5];
2435       vidmode_keyname(videoentry.keynum, vidmde);
2436       sprintf(buf,"%s",vidmde);
2437       out = buf;
2438    }
2439    else
2440    {
2441       static char far msg[] = {"Unknown comment variable xxxxxxxxxxxxxxx"};
2442       msg[25] = '\0';
2443       far_strcat(msg,var);
2444       stopmsg(0,msg);
2445       out = "";
2446    }
2447    return(out);
2448 }
2449 
2450 #define MAXVNAME  13
2451 
2452 static const char esc_char = '$';
2453 
2454 /* extract comments from the comments= command */
expand_comments(char far * target,char far * source)2455 void expand_comments(char far *target, char far *source)
2456 {
2457    int i,j, k, escape = 0;
2458    char c, oldc, varname[MAXVNAME];
2459    i=j=k=0;
2460    c = oldc = 0;
2461    while(i < MAXCMT && j < MAXCMT && (c = *(source+i++)) != '\0')
2462    {
2463       if(c == '\\' && oldc != '\\')
2464       {
2465          oldc = c;
2466          continue;
2467       }
2468       /* expand underscores to blanks */
2469       if(c == '_' && oldc != '\\')
2470          c = ' ';
2471       /* esc_char marks start and end of variable names */
2472       if(c == esc_char && oldc != '\\')
2473          escape = 1 - escape;
2474       if(c != esc_char && escape != 0) /* if true, building variable name */
2475       {
2476          if(k < MAXVNAME-1)
2477             varname[k++] = c;
2478       }
2479       /* got variable name */
2480       else if(c == esc_char && escape == 0 && oldc != '\\')
2481       {
2482          char buf[100];
2483          char *varstr;
2484          varname[k] = 0;
2485          varstr = expand_var(varname,buf);
2486          far_strncpy(target+j,varstr,MAXCMT-j-1);
2487          j += strlen(varstr);
2488       }
2489       else if (c == esc_char && escape != 0 && oldc != '\\')
2490          k = 0;
2491       else if ((c != esc_char || oldc == '\\') && escape == 0)
2492          *(target+j++) = c;
2493       oldc = c;
2494    }
2495    if(*source != '\0')
2496       *(target+min(j,MAXCMT-1)) = '\0';
2497 }
2498 
2499 /* extract comments from the comments= command */
parse_comments(char * value)2500 void parse_comments(char *value)
2501 {
2502    int i;
2503    char *next,save;
2504    for(i=0;i<4;i++)
2505    {
2506       save = '\0';
2507       if (*value == 0)
2508          break;
2509       next = strchr(value,'/');
2510       if (*value != '/')
2511       {
2512          if(next != NULL)
2513          {
2514             save = *next;
2515             *next = '\0';
2516          }
2517          far_strncpy(par_comment[i],value, MAXCMT);
2518       }
2519       if(next == NULL)
2520          break;
2521       if(save != '\0')
2522          *next = save;
2523       value = next+1;
2524    }
2525 }
2526 
init_comments()2527 void init_comments()
2528 {
2529    int i;
2530    for(i=0;i<4;i++)
2531       par_comment[i][0] = '\0';
2532 }
2533