File: common\loadfile.c

    1 /*
    2         loadfile.c - load an existing fractal image, control level
    3 */
    4 
    5 #include <string.h>
    6 #include <time.h>
    7 #include <errno.h>
    8   /* see Fractint.c for a description of the "include"  hierarchy */
    9 #include "port.h"
   10 #include "prototyp.h"
   11 #include "fractype.h"
   12 #include "helpdefs.h"
   13 #include "targa_lc.h"
   14 
   15 /* routines in this module      */
   16 
   17 static int  find_fractal_info(char *,struct fractal_info *,
   18                               struct ext_blk_2 *,
   19                               struct ext_blk_3 *,
   20                               struct ext_blk_4 *,
   21                               struct ext_blk_5 *,
   22                               struct ext_blk_6 *,
   23                               struct ext_blk_7 *);
   24 static void load_ext_blk(char far *loadptr,int loadlen);
   25 static void skip_ext_blk(int *,int *);
   26 static void backwardscompat(struct fractal_info *info);
   27 static int fix_bof(void);
   28 static int fix_period_bof(void);
   29 
   30 int filetype;
   31 int loaded3d;
   32 static FILE *fp;
   33 int fileydots, filexdots, filecolors;
   34 float fileaspectratio;
   35 short skipxdots,skipydots;      /* for decoder, when reducing image */
   36 int bad_outside = 0;
   37 int ldcheck = 0;
   38 
   39 int read_overlay()      /* read overlay/3D files, if reqr'd */
   40 {
   41    struct fractal_info read_info;
   42    char oldfloatflag;
   43    char msg[110];
   44    struct ext_blk_2 blk_2_info;
   45    struct ext_blk_3 blk_3_info;
   46    struct ext_blk_4 blk_4_info;
   47    struct ext_blk_5 blk_5_info;
   48    struct ext_blk_6 blk_6_info;
   49    struct ext_blk_7 blk_7_info;
   50 
   51    showfile = 1;                /* for any abort exit, pretend done */
   52    initmode = -1;               /* no viewing mode set yet */
   53    oldfloatflag = usr_floatflag;
   54    loaded3d = 0;
   55    if(fastrestore)
   56       viewwindow=0;
   57    if(has_ext(readname) == NULL)
   58       strcat(readname,".gif");
   59 
   60    if(find_fractal_info(readname,&read_info,&blk_2_info,&blk_3_info,
   61                         &blk_4_info,&blk_5_info,&blk_6_info,&blk_7_info)) {
   62       /* didn't find a useable file */
   63       sprintf(msg,"Sorry, %s isn't a file I can decode.",readname);
   64       stopmsg(0,msg);
   65       return(-1);
   66       }
   67 
   68    maxit        = read_info.iterationsold;
   69    fractype     = read_info.fractal_type;
   70    if (fractype < 0 || fractype >= num_fractal_types) {
   71       sprintf(msg,"Warning: %s has a bad fractal type; using 0",readname);
   72       fractype = 0;
   73    }
   74    curfractalspecific = &fractalspecific[fractype];
   75    xxmin        = read_info.xmin;
   76    xxmax        = read_info.xmax;
   77    yymin        = read_info.ymin;
   78    yymax        = read_info.ymax;
   79    param[0]     = read_info.creal;
   80    param[1]     = read_info.cimag;
   81    save_release = 1100; /* unless we find out better later on */
   82 
   83    invert = 0;
   84    if(read_info.version > 0) {
   85       param[2]      = read_info.parm3;
   86       roundfloatd(&param[2]);
   87       param[3]      = read_info.parm4;
   88       roundfloatd(&param[3]);
   89       potparam[0]   = read_info.potential[0];
   90       potparam[1]   = read_info.potential[1];
   91       potparam[2]   = read_info.potential[2];
   92       if(*s_makepar == '\0')
   93          colors = read_info.colors;
   94       potflag       = (potparam[0] != 0.0);
   95       rflag         = read_info.rflag;
   96       rseed         = read_info.rseed;
   97       inside        = read_info.inside;
   98       LogFlag       = read_info.logmapold;
   99       inversion[0]  = read_info.invert[0];
  100       inversion[1]  = read_info.invert[1];
  101       inversion[2]  = read_info.invert[2];
  102       if (inversion[0] != 0.0)
  103          invert = 3;
  104       decomp[0]     = read_info.decomp[0];
  105       decomp[1]     = read_info.decomp[1];
  106       usr_biomorph  = read_info.biomorph;
  107       forcesymmetry = read_info.symmetry;
  108       }
  109 
  110    if(read_info.version > 1) {
  111       save_release  = 1200;
  112       if (!display3d
  113         && (read_info.version <= 4 || read_info.flag3d > 0
  114             || (curfractalspecific->flags&PARMS3D) )) {
  115          int i;
  116          for (i = 0; i < 16; i++)
  117             init3d[i] = read_info.init3d[i];
  118          previewfactor   = read_info.previewfactor;
  119          xtrans          = read_info.xtrans;
  120          ytrans          = read_info.ytrans;
  121          red_crop_left   = read_info.red_crop_left;
  122          red_crop_right  = read_info.red_crop_right;
  123          blue_crop_left  = read_info.blue_crop_left;
  124          blue_crop_right = read_info.blue_crop_right;
  125          red_bright      = read_info.red_bright;
  126          blue_bright     = read_info.blue_bright;
  127          xadjust         = read_info.xadjust;
  128          eyeseparation   = read_info.eyeseparation;
  129          glassestype     = read_info.glassestype;
  130          }
  131       }
  132 
  133    if(read_info.version > 2) {
  134       save_release = 1300;
  135       outside      = read_info.outside;
  136       }
  137 
  138    calc_status = 0;       /* defaults if version < 4 */
  139    xx3rd = xxmin;
  140    yy3rd = yymin;
  141    usr_distest = 0;
  142    calctime = 0;
  143    if(read_info.version > 3) {
  144       save_release = 1400;
  145       xx3rd       = read_info.x3rd;
  146       yy3rd       = read_info.y3rd;
  147       calc_status = read_info.calc_status;
  148       usr_stdcalcmode = read_info.stdcalcmode;
  149       three_pass = 0;
  150       if(usr_stdcalcmode == 127)
  151       {
  152          three_pass = 1;
  153          usr_stdcalcmode = '3';
  154       }
  155       usr_distest     = read_info.distestold;
  156       usr_floatflag   = (char)read_info.floatflag;
  157       bailout     = read_info.bailoutold;
  158       calctime    = read_info.calctime;
  159       trigndx[0]  = read_info.trigndx[0];
  160       trigndx[1]  = read_info.trigndx[1];
  161       trigndx[2]  = read_info.trigndx[2];
  162       trigndx[3]  = read_info.trigndx[3];
  163       finattract  = read_info.finattract;
  164       initorbit.x = read_info.initorbit[0];
  165       initorbit.y = read_info.initorbit[1];
  166       useinitorbit = read_info.useinitorbit;
  167       usr_periodicitycheck = read_info.periodicity;
  168       }
  169 
  170    pot16bit = 0;
  171    save_system = 0;
  172    if(read_info.version > 4) {
  173       pot16bit     = read_info.pot16bit;
  174       if (pot16bit)
  175          filexdots >>= 1;
  176       fileaspectratio = read_info.faspectratio;
  177       if (fileaspectratio < 0.01)       /* fix files produced in early v14.1 */
  178          fileaspectratio = screenaspect;
  179       save_system  = read_info.system;
  180       save_release = read_info.release; /* from fmt 5 on we know real number */
  181       if (read_info.version == 5        /* except a few early fmt 5 cases: */
  182           && (save_release <= 0 || save_release >= 4000)) {
  183          save_release = 1410;
  184          save_system = 0;
  185          }
  186       if (!display3d && read_info.flag3d > 0) {
  187          loaded3d       = 1;
  188          Ambient        = read_info.ambient;
  189          RANDOMIZE      = read_info.randomize;
  190          haze           = read_info.haze;
  191          transparent[0] = read_info.transparent[0];
  192          transparent[1] = read_info.transparent[1];
  193          }
  194       }
  195 
  196    rotate_lo = 1; rotate_hi = 255;
  197    distestwidth = 71;
  198    if(read_info.version > 5) {
  199       rotate_lo         = read_info.rotate_lo;
  200       rotate_hi         = read_info.rotate_hi;
  201       distestwidth      = read_info.distestwidth;
  202       }
  203 
  204    if(read_info.version > 6) {
  205       param[2]          = read_info.dparm3;
  206       param[3]          = read_info.dparm4;
  207       }
  208 
  209    if(read_info.version > 7) {
  210       fillcolor         = read_info.fillcolor;
  211       }
  212 
  213    if(read_info.version > 8) {
  214    mxmaxfp   =  read_info.mxmaxfp        ;
  215    mxminfp   =  read_info.mxminfp        ;
  216    mymaxfp   =  read_info.mymaxfp        ;
  217    myminfp   =  read_info.myminfp        ;
  218    zdots     =  read_info.zdots          ;
  219    originfp  =  read_info.originfp       ;
  220    depthfp   =  read_info.depthfp        ;
  221    heightfp  =  read_info.heightfp       ;
  222    widthfp   =  read_info.widthfp        ;
  223    distfp    =  read_info.distfp         ;
  224    eyesfp    =  read_info.eyesfp         ;
  225    neworbittype = read_info.orbittype    ;
  226    juli3Dmode   = read_info.juli3Dmode   ;
  227    maxfn    =   (char)read_info.maxfn          ;
  228    major_method = (enum Major)read_info.inversejulia >> 8;
  229    minor_method = (enum Minor)read_info.inversejulia & 255;
  230    param[4] = read_info.dparm5;
  231    param[5] = read_info.dparm6;
  232    param[6] = read_info.dparm7;
  233    param[7] = read_info.dparm8;
  234    param[8] = read_info.dparm9;
  235    param[9] = read_info.dparm10;
  236       }
  237 
  238    if(read_info.version < 4 && read_info.version != 0) { /* pre-version 14.0? */
  239       backwardscompat(&read_info); /* translate obsolete types */
  240       if(LogFlag)
  241          LogFlag = 2;
  242       usr_floatflag = (char)((curfractalspecific->isinteger) ? 0 : 1);
  243       }
  244 
  245    if (read_info.version < 5 && read_info.version != 0) { /* pre-version 15.0? */
  246       if (LogFlag == 2) /* logmap=old changed again in format 5! */
  247          LogFlag = -1;
  248       if (decomp[0] > 0 && decomp[1] > 0)
  249          bailout = decomp[1];
  250       }
  251    if(potflag) /* in version 15.x and 16.x logmap didn't work with pot */
  252       if(read_info.version == 6 || read_info.version == 7)
  253          LogFlag = 0;
  254    set_trig_pointers(-1);
  255 
  256    if(read_info.version < 9 && read_info.version != 0) { /* pre-version 18.0? */
  257       /* forcesymmetry==1000 means we want to force symmetry but don't
  258          know which symmetry yet, will find out in setsymmetry() */
  259       if(outside==REAL || outside==IMAG || outside==MULT || outside==SUM
  260         || outside==ATAN)
  261          if(forcesymmetry == 999)
  262             forcesymmetry = 1000;
  263       }
  264    if(save_release < 1725 && read_info.version != 0) { /* pre-version 17.25 */
  265       set_if_old_bif(); /* translate bifurcation types */
  266       functionpreloaded = 1;
  267    }
  268 
  269    if(read_info.version > 9)
  270    { /* post-version 18.22 */
  271       bailout     = read_info.bailout; /* use long bailout */
  272       bailoutest = (enum bailouts)read_info.bailoutest;
  273    }
  274    else
  275       bailoutest = Mod;
  276    setbailoutformula(bailoutest);
  277 
  278    if(read_info.version > 9) {
  279      /* post-version 18.23 */
  280       maxit = read_info.iterations; /* use long maxit */
  281      /* post-version 18.27 */
  282       old_demm_colors = read_info.old_demm_colors;
  283    }
  284 
  285    if (read_info.version > 10) { /* post-version 19.20 */
  286       LogFlag = read_info.logmap;
  287       usr_distest= read_info.distest;
  288    }
  289 
  290    if (read_info.version > 11) { /* post-version 19.20, inversion fix */
  291       inversion[0] = read_info.dinvert[0];
  292       inversion[1] = read_info.dinvert[1];
  293       inversion[2] = read_info.dinvert[2];
  294       Log_Fly_Calc = read_info.logcalc;
  295       stoppass     = read_info.stoppass;
  296    }
  297 
  298    if (read_info.version > 12) { /* post-version 19.60 */
  299       quick_calc   = read_info.quick_calc;
  300       closeprox    = read_info.closeprox;
  301       if (fractype == FPPOPCORN || fractype == LPOPCORN ||
  302           fractype == FPPOPCORNJUL || fractype == LPOPCORNJUL ||
  303           fractype == LATOO)
  304             functionpreloaded = 1;
  305    }
  306 
  307    nobof=0;
  308    if (read_info.version > 13) { /* post-version 20.1.2 */
  309       nobof = read_info.nobof;
  310    }
  311 
  312    /* if (read_info.version > 14)  post-version 20.1.12 */
  313    /* modified saved evolver structure JCO 12JUL01 */
  314    Log_Auto_Calc = 0;  /* make sure it's turned off */
  315 
  316    orbit_interval = 1;
  317    if (read_info.version > 15) { /* post-version 20.3.2 */
  318       orbit_interval = read_info.orbit_interval;
  319    }
  320 
  321    orbit_delay = 0;
  322    math_tol[0] = 0.05;
  323    math_tol[1] = 0.05;
  324    if (read_info.version > 16) { /* post-version 20.4.0 */
  325       orbit_delay = read_info.orbit_delay;
  326       math_tol[0] = read_info.math_tol[0];
  327       math_tol[1] = read_info.math_tol[1];
  328    }
  329 
  330    backwards_v18();
  331    backwards_v19();
  332    backwards_v20();
  333 
  334    if (display3d)                   /* PB - a klooge till the meaning of */
  335       usr_floatflag = oldfloatflag; /*  floatflag in line3d is clarified */
  336 
  337    if (overlay3d) {
  338       initmode = adapter;          /* use previous adapter mode for overlays */
  339       if (filexdots > xdots || fileydots > ydots) {
  340          static FCODE msg[]={"Can't overlay with a larger image"};
  341          stopmsg(0,msg);
  342          initmode = -1;
  343          return(-1);
  344          }
  345       }
  346    else {
  347       int olddisplay3d,i;
  348       char oldfloatflag;
  349       olddisplay3d = display3d;
  350       oldfloatflag = floatflag;
  351       display3d = loaded3d;      /* for <tab> display during next */
  352       floatflag = usr_floatflag; /* ditto */
  353       i = get_video_mode(&read_info,&blk_3_info);
  354       display3d = olddisplay3d;
  355       floatflag = oldfloatflag;
  356       if (i) {
  357          if(blk_2_info.got_data == 1) {
  358             MemoryRelease((U16)blk_2_info.resume_data);
  359             blk_2_info.length = 0;
  360          }
  361          initmode = -1;
  362          return(-1);
  363          }
  364       }
  365 
  366    if (display3d) {
  367       calc_status = 0;
  368       fractype = PLASMA;
  369       curfractalspecific = &fractalspecific[PLASMA];
  370       param[0] = 0;
  371       if (!initbatch)
  372          if (get_3d_params() < 0) {
  373             initmode = -1;
  374             return(-1);
  375             }
  376       }
  377 
  378    if (resume_info != 0) { /* free the prior area if there is one */
  379       MemoryRelease(resume_info);
  380       resume_info = 0;
  381       }
  382 
  383    if(blk_2_info.got_data == 1)
  384           {
  385           resume_info = (U16)blk_2_info.resume_data;
  386           resume_len = blk_2_info.length;
  387           }
  388 
  389    if(blk_3_info.got_data == 1)
  390           {
  391           char *nameptr;
  392           switch (read_info.fractal_type) {
  393              case LSYSTEM:
  394                 nameptr = LName;
  395                 break;
  396              case IFS:
  397              case IFS3D:
  398                 nameptr = IFSName;
  399                 break;
  400              default:
  401                 nameptr = FormName;
  402                 uses_p1 = blk_3_info.uses_p1;
  403                 uses_p2 = blk_3_info.uses_p2;
  404                 uses_p3 = blk_3_info.uses_p3;
  405                 uses_ismand = blk_3_info.uses_ismand;
  406                 ismand = blk_3_info.ismand;
  407                 uses_p4 = blk_3_info.uses_p4;
  408                 uses_p5 = blk_3_info.uses_p5;
  409                 break;
  410              }
  411           blk_3_info.form_name[ITEMNAMELEN] = 0;
  412           strcpy(nameptr,blk_3_info.form_name);
  413           /* perhaps in future add more here, check block_len for
  414              backward compatibility */
  415           }
  416 
  417    if (rangeslen) { /* free prior ranges */
  418      farmemfree((char far *)ranges);
  419      rangeslen = 0;
  420    }
  421 
  422    if(blk_4_info.got_data == 1)
  423           {
  424           ranges = (int far *)blk_4_info.range_data;
  425           rangeslen = blk_4_info.length;
  426 #ifdef XFRACT
427 fix_ranges(ranges,rangeslen,1);
428 #endif 429 } 430 431 if(blk_5_info.got_data == 1) 432 { 433 bf_math = 1; 434 init_bf_length(read_info.bflength); 435 far_memcpy((char far *)bfxmin,blk_5_info.apm_data,blk_5_info.length); 436 farmemfree(blk_5_info.apm_data); 437 } 438 else 439 bf_math = 0; 440 441 if(blk_6_info.got_data == 1) 442 { 443 struct evolution_info resume_e_info; 444 GENEBASE gene[NUMGENES]; 445 int i; 446 447 if (gene_handle == 0) 448 gene_handle = MemoryAlloc((U16)sizeof(gene),1L,FARMEM); 449 MoveFromMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); 450 if (read_info.version < 15) /* This is VERY Ugly! JCO 14JUL01 */ 451 /* Increasing NUMGENES moves ecount in the data structure */ 452 /* We added 4 to NUMGENES, so ecount is at NUMGENES-4 */ 453 blk_6_info.ecount = blk_6_info.mutate[NUMGENES-4]; 454 if (blk_6_info.ecount != blk_6_info.gridsz * blk_6_info.gridsz 455 && calc_status != 4) { 456 calc_status = 2; 457 if (evolve_handle == 0) 458 evolve_handle = MemoryAlloc((U16)sizeof(resume_e_info),1L,FARMEM); 459 resume_e_info.paramrangex = blk_6_info.paramrangex; 460 resume_e_info.paramrangey = blk_6_info.paramrangey; 461 resume_e_info.opx = blk_6_info.opx; 462 resume_e_info.opy = blk_6_info.opy; 463 resume_e_info.odpx = blk_6_info.odpx; 464 resume_e_info.odpy = blk_6_info.odpy; 465 resume_e_info.px = blk_6_info.px; 466 resume_e_info.py = blk_6_info.py; 467 resume_e_info.sxoffs = blk_6_info.sxoffs; 468 resume_e_info.syoffs = blk_6_info.syoffs; 469 resume_e_info.xdots = blk_6_info.xdots; 470 resume_e_info.ydots = blk_6_info.ydots; 471 resume_e_info.gridsz = blk_6_info.gridsz; 472 resume_e_info.evolving = blk_6_info.evolving; 473 resume_e_info.this_gen_rseed = blk_6_info.this_gen_rseed; 474 resume_e_info.fiddlefactor = blk_6_info.fiddlefactor; 475 resume_e_info.ecount = blk_6_info.ecount; 476 MoveToMemory((BYTE *)&resume_e_info,(U16)sizeof(resume_e_info),1L,0L,evolve_handle); 477 } else { 478 if (evolve_handle != 0) /* Image completed, release it. */ 479 MemoryRelease(evolve_handle); 480 evolve_handle = 0; 481 calc_status = 4; 482 } 483 paramrangex = blk_6_info.paramrangex; 484 paramrangey = blk_6_info.paramrangey; 485 opx = newopx = blk_6_info.opx; 486 opy = newopy = blk_6_info.opy; 487 odpx = newodpx = (char)blk_6_info.odpx; 488 odpy = newodpy = (char)blk_6_info.odpy; 489 px = blk_6_info.px; 490 py = blk_6_info.py; 491 sxoffs = blk_6_info.sxoffs; 492 syoffs = blk_6_info.syoffs; 493 xdots = blk_6_info.xdots; 494 ydots = blk_6_info.ydots; 495 gridsz = blk_6_info.gridsz; 496 this_gen_rseed = blk_6_info.this_gen_rseed; 497 fiddlefactor = blk_6_info.fiddlefactor; 498 evolving = viewwindow = (int)blk_6_info.evolving; 499 dpx=paramrangex/(gridsz-1); 500 dpy=paramrangey/(gridsz-1); 501 if (read_info.version > 14) 502 for (i = 0; i < NUMGENES; i++) 503 gene[i].mutate = (int)blk_6_info.mutate[i]; 504 else { 505 for (i = 0; i < 6; i++) 506 gene[i].mutate = (int)blk_6_info.mutate[i]; 507 for (i = 6; i < 10; i++) 508 gene[i].mutate = 0; 509 for (i = 10; i < NUMGENES; i++) 510 gene[i].mutate = (int)blk_6_info.mutate[i-4]; 511 } 512 MoveToMemory((BYTE *)&gene, (U16)sizeof(gene), 1L, 0L, gene_handle); 513 param_history(0); /* store history */ 514 } 515 else { 516 evolving = FALSE; 517 } 518 519 if(blk_7_info.got_data == 1) { 520 oxmin = blk_7_info.oxmin; 521 oxmax = blk_7_info.oxmax; 522 oymin = blk_7_info.oymin; 523 oymax = blk_7_info.oymax; 524 ox3rd = blk_7_info.ox3rd; 525 oy3rd = blk_7_info.oy3rd; 526 keep_scrn_coords = blk_7_info.keep_scrn_coords; 527 drawmode = blk_7_info.drawmode; 528 if(keep_scrn_coords) set_orbit_corners = 1; 529 } 530 531 showfile = 0; /* trigger the file load */ 532 return(0); 533 } 534 535 static int find_fractal_info(char *gif_file,struct fractal_info *info, 536 struct ext_blk_2 *blk_2_info, 537 struct ext_blk_3 *blk_3_info, 538 struct ext_blk_4 *blk_4_info, 539 struct ext_blk_5 *blk_5_info, 540 struct ext_blk_6 *blk_6_info, 541 struct ext_blk_7 *blk_7_info) 542 { 543 BYTE gifstart[18]; 544 char temp1[81]; 545 int scan_extend, block_type, block_len, data_len; 546 int fractinf_len; 547 int hdr_offset; 548 struct formula_info fload_info; 549 struct evolution_info eload_info; 550 struct orbits_info oload_info; 551 int i, j, k = 0; 552 553 blk_2_info->got_data = 0; /* initialize to no data */ 554 blk_3_info->got_data = 0; /* initialize to no data */ 555 blk_4_info->got_data = 0; /* initialize to no data */ 556 blk_5_info->got_data = 0; /* initialize to no data */ 557 blk_6_info->got_data = 0; /* initialize to no data */ 558 blk_7_info->got_data = 0; /* initialize to no data */ 559 560 if((fp = fopen(gif_file,"rb"))==NULL) 561 return(-1); 562 fread(gifstart,13,1,fp); 563 if (strncmp((char *)gifstart,"GIF",3) != 0) { /* not GIF, maybe old .tga? */ 564 fclose(fp); 565 return(-1); 566 } 567 568 filetype = 0; /* GIF */ 569 GET16(gifstart[6],filexdots); 570 GET16(gifstart[8],fileydots); 571 filecolors = 2 << (gifstart[10] & 7); 572 fileaspectratio = 0; /* unknown */ 573 if (gifstart[12]) { /* calc reasonably close value from gif header */ 574 fileaspectratio = (float)((64.0 / ((double)(gifstart[12]) + 15.0)) 575 * (double)fileydots / (double)filexdots); 576 if ( fileaspectratio > screenaspect-0.03 577 && fileaspectratio < screenaspect+0.03) 578 fileaspectratio = screenaspect; 579 } 580 else 581 if (fileydots * 4 == filexdots * 3) /* assume the common square pixels */ 582 fileaspectratio = screenaspect; 583 584 if(*s_makepar == 0 && (gifstart[10] & 0x80)!=0) 585 { 586 for (i = 0; i < filecolors; i++) 587 { 588 for (j = 0; j < 3; j++) { 589 if ((k = getc(fp)) < 0) 590 break; 591 dacbox[i][j] = (BYTE)(k >> 2); 592 } 593 if(k < 0) 594 break; 595 } 596 } 597 598 /* Format of .gif extension blocks is: 599 1 byte '!', extension block identifier 600 1 byte extension block number, 255 601 1 byte length of id, 11 602 11 bytes alpha id, "fractintnnn" with fractint, nnn is secondary id 603 n * { 604 1 byte length of block info in bytes 605 x bytes block info 606 } 607 1 byte 0, extension terminator 608 To scan extension blocks, we first look in file at length of fractal_info 609 (the main extension block) from end of file, looking for a literal known 610 to be at start of our block info. Then we scan forward a bit, in case 611 the file is from an earlier fractint vsn with shorter fractal_info. 612 If fractal_info is found and is from vsn>=14, it includes the total length 613 of all extension blocks; we then scan them all first to last to load 614 any optional ones which are present. 615 Defined extension blocks: 616 fractint001 header, always present 617 fractint002 resume info for interrupted resumable image 618 fractint003 additional formula type info 619 fractint004 ranges info 620 fractint005 extended precision parameters 621 fractint006 evolver params 622 */ 623 624 memset(info,0,FRACTAL_INFO_SIZE); 625 fractinf_len = FRACTAL_INFO_SIZE + (FRACTAL_INFO_SIZE+254)/255; 626 fseek(fp,(long)(-1-fractinf_len),SEEK_END); 627 fread(info,1,FRACTAL_INFO_SIZE,fp); 628 if (strcmp(INFO_ID,info->info_id) == 0) { 629 #ifdef XFRACT
630 decode_fractal_info(info,1);
631 #endif 632 hdr_offset = -1-fractinf_len; 633 } else { 634 /* didn't work 1st try, maybe an older vsn, maybe junk at eof, scan: */ 635 int offset,i; 636 char tmpbuf[110]; 637 hdr_offset = 0; 638 offset = 80; /* don't even check last 80 bytes of file for id */ 639 while (offset < fractinf_len+513) { /* allow 512 garbage at eof */ 640 offset += 100; /* go back 100 bytes at a time */ 641 fseek(fp,(long)(0-offset),SEEK_END); 642 fread(tmpbuf,1,110,fp); /* read 10 extra for string compare */ 643 for (i = 0; i < 100; ++i) 644 if (!strcmp(INFO_ID,&tmpbuf[i])) { /* found header? */ 645 strcpy(info->info_id,INFO_ID); 646 fseek(fp,(long)(hdr_offset=i-offset),SEEK_END); 647 fread(info,1,FRACTAL_INFO_SIZE,fp); 648 #ifdef XFRACT
649 decode_fractal_info(info,1);
650 #endif 651 offset = 10000; /* force exit from outer loop */ 652 break; 653 } 654 } 655 } 656 657 if (hdr_offset) { /* we found INFO_ID */ 658 659 if (info->version >= 4) { 660 /* first reload main extension block, reasons: 661 might be over 255 chars, and thus earlier load might be bad 662 find exact endpoint, so scan back to start of ext blks works 663 */ 664 fseek(fp,(long)(hdr_offset-15),SEEK_END); 665 scan_extend = 1; 666 while (scan_extend) { 667 if (fgetc(fp) != '!' /* if not what we expect just give up */ 668 || fread(temp1,1,13,fp) != 13 669 || strncmp(&temp1[2],"fractint",8)) 670 break; 671 temp1[13] = 0; 672 block_type = atoi(&temp1[10]); /* e.g. "fractint002" */ 673 switch (block_type) { 674 case 1: /* "fractint001", the main extension block */ 675 if (scan_extend == 2) { /* we've been here before, done now */ 676 scan_extend = 0; 677 break; 678 } 679 load_ext_blk((char far *)info,FRACTAL_INFO_SIZE); 680 #ifdef XFRACT
681 decode_fractal_info(info,1);
682 #endif 683 scan_extend = 2; 684 /* now we know total extension len, back up to first block */ 685 fseek(fp,0L-info->tot_extend_len,SEEK_CUR); 686 break; 687 case 2: /* resume info */ 688 skip_ext_blk(&block_len,&data_len); /* once to get lengths */ 689 if ((blk_2_info->resume_data = MemoryAlloc((U16)1,(long)data_len,FARMEM)) == 0) 690 info->calc_status = 3; /* not resumable after all */ 691 else { 692 fseek(fp,(long)(0-block_len),SEEK_CUR); 693 load_ext_blk((char far *)block,data_len); 694 MoveToMemory((BYTE *)block,(U16)1,(long)data_len,0,(U16)blk_2_info->resume_data); 695 blk_2_info->length = data_len; 696 blk_2_info->got_data = 1; /* got data */ 697 } 698 break; 699 case 3: /* formula info */ 700 skip_ext_blk(&block_len,&data_len); /* once to get lengths */ 701 /* check data_len for backward compatibility */ 702 fseek(fp,(long)(0-block_len),SEEK_CUR); 703 load_ext_blk((char far *)&fload_info,data_len); 704 strcpy(blk_3_info->form_name,fload_info.form_name); 705 blk_3_info->length = data_len; 706 blk_3_info->got_data = 1; /* got data */ 707 if (data_len < sizeof(fload_info)) { /* must be old GIF */ 708 blk_3_info->uses_p1 = 1; 709 blk_3_info->uses_p2 = 1; 710 blk_3_info->uses_p3 = 1; 711 blk_3_info->uses_ismand = 0; 712 blk_3_info->ismand = 1; 713 blk_3_info->uses_p4 = 0; 714 blk_3_info->uses_p5 = 0; 715 } 716 else { 717 blk_3_info->uses_p1 = fload_info.uses_p1; 718 blk_3_info->uses_p2 = fload_info.uses_p2; 719 blk_3_info->uses_p3 = fload_info.uses_p3; 720 blk_3_info->uses_ismand = fload_info.uses_ismand; 721 blk_3_info->ismand = fload_info.ismand; 722 blk_3_info->uses_p4 = fload_info.uses_p4; 723 blk_3_info->uses_p5 = fload_info.uses_p5; 724 } 725 break; 726 case 4: /* ranges info */ 727 skip_ext_blk(&block_len,&data_len); /* once to get lengths */ 728 if ((blk_4_info->range_data = (int far *)farmemalloc((long)data_len)) != NULL) { 729 fseek(fp,(long)(0-block_len),SEEK_CUR); 730 load_ext_blk((char far *)blk_4_info->range_data,data_len); 731 blk_4_info->length = data_len/2; 732 blk_4_info->got_data = 1; /* got data */ 733 } 734 break; 735 case 5: /* extended precision parameters */ 736 skip_ext_blk(&block_len,&data_len); /* once to get lengths */ 737 if ((blk_5_info->apm_data = (char far *)farmemalloc((long)data_len)) != NULL) { 738 fseek(fp,(long)(0-block_len),SEEK_CUR); 739 load_ext_blk(blk_5_info->apm_data,data_len); 740 blk_5_info->length = data_len; 741 blk_5_info->got_data = 1; /* got data */ 742 } 743 break; 744 case 6: /* evolver params */ 745 skip_ext_blk(&block_len,&data_len); /* once to get lengths */ 746 fseek(fp,(long)(0-block_len),SEEK_CUR); 747 load_ext_blk((char far *)&eload_info,data_len); 748 /* XFRACT processing of doubles here */ 749 #ifdef XFRACT
750 decode_evolver_info(&eload_info,1);
751 #endif 752 blk_6_info->length = data_len; 753 blk_6_info->got_data = 1; /* got data */ 754 755 blk_6_info->paramrangex = eload_info.paramrangex; 756 blk_6_info->paramrangey = eload_info.paramrangey; 757 blk_6_info->opx = eload_info.opx; 758 blk_6_info->opy = eload_info.opy; 759 blk_6_info->odpx = (char)eload_info.odpx; 760 blk_6_info->odpy = (char)eload_info.odpy; 761 blk_6_info->px = eload_info.px; 762 blk_6_info->py = eload_info.py; 763 blk_6_info->sxoffs = eload_info.sxoffs; 764 blk_6_info->syoffs = eload_info.syoffs; 765 blk_6_info->xdots = eload_info.xdots; 766 blk_6_info->ydots = eload_info.ydots; 767 blk_6_info->gridsz = eload_info.gridsz; 768 blk_6_info->evolving = eload_info.evolving; 769 blk_6_info->this_gen_rseed = eload_info.this_gen_rseed; 770 blk_6_info->fiddlefactor = eload_info.fiddlefactor; 771 blk_6_info->ecount = eload_info.ecount; 772 for (i = 0; i < NUMGENES; i++) 773 blk_6_info->mutate[i] = eload_info.mutate[i]; 774 break; 775 case 7: /* orbits parameters */ 776 skip_ext_blk(&block_len,&data_len); /* once to get lengths */ 777 fseek(fp,(long)(0-block_len),SEEK_CUR); 778 load_ext_blk((char far *)&oload_info,data_len); 779 /* XFRACT processing of doubles here */ 780 #ifdef XFRACT
781 decode_orbits_info(&oload_info,1);
782 #endif 783 blk_7_info->length = data_len; 784 blk_7_info->got_data = 1; /* got data */ 785 blk_7_info->oxmin = oload_info.oxmin; 786 blk_7_info->oxmax = oload_info.oxmax; 787 blk_7_info->oymin = oload_info.oymin; 788 blk_7_info->oymax = oload_info.oymax; 789 blk_7_info->ox3rd = oload_info.ox3rd; 790 blk_7_info->oy3rd = oload_info.oy3rd; 791 blk_7_info->keep_scrn_coords= oload_info.keep_scrn_coords; 792 blk_7_info->drawmode = oload_info.drawmode; 793 break; 794 default: 795 skip_ext_blk(&block_len,&data_len); 796 } 797 } 798 } 799 800 fclose(fp); 801 fileaspectratio = screenaspect; /* if not >= v15, this is correct */ 802 return(0); 803 } 804 805 strcpy(info->info_id, "GIFFILE"); 806 info->iterations = 150; 807 info->iterationsold = 150; 808 info->fractal_type = PLASMA; 809 info->xmin = -1; 810 info->xmax = 1; 811 info->ymin = -1; 812 info->ymax = 1; 813 info->x3rd = -1; 814 info->y3rd = -1; 815 info->creal = 0; 816 info->cimag = 0; 817 info->videomodeax=255; 818 info->videomodebx=255; 819 info->videomodecx=255; 820 info->videomodedx=255; 821 info->dotmode = 0; 822 info->xdots = (short)filexdots; 823 info->ydots = (short)fileydots; 824 info->colors = (short)filecolors; 825 info->version = 0; /* this forces lots more init at calling end too */ 826 827 /* zero means we won */ 828 fclose(fp); 829 return(0); 830 } 831 832 static void load_ext_blk(char far *loadptr,int loadlen) 833 { 834 int len; 835 while ((len = fgetc(fp)) > 0) { 836 while (--len >= 0) { 837 if (--loadlen >= 0) 838 *(loadptr++) = (char)fgetc(fp); 839 else 840 fgetc(fp); /* discard excess characters */ 841 } 842 } 843 } 844 845 static void skip_ext_blk(int *block_len, int *data_len) 846 { 847 int len; 848 *data_len = 0; 849 *block_len = 1; 850 while ((len = fgetc(fp)) > 0) { 851 fseek(fp,(long)len,SEEK_CUR); 852 *data_len += len; 853 *block_len += len + 1; 854 } 855 } 856 857 858 /* switch obsolete fractal types to new generalizations */ 859 static void backwardscompat(struct fractal_info *info) 860 { 861 switch(fractype) { 862 case LAMBDASINE: 863 fractype = LAMBDATRIGFP; 864 trigndx[0] = SIN; 865 break; 866 case LAMBDACOS : 867 fractype = LAMBDATRIGFP; 868 trigndx[0] = COS; 869 break; 870 case LAMBDAEXP : 871 fractype = LAMBDATRIGFP; 872 trigndx[0] = EXP; 873 break; 874 case MANDELSINE : 875 fractype = MANDELTRIGFP; 876 trigndx[0] = SIN; 877 break; 878 case MANDELCOS : 879 fractype = MANDELTRIGFP; 880 trigndx[0] = COS; 881 break; 882 case MANDELEXP : 883 fractype = MANDELTRIGFP; 884 trigndx[0] = EXP; 885 break; 886 case MANDELSINH : 887 fractype = MANDELTRIGFP; 888 trigndx[0] = SINH; 889 break; 890 case LAMBDASINH : 891 fractype = LAMBDATRIGFP; 892 trigndx[0] = SINH; 893 break; 894 case MANDELCOSH : 895 fractype = MANDELTRIGFP; 896 trigndx[0] = COSH; 897 break; 898 case LAMBDACOSH : 899 fractype = LAMBDATRIGFP; 900 trigndx[0] = COSH; 901 break; 902 case LMANDELSINE : 903 fractype = MANDELTRIG; 904 trigndx[0] = SIN; 905 break; 906 case LLAMBDASINE : 907 fractype = LAMBDATRIG; 908 trigndx[0] = SIN; 909 break; 910 case LMANDELCOS : 911 fractype = MANDELTRIG; 912 trigndx[0] = COS; 913 break; 914 case LLAMBDACOS : 915 fractype = LAMBDATRIG; 916 trigndx[0] = COS; 917 break; 918 case LMANDELSINH : 919 fractype = MANDELTRIG; 920 trigndx[0] = SINH; 921 break; 922 case LLAMBDASINH : 923 fractype = LAMBDATRIG; 924 trigndx[0] = SINH; 925 break; 926 case LMANDELCOSH : 927 fractype = MANDELTRIG; 928 trigndx[0] = COSH; 929 break; 930 case LLAMBDACOSH : 931 fractype = LAMBDATRIG; 932 trigndx[0] = COSH; 933 break; 934 case LMANDELEXP : 935 fractype = MANDELTRIG; 936 trigndx[0] = EXP; 937 break; 938 case LLAMBDAEXP : 939 fractype = LAMBDATRIG; 940 trigndx[0] = EXP; 941 break; 942 case DEMM : 943 fractype = MANDELFP; 944 usr_distest = (info->ydots - 1) * 2; 945 break; 946 case DEMJ : 947 fractype = JULIAFP; 948 usr_distest = (info->ydots - 1) * 2; 949 break; 950 case MANDELLAMBDA : 951 useinitorbit = 2; 952 break; 953 } 954 curfractalspecific = &fractalspecific[fractype]; 955 } 956 957 /* switch old bifurcation fractal types to new generalizations */ 958 void set_if_old_bif(void) 959 { 960 /* set functions if not set already, may need to check 'functionpreloaded' 961 before calling this routine. JCO 7/5/92 */ 962 963 switch(fractype) { 964 case BIFURCATION: 965 case LBIFURCATION: 966 case BIFSTEWART: 967 case LBIFSTEWART: 968 case BIFLAMBDA: 969 case LBIFLAMBDA: 970 set_trig_array(0,s_ident); 971 break; 972 973 case BIFEQSINPI: 974 case LBIFEQSINPI: 975 case BIFADSINPI: 976 case LBIFADSINPI: 977 set_trig_array(0,s_sin); 978 break; 979 } 980 } 981 982 /* miscellaneous function variable defaults */ 983 void set_function_parm_defaults(void) 984 { 985 switch(fractype) 986 { 987 case FPPOPCORN: 988 case LPOPCORN: 989 case FPPOPCORNJUL: 990 case LPOPCORNJUL: 991 set_trig_array(0,s_sin); 992 set_trig_array(1,s_tan); 993 set_trig_array(2,s_sin); 994 set_trig_array(3,s_tan); 995 break; 996 case LATOO: 997 set_trig_array(0,s_sin); 998 set_trig_array(1,s_sin); 999 set_trig_array(2,s_sin); 1000 set_trig_array(3,s_sin); 1001 break; 1002 } 1003 } 1004 1005 void backwards_v18(void) 1006 { 1007 if(!functionpreloaded) 1008 set_if_old_bif(); /* old bifs need function set, JCO 7/5/92 */ 1009 if(fractype==MANDELTRIG && usr_floatflag==1 1010 && save_release < 1800 && bailout == 0) 1011 bailout = 2500; 1012 if(fractype==LAMBDATRIG && usr_floatflag==1 1013 && save_release < 1800 && bailout == 0) 1014 bailout = 2500; 1015 } 1016 1017 void backwards_v19(void) 1018 { 1019 if(fractype==MARKSJULIA && save_release < 1825) { 1020 if(param[2] == 0) 1021 param[2] = 2; 1022 else 1023 param[2] += 1; 1024 } 1025 if(fractype==MARKSJULIAFP && save_release < 1825) { 1026 if(param[2] == 0) 1027 param[2] = 2; 1028 else 1029 param[2] += 1; 1030 } 1031 if((fractype==FORMULA || fractype==FFORMULA) && save_release < 1824) 1032 inversion[0] = inversion[1] = inversion[2] = invert = 0; 1033 if(fix_bof()) 1034 no_mag_calc = 1; /* fractal has old bof60/61 problem with magnitude */ 1035 else 1036 no_mag_calc = 0; 1037 if(fix_period_bof()) 1038 use_old_period = 1; /* fractal uses old periodicity method */ 1039 else 1040 use_old_period = 0; 1041 if(save_release < 1827 && distest) 1042 use_old_distest = 1; /* use old distest code */ 1043 else 1044 use_old_distest = 0; /* use new distest code */ 1045 } 1046 1047 void backwards_v20(void) 1048 { /* Fractype == FP type is not seen from PAR file ????? */ 1049 if((fractype == MANDELFP || fractype == JULIAFP || 1050 fractype == MANDEL || fractype == JULIA) && 1051 (outside <= REAL && outside >= SUM) && save_release <= 1960) 1052 bad_outside = 1; 1053 else 1054 bad_outside = 0; 1055 if((fractype == FORMULA || fractype == FFORMULA) && 1056 (save_release < 1900 || debugflag == 94)) 1057 ldcheck = 1; 1058 else 1059 ldcheck = 0; 1060 if(inside == EPSCROSS && save_release < 1961) 1061 closeprox = 0.01; 1062 if(!functionpreloaded) 1063 set_function_parm_defaults(); 1064 } 1065 1066 int check_back(void) { 1067 /* 1068 put the features that need to save the value in save_release for backwards 1069 compatibility in this routine 1070 */ 1071 int ret = 0; 1072 if (fractype == LYAPUNOV || 1073 fractype == FROTH || fractype == FROTHFP || 1074 fix_bof() || fix_period_bof() || use_old_distest || decomp[0] == 2 || 1075 (fractype == FORMULA && save_release <= 1920) || 1076 (fractype == FFORMULA && save_release <= 1920) || 1077 (LogFlag != 0 && save_release <= 2001) || 1078 (fractype == TRIGSQR && save_release < 1900) || 1079 (inside == STARTRAIL && save_release < 1825) || 1080 (maxit > 32767 && save_release <= 1950) || 1081 (distest && save_release <=1950) || 1082 ((outside <= REAL && outside >= ATAN) && 1083 save_release <= 1960) || 1084 (fractype == FPPOPCORN && save_release <= 1960) || 1085 (fractype == LPOPCORN && save_release <= 1960) || 1086 (fractype == FPPOPCORNJUL && save_release <= 1960) || 1087 (fractype == LPOPCORNJUL && save_release <= 1960) || 1088 (inside == FMODI && save_release <= 2000) || 1089 ((inside == ATANI || outside == ATAN) && save_release <= 2002) || 1090 (fractype == LAMBDATRIGFP && trigndx[0] == EXP && save_release <= 2002) || 1091 ((fractype == JULIBROT || fractype == JULIBROTFP) && 1092 (neworbittype == QUATFP || neworbittype == HYPERCMPLXFP) && 1093 save_release <= 2002) 1094 ) 1095 ret = 1; 1096 return(ret); 1097 } 1098 1099 static int fix_bof(void) 1100 { 1101 int ret = 0; 1102 if (inside <= BOF60 && inside >= BOF61 && save_release < 1826) 1103 if ((curfractalspecific->calctype == StandardFractal && 1104 (curfractalspecific->flags & BAILTEST) == 0) || 1105 (fractype==FORMULA || fractype==FFORMULA)) 1106 ret = 1; 1107 return (ret); 1108 } 1109 1110 static int fix_period_bof(void) 1111 { 1112 int ret = 0; 1113 if (inside <= BOF60 && inside >= BOF61 && save_release < 1826) 1114 ret = 1; 1115 return (ret); 1116 } 1117 1118 /* browse code RB*/ 1119 1120 #define MAX_WINDOWS_OPEN 450 1121 1122 struct window { /* for fgetwindow on screen browser */ 1123 struct coords itl; /* screen coordinates */ 1124 struct coords ibl; 1125 struct coords itr; 1126 struct coords ibr; 1127 double win_size; /* box size for drawindow() */ 1128 char name[13]; /* for filename */ 1129 int boxcount; /* bytes of saved screen info */ 1130 }; 1131 1132 /* prototypes */ 1133 static void drawindow( int, struct window * ); 1134 static char is_visible_window 1135 ( struct window *, struct fractal_info *, struct ext_blk_5 * ); 1136 static void transform( struct dblcoords * ); 1137 static char paramsOK( struct fractal_info * ); 1138 static char typeOK( struct fractal_info *, struct ext_blk_3 * ); 1139 static char functionOK( struct fractal_info *, int ); 1140 static void check_history( char *, char * ); 1141 static void bfsetup_convert_to_screen( void ); 1142 static void bftransform( bf_t, bf_t, struct dblcoords * ); 1143 1144 char browsename[13]; /* name for browse file */ 1145 U16 browsehandle; 1146 U16 boxxhandle; 1147 U16 boxyhandle; 1148 U16 boxvalueshandle; 1149 1150 /* here because must be visible inside several routines */ 1151 static struct affine *cvt; 1152 static bf_t bt_a, bt_b, bt_c, bt_d, bt_e, bt_f; 1153 static bf_t n_a, n_b, n_c, n_d, n_e, n_f; 1154 int oldbf_math; 1155 1156 /* fgetwindow reads all .GIF files and draws window outlines on the screen */ 1157 int fgetwindow(void) 1158 { 1159 struct affine stack_cvt; 1160 struct fractal_info read_info; 1161 struct ext_blk_2 blk_2_info; 1162 struct ext_blk_3 blk_3_info; 1163 struct ext_blk_4 blk_4_info; 1164 struct ext_blk_5 blk_5_info; 1165 struct ext_blk_6 blk_6_info; 1166 struct ext_blk_7 blk_7_info; 1167 time_t thistime,lastime; 1168 char mesg[40],newname[60],oldname[60]; 1169 int c,i,index,done,wincount,toggle,color_of_box; 1170 struct window winlist; 1171 char drive[FILE_MAX_DRIVE]; 1172 char dir[FILE_MAX_DIR]; 1173 char fname[FILE_MAX_FNAME]; 1174 char ext[FILE_MAX_EXT]; 1175 char tmpmask[FILE_MAX_PATH]; 1176 int vid_too_big = 0; 1177 int no_memory = 0; 1178 U16 vidlength; 1179 BYTE *winlistptr = (BYTE *)&winlist; 1180 int saved; 1181 #ifdef XFRACT
1182 U32 blinks;
1183 #endif 1184 1185 oldbf_math = bf_math; 1186 bf_math = BIGFLT; 1187 if (!oldbf_math) { 1188 int oldcalc_status = calc_status; /* kludge because next sets it = 0 */ 1189 fractal_floattobf(); 1190 calc_status = oldcalc_status; 1191 } 1192 saved = save_stack(); 1193 bt_a = alloc_stack(rbflength+2); 1194 bt_b = alloc_stack(rbflength+2); 1195 bt_c = alloc_stack(rbflength+2); 1196 bt_d = alloc_stack(rbflength+2); 1197 bt_e = alloc_stack(rbflength+2); 1198 bt_f = alloc_stack(rbflength+2); 1199 1200 if ((vidlength = (U16)(sxdots + sydots)) > (U16)4096) 1201 vid_too_big = 2; 1202 /* 4096 based on 4096B in boxx... max 1/4 pixels plotted, and need words */ 1203 /* 4096 = 10240/2.5 based on size of boxx+boxy+boxvalues */ 1204 #ifdef XFRACT
1205 vidlength = 4; /* Xfractint only needs the 4 corners saved. */
1206 #endif 1207 browsehandle = MemoryAlloc((U16)sizeof(struct window),(long)MAX_WINDOWS_OPEN,FARMEM); 1208 boxxhandle = MemoryAlloc((U16)(vidlength),(long)MAX_WINDOWS_OPEN,EXPANDED); 1209 boxyhandle = MemoryAlloc((U16)(vidlength),(long)MAX_WINDOWS_OPEN,EXPANDED); 1210 boxvalueshandle = MemoryAlloc((U16)(vidlength>>1),(long)MAX_WINDOWS_OPEN,EXPANDED); 1211 if(!browsehandle || !boxxhandle || !boxyhandle || !boxvalueshandle) 1212 no_memory = 1; 1213 1214 /* set up complex-plane-to-screen transformation */ 1215 if (oldbf_math) { 1216 bfsetup_convert_to_screen(); 1217 } 1218 else { 1219 cvt = &stack_cvt; /* use stack */ 1220 setup_convert_to_screen(cvt); 1221 /* put in bf variables */ 1222 floattobf(bt_a, cvt->a); 1223 floattobf(bt_b, cvt->b); 1224 floattobf(bt_c, cvt->c); 1225 floattobf(bt_d, cvt->d); 1226 floattobf(bt_e, cvt->e); 1227 floattobf(bt_f, cvt->f); 1228 } 1229 find_special_colors(); 1230 color_of_box = color_medium; 1231 rescan: /* entry for changed browse parms */ 1232 time(&lastime); 1233 toggle = 0; 1234 wincount = 0; 1235 no_sub_images = FALSE; 1236 splitpath(readname,drive,dir,NULL,NULL); 1237 splitpath(browsemask,NULL,NULL,fname,ext); 1238 makepath(tmpmask,drive,dir,fname,ext); 1239 done=(vid_too_big==2) || no_memory || fr_findfirst(tmpmask); 1240 /* draw all visible windows */ 1241 while (!done) 1242 { 1243 if(keypressed()) 1244 { 1245 getakey(); 1246 break; 1247 } 1248 splitpath(DTA.filename,NULL,NULL,fname,ext); 1249 makepath(tmpmask,drive,dir,fname,ext); 1250 if( !find_fractal_info(tmpmask,&read_info,&blk_2_info,&blk_3_info, 1251 &blk_4_info,&blk_5_info,&blk_6_info, 1252 &blk_7_info) && 1253 (typeOK(&read_info,&blk_3_info) || !brwschecktype) && 1254 (paramsOK(&read_info) || !brwscheckparms) && 1255 stricmp(browsename,DTA.filename) && 1256 blk_6_info.got_data != 1 && 1257 is_visible_window(&winlist,&read_info,&blk_5_info) 1258 ) 1259 { 1260 far_strcpy(winlist.name,DTA.filename); 1261 drawindow(color_of_box,&winlist); 1262 boxcount <<= 1; /*boxcount*2;*/ /* double for byte count */ 1263 winlist.boxcount = boxcount; 1264 MoveToMemory(winlistptr,(U16)sizeof(struct window),1L,(long)wincount,browsehandle); 1265 MoveToMemory((BYTE *)boxx,vidlength,1L,(long)wincount,boxxhandle); 1266 MoveToMemory((BYTE *)boxy,vidlength,1L,(long)wincount,boxyhandle); 1267 MoveToMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)wincount,boxvalueshandle); 1268 wincount++; 1269 } 1270 1271 if(blk_2_info.got_data == 1) /* Clean up any far memory allocated */ 1272 MemoryRelease((U16)blk_2_info.resume_data); 1273 if(blk_4_info.got_data == 1) /* Clean up any far memory allocated */ 1274 farmemfree(blk_4_info.range_data); 1275 if(blk_5_info.got_data == 1) /* Clean up any far memory allocated */ 1276 farmemfree(blk_5_info.apm_data); 1277 1278 done=(fr_findnext() || wincount >= MAX_WINDOWS_OPEN); 1279 } 1280 1281 if (no_memory) 1282 { 1283 static FCODE msg[] = {"Sorry...not enough memory to browse."}; 1284 texttempmsg(msg);/* doesn't work if NO far memory available, go figure */ 1285 } 1286 if (wincount >= MAX_WINDOWS_OPEN) 1287 { /* hard code message at MAX_WINDOWS_OPEN = 450 */ 1288 static FCODE msg[] = {"Sorry...no more space, 450 displayed."}; 1289 texttempmsg(msg); 1290 } 1291 if (vid_too_big==2) 1292 { 1293 static FCODE msg[] = {"Xdots + Ydots > 4096."}; 1294 texttempmsg(msg); 1295 } 1296 c=0; 1297 if (wincount) 1298 { 1299 buzzer(0); /*let user know we've finished */ 1300 index=0;done = 0; 1301 MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); 1302 MoveFromMemory((BYTE *)boxx,vidlength,1L,(long)index,boxxhandle); 1303 MoveFromMemory((BYTE *)boxy,vidlength,1L,(long)index,boxyhandle); 1304 MoveFromMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)index,boxvalueshandle); 1305 showtempmsg(winlist.name); 1306 while ( !done) /* on exit done = 1 for quick exit, 1307 done = 2 for erase boxes and exit 1308 done = 3 for rescan 1309 done = 4 for set boxes and exit to save image */ 1310 { 1311 #ifdef XFRACT
1312 blinks = 1;
1313 #endif 1314 while (!keypressed()) 1315 { 1316 time(&thistime); 1317 if (difftime(thistime,lastime) > .2 ) { 1318 lastime=thistime; 1319 toggle = 1- toggle; 1320 } 1321 if (toggle) 1322 drawindow(color_bright,&winlist); /* flash current window */ 1323 else 1324 drawindow(color_dark,&winlist); 1325 #ifdef XFRACT
1326 blinks++;
1327 #endif 1328 } 1329 #ifdef XFRACT
1330 if ((blinks & 1) == 1) /* Need an odd # of blinks, so next one leaves box turned off */ 1331 drawindow(color_bright,&winlist);
1332 #endif 1333 1334 c=getakey(); 1335 switch (c) { 1336 case RIGHT_ARROW: 1337 case LEFT_ARROW: 1338 case DOWN_ARROW: 1339 case UP_ARROW: 1340 cleartempmsg(); 1341 drawindow(color_of_box,&winlist);/* dim last window */ 1342 if (c==RIGHT_ARROW || c== UP_ARROW) { 1343 index++; /* shift attention to next window */ 1344 if (index >= wincount) index=0; 1345 } 1346 else { 1347 index -- ; 1348 if ( index < 0 ) index = wincount -1 ; 1349 } 1350 MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); 1351 MoveFromMemory((BYTE *)boxx,vidlength,1L,(long)index,boxxhandle); 1352 MoveFromMemory((BYTE *)boxy,vidlength,1L,(long)index,boxyhandle); 1353 MoveFromMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)index,boxvalueshandle); 1354 showtempmsg(winlist.name); 1355 break; 1356 #ifndef XFRACT 1357 case CTL_INSERT: 1358 color_of_box += key_count(CTL_INSERT); 1359 for (i=0 ; i < wincount ; i++) { 1360 MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)i,browsehandle); 1361 drawindow(color_of_box,&winlist); 1362 } 1363 MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); 1364 drawindow(color_of_box,&winlist); 1365 break; 1366 1367 case CTL_DEL: 1368 color_of_box -= key_count(CTL_DEL); 1369 for (i=0 ; i < wincount ; i++) { 1370 MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)i,browsehandle); 1371 drawindow(color_of_box,&winlist); 1372 } 1373 MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); 1374 drawindow(color_of_box,&winlist); 1375 break; 1376 #endif 1377 case ENTER: 1378 case ENTER_2: /* this file please */ 1379 far_strcpy(browsename,winlist.name); 1380 done = 1; 1381 break; 1382 1383 case ESC: 1384 case 'l': 1385 case 'L': 1386 #ifdef XFRACT
1387 /* Need all boxes turned on, turn last one back on. */ 1388 drawindow(color_bright,&winlist);
1389 #endif 1390 autobrowse = FALSE; 1391 done = 2; 1392 break; 1393 1394 case 'D': /* delete file */ 1395 cleartempmsg(); 1396 strcpy(mesg,""); 1397 strcat(mesg,"Delete "); 1398 far_strcat(mesg,winlist.name); 1399 strcat(mesg,"? (Y/N)"); 1400 showtempmsg(mesg); 1401 while (!keypressed()) ; 1402 cleartempmsg(); 1403 c = getakey(); 1404 if ( c == 'Y' && doublecaution ) { 1405 static FCODE msg[] = {"ARE YOU SURE???? (Y/N)"}; 1406 texttempmsg(msg); 1407 if ( getakey() != 'Y') c = 'N'; 1408 } 1409 if ( c == 'Y' ) { 1410 splitpath(readname,drive,dir,NULL,NULL); 1411 splitpath(winlist.name,NULL,NULL,fname,ext); 1412 makepath(tmpmask,drive,dir,fname,ext); 1413 if ( !unlink(tmpmask)) { 1414 /* do a rescan */ 1415 done = 3; 1416 far_strcpy(oldname,winlist.name); 1417 tmpmask[0] = '\0'; 1418 check_history(oldname,tmpmask); 1419 break; 1420 } 1421 else if( errno == EACCES ) { 1422 static FCODE msg[] = {"Sorry...it's a read only file, can't del"}; 1423 texttempmsg(msg); 1424 showtempmsg(winlist.name); 1425 break; 1426 } 1427 } 1428 { 1429 static FCODE msg[] = {"file not deleted (phew!)"}; 1430 texttempmsg(msg); 1431 } 1432 showtempmsg(winlist.name); 1433 break; 1434 1435 case 'R': 1436 cleartempmsg(); 1437 stackscreen(); 1438 newname[0] = 0; 1439 strcpy(mesg,""); 1440 { 1441 static FCODE msg[] = {"Enter the new filename for "}; 1442 far_strcat((char far *)mesg,msg); 1443 } 1444 splitpath(readname,drive,dir,NULL,NULL); 1445 splitpath(winlist.name,NULL,NULL,fname,ext); 1446 makepath(tmpmask,drive,dir,fname,ext); 1447 strcpy(newname,tmpmask); 1448 strcat(mesg,tmpmask); 1449 i = field_prompt(0,mesg,NULL,newname,60,NULL); 1450 unstackscreen(); 1451 if( i != -1) 1452 if (!rename(tmpmask,newname)) { 1453 if (errno == EACCES) 1454 { 1455 static FCODE msg[] = {"sorry....can't rename"}; 1456 texttempmsg(msg); 1457 } 1458 else { 1459 splitpath(newname,NULL,NULL,fname,ext); 1460 makepath(tmpmask,NULL,NULL,fname,ext); 1461 far_strcpy(oldname,winlist.name); 1462 check_history(oldname,tmpmask); 1463 far_strcpy(winlist.name,tmpmask); 1464 } 1465 } 1466 MoveToMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); 1467 showtempmsg(winlist.name); 1468 break; 1469 1470 case 2: /* ctrl B */ 1471 cleartempmsg(); 1472 stackscreen(); 1473 done = abs(get_browse_params()); 1474 unstackscreen(); 1475 showtempmsg(winlist.name); 1476 break; 1477 1478 case 's': /* save image with boxes */ 1479 autobrowse = FALSE; 1480 drawindow(color_of_box,&winlist); /* current window white */ 1481 done = 4; 1482 break; 1483 1484 case '\\': /*back out to last image */ 1485 done = 2; 1486 break; 1487 1488 default: 1489 break; 1490 } /*switch */ 1491 } /*while*/ 1492 1493 /* now clean up memory (and the screen if necessary) */ 1494 cleartempmsg(); 1495 if (done >= 1 && done < 4) { 1496 for (index=wincount-1;index>=0;index--){ /* don't need index, reuse it */ 1497 MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle); 1498 boxcount = winlist.boxcount; 1499 MoveFromMemory((BYTE *)boxx,vidlength,1L,(long)index,boxxhandle); 1500 MoveFromMemory((BYTE *)boxy,vidlength,1L,(long)index,boxyhandle); 1501 MoveFromMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)index,boxvalueshandle); 1502 boxcount >>= 1; 1503 if (boxcount > 0 ) 1504 #ifdef XFRACT
1505 /* Turn all boxes off */ 1506 drawindow(color_bright,&winlist);
1507 #else 1508 clearbox(); 1509 #endif 1510 } 1511 } 1512 if (done == 3) { 1513 goto rescan; /* hey everybody I just used the g word! */ 1514 } 1515 }/*if*/ 1516 else { 1517 static FCODE msg[] = {"sorry.. I can't find anything"}; 1518 buzzer(1); /*no suitable files in directory! */ 1519 texttempmsg(msg); 1520 no_sub_images = TRUE; 1521 } 1522 1523 MemoryRelease(browsehandle); 1524 MemoryRelease(boxxhandle); 1525 MemoryRelease(boxyhandle); 1526 MemoryRelease(boxvalueshandle); 1527 restore_stack(saved); 1528 if (!oldbf_math) 1529 free_bf_vars(); 1530 bf_math = oldbf_math; 1531 floatflag = usr_floatflag; 1532 1533 return(c); 1534 } 1535 1536 1537 static void drawindow(int colour,struct window *info) 1538 { 1539 #ifndef XFRACT 1540 int cross_size; 1541 struct coords ibl,itr; 1542 #endif 1543 1544 boxcolor=colour; 1545 boxcount = 0; 1546 if (info->win_size >= minbox) { 1547 /* big enough on screen to show up as a box so draw it */ 1548 /* corner pixels */ 1549 #ifndef XFRACT 1550 addbox(info->itl); 1551 addbox(info->itr); 1552 addbox(info->ibl); 1553 addbox(info->ibr); 1554 drawlines(info->itl,info->itr,info->ibl.x-info->itl.x,info->ibl.y-info->itl.y); /* top & bottom lines */ 1555 drawlines(info->itl,info->ibl,info->itr.x-info->itl.x,info->itr.y-info->itl.y); /* left & right lines */
1556 #else 1557 boxx[0] = info->itl.x + sxoffs; 1558 boxy[0] = info->itl.y + syoffs; 1559 boxx[1] = info->itr.x + sxoffs; 1560 boxy[1] = info->itr.y + syoffs; 1561 boxx[2] = info->ibr.x + sxoffs; 1562 boxy[2] = info->ibr.y + syoffs; 1563 boxx[3] = info->ibl.x + sxoffs; 1564 boxy[3] = info->ibl.y + syoffs; 1565 boxcount = 4;
1566 #endif 1567 dispbox(); 1568 } 1569 else { /* draw crosshairs */ 1570 #ifndef XFRACT 1571 cross_size = ydots / 45; 1572 if (cross_size < 2) cross_size = 2; 1573 itr.x = info->itl.x - cross_size; 1574 itr.y = info->itl.y; 1575 ibl.y = info->itl.y - cross_size; 1576 ibl.x = info->itl.x; 1577 drawlines(info->itl,itr,ibl.x-itr.x,0); /* top & bottom lines */ 1578 drawlines(info->itl,ibl,0,itr.y-ibl.y); /* left & right lines */ 1579 dispbox(); 1580 #endif 1581 } 1582 } 1583 1584 /* maps points onto view screen*/ 1585 static void transform(struct dblcoords *point) 1586 { 1587 double tmp_pt_x; 1588 tmp_pt_x = cvt->a * point->x + cvt->b * point->y + cvt->e; 1589 point->y = cvt->c * point->x + cvt->d * point->y + cvt->f; 1590 point->x = tmp_pt_x; 1591 } 1592 1593 static char is_visible_window 1594 ( struct window *list, struct fractal_info *info, 1595 struct ext_blk_5 *blk_5_info ) 1596 { 1597 struct dblcoords tl,tr,bl,br; 1598 bf_t bt_x, bt_y; 1599 bf_t bt_xmin, bt_xmax, bt_ymin, bt_ymax, bt_x3rd, bt_y3rd; 1600 int saved; 1601 int two_len; 1602 int cornercount, cant_see; 1603 int orig_bflength, 1604 orig_bnlength, 1605 orig_padding, 1606 orig_rlength, 1607 orig_shiftfactor, 1608 orig_rbflength; 1609 double toobig, tmp_sqrt; 1610 toobig = sqrt(sqr((double)sxdots)+sqr((double)sydots)) * 1.5; 1611 /* arbitrary value... stops browser zooming out too far */ 1612 cornercount=0; 1613 cant_see = 0; 1614 1615 saved = save_stack(); 1616 /* Save original values. */ 1617 orig_bflength = bflength; 1618 orig_bnlength = bnlength; 1619 orig_padding = padding; 1620 orig_rlength = rlength; 1621 orig_shiftfactor = shiftfactor; 1622 orig_rbflength = rbflength; 1623 /* 1624 if (oldbf_math && info->bf_math && (bnlength+4 < info->bflength)) { 1625 bnlength = info->bflength; 1626 calc_lengths(); 1627 } 1628 */ 1629 two_len = bflength + 2; 1630 bt_x = alloc_stack(two_len); 1631 bt_y = alloc_stack(two_len); 1632 bt_xmin = alloc_stack(two_len); 1633 bt_xmax = alloc_stack(two_len); 1634 bt_ymin = alloc_stack(two_len); 1635 bt_ymax = alloc_stack(two_len); 1636 bt_x3rd = alloc_stack(two_len); 1637 bt_y3rd = alloc_stack(two_len); 1638 1639 if (info->bf_math) { 1640 bf_t bt_t1, bt_t2, bt_t3, bt_t4, bt_t5, bt_t6; 1641 int di_bflength, two_di_len, two_rbf; 1642 1643 di_bflength = info->bflength + bnstep; 1644 two_di_len = di_bflength + 2; 1645 two_rbf = rbflength + 2; 1646 1647 n_a = alloc_stack(two_rbf); 1648 n_b = alloc_stack(two_rbf); 1649 n_c = alloc_stack(two_rbf); 1650 n_d = alloc_stack(two_rbf); 1651 n_e = alloc_stack(two_rbf); 1652 n_f = alloc_stack(two_rbf); 1653 1654 convert_bf(n_a, bt_a, rbflength, orig_rbflength); 1655 convert_bf(n_b, bt_b, rbflength, orig_rbflength); 1656 convert_bf(n_c, bt_c, rbflength, orig_rbflength); 1657 convert_bf(n_d, bt_d, rbflength, orig_rbflength); 1658 convert_bf(n_e, bt_e, rbflength, orig_rbflength); 1659 convert_bf(n_f, bt_f, rbflength, orig_rbflength); 1660 1661 bt_t1 = alloc_stack(two_di_len); 1662 bt_t2 = alloc_stack(two_di_len); 1663 bt_t3 = alloc_stack(two_di_len); 1664 bt_t4 = alloc_stack(two_di_len); 1665 bt_t5 = alloc_stack(two_di_len); 1666 bt_t6 = alloc_stack(two_di_len); 1667 1668 far_memcpy((char far *)bt_t1,blk_5_info->apm_data,(two_di_len)); 1669 far_memcpy((char far *)bt_t2,blk_5_info->apm_data+two_di_len,(two_di_len)); 1670 far_memcpy((char far *)bt_t3,blk_5_info->apm_data+2*two_di_len,(two_di_len)); 1671 far_memcpy((char far *)bt_t4,blk_5_info->apm_data+3*two_di_len,(two_di_len)); 1672 far_memcpy((char far *)bt_t5,blk_5_info->apm_data+4*two_di_len,(two_di_len)); 1673 far_memcpy((char far *)bt_t6,blk_5_info->apm_data+5*two_di_len,(two_di_len)); 1674 1675 convert_bf(bt_xmin, bt_t1, two_len, two_di_len); 1676 convert_bf(bt_xmax, bt_t2, two_len, two_di_len); 1677 convert_bf(bt_ymin, bt_t3, two_len, two_di_len); 1678 convert_bf(bt_ymax, bt_t4, two_len, two_di_len); 1679 convert_bf(bt_x3rd, bt_t5, two_len, two_di_len); 1680 convert_bf(bt_y3rd, bt_t6, two_len, two_di_len); 1681 } 1682 1683 /* tranform maps real plane co-ords onto the current screen view 1684 see above */ 1685 if (oldbf_math || info->bf_math) { 1686 if (!info->bf_math) { 1687 floattobf(bt_x, info->xmin); 1688 floattobf(bt_y, info->ymax); 1689 } 1690 else { 1691 copy_bf(bt_x, bt_xmin); 1692 copy_bf(bt_y, bt_ymax); 1693 } 1694 bftransform(bt_x, bt_y, &tl); 1695 } 1696 else { 1697 tl.x=info->xmin; 1698 tl.y=info->ymax; 1699 transform(&tl); 1700 } 1701 list->itl.x=(int)(tl.x + 0.5); 1702 list->itl.y=(int)(tl.y + 0.5); 1703 if (oldbf_math || info->bf_math) { 1704 if (!info->bf_math) { 1705 floattobf(bt_x, (info->xmax)-(info->x3rd-info->xmin)); 1706 floattobf(bt_y, (info->ymax)+(info->ymin-info->y3rd)); 1707 } 1708 else { 1709 neg_a_bf(sub_bf(bt_x, bt_x3rd, bt_xmin)); 1710 add_a_bf(bt_x, bt_xmax); 1711 sub_bf(bt_y, bt_ymin, bt_y3rd); 1712 add_a_bf(bt_y, bt_ymax); 1713 } 1714 bftransform(bt_x, bt_y, &tr); 1715 } 1716 else { 1717 tr.x=(info->xmax)-(info->x3rd-info->xmin); 1718 tr.y=(info->ymax)+(info->ymin-info->y3rd); 1719 transform(&tr); 1720 } 1721 list->itr.x=(int)(tr.x + 0.5); 1722 list->itr.y=(int)(tr.y + 0.5); 1723 if (oldbf_math || info->bf_math) { 1724 if (!info->bf_math) { 1725 floattobf(bt_x, info->x3rd); 1726 floattobf(bt_y, info->y3rd); 1727 } 1728 else { 1729 copy_bf(bt_x, bt_x3rd); 1730 copy_bf(bt_y, bt_y3rd); 1731 } 1732 bftransform(bt_x, bt_y, &bl); 1733 } 1734 else { 1735 bl.x=info->x3rd; 1736 bl.y=info->y3rd; 1737 transform(&bl); 1738 } 1739 list->ibl.x=(int)(bl.x + 0.5); 1740 list->ibl.y=(int)(bl.y + 0.5); 1741 if (oldbf_math || info->bf_math) { 1742 if (!info->bf_math) { 1743 floattobf(bt_x, info->xmax); 1744 floattobf(bt_y, info->ymin); 1745 } 1746 else { 1747 copy_bf(bt_x, bt_xmax); 1748 copy_bf(bt_y, bt_ymin); 1749 } 1750 bftransform(bt_x, bt_y, &br); 1751 } 1752 else { 1753 br.x=info->xmax; 1754 br.y=info->ymin; 1755 transform(&br); 1756 } 1757 list->ibr.x=(int)(br.x + 0.5); 1758 list->ibr.y=(int)(br.y + 0.5); 1759 1760 tmp_sqrt = sqrt(sqr(tr.x-bl.x) + sqr(tr.y-bl.y)); 1761 list->win_size = tmp_sqrt; /* used for box vs crosshair in drawindow() */ 1762 if (tmp_sqrt < toosmall ) cant_see = 1; 1763 /* reject anything too small onscreen */ 1764 if (tmp_sqrt > toobig ) cant_see = 1; 1765 /* or too big... */ 1766 1767 /* restore original values */ 1768 bflength = orig_bflength; 1769 bnlength = orig_bnlength; 1770 padding = orig_padding; 1771 rlength = orig_rlength; 1772 shiftfactor = orig_shiftfactor; 1773 rbflength = orig_rbflength; 1774 1775 restore_stack(saved); 1776 if (cant_see) /* do it this way so bignum stack is released */ 1777 return(FALSE); 1778 1779 /* now see how many corners are on the screen, accept if one or more */ 1780 if ( tl.x >=(0-sxoffs) && tl.x <= (sxdots-sxoffs) && tl.y >=(0-syoffs) && tl.y<= (sydots-syoffs) ) cornercount ++; 1781 if ( bl.x >=(0-sxoffs) && bl.x <= (sxdots-sxoffs) && bl.y >=(0-syoffs) && bl.y<= (sydots-syoffs) ) cornercount ++; 1782 if ( tr.x >=(0-sxoffs) && tr.x <= (sxdots-sxoffs) && tr.y >=(0-syoffs) && tr.y<= (sydots-syoffs) ) cornercount ++; 1783 if ( br.x >=(0-sxoffs) && br.x <= (sxdots-sxoffs) && br.y >=(0-syoffs) && br.y<= (sydots-syoffs) ) cornercount ++; 1784 1785 if (cornercount >=1 ) return( TRUE ); 1786 else return( FALSE ); 1787 } 1788 1789 static char paramsOK( struct fractal_info *info ) 1790 { 1791 double tmpparm3, tmpparm4; 1792 double tmpparm5, tmpparm6; 1793 double tmpparm7, tmpparm8; 1794 double tmpparm9, tmpparm10; 1795 #define MINDIF 0.001 1796 1797 if( info->version > 6) { 1798 tmpparm3 = info->dparm3; 1799 tmpparm4 = info->dparm4; 1800 } 1801 else{ 1802 tmpparm3 = info->parm3; 1803 roundfloatd(&tmpparm3); 1804 tmpparm4 = info->parm4; 1805 roundfloatd(&tmpparm4); 1806 } 1807 if( info->version > 8) { 1808 tmpparm5 = info->dparm5; 1809 tmpparm6 = info->dparm6; 1810 tmpparm7 = info->dparm7; 1811 tmpparm8 = info->dparm8; 1812 tmpparm9 = info->dparm9; 1813 tmpparm10 = info->dparm10; 1814 } 1815 else{ 1816 tmpparm5 = 0.0; 1817 tmpparm6 = 0.0; 1818 tmpparm7 = 0.0; 1819 tmpparm8 = 0.0; 1820 tmpparm9 = 0.0; 1821 tmpparm10 = 0.0; 1822 } 1823 if( fabs(info->creal - param[0]) < MINDIF && 1824 fabs(info->cimag - param[1]) < MINDIF && 1825 fabs(tmpparm3 - param[2]) < MINDIF && 1826 fabs(tmpparm4 - param[3]) < MINDIF && 1827 fabs(tmpparm5 - param[4]) < MINDIF && 1828 fabs(tmpparm6 - param[5]) < MINDIF && 1829 fabs(tmpparm7 - param[6]) < MINDIF && 1830 fabs(tmpparm8 - param[7]) < MINDIF && 1831 fabs(tmpparm9 - param[8]) < MINDIF && 1832 fabs(tmpparm10 - param[9]) < MINDIF && 1833 info->invert[0] - inversion[0] < MINDIF) 1834 return(1); /* parameters are in range */ 1835 else 1836 return(0); 1837 } 1838 1839 static char functionOK( struct fractal_info *info, int numfn) 1840 { 1841 int i, mzmatch; 1842 mzmatch = 0; 1843 for(i=0; i<numfn; i++){ 1844 if( info->trigndx[i] != trigndx[i] ) 1845 mzmatch++; 1846 } 1847 if(mzmatch > 0) 1848 return(0); 1849 else 1850 return(1); /* they all match */ 1851 } 1852 1853 static char typeOK( struct fractal_info *info, struct ext_blk_3 *blk_3_info ) 1854 { 1855 int numfn; 1856 if( (fractype == FORMULA || fractype == FFORMULA) && 1857 (info->fractal_type == FORMULA || info->fractal_type == FFORMULA) ) 1858 { 1859 if( !stricmp(blk_3_info->form_name,FormName) ) 1860 { 1861 numfn = maxfn; 1862 if (numfn>0) 1863 return(functionOK(info, numfn)); 1864 else 1865 return(1); /* match up formula names with no functions */ 1866 } 1867 else 1868 return(0); /* two formulas but names don't match */ 1869 } 1870 else if(info->fractal_type == fractype || 1871 info->fractal_type == curfractalspecific->tofloat) 1872 { 1873 numfn = (curfractalspecific->flags >> 6) & 7; 1874 if (numfn>0) 1875 return(functionOK(info, numfn)); 1876 else 1877 return(1); /* match types with no functions */ 1878 } 1879 else 1880 return(0); /* no match */ 1881 } 1882 1883 static void check_history ( char *oldname, char *newname ) 1884 { 1885 int i; 1886 1887 /* file_name_stack[] is maintained in framain2.c. It is the history */ 1888 /* file for the browser and holds a maximum of 16 images. The history */ 1889 /* file needs to be adjusted if the rename or delete functions of the */ 1890 /* browser are used. */ 1891 /* name_stack_ptr is also maintained in framain2.c. It is the index into */ 1892 /* file_name_stack[]. */ 1893 1894 for (i=0;i<name_stack_ptr;i++) { 1895 if (stricmp(file_name_stack[i],oldname) == 0) /* we have a match */ 1896 strcpy(file_name_stack[i],newname); /* insert the new name */ 1897 } 1898 } 1899 1900 static void bfsetup_convert_to_screen(void) 1901 { 1902 /* setup_convert_to_screen() in LORENZ.C, converted to bf_math */ 1903 /* Call only from within fgetwindow() */ 1904 bf_t bt_det, bt_xd, bt_yd, bt_tmp1, bt_tmp2; 1905 bf_t bt_inter1, bt_inter2; 1906 int saved; 1907 1908 saved = save_stack(); 1909 bt_inter1 = alloc_stack(rbflength+2); 1910 bt_inter2 = alloc_stack(rbflength+2); 1911 bt_det = alloc_stack(rbflength+2); 1912 bt_xd = alloc_stack(rbflength+2); 1913 bt_yd = alloc_stack(rbflength+2); 1914 bt_tmp1 = alloc_stack(rbflength+2); 1915 bt_tmp2 = alloc_stack(rbflength+2); 1916 1917 /* xx3rd-xxmin */ 1918 sub_bf(bt_inter1, bfx3rd, bfxmin); 1919 /* yymin-yymax */ 1920 sub_bf(bt_inter2, bfymin, bfymax); 1921 /* (xx3rd-xxmin)*(yymin-yymax) */ 1922 mult_bf(bt_tmp1, bt_inter1, bt_inter2); 1923 1924 /* yymax-yy3rd */ 1925 sub_bf(bt_inter1, bfymax, bfy3rd); 1926 /* xxmax-xxmin */ 1927 sub_bf(bt_inter2, bfxmax, bfxmin); 1928 /* (yymax-yy3rd)*(xxmax-xxmin) */ 1929 mult_bf(bt_tmp2, bt_inter1, bt_inter2); 1930 1931 /* det = (xx3rd-xxmin)*(yymin-yymax) + (yymax-yy3rd)*(xxmax-xxmin) */ 1932 add_bf(bt_det, bt_tmp1, bt_tmp2); 1933 1934 /* xd = dxsize/det */ 1935 floattobf(bt_tmp1, dxsize); 1936 div_bf(bt_xd, bt_tmp1, bt_det); 1937 1938 /* a = xd*(yymax-yy3rd) */ 1939 sub_bf(bt_inter1, bfymax, bfy3rd); 1940 mult_bf(bt_a, bt_xd, bt_inter1); 1941 1942 /* b = xd*(xx3rd-xxmin) */ 1943 sub_bf(bt_inter1, bfx3rd, bfxmin); 1944 mult_bf(bt_b, bt_xd, bt_inter1); 1945 1946 /* e = -(a*xxmin + b*yymax) */ 1947 mult_bf(bt_tmp1, bt_a, bfxmin); 1948 mult_bf(bt_tmp2, bt_b, bfymax); 1949 neg_a_bf(add_bf(bt_e, bt_tmp1, bt_tmp2)); 1950 1951 /* xx3rd-xxmax */ 1952 sub_bf(bt_inter1, bfx3rd, bfxmax); 1953 /* yymin-yymax */ 1954 sub_bf(bt_inter2, bfymin, bfymax); 1955 /* (xx3rd-xxmax)*(yymin-yymax) */ 1956 mult_bf(bt_tmp1, bt_inter1, bt_inter2); 1957 1958 /* yymin-yy3rd */ 1959 sub_bf(bt_inter1, bfymin, bfy3rd); 1960 /* xxmax-xxmin */ 1961 sub_bf(bt_inter2, bfxmax, bfxmin); 1962 /* (yymin-yy3rd)*(xxmax-xxmin) */ 1963 mult_bf(bt_tmp2, bt_inter1, bt_inter2); 1964 1965 /* det = (xx3rd-xxmax)*(yymin-yymax) + (yymin-yy3rd)*(xxmax-xxmin) */ 1966 add_bf(bt_det, bt_tmp1, bt_tmp2); 1967 1968 /* yd = dysize/det */ 1969 floattobf(bt_tmp2, dysize); 1970 div_bf(bt_yd, bt_tmp2, bt_det); 1971 1972 /* c = yd*(yymin-yy3rd) */ 1973 sub_bf(bt_inter1, bfymin, bfy3rd); 1974 mult_bf(bt_c, bt_yd, bt_inter1); 1975 1976 /* d = yd*(xx3rd-xxmax) */ 1977 sub_bf(bt_inter1, bfx3rd, bfxmax); 1978 mult_bf(bt_d, bt_yd, bt_inter1); 1979 1980 /* f = -(c*xxmin + d*yymax) */ 1981 mult_bf(bt_tmp1, bt_c, bfxmin); 1982 mult_bf(bt_tmp2, bt_d, bfymax); 1983 neg_a_bf(add_bf(bt_f, bt_tmp1, bt_tmp2)); 1984 1985 restore_stack(saved); 1986 } 1987 1988 /* maps points onto view screen*/ 1989 static void bftransform(bf_t bt_x, bf_t bt_y, struct dblcoords *point) 1990 { 1991 bf_t bt_tmp1, bt_tmp2; 1992 int saved; 1993 1994 saved = save_stack(); 1995 bt_tmp1 = alloc_stack(rbflength+2); 1996 bt_tmp2 = alloc_stack(rbflength+2); 1997 1998 /* point->x = cvt->a * point->x + cvt->b * point->y + cvt->e; */ 1999 mult_bf(bt_tmp1, n_a, bt_x); 2000 mult_bf(bt_tmp2, n_b, bt_y); 2001 add_a_bf(bt_tmp1, bt_tmp2); 2002 add_a_bf(bt_tmp1, n_e); 2003 point->x = (double)bftofloat(bt_tmp1); 2004 2005 /* point->y = cvt->c * point->x + cvt->d * point->y + cvt->f; */ 2006 mult_bf(bt_tmp1, n_c, bt_x); 2007 mult_bf(bt_tmp2, n_d, bt_y); 2008 add_a_bf(bt_tmp1, bt_tmp2); 2009 add_a_bf(bt_tmp1, n_f); 2010 point->y = (double)bftofloat(bt_tmp1); 2011 2012 restore_stack(saved); 2013 } 2014