File: common\miscovl.c

    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 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[14]; 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) 171 { /* colors match colorfile */ 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, 12); 185 colorspec[13] = 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 (patchlevel != 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 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 if(soundflag != 9) { 1026 if((soundflag&7) == 0) 1027 put_parm(s_seqs,s_sound,s_off); 1028 else if((soundflag&7) == 1) 1029 put_parm(s_seqs,s_sound,s_beep); 1030 else if((soundflag&7) == 2) 1031 put_parm(s_seqs,s_sound,s_x); 1032 else if((soundflag&7) == 3) 1033 put_parm(s_seqs,s_sound,s_y); 1034 else if((soundflag&7) == 4) 1035 put_parm(s_seqs,s_sound,s_z); 1036 #ifndef XFRACT 1037 if((soundflag&7) && (soundflag&7) <=4) { 1038 if(soundflag&8) 1039 put_parm("/pc"); 1040 if(soundflag&16) 1041 put_parm("/fm"); 1042 if(soundflag&32) 1043 put_parm("/midi"); 1044 if(soundflag&64) 1045 put_parm("/quant"); 1046 } 1047 #endif 1048 } 1049 1050 #ifndef XFRACT 1051 if(fm_vol != 63) 1052 put_parm(s_seqd,s_volume,fm_vol); 1053 1054 if(hi_atten != 0) { 1055 if(hi_atten == 1) 1056 put_parm(s_seqs,s_atten,s_low); 1057 else if(hi_atten == 2) 1058 put_parm(s_seqs,s_atten,s_mid); 1059 else if(hi_atten == 3) 1060 put_parm(s_seqs,s_atten,s_high); 1061 else /* just in case */ 1062 put_parm(s_seqs,s_atten,s_none); 1063 } 1064 1065 if(polyphony != 0) 1066 put_parm(s_seqd,s_polyphony,polyphony+1); 1067 1068 if(fm_wavetype !=0) 1069 put_parm(s_seqd,s_wavetype,fm_wavetype); 1070 1071 if(fm_attack != 5) 1072 put_parm(s_seqd,s_attack,fm_attack); 1073 1074 if(fm_decay != 10) 1075 put_parm(s_seqd,s_decay,fm_decay); 1076 1077 if(fm_sustain != 13) 1078 put_parm(s_seqd,s_sustain,fm_sustain); 1079 1080 if(fm_release != 5) 1081 put_parm(s_seqd,s_srelease,fm_release); 1082 1083 if(soundflag&64) { /* quantize turned on */ 1084 for(i=0;i<=11;i++) if(scale_map[i] != i+1) i=15; 1085 if(i>12) 1086 put_parm(s_seqd12,s_scalemap,scale_map[0],scale_map[1],scale_map[2],scale_map[3] 1087 ,scale_map[4],scale_map[5],scale_map[6],scale_map[7],scale_map[8] 1088 ,scale_map[9],scale_map[10],scale_map[11]); 1089 } 1090 1091 #endif 1092 1093 if(nobof > 0) 1094 put_parm(s_seqs,s_nobof,s_yes); 1095 1096 if(orbit_delay > 0) 1097 put_parm(s_seqd,s_orbitdelay,orbit_delay); 1098 1099 if(orbit_interval != 1) 1100 put_parm(s_seqd,s_orbitinterval,orbit_interval); 1101 1102 if(start_showorbit > 0) 1103 put_parm(s_seqs,s_showorbit,s_yes); 1104 1105 if (keep_scrn_coords) 1106 put_parm(s_seqs,s_screencoords,s_yes); 1107 1108 if (usr_stdcalcmode == 'o' && set_orbit_corners && keep_scrn_coords) 1109 { 1110 int xdigits,ydigits; 1111 put_parm( " %s=",s_orbitcorners); 1112 xdigits = getprec(oxmin,oxmax,ox3rd); 1113 ydigits = getprec(oymin,oymax,oy3rd); 1114 put_float(0,oxmin,xdigits); 1115 put_float(1,oxmax,xdigits); 1116 put_float(1,oymin,ydigits); 1117 put_float(1,oymax,ydigits); 1118 if (ox3rd != oxmin || oy3rd != oymin) 1119 { 1120 put_float(1,ox3rd,xdigits); 1121 put_float(1,oy3rd,ydigits); 1122 } 1123 } 1124 1125 if (drawmode != 'r') 1126 put_parm(" %s=%c",s_orbitdrawmode, drawmode); 1127 1128 if (math_tol[0] != 0.05 || math_tol[1] != 0.05) 1129 put_parm(" %s=%g/%g",s_mathtolerance,math_tol[0],math_tol[1]); 1130 1131 } 1132 1133 if (*colorinf != 'n') 1134 { 1135 if(recordcolors=='c' && *colorinf == '@') 1136 { 1137 put_parm_line(); 1138 put_parm("; %s=",s_colors); 1139 put_parm(colorinf); 1140 put_parm_line(); 1141 } 1142 docolors: 1143 put_parm(" %s=",s_colors); 1144 if (recordcolors !='c' && recordcolors != 'y' && *colorinf == '@') 1145 put_parm(colorinf); 1146 else { 1147 int curc,scanc,force,diffmag = -1; 1148 int delta,diff1[4][3],diff2[4][3]; 1149 curc = force = 0; 1150 #ifdef XFRACT
1151 if (fake_lut && !truemode) loaddac(); /* stupid kludge JCO 6/23/2001 */
1152 #endif 1153 for(;;) { 1154 /* emit color in rgb 3 char encoded form */ 1155 for (j = 0; j < 3; ++j) { 1156 if ((k = dacbox[curc][j]) < 10) k += '0'; 1157 else if (k < 36) k += ('A' - 10); 1158 else k += ('_' - 36); 1159 buf[j] = (char)k; 1160 } 1161 buf[3] = 0; 1162 put_parm(buf); 1163 if (++curc >= maxcolor) /* quit if done last color */ 1164 break; 1165 if(debugflag == 920) /* lossless compression */ 1166 continue; 1167 /* Next a P Branderhorst special, a tricky scan for smooth-shaded 1168 ranges which can be written as <nn> to compress .par file entry. 1169 Method used is to check net change in each color value over 1170 spans of 2 to 5 color numbers. First time for each span size 1171 the value change is noted. After first time the change is 1172 checked against noted change. First time it differs, a 1173 a difference of 1 is tolerated and noted as an alternate 1174 acceptable change. When change is not one of the tolerated 1175 values, loop exits. */ 1176 if (force) { 1177 --force; 1178 continue; 1179 } 1180 scanc = curc; 1181 while (scanc < maxcolor) { /* scan while same diff to next */ 1182 if ((i = scanc - curc) > 3) /* check spans up to 4 steps */ 1183 i = 3; 1184 for (k = 0; k <= i; ++k) { 1185 for (j = 0; j < 3; ++j) { /* check pattern of chg per color */ 1186 /* Sylvie Gallet's fix */ 1187 if (debugflag != 910 && scanc > (curc+4) && scanc < maxcolor-5) 1188 if (abs(2*dacbox[scanc][j] - dacbox[scanc-5][j] 1189 - dacbox[scanc+5][j]) >= 2) 1190 break; 1191 /* end Sylvie's fix */ 1192 delta = (int)dacbox[scanc][j] - (int)dacbox[scanc-k-1][j]; 1193 if (k == scanc - curc) 1194 diff1[k][j] = diff2[k][j] = delta; 1195 else 1196 if (delta != diff1[k][j] && delta != diff2[k][j]) { 1197 diffmag = abs(delta - diff1[k][j]); 1198 if (diff1[k][j] != diff2[k][j] || diffmag != 1) 1199 break; 1200 diff2[k][j] = delta; 1201 } 1202 } 1203 if (j < 3) break; /* must've exited from inner loop above */ 1204 } 1205 if (k <= i) break; /* must've exited from inner loop above */ 1206 ++scanc; 1207 } 1208 /* now scanc-1 is next color which must be written explicitly */ 1209 if (scanc - curc > 2) { /* good, we have a shaded range */ 1210 if (scanc != maxcolor) { 1211 if (diffmag < 3) { /* not a sharp slope change? */ 1212 force = 2; /* force more between ranges, to stop */ 1213 --scanc; /* "drift" when load/store/load/store/ */ 1214 } 1215 if (k) { /* more of the same */ 1216 force += k; 1217 --scanc; 1218 } 1219 } 1220 if (--scanc - curc > 1) { 1221 put_parm("<%d>",scanc-curc); 1222 curc = scanc; 1223 } 1224 else /* changed our mind */ 1225 force = 0; 1226 } 1227 } 1228 } 1229 } 1230 1231 while (wbdata->len) /* flush the buffer */ 1232 put_parm_line(); 1233 /* restore previous boxx data from extraseg */ 1234 far_memcpy(boxx, saveshared, 10000); 1235 restore_stack(saved); 1236 } 1237 1238 static void put_filename(char *keyword,char *fname) 1239 { 1240 char *p; 1241 if (*fname && !endswithslash(fname)) { 1242 if ((p = strrchr(fname, SLASHC)) != NULL) 1243 if (*(fname = p+1) == 0) return; 1244 put_parm(s_seqs,keyword,fname); 1245 } 1246 } 1247 1248 #ifndef USE_VARARGS 1249 static void put_parm(char *parm,...)
1250 #else 1251 static void put_parm(va_alist) 1252 va_dcl
1253 #endif 1254 { 1255 char *bufptr; 1256 va_list args; 1257 1258 #ifndef USE_VARARGS 1259 va_start(args,parm);
1260 #else 1261 char * parm; 1262 1263 va_start(args); 1264 parm = va_arg(args,char *);
1265 #endif 1266 if (*parm == ' ' /* starting a new parm */ 1267 && wbdata->len == 0) /* skip leading space */ 1268 ++parm; 1269 bufptr = wbdata->buf + wbdata->len; 1270 vsprintf(bufptr,parm,args); 1271 while (*(bufptr++)) 1272 ++wbdata->len; 1273 while (wbdata->len > 200) 1274 put_parm_line(); 1275 } 1276 1277 int maxlinelength=72; 1278 #define MAXLINELEN maxlinelength 1279 #define NICELINELEN (MAXLINELEN-4) 1280 1281 static void put_parm_line() 1282 { 1283 int len,c; 1284 if ((len = wbdata->len) > NICELINELEN) { 1285 len = NICELINELEN+1; 1286 while (--len != 0 && wbdata->buf[len] != ' ') { } 1287 if (len == 0) { 1288 len = NICELINELEN-1; 1289 while (++len < MAXLINELEN 1290 && wbdata->buf[len] && wbdata->buf[len] != ' ') { } 1291 } 1292 } 1293 c = wbdata->buf[len]; 1294 wbdata->buf[len] = 0; 1295 fputs(" ",parmfile); 1296 fputs(wbdata->buf,parmfile); 1297 if (c && c != ' ') 1298 fputc('\\',parmfile); 1299 fputc('\n',parmfile); 1300 if ((wbdata->buf[len] = (char)c) == ' ') 1301 ++len; 1302 wbdata->len -= len; 1303 strcpy(wbdata->buf,wbdata->buf+len); 1304 } 1305 1306 int getprecbf_mag() 1307 { 1308 double Xmagfactor, Rotation, Skew; 1309 LDBL Magnification; 1310 bf_t bXctr, bYctr; 1311 int saved,dec; 1312 1313 saved = save_stack(); 1314 bXctr = alloc_stack(bflength+2); 1315 bYctr = alloc_stack(bflength+2); 1316 /* this is just to find Magnification */ 1317 cvtcentermagbf(bXctr, bYctr, &Magnification, &Xmagfactor, &Rotation, &Skew); 1318 restore_stack(saved); 1319 1320 /* I don't know if this is portable, but something needs to */ 1321 /* be used in case compiler's LDBL_MAX is not big enough */ 1322 if (Magnification > LDBL_MAX || Magnification < -LDBL_MAX) 1323 return(-1); 1324 1325 dec = getpower10(Magnification) + 4; /* 4 digits of padding sounds good */ 1326 return(dec); 1327 } 1328 1329 static int getprec(double a,double b,double c) 1330 { 1331 double diff,temp; 1332 int digits; 1333 double highv = 1.0E20; 1334 if ((diff = fabs(a - b)) == 0.0) diff = highv; 1335 if ((temp = fabs(a - c)) == 0.0) temp = highv; 1336 if (temp < diff) diff = temp; 1337 if ((temp = fabs(b - c)) == 0.0) temp = highv; 1338 if (temp < diff) diff = temp; 1339 digits = 7; 1340 if(debugflag >= 700 && debugflag < 720 ) 1341 digits = debugflag - 700; 1342 while (diff < 1.0 && digits <= DBL_DIG+1) { 1343 diff *= 10; 1344 ++digits; 1345 } 1346 return(digits); 1347 } 1348 1349 /* This function calculates the precision needed to distiguish adjacent 1350 pixels at Fractint's maximum resolution of MAXPIXELS by MAXPIXELS 1351 (if rez==MAXREZ) or at current resolution (if rez==CURRENTREZ) */ 1352 int getprecbf(int rezflag) 1353 { 1354 bf_t del1,del2, one, bfxxdel, bfxxdel2, bfyydel, bfyydel2; 1355 int digits,dec; 1356 int saved; 1357 int rez; 1358 saved = save_stack(); 1359 del1 = alloc_stack(bflength+2); 1360 del2 = alloc_stack(bflength+2); 1361 one = alloc_stack(bflength+2); 1362 bfxxdel = alloc_stack(bflength+2); 1363 bfxxdel2 = alloc_stack(bflength+2); 1364 bfyydel = alloc_stack(bflength+2); 1365 bfyydel2 = alloc_stack(bflength+2); 1366 floattobf(one,1.0); 1367 if(rezflag == MAXREZ) 1368 rez = OLDMAXPIXELS -1; 1369 else 1370 rez = xdots-1; 1371 1372 /* bfxxdel = (bfxmax - bfx3rd)/(xdots-1) */ 1373 sub_bf(bfxxdel, bfxmax, bfx3rd); 1374 div_a_bf_int(bfxxdel, (U16)rez); 1375 1376 /* bfyydel2 = (bfy3rd - bfymin)/(xdots-1) */ 1377 sub_bf(bfyydel2, bfy3rd, bfymin); 1378 div_a_bf_int(bfyydel2, (U16)rez); 1379 1380 if(rezflag == CURRENTREZ) 1381 rez = ydots-1; 1382 1383 /* bfyydel = (bfymax - bfy3rd)/(ydots-1) */ 1384 sub_bf(bfyydel, bfymax, bfy3rd); 1385 div_a_bf_int(bfyydel, (U16)rez); 1386 1387 /* bfxxdel2 = (bfx3rd - bfxmin)/(ydots-1) */ 1388 sub_bf(bfxxdel2, bfx3rd, bfxmin); 1389 div_a_bf_int(bfxxdel2, (U16)rez); 1390 1391 abs_a_bf(add_bf(del1,bfxxdel,bfxxdel2)); 1392 abs_a_bf(add_bf(del2,bfyydel,bfyydel2)); 1393 if(cmp_bf(del2,del1) < 0) 1394 copy_bf(del1, del2); 1395 if(cmp_bf(del1,clear_bf(del2)) == 0) 1396 { 1397 restore_stack(saved); 1398 return(-1); 1399 } 1400 digits = 1; 1401 while(cmp_bf(del1,one) < 0) 1402 { 1403 digits++; 1404 mult_a_bf_int(del1,10); 1405 } 1406 digits = max(digits,3); 1407 restore_stack(saved); 1408 dec = getprecbf_mag(); 1409 return(max(digits,dec)); 1410 } 1411 1412 #ifdef _MSC_VER 1413 #pragma optimize("e",off) /* MSC 7.00 messes up next with "e" on */ 1414 #endif 1415 1416 /* This function calculates the precision needed to distiguish adjacent 1417 pixels at Fractint's maximum resolution of MAXPIXELS by MAXPIXELS 1418 (if rez==MAXREZ) or at current resolution (if rez==CURRENTREZ) */ 1419 int getprecdbl(int rezflag) 1420 { 1421 LDBL del1,del2, xdel, xdel2, ydel, ydel2; 1422 int digits; 1423 LDBL rez; 1424 if(rezflag == MAXREZ) 1425 rez = OLDMAXPIXELS -1; 1426 else 1427 rez = xdots-1; 1428 1429 xdel = ((LDBL)xxmax - (LDBL)xx3rd)/rez; 1430 ydel2 = ((LDBL)yy3rd - (LDBL)yymin)/rez; 1431 1432 if(rezflag == CURRENTREZ) 1433 rez = ydots-1; 1434 1435 ydel = ((LDBL)yymax - (LDBL)yy3rd)/rez; 1436 xdel2 = ((LDBL)xx3rd - (LDBL)xxmin)/rez; 1437 1438 del1 = fabsl(xdel) + fabsl(xdel2); 1439 del2 = fabsl(ydel) + fabsl(ydel2); 1440 if(del2 < del1) 1441 del1 = del2; 1442 if(del1 == 0) 1443 { 1444 #ifdef DEBUG
1445 showcornersdbl("getprecdbl");
1446 #endif 1447 return(-1); 1448 } 1449 digits = 1; 1450 while(del1 < 1.0) 1451 { 1452 digits++; 1453 del1 *= 10; 1454 } 1455 digits = max(digits,3); 1456 return(digits); 1457 } 1458 1459 #ifdef _MSC_VER 1460 #pragma optimize("e",on) 1461 #endif 1462 1463 /* 1464 Strips zeros from the non-exponent part of a number. This logic 1465 was originally in put_bf(), but is split into this routine so it can be 1466 shared with put_float(), which had a bug in Fractint 19.2 (used to strip 1467 zeros from the exponent as well.) 1468 */ 1469 1470 static void strip_zeros(char *buf) 1471 { 1472 char *dptr, *bptr, *exptr; 1473 strlwr(buf); 1474 if ((dptr = strchr(buf,'.')) != 0) { 1475 ++dptr; 1476 if ((exptr = strchr(buf,'e')) !=0) /* scientific notation with 'e'? */ 1477 bptr = exptr; 1478 else 1479 bptr = buf + strlen(buf); 1480 while (--bptr > dptr && *bptr == '0') 1481 *bptr = 0; 1482 if(exptr && bptr < exptr -1) 1483 strcat(buf,exptr); 1484 } 1485 } 1486 1487 static void put_float(int slash,double fnum,int prec) 1488 { char buf[40]; 1489 char *bptr; 1490 bptr = buf; 1491 if (slash) 1492 *(bptr++) = '/'; 1493 /* sprintf(bptr,"%1.*f",prec,fnum); */ 1494 #ifdef USE_LONG_DOUBLE 1495 /* Idea of long double cast is to squeeze out another digit or two 1496 which might be needed (we have found cases where this digit makes 1497 a difference.) But lets not do this at lower precision */ 1498 if(prec > 15) 1499 sprintf(bptr,"%1.*Lg",prec,(long double)fnum); 1500 else 1501 #endif 1502 sprintf(bptr,"%1.*g",prec,(double)fnum); 1503 strip_zeros(bptr); 1504 put_parm(buf); 1505 } 1506 1507 static void put_bf(int slash,bf_t r, int prec) 1508 { 1509 char *buf; /* "/-1.xxxxxxE-1234" */ 1510 char *bptr; 1511 /* buf = malloc(decimals+11); */ 1512 buf = wbdata->buf+5000; /* end of use suffix buffer, 5000 bytes safe */ 1513 bptr = buf; 1514 if (slash) 1515 *(bptr++) = '/'; 1516 bftostr(bptr, prec, r); 1517 strip_zeros(bptr); 1518 put_parm(buf); 1519 } 1520 1521 #ifndef XFRACT 1522 #include <direct.h> 1523 void shell_to_dos() 1524 { 1525 int drv; 1526 char *comspec; 1527 char curdir[FILE_MAX_DIR],*s; 1528 if ((comspec = getenv("COMSPEC")) == NULL) 1529 printf("Cannot find COMMAND.COM.\n"); 1530 else { 1531 putenv("PROMPT='EXIT' returns to FRACTINT.$_$p$g"); 1532 s = getcwd(curdir,100); 1533 drv = _getdrive(); 1534 spawnl(P_WAIT, comspec, NULL); 1535 if(drv) 1536 _chdrive(drv); 1537 if(s) 1538 chdir(s); 1539 } 1540 } 1541 1542 size_t showstack(void) 1543 { 1544 return(stackavail()); 1545 } 1546 1547 long fr_farfree(void) 1548 { 1549 long j,j2; 1550 BYTE huge *fartempptr; 1551 j = 0; 1552 j2 = 0x80000L; 1553 while ((j2 >>= 1) != 0) 1554 if ((fartempptr = (BYTE huge *)farmemalloc(j+j2)) != NULL) { 1555 farmemfree((void far*)fartempptr); 1556 j += j2; 1557 } 1558 return(j); 1559 } 1560 1561 void showfreemem(void) 1562 { 1563 char *tempptr; 1564 unsigned i,i2; 1565 1566 char adapter_name[8]; /* entry lenth from VIDEO.ASM */ 1567 char *adapter_ptr; 1568 1569 printf("\n CPU type: %d FPU type: %d Video: %d", 1570 cpu, fpu, video_type); 1571 1572 adapter_ptr = &supervga_list; 1573 1574 for(i = 0 ; ; i++) { /* find the SuperVGA entry */ 1575 int j; 1576 memcpy(adapter_name , adapter_ptr, 8); 1577 adapter_ptr += 8; 1578 if (adapter_name[0] == ' ') break; /* end-of-the-list */ 1579 if (adapter_name[6] == 0) continue; /* not our adapter */ 1580 adapter_name[6] = ' '; 1581 for (j = 0; j < 8; j++) 1582 if(adapter_name[j] == ' ') 1583 adapter_name[j] = 0; 1584 printf(" Video chip: %d (%s)",i+1,adapter_name); 1585 } 1586 printf("\n\n"); 1587 1588 i = 0; 1589 i2 = 0x8000; 1590 while ((i2 >>= 1) != 0) 1591 if ((tempptr = malloc(i+i2)) != NULL) { 1592 free(tempptr); 1593 i += i2; 1594 } 1595 printf(" %d NEAR bytes free \n", i); 1596 1597 printf(" %ld FAR bytes free ", fr_farfree()); 1598 { 1599 size_t stack; 1600 stack = showstack(); 1601 /* if(stack >= 0) */ /* stack is unsigned */ 1602 printf("\n %u STACK bytes free",stack); 1603 } 1604 printf("\n %ld used by HISTORY structure", 1605 sizeof(HISTORY)*(unsigned long)maxhistory); 1606 printf("\n %d video table used",showvidlength()); 1607 printf("\n\n %Fs...\n",s_pressanykeytocontinue); 1608 getakey(); 1609 } 1610 #endif 1611 1612 int edit_text_colors() 1613 { 1614 int save_debugflag,save_lookatmouse; 1615 int row,col,bkgrd; 1616 int rowf,colf,rowt,colt; 1617 char far *vidmem; 1618 char far *savescreen; 1619 char far *farp1; char far *farp2; 1620 int i,j,k; 1621 save_debugflag = debugflag; 1622 save_lookatmouse = lookatmouse; 1623 debugflag = 0; /* don't get called recursively */ 1624 lookatmouse = 2; /* text mouse sensitivity */ 1625 row = col = bkgrd = rowt = rowf = colt = colf = 0; 1626 vidmem = MK_FP(0xB800,0); 1627 for(;;) { 1628 if (row < 0) row = 0; 1629 if (row > 24) row = 24; 1630 if (col < 0) col = 0; 1631 if (col > 79) col = 79; 1632 movecursor(row,col); 1633 i = getakey(); 1634 if (i >= 'a' && i <= 'z') i -= 32; /* uppercase */ 1635 switch (i) { 1636 case 27: /* esc */ 1637 debugflag = save_debugflag; 1638 lookatmouse = save_lookatmouse; 1639 movecursor(25,80); 1640 return 0; 1641 case '/': 1642 farp1 = savescreen = (char far *)farmemalloc(4000L); 1643 farp2 = vidmem; 1644 for (i = 0; i < 4000; ++i) { /* save and blank */ 1645 *(farp1++) = *farp2; 1646 *(farp2++) = 0; 1647 } 1648 for (i = 0; i < 8; ++i) /* 8 bkgrd attrs */ 1649 for (j = 0; j < 16; ++j) { /* 16 fgrd attrs */ 1650 k = i*16 + j; 1651 farp1 = vidmem + i*320 + j*10; 1652 *(farp1++) = ' '; *(farp1++) = (char)k; 1653 *(farp1++) = (char)(i+'0'); *(farp1++) = (char)k; 1654 *(farp1++) = (char)((j < 10) ? j+'0' : j+'A'-10); *(farp1++) = (char)k; 1655 *(farp1++) = ' '; *(farp1++) = (char)k; 1656 } 1657 getakey(); 1658 farp1 = vidmem; 1659 farp2 = savescreen; 1660 for (i = 0; i < 4000; ++i) /* restore */ 1661 *(farp1++) = *(farp2++); 1662 farmemfree(savescreen); 1663 break; 1664 case ',': 1665 rowf = row; colf = col; break; 1666 case '.': 1667 rowt = row; colt = col; break; 1668 case ' ': /* next color is background */ 1669 bkgrd = 1; break; 1670 case 1075: /* cursor left */ 1671 --col; break; 1672 case 1077: /* cursor right */ 1673 ++col; break; 1674 case 1072: /* cursor up */ 1675 --row; break; 1676 case 1080: /* cursor down */ 1677 ++row; break; 1678 case 13: /* enter */ 1679 *(vidmem + row*160 + col*2) = (char)getakey(); 1680 break; 1681 default: 1682 if (i >= '0' && i <= '9') i -= '0'; 1683 else if (i >= 'A' && i <= 'F') i -= 'A'-10; 1684 else break; 1685 for (j = rowf; j <= rowt; ++j) 1686 for (k = colf; k <= colt; ++k) { 1687 farp1 = vidmem + j*160 + k*2 + 1; 1688 if (bkgrd) *farp1 = (char)((*farp1 & 15) + i * 16); 1689 else *farp1 = (char)((*farp1 & 0xf0) + i); 1690 } 1691 bkgrd = 0; 1692 } 1693 } 1694 } 1695 1696 static int *entsptr; 1697 static int modes_changed; 1698 1699 int select_video_mode(int curmode) 1700 { 1701 static FCODE o_hdg2[]={"key...name.......................xdot..ydot.colr.comment.................."}; 1702 static FCODE o_hdg1[]={"Select Video Mode"}; 1703 char hdg2[sizeof(o_hdg2)]; 1704 char hdg1[sizeof(o_hdg1)]; 1705 1706 int entnums[MAXVIDEOMODES]; 1707 int attributes[MAXVIDEOMODES]; 1708 int i,k,ret; 1709 #ifndef XFRACT 1710 int j; 1711 int oldtabmode,oldhelpmode; 1712 #endif 1713 1714 load_fractint_cfg(0); /* load fractint.cfg to extraseg */ 1715 1716 far_strcpy(hdg1,o_hdg1); 1717 far_strcpy(hdg2,o_hdg2); 1718 1719 for (i = 0; i < vidtbllen; ++i) { /* init tables */ 1720 entnums[i] = i; 1721 attributes[i] = 1; 1722 } 1723 entsptr = entnums; /* for indirectly called subroutines */ 1724 1725 qsort(entnums,vidtbllen,sizeof(entnums[0]),entcompare); /* sort modes */ 1726 1727 /* pick default mode */ 1728 if (curmode < 0) { 1729 switch (video_type) { /* set up a reasonable default (we hope) */ 1730 case 1: videoentry.videomodeax = 8; /* hgc */ 1731 videoentry.colors = 2; 1732 break; 1733 case 2: videoentry.videomodeax = 4; /* cga */ 1734 videoentry.colors = 4; 1735 break; 1736 case 3: videoentry.videomodeax = 16; /* ega */ 1737 videoentry.colors = 16; 1738 if (mode7text) { /* egamono */ 1739 videoentry.videomodeax = 15; 1740 videoentry.colors = 2; 1741 } 1742 break; 1743 default: videoentry.videomodeax = 19; /* mcga/vga? */ 1744 videoentry.colors = 256; 1745 break; 1746 } 1747 } 1748 else 1749 far_memcpy((char far *)&videoentry,(char far *)&videotable[curmode], 1750 sizeof(videoentry)); 1751 #ifndef XFRACT 1752 for (i = 0; i < vidtbllen; ++i) { /* find default mode */ 1753 if ( videoentry.videomodeax == vidtbl[entnums[i]].videomodeax 1754 && videoentry.colors == vidtbl[entnums[i]].colors 1755 && (curmode < 0 1756 || far_memcmp((char far *)&videoentry,(char far *)&vidtbl[entnums[i]], 1757 sizeof(videoentry)) == 0)) 1758 break; 1759 } 1760 if (i >= vidtbllen) /* no match, default to first entry */ 1761 i = 0; 1762 1763 oldtabmode = tabmode; 1764 oldhelpmode = helpmode; 1765 modes_changed = 0; 1766 tabmode = 0; 1767 helpmode = HELPVIDSEL; 1768 i = fullscreen_choice(CHOICEHELP,hdg1,hdg2,NULL,vidtbllen,NULL,attributes, 1769 1,16,74,i,format_vid_table,NULL,NULL,check_modekey); 1770 tabmode = oldtabmode; 1771 helpmode = oldhelpmode; 1772 if (i == -1) { 1773 static FCODE msg[]={"Save new function key assignments or cancel changes?"}; 1774 if (modes_changed /* update fractint.cfg for new key assignments */ 1775 && badconfig == 0 1776 && stopmsg(22,msg) == 0) 1777 update_fractint_cfg(); 1778 return(-1); 1779 } 1780 if (i < 0) /* picked by function key */ 1781 i = -1 - i; 1782 else /* picked by Enter key */ 1783 i = entnums[i]; 1784 #endif 1785 far_memcpy((char far *)&videoentry,(char far *)&vidtbl[i], 1786 sizeof(videoentry)); /* the selected entry now in videoentry */ 1787 1788 #ifndef XFRACT 1789 /* copy fractint.cfg table to resident table, note selected entry */ 1790 j = k = 0; 1791 far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE); 1792 for (i = 0; i < vidtbllen; ++i) { 1793 if (vidtbl[i].keynum > 0) { 1794 far_memcpy((char far *)&videotable[j],(char far *)&vidtbl[i], 1795 sizeof(*vidtbl)); 1796 if (far_memcmp((char far *)&videoentry,(char far *)&vidtbl[i], 1797 sizeof(videoentry)) == 0) 1798 k = vidtbl[i].keynum; 1799 if (++j >= MAXVIDEOTABLE-1) 1800 break; 1801 } 1802 }
1803 #else 1804 k = vidtbl[0].keynum;
1805 #endif 1806 if ((ret = k) == 0) { /* selected entry not a copied (assigned to key) one */ 1807 far_memcpy((char far *)&videotable[MAXVIDEOTABLE-1], 1808 (char far *)&videoentry,sizeof(*vidtbl)); 1809 ret = 1400; /* special value for check_vidmode_key */ 1810 } 1811 1812 if (modes_changed /* update fractint.cfg for new key assignments */ 1813 && badconfig == 0) 1814 update_fractint_cfg(); 1815 1816 return(ret); 1817 } 1818 1819 void format_vid_table(int choice,char *buf) 1820 { 1821 char local_buf[81]; 1822 char kname[5]; 1823 char biosflag; 1824 int truecolorbits; 1825 far_memcpy((char far *)&videoentry,(char far *)&vidtbl[entsptr[choice]], 1826 sizeof(videoentry)); 1827 vidmode_keyname(videoentry.keynum,kname); 1828 biosflag = (char)((videoentry.dotmode % 100 == 1) ? 'B' : ' '); 1829 sprintf(buf,"%-5s %-25s %5d %5d ", /* 44 chars */ 1830 kname, videoentry.name, videoentry.xdots, videoentry.ydots); 1831 if((truecolorbits = videoentry.dotmode/1000) == 0) 1832 sprintf(local_buf,"%s%3d", /* 47 chars */ 1833 buf, videoentry.colors); 1834 else 1835 sprintf(local_buf,"%s%3s", /* 47 chars */ 1836 buf, (truecolorbits == 4)?" 4g": 1837 (truecolorbits == 3)?"16m": 1838 (truecolorbits == 2)?"64k": 1839 (truecolorbits == 1)?"32k":"???"); 1840 sprintf(buf,"%s%c %-25s", /* 74 chars */ 1841 local_buf, biosflag, videoentry.comment); 1842 } 1843 1844 #ifndef XFRACT 1845 static int check_modekey(int curkey,int choice) 1846 { 1847 int i,j,k,ret; 1848 if ((i = check_vidmode_key(1,curkey)) >= 0) 1849 return(-1-i); 1850 i = entsptr[choice]; 1851 ret = 0; 1852 if ( (curkey == '-' || curkey == '+') 1853 && (vidtbl[i].keynum == 0 || vidtbl[i].keynum >= 1084)) { 1854 static FCODE msg[]={"Missing or bad FRACTINT.CFG file. Can't reassign keys."}; 1855 if (badconfig) 1856 stopmsg(0,msg); 1857 else { 1858 if (curkey == '-') { /* deassign key? */ 1859 if (vidtbl[i].keynum >= 1084) { 1860 vidtbl[i].keynum = 0; 1861 modes_changed = 1; 1862 } 1863 } 1864 else { /* assign key? */ 1865 j = getakeynohelp(); 1866 if (j >= 1084 && j <= 1113) { 1867 for (k = 0; k < vidtbllen; ++k) { 1868 if (vidtbl[k].keynum == j) { 1869 vidtbl[k].keynum = 0; 1870 ret = -1; /* force redisplay */ 1871 } 1872 } 1873 vidtbl[i].keynum = j; 1874 modes_changed = 1; 1875 } 1876 } 1877 } 1878 } 1879 return(ret); 1880 } 1881 #endif 1882 1883 static int entcompare(VOIDCONSTPTR p1,VOIDCONSTPTR p2) 1884 { 1885 int i,j; 1886 if ((i = vidtbl[*((int *)p1)].keynum) == 0) i = 9999; 1887 if ((j = vidtbl[*((int *)p2)].keynum) == 0) j = 9999; 1888 if (i < j || (i == j && *((int *)p1) < *((int *)p2))) 1889 return(-1); 1890 return(1); 1891 } 1892 1893 static void update_fractint_cfg() 1894 { 1895 #ifndef XFRACT 1896 char cfgname[100],outname[100],buf[121],kname[5]; 1897 FILE *cfgfile,*outfile; 1898 int far *cfglinenums; 1899 int i,j,linenum,nextlinenum,nextmode; 1900 struct videoinfo vident; 1901 1902 findpath("fractint.cfg",cfgname); 1903 1904 if (access(cfgname,6)) { 1905 sprintf(buf,s_cantwrite,cfgname); 1906 stopmsg(0,buf); 1907 return; 1908 } 1909 strcpy(outname,cfgname); 1910 i = strlen(outname); 1911 while (--i >= 0 && outname[i] != SLASHC) 1912 outname[i] = 0; 1913 strcat(outname,"fractint.tmp"); 1914 if ((outfile = fopen(outname,"w")) == NULL) { 1915 sprintf(buf,s_cantcreate,outname); 1916 stopmsg(0,buf); 1917 return; 1918 } 1919 cfgfile = fopen(cfgname,"r"); 1920 1921 cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]); 1922 linenum = nextmode = 0; 1923 nextlinenum = cfglinenums[0]; 1924 while (fgets(buf,120,cfgfile)) { 1925 int truecolorbits; 1926 char colorsbuf[10]; 1927 ++linenum; 1928 if (linenum == nextlinenum) { /* replace this line */ 1929 far_memcpy((char far *)&vident,(char far *)&vidtbl[nextmode], 1930 sizeof(videoentry)); 1931 vidmode_keyname(vident.keynum,kname); 1932 strcpy(buf,vident.name); 1933 i = strlen(buf); 1934 while (i && buf[i-1] == ' ') /* strip trailing spaces to compress */ 1935 --i; 1936 j = i + 5; 1937 while (j < 32) { /* tab to column 33 */ 1938 buf[i++] = '\t'; 1939 j += 8; 1940 } 1941 buf[i] = 0; 1942 if((truecolorbits = vident.dotmode/1000) == 0) 1943 sprintf(colorsbuf,"%3d",vident.colors); 1944 else 1945 sprintf(colorsbuf,"%3s", 1946 (truecolorbits == 4)?" 4g": 1947 (truecolorbits == 3)?"16m": 1948 (truecolorbits == 2)?"64k": 1949 (truecolorbits == 1)?"32k":"???"); 1950 fprintf(outfile,"%-4s,%s,%4x,%4x,%4x,%4x,%4d,%5d,%5d,%s,%s\n", 1951 kname, 1952 buf, 1953 vident.videomodeax, 1954 vident.videomodebx, 1955 vident.videomodecx, 1956 vident.videomodedx, 1957 vident.dotmode%1000, /* remove true-color flag, keep textsafe */ 1958 vident.xdots, 1959 vident.ydots, 1960 colorsbuf, 1961 vident.comment); 1962 if (++nextmode >= vidtbllen) 1963 nextlinenum = 32767; 1964 else 1965 nextlinenum = cfglinenums[nextmode]; 1966 } 1967 else 1968 fputs(buf,outfile); 1969 } 1970 1971 fclose(cfgfile); 1972 fclose(outfile); 1973 unlink(cfgname); /* success assumed on these lines */ 1974 rename(outname,cfgname); /* since we checked earlier with access */ 1975 #endif 1976 } 1977 1978 /* make_mig() takes a collection of individual GIF images (all 1979 presumably the same resolution and all presumably generated 1980 by Fractint and its "divide and conquer" algorithm) and builds 1981 a single multiple-image GIF out of them. This routine is 1982 invoked by the "batch=stitchmode/x/y" option, and is called 1983 with the 'x' and 'y' parameters 1984 */ 1985 1986 void make_mig(unsigned int xmult, unsigned int ymult) 1987 { 1988 unsigned int xstep, ystep; 1989 unsigned int xres, yres; 1990 unsigned int allxres, allyres, xtot, ytot; 1991 unsigned int xloc, yloc; 1992 unsigned char ichar; 1993 unsigned int allitbl, itbl; 1994 unsigned int i; 1995 char gifin[15], gifout[15]; 1996 int errorflag, inputerrorflag; 1997 unsigned char *temp; 1998 FILE *out, *in; 1999 char msgbuf[81]; 2000 2001 errorflag = 0; /* no errors so far */ 2002 inputerrorflag = 0; 2003 allxres = allyres = allitbl = 0; 2004 out = in = NULL; 2005 2006 strcpy(gifout,"fractmig.gif"); 2007 2008 temp= &olddacbox[0][0]; /* a safe place for our temp data */ 2009 2010 gif87a_flag = 1; /* for now, force this */ 2011 2012 /* process each input image, one at a time */ 2013 for (ystep = 0; ystep < ymult; ystep++) { 2014 for (xstep = 0; xstep < xmult; xstep++) { 2015 2016 if (xstep == 0 && ystep == 0) { /* first time through? */ 2017 static FCODE msg1[] = "Cannot create output file %s!\n"; 2018 static FCODE msg2[] = " \n Generating multi-image GIF file %s using"; 2019 static FCODE msg3[] = " %d X and %d Y components\n\n"; 2020 far_strcpy(msgbuf, msg2); 2021 printf(msgbuf, gifout); 2022 far_strcpy(msgbuf, msg3); 2023 printf(msgbuf, xmult, ymult); 2024 /* attempt to create the output file */ 2025 if ((out = fopen(gifout,"wb")) == NULL) { 2026 far_strcpy(msgbuf, msg1); 2027 printf(msgbuf, gifout); 2028 exit(1); 2029 } 2030 } 2031 2032 sprintf(gifin, "frmig_%c%c.gif", PAR_KEY(xstep), PAR_KEY(ystep)); 2033 2034 if ((in = fopen(gifin,"rb")) == NULL) { 2035 static FCODE msg1[] = "Can't open file %s!\n"; 2036 far_strcpy(msgbuf, msg1); 2037 printf(msgbuf, gifin); 2038 exit(1); 2039 } 2040 2041 /* (read, but only copy this if it's the first time through) */ 2042 if (fread(temp,13,1,in) != 1) /* read the header and LDS */ 2043 inputerrorflag = 1; 2044 memcpy(&xres, &temp[6], 2); /* X-resolution */ 2045 memcpy(&yres, &temp[8], 2); /* Y-resolution */ 2046 2047 if (xstep == 0 && ystep == 0) { /* first time through? */ 2048 allxres = xres; /* save the "master" resolution */ 2049 allyres = yres; 2050 xtot = xres * xmult; /* adjust the image size */ 2051 ytot = yres * ymult; 2052 memcpy(&temp[6], &xtot, 2); 2053 memcpy(&temp[8], &ytot, 2); 2054 if (gif87a_flag) { 2055 temp[3] = '8'; 2056 temp[4] = '7'; 2057 temp[5] = 'a'; 2058 } 2059 temp[12] = 0; /* reserved */ 2060 if (fwrite(temp,13,1,out) != 1) /* write out the header */ 2061 errorflag = 1; 2062 } /* end of first-time-through */ 2063 2064 2065 ichar = (char)(temp[10] & 0x07); /* find the color table size */ 2066 itbl = 1 << (++ichar); 2067 ichar = (char)(temp[10] & 0x80); /* is there a global color table? */ 2068 if (xstep == 0 && ystep == 0) /* first time through? */ 2069 allitbl = itbl; /* save the color table size */ 2070 if (ichar != 0) { /* yup */ 2071 /* (read, but only copy this if it's the first time through) */ 2072 if(fread(temp,3*itbl,1,in) != 1) /* read the global color table */ 2073 inputerrorflag = 2; 2074 if (xstep == 0 && ystep == 0) /* first time through? */ 2075 if (fwrite(temp,3*itbl,1,out) != 1) /* write out the GCT */ 2076 errorflag = 2; 2077 } 2078 2079 if (xres != allxres || yres != allyres || itbl != allitbl) { 2080 /* Oops - our pieces don't match */ 2081 static FCODE msg1[] = "File %s doesn't have the same resolution as its predecessors!\n"; 2082 far_strcpy(msgbuf, msg1); 2083 printf(msgbuf, gifin); 2084 exit(1); 2085 } 2086 2087 for (;;) { /* process each information block */ 2088 memset(temp,0,10); 2089 if (fread(temp,1,1,in) != 1) /* read the block identifier */ 2090 inputerrorflag = 3; 2091 2092 if (temp[0] == 0x2c) { /* image descriptor block */ 2093 if (fread(&temp[1],9,1,in) != 1) /* read the Image Descriptor */ 2094 inputerrorflag = 4; 2095 memcpy(&xloc, &temp[1], 2); /* X-location */ 2096 memcpy(&yloc, &temp[3], 2); /* Y-location */ 2097 xloc += (xstep * xres); /* adjust the locations */ 2098 yloc += (ystep * yres); 2099 memcpy(&temp[1], &xloc, 2); 2100 memcpy(&temp[3], &yloc, 2); 2101 if (fwrite(temp,10,1,out) != 1) /* write out the Image Descriptor */ 2102 errorflag = 4; 2103 2104 ichar = (char)(temp[9] & 0x80); /* is there a local color table? */ 2105 if (ichar != 0) { /* yup */ 2106 if (fread(temp,3*itbl,1,in) != 1) /* read the local color table */ 2107 inputerrorflag = 5; 2108 if (fwrite(temp,3*itbl,1,out) != 1) /* write out the LCT */ 2109 errorflag = 5; 2110 } 2111 2112 if (fread(temp,1,1,in) != 1) /* LZH table size */ 2113 inputerrorflag = 6; 2114 if (fwrite(temp,1,1,out) != 1) 2115 errorflag = 6; 2116 for(;;) { 2117 if (errorflag != 0 || inputerrorflag != 0) /* oops - did something go wrong? */ 2118 break; 2119 if (fread(temp,1,1,in) != 1) /* block size */ 2120 inputerrorflag = 7; 2121 if (fwrite(temp,1,1,out) != 1) 2122 errorflag = 7; 2123 if ((i = temp[0]) == 0) 2124 break; 2125 if (fread(temp,i,1,in) != 1) /* LZH data block */ 2126 inputerrorflag = 8; 2127 if (fwrite(temp,i,1,out) != 1) 2128 errorflag = 8; 2129 } 2130 } 2131 2132 if (temp[0] == 0x21) { /* extension block */ 2133 /* (read, but only copy this if it's the last time through) */ 2134 if (fread(&temp[2],1,1,in) != 1) /* read the block type */ 2135 inputerrorflag = 9; 2136 if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1) 2137 if (fwrite(temp,2,1,out) != 1) 2138 errorflag = 9; 2139 for(;;) { 2140 if (errorflag != 0 || inputerrorflag != 0) /* oops - did something go wrong? */ 2141 break; 2142 if (fread(temp,1,1,in) != 1) /* block size */ 2143 inputerrorflag = 10; 2144 if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1) 2145 if (fwrite(temp,1,1,out) != 1) 2146 errorflag = 10; 2147 if ((i = temp[0]) == 0) 2148 break; 2149 if (fread(temp,i,1,in) != 1) /* data block */ 2150 inputerrorflag = 11; 2151 if ((!gif87a_flag) && xstep == xmult-1 && ystep == ymult-1) 2152 if (fwrite(temp,i,1,out) != 1) 2153 errorflag = 11; 2154 } 2155 } 2156 2157 if (temp[0] == 0x3b) { /* end-of-stream indicator */ 2158 break; /* done with this file */ 2159 } 2160 2161 if (errorflag != 0 || inputerrorflag != 0) /* oops - did something go wrong? */ 2162 break; 2163 2164 } 2165 fclose(in); /* done with an input GIF */ 2166 2167 if (errorflag != 0 || inputerrorflag != 0) /* oops - did something go wrong? */ 2168 break; 2169 } 2170 2171 if (errorflag != 0 || inputerrorflag != 0) /* oops - did something go wrong? */ 2172 break; 2173 } 2174 2175 temp[0] = 0x3b; /* end-of-stream indicator */ 2176 if (fwrite(temp,1,1,out) != 1) 2177 errorflag = 12; 2178 fclose(out); /* done with the output GIF */ 2179 2180 if (inputerrorflag != 0) { /* uh-oh - something failed */ 2181 static FCODE msg1[] = "\007 Process failed = early EOF on input file %s\n"; 2182 far_strcpy(msgbuf, msg1); 2183 printf(msgbuf, gifin); 2184 /* following line was for debugging 2185 printf("inputerrorflag = %d\n", inputerrorflag); 2186 */ 2187 } 2188 2189 if (errorflag != 0) { /* uh-oh - something failed */ 2190 static FCODE msg1[] = "\007 Process failed = out of disk space?\n"; 2191 far_strcpy(msgbuf, msg1); 2192 printf(msgbuf); 2193 /* following line was for debugging 2194 printf("errorflag = %d\n", errorflag); 2195 */ 2196 } 2197 2198 /* now delete each input image, one at a time */ 2199 if (errorflag == 0 && inputerrorflag == 0) 2200 for (ystep = 0; ystep < ymult; ystep++) { 2201 for (xstep = 0; xstep < xmult; xstep++) { 2202 sprintf(gifin, "frmig_%c%c.gif", PAR_KEY(xstep), PAR_KEY(ystep)); 2203 remove(gifin); 2204 } 2205 } 2206 2207 /* tell the world we're done */ 2208 if (errorflag == 0 && inputerrorflag == 0) { 2209 static FCODE msg1[] = "File %s has been created (and its component files deleted)\n"; 2210 far_strcpy(msgbuf, msg1); 2211 printf(msgbuf, gifout); 2212 } 2213 } 2214 2215 /* This routine copies the current screen to by flipping x-axis, y-axis, 2216 or both. Refuses to work if calculation in progress or if fractal 2217 non-resumable. Clears zoombox if any. Resets corners so resulting fractal 2218 is still valid. */ 2219 void flip_image(int key) 2220 { 2221 int i, j, ixhalf, iyhalf, tempdot; 2222 2223 /* fractal must be rotate-able and be finished */ 2224 if ((curfractalspecific->flags&NOROTATE) != 0 2225 || calc_status == 1 2226 || calc_status == 2) 2227 return; 2228 if(bf_math) 2229 clear_zoombox(); /* clear, don't copy, the zoombox */ 2230 ixhalf = xdots / 2; 2231 iyhalf = ydots / 2; 2232 switch(key) 2233 { 2234 case 24: /* control-X - reverse X-axis */ 2235 for (i = 0; i < ixhalf; i++) 2236 { 2237 if(keypressed()) 2238 break; 2239 for (j = 0; j < ydots; j++) 2240 { 2241 tempdot=getcolor(i,j); 2242 putcolor(i, j, getcolor(xdots-1-i,j)); 2243 putcolor(xdots-1-i, j, tempdot); 2244 } 2245 } 2246 sxmin = xxmax + xxmin - xx3rd; 2247 symax = yymax + yymin - yy3rd; 2248 sxmax = xx3rd; 2249 symin = yy3rd; 2250 sx3rd = xxmax; 2251 sy3rd = yymin; 2252 if(bf_math) 2253 { 2254 add_bf(bfsxmin, bfxmax, bfxmin); /* sxmin = xxmax + xxmin - xx3rd; */ 2255 sub_a_bf(bfsxmin, bfx3rd); 2256 add_bf(bfsymax, bfymax, bfymin); /* symax = yymax + yymin - yy3rd; */ 2257 sub_a_bf(bfsymax, bfy3rd); 2258 copy_bf(bfsxmax, bfx3rd); /* sxmax = xx3rd; */ 2259 copy_bf(bfsymin, bfy3rd); /* symin = yy3rd; */ 2260 copy_bf(bfsx3rd, bfxmax); /* sx3rd = xxmax; */ 2261 copy_bf(bfsy3rd, bfymin); /* sy3rd = yymin; */ 2262 } 2263 break; 2264 case 25: /* control-Y - reverse Y-aXis */ 2265 for (j = 0; j < iyhalf; j++) 2266 { 2267 if(keypressed()) 2268 break; 2269 for (i = 0; i < xdots; i++) 2270 { 2271 tempdot=getcolor(i,j); 2272 putcolor(i, j, getcolor(i,ydots-1-j)); 2273 putcolor(i,ydots-1-j, tempdot); 2274 } 2275 } 2276 sxmin = xx3rd; 2277 symax = yy3rd; 2278 sxmax = xxmax + xxmin - xx3rd; 2279 symin = yymax + yymin - yy3rd; 2280 sx3rd = xxmin; 2281 sy3rd = yymax; 2282 if(bf_math) 2283 { 2284 copy_bf(bfsxmin, bfx3rd); /* sxmin = xx3rd; */ 2285 copy_bf(bfsymax, bfy3rd); /* symax = yy3rd; */ 2286 add_bf(bfsxmax, bfxmax, bfxmin); /* sxmax = xxmax + xxmin - xx3rd; */ 2287 sub_a_bf(bfsxmax, bfx3rd); 2288 add_bf(bfsymin, bfymax, bfymin); /* symin = yymax + yymin - yy3rd; */ 2289 sub_a_bf(bfsymin, bfy3rd); 2290 copy_bf(bfsx3rd, bfxmin); /* sx3rd = xxmin; */ 2291 copy_bf(bfsy3rd, bfymax); /* sy3rd = yymax; */ 2292 } 2293 break; 2294 case 26: /* control-Z - reverse X and Y aXis */ 2295 for (i = 0; i < ixhalf; i++) 2296 { 2297 if(keypressed()) 2298 break; 2299 for (j = 0; j < ydots; j++) 2300 { 2301 tempdot=getcolor(i,j); 2302 putcolor(i, j, getcolor(xdots-1-i,ydots-1-j)); 2303 putcolor(xdots-1-i, ydots-1-j, tempdot); 2304 } 2305 } 2306 sxmin = xxmax; 2307 symax = yymin; 2308 sxmax = xxmin; 2309 symin = yymax; 2310 sx3rd = xxmax + xxmin - xx3rd; 2311 sy3rd = yymax + yymin - yy3rd; 2312 if(bf_math) 2313 { 2314 copy_bf(bfsxmin, bfxmax); /* sxmin = xxmax; */ 2315 copy_bf(bfsymax, bfymin); /* symax = yymin; */ 2316 copy_bf(bfsxmax, bfxmin); /* sxmax = xxmin; */ 2317 copy_bf(bfsymin, bfymax); /* symin = yymax; */ 2318 add_bf(bfsx3rd, bfxmax, bfxmin); /* sx3rd = xxmax + xxmin - xx3rd; */ 2319 sub_a_bf(bfsx3rd, bfx3rd); 2320 add_bf(bfsy3rd, bfymax, bfymin); /* sy3rd = yymax + yymin - yy3rd; */ 2321 sub_a_bf(bfsy3rd, bfy3rd); 2322 } 2323 break; 2324 } 2325 reset_zoom_corners(); 2326 calc_status = 0; 2327 } 2328 static char *expand_var(char *var, char *buf) 2329 { 2330 static FCODE s_year [] = {"year" }; 2331 static FCODE s_month [] = {"month" }; 2332 static FCODE s_day [] = {"day" }; 2333 static FCODE s_hour [] = {"hour" }; 2334 static FCODE s_min [] = {"min" }; 2335 static FCODE s_sec [] = {"sec" }; 2336 static FCODE s_time [] = {"time" }; 2337 static FCODE s_date [] = {"date" }; 2338 static FCODE s_calctime[] = {"calctime"}; 2339 static FCODE s_version [] = {"version" }; 2340 static FCODE s_patch [] = {"patch" }; 2341 static FCODE s_xdots [] = {"xdots" }; 2342 static FCODE s_ydots [] = {"ydots" }; 2343 static FCODE s_vidkey [] = {"vidkey" }; 2344 2345 time_t ltime; 2346 char *str, *out; 2347 2348 time( &ltime ); 2349 str = ctime(&ltime); 2350 2351 /* ctime format */ 2352 /* Sat Aug 17 21:34:14 1996 */ 2353 /* 012345678901234567890123 */ 2354 /* 1 2 */ 2355 if(far_strcmp(var,s_year) == 0) /* 4 chars */ 2356 { 2357 str[24] = '\0'; 2358 out = &str[20]; 2359 } 2360 else if(far_strcmp(var,s_month) == 0) /* 3 chars */ 2361 { 2362 str[7] = '\0'; 2363 out = &str[4]; 2364 } 2365 else if(far_strcmp(var,s_day) == 0) /* 2 chars */ 2366 { 2367 str[10] = '\0'; 2368 out = &str[8]; 2369 } 2370 else if(far_strcmp(var,s_hour) == 0) /* 2 chars */ 2371 { 2372 str[13] = '\0'; 2373 out = &str[11]; 2374 } 2375 else if(far_strcmp(var,s_min) == 0) /* 2 chars */ 2376 { 2377 str[16] = '\0'; 2378 out = &str[14]; 2379 } 2380 else if(far_strcmp(var,s_sec) == 0) /* 2 chars */ 2381 { 2382 str[19] = '\0'; 2383 out = &str[17]; 2384 } 2385 else if(far_strcmp(var,s_time) == 0) /* 8 chars */ 2386 { 2387 str[19] = '\0'; 2388 out = &str[11]; 2389 } 2390 else if(far_strcmp(var,s_date) == 0) 2391 { 2392 str[10] = '\0'; 2393 str[24] = '\0'; 2394 out = &str[4]; 2395 strcat(out,", "); 2396 strcat(out,&str[20]); 2397 } 2398 else if(far_strcmp(var,s_calctime) == 0) 2399 { 2400 get_calculation_time(buf,calctime); 2401 out = buf; 2402 } 2403 else if(far_strcmp(var,s_version) == 0) /* 4 chars */ 2404 { 2405 sprintf(buf,"%d",release); 2406 out = buf; 2407 } 2408 else if(far_strcmp(var,s_patch) == 0) /* 1 or 2 chars */ 2409 { 2410 sprintf(buf,"%d",patchlevel); 2411 out = buf; 2412 } 2413 else if(far_strcmp(var,s_xdots) == 0) /* 2 to 4 chars */ 2414 { 2415 sprintf(buf,"%d",xdots); 2416 out = buf; 2417 } 2418 else if(far_strcmp(var,s_ydots) == 0) /* 2 to 4 chars */ 2419 { 2420 sprintf(buf,"%d",ydots); 2421 out = buf; 2422 } 2423 else if(far_strcmp(var,s_vidkey) == 0) /* 2 to 3 chars */ 2424 { 2425 char vidmde[5]; 2426 vidmode_keyname(videoentry.keynum, vidmde); 2427 sprintf(buf,"%s",vidmde); 2428 out = buf; 2429 } 2430 else 2431 { 2432 static char far msg[] = {"Unknown comment variable xxxxxxxxxxxxxxx"}; 2433 msg[25] = '\0'; 2434 far_strcat(msg,var); 2435 stopmsg(0,msg); 2436 out = ""; 2437 } 2438 return(out); 2439 } 2440 2441 #define MAXVNAME 13 2442 2443 static const char esc_char = '$'; 2444 2445 /* extract comments from the comments= command */ 2446 void expand_comments(char far *target, char far *source) 2447 { 2448 int i,j, k, escape = 0; 2449 char c, oldc, varname[MAXVNAME]; 2450 i=j=k=0; 2451 c = oldc = 0; 2452 while(i < MAXCMT && j < MAXCMT && (c = *(source+i++)) != '\0') 2453 { 2454 if(c == '\\' && oldc != '\\') 2455 { 2456 oldc = c; 2457 continue; 2458 } 2459 /* expand underscores to blanks */ 2460 if(c == '_' && oldc != '\\') 2461 c = ' '; 2462 /* esc_char marks start and end of variable names */ 2463 if(c == esc_char && oldc != '\\') 2464 escape = 1 - escape; 2465 if(c != esc_char && escape != 0) /* if true, building variable name */ 2466 { 2467 if(k < MAXVNAME-1) 2468 varname[k++] = c; 2469 } 2470 /* got variable name */ 2471 else if(c == esc_char && escape == 0 && oldc != '\\') 2472 { 2473 char buf[100]; 2474 char *varstr; 2475 varname[k] = 0; 2476 varstr = expand_var(varname,buf); 2477 far_strncpy(target+j,varstr,MAXCMT-j-1); 2478 j += strlen(varstr); 2479 } 2480 else if (c == esc_char && escape != 0 && oldc != '\\') 2481 k = 0; 2482 else if ((c != esc_char || oldc == '\\') && escape == 0) 2483 *(target+j++) = c; 2484 oldc = c; 2485 } 2486 if(*source != '\0') 2487 *(target+min(j,MAXCMT-1)) = '\0'; 2488 } 2489 2490 /* extract comments from the comments= command */ 2491 void parse_comments(char *value) 2492 { 2493 int i; 2494 char *next,save; 2495 for(i=0;i<4;i++) 2496 { 2497 save = '\0'; 2498 if (*value == 0) 2499 break; 2500 next = strchr(value,'/'); 2501 if (*value != '/') 2502 { 2503 if(next != NULL) 2504 { 2505 save = *next; 2506 *next = '\0'; 2507 } 2508 far_strncpy(par_comment[i],value, MAXCMT); 2509 } 2510 if(next == NULL) 2511 break; 2512 if(save != '\0') 2513 *next = save; 2514 value = next+1; 2515 } 2516 } 2517 2518 void init_comments() 2519 { 2520 int i; 2521 for(i=0;i<4;i++) 2522 par_comment[i][0] = '\0'; 2523 } 2524