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( <ime );
2358 str = ctime(<ime);
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