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 
read_overlay()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 
find_fractal_info(char * gif_file,struct fractal_info * info,struct ext_blk_2 * blk_2_info,struct ext_blk_3 * blk_3_info,struct ext_blk_4 * blk_4_info,struct ext_blk_5 * blk_5_info,struct ext_blk_6 * blk_6_info,struct ext_blk_7 * blk_7_info)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    int dummy; /* to quiet compiler */
553 
554    blk_2_info->got_data = 0; /* initialize to no data */
555    blk_3_info->got_data = 0; /* initialize to no data */
556    blk_4_info->got_data = 0; /* initialize to no data */
557    blk_5_info->got_data = 0; /* initialize to no data */
558    blk_6_info->got_data = 0; /* initialize to no data */
559    blk_7_info->got_data = 0; /* initialize to no data */
560 
561    if((fp = fopen(gif_file,"rb"))==NULL)
562       return(-1);
563    dummy = fread(gifstart,13,1,fp);
564    if (strncmp((char *)gifstart,"GIF",3) != 0) { /* not GIF, maybe old .tga? */
565       fclose(fp);
566       return(-1);
567    }
568 
569    filetype = 0; /* GIF */
570    GET16(gifstart[6],filexdots);
571    GET16(gifstart[8],fileydots);
572    filecolors = 2 << (gifstart[10] & 7);
573    fileaspectratio = 0; /* unknown */
574    if (gifstart[12]) { /* calc reasonably close value from gif header */
575       fileaspectratio = (float)((64.0 / ((double)(gifstart[12]) + 15.0))
576                       * (double)fileydots / (double)filexdots);
577       if ( fileaspectratio > screenaspect-0.03
578         && fileaspectratio < screenaspect+0.03)
579          fileaspectratio = screenaspect;
580       }
581    else
582       if (fileydots * 4 == filexdots * 3) /* assume the common square pixels */
583          fileaspectratio = screenaspect;
584 
585    if(*s_makepar == 0 && (gifstart[10] & 0x80)!=0)
586    {
587       for (i = 0; i < filecolors; i++)
588       {
589          for (j = 0; j < 3; j++) {
590             if ((k = getc(fp)) < 0)
591                break;
592             dacbox[i][j] = (BYTE)(k >> 2);
593          }
594          if(k < 0)
595             break;
596       }
597    }
598 
599    /* Format of .gif extension blocks is:
600           1 byte    '!', extension block identifier
601           1 byte    extension block number, 255
602           1 byte    length of id, 11
603          11 bytes   alpha id, "fractintnnn" with fractint, nnn is secondary id
604        n * {
605           1 byte    length of block info in bytes
606           x bytes   block info
607            }
608           1 byte    0, extension terminator
609       To scan extension blocks, we first look in file at length of fractal_info
610       (the main extension block) from end of file, looking for a literal known
611       to be at start of our block info.  Then we scan forward a bit, in case
612       the file is from an earlier fractint vsn with shorter fractal_info.
613       If fractal_info is found and is from vsn>=14, it includes the total length
614       of all extension blocks; we then scan them all first to last to load
615       any optional ones which are present.
616       Defined extension blocks:
617         fractint001     header, always present
618         fractint002     resume info for interrupted resumable image
619         fractint003     additional formula type info
620         fractint004     ranges info
621         fractint005     extended precision parameters
622         fractint006     evolver params
623    */
624 
625    memset(info,0,FRACTAL_INFO_SIZE);
626    fractinf_len = FRACTAL_INFO_SIZE + (FRACTAL_INFO_SIZE+254)/255;
627    fseek(fp,(long)(-1-fractinf_len),SEEK_END);
628    dummy = fread(info,1,FRACTAL_INFO_SIZE,fp);
629    if (strcmp(INFO_ID,info->info_id) == 0) {
630 #ifdef XFRACT
631        decode_fractal_info(info,1);
632 #endif
633       hdr_offset = -1-fractinf_len;
634    } else {
635       /* didn't work 1st try, maybe an older vsn, maybe junk at eof, scan: */
636       int offset,i;
637       char tmpbuf[110];
638       hdr_offset = 0;
639       offset = 80; /* don't even check last 80 bytes of file for id */
640       while (offset < fractinf_len+513) { /* allow 512 garbage at eof */
641          offset += 100; /* go back 100 bytes at a time */
642          fseek(fp,(long)(0-offset),SEEK_END);
643          dummy = fread(tmpbuf,1,110,fp); /* read 10 extra for string compare */
644          for (i = 0; i < 100; ++i)
645             if (!strcmp(INFO_ID,&tmpbuf[i])) { /* found header? */
646                strcpy(info->info_id,INFO_ID);
647                fseek(fp,(long)(hdr_offset=i-offset),SEEK_END);
648                dummy = fread(info,1,FRACTAL_INFO_SIZE,fp);
649 #ifdef XFRACT
650                decode_fractal_info(info,1);
651 #endif
652                offset = 10000; /* force exit from outer loop */
653                break;
654                }
655          }
656       }
657 
658    if (hdr_offset) { /* we found INFO_ID */
659 
660       if (info->version >= 4) {
661          /* first reload main extension block, reasons:
662               might be over 255 chars, and thus earlier load might be bad
663               find exact endpoint, so scan back to start of ext blks works
664             */
665          fseek(fp,(long)(hdr_offset-15),SEEK_END);
666          scan_extend = 1;
667          while (scan_extend) {
668             if (fgetc(fp) != '!' /* if not what we expect just give up */
669               || fread(temp1,1,13,fp) != 13
670               || strncmp(&temp1[2],"fractint",8))
671                break;
672             temp1[13] = 0;
673             block_type = atoi(&temp1[10]); /* e.g. "fractint002" */
674             switch (block_type) {
675                case 1: /* "fractint001", the main extension block */
676                   if (scan_extend == 2) { /* we've been here before, done now */
677                      scan_extend = 0;
678                      break;
679                      }
680                   load_ext_blk((char far *)info,FRACTAL_INFO_SIZE);
681 #ifdef XFRACT
682                   decode_fractal_info(info,1);
683 #endif
684                   scan_extend = 2;
685                   /* now we know total extension len, back up to first block */
686                   fseek(fp,0L-info->tot_extend_len,SEEK_CUR);
687                   break;
688                case 2: /* resume info */
689                   skip_ext_blk(&block_len,&data_len); /* once to get lengths */
690                   if ((blk_2_info->resume_data = MemoryAlloc((U16)1,(long)data_len,FARMEM)) == 0)
691                      info->calc_status = 3; /* not resumable after all */
692                   else {
693                      fseek(fp,(long)(0-block_len),SEEK_CUR);
694                      load_ext_blk((char far *)block,data_len);
695                      MoveToMemory((BYTE *)block,(U16)1,(long)data_len,0,(U16)blk_2_info->resume_data);
696                      blk_2_info->length = data_len;
697                      blk_2_info->got_data = 1; /* got data */
698                      }
699                   break;
700                case 3: /* formula info */
701                   skip_ext_blk(&block_len,&data_len); /* once to get lengths */
702                 /* check data_len for backward compatibility */
703                   fseek(fp,(long)(0-block_len),SEEK_CUR);
704                   load_ext_blk((char far *)&fload_info,data_len);
705                   strcpy(blk_3_info->form_name,fload_info.form_name);
706                   blk_3_info->length = data_len;
707                   blk_3_info->got_data = 1; /* got data */
708                   if (data_len < sizeof(fload_info)) { /* must be old GIF */
709                      blk_3_info->uses_p1 = 1;
710                      blk_3_info->uses_p2 = 1;
711                      blk_3_info->uses_p3 = 1;
712                      blk_3_info->uses_ismand = 0;
713                      blk_3_info->ismand = 1;
714                      blk_3_info->uses_p4 = 0;
715                      blk_3_info->uses_p5 = 0;
716                   }
717                   else {
718                      blk_3_info->uses_p1 = fload_info.uses_p1;
719                      blk_3_info->uses_p2 = fload_info.uses_p2;
720                      blk_3_info->uses_p3 = fload_info.uses_p3;
721                      blk_3_info->uses_ismand = fload_info.uses_ismand;
722                      blk_3_info->ismand = fload_info.ismand;
723                      blk_3_info->uses_p4 = fload_info.uses_p4;
724                      blk_3_info->uses_p5 = fload_info.uses_p5;
725                   }
726                   break;
727                case 4: /* ranges info */
728                   skip_ext_blk(&block_len,&data_len); /* once to get lengths */
729                   if ((blk_4_info->range_data = (int far *)farmemalloc((long)data_len)) != NULL) {
730                      fseek(fp,(long)(0-block_len),SEEK_CUR);
731                      load_ext_blk((char far *)blk_4_info->range_data,data_len);
732                      blk_4_info->length = data_len/2;
733                      blk_4_info->got_data = 1; /* got data */
734                      }
735                   break;
736                case 5: /* extended precision parameters  */
737                   skip_ext_blk(&block_len,&data_len); /* once to get lengths */
738                   if ((blk_5_info->apm_data = (char far *)farmemalloc((long)data_len)) != NULL) {
739                      fseek(fp,(long)(0-block_len),SEEK_CUR);
740                      load_ext_blk(blk_5_info->apm_data,data_len);
741                      blk_5_info->length = data_len;
742                      blk_5_info->got_data = 1; /* got data */
743                      }
744                   break;
745                case 6: /* evolver params */
746                   skip_ext_blk(&block_len,&data_len); /* once to get lengths */
747                   fseek(fp,(long)(0-block_len),SEEK_CUR);
748                   load_ext_blk((char far *)&eload_info,data_len);
749                   /* XFRACT processing of doubles here */
750 #ifdef XFRACT
751                   decode_evolver_info(&eload_info,1);
752 #endif
753                   blk_6_info->length = data_len;
754                   blk_6_info->got_data = 1; /* got data */
755 
756                   blk_6_info->paramrangex     = eload_info.paramrangex;
757                   blk_6_info->paramrangey     = eload_info.paramrangey;
758                   blk_6_info->opx             = eload_info.opx;
759                   blk_6_info->opy             = eload_info.opy;
760                   blk_6_info->odpx            = (char)eload_info.odpx;
761                   blk_6_info->odpy            = (char)eload_info.odpy;
762                   blk_6_info->px              = eload_info.px;
763                   blk_6_info->py              = eload_info.py;
764                   blk_6_info->sxoffs          = eload_info.sxoffs;
765                   blk_6_info->syoffs          = eload_info.syoffs;
766                   blk_6_info->xdots           = eload_info.xdots;
767                   blk_6_info->ydots           = eload_info.ydots;
768                   blk_6_info->gridsz          = eload_info.gridsz;
769                   blk_6_info->evolving        = eload_info.evolving;
770                   blk_6_info->this_gen_rseed  = eload_info.this_gen_rseed;
771                   blk_6_info->fiddlefactor    = eload_info.fiddlefactor;
772                   blk_6_info->ecount          = eload_info.ecount;
773                   for (i = 0; i < NUMGENES; i++)
774                      blk_6_info->mutate[i]    = eload_info.mutate[i];
775                   break;
776                case 7: /* orbits parameters  */
777                   skip_ext_blk(&block_len,&data_len); /* once to get lengths */
778                   fseek(fp,(long)(0-block_len),SEEK_CUR);
779                   load_ext_blk((char far *)&oload_info,data_len);
780                   /* XFRACT processing of doubles here */
781 #ifdef XFRACT
782                   decode_orbits_info(&oload_info,1);
783 #endif
784                   blk_7_info->length = data_len;
785                   blk_7_info->got_data = 1; /* got data */
786                   blk_7_info->oxmin           = oload_info.oxmin;
787                   blk_7_info->oxmax           = oload_info.oxmax;
788                   blk_7_info->oymin           = oload_info.oymin;
789                   blk_7_info->oymax           = oload_info.oymax;
790                   blk_7_info->ox3rd           = oload_info.ox3rd;
791                   blk_7_info->oy3rd           = oload_info.oy3rd;
792                   blk_7_info->keep_scrn_coords= oload_info.keep_scrn_coords;
793                   blk_7_info->drawmode        = oload_info.drawmode;
794                   break;
795                default:
796                   skip_ext_blk(&block_len,&data_len);
797                }
798             }
799          }
800 
801       fclose(fp);
802       fileaspectratio = screenaspect; /* if not >= v15, this is correct */
803       return(0);
804       }
805 
806    strcpy(info->info_id, "GIFFILE");
807    info->iterations = 150;
808    info->iterationsold = 150;
809    info->fractal_type = PLASMA;
810    info->xmin = -1;
811    info->xmax = 1;
812    info->ymin = -1;
813    info->ymax = 1;
814    info->x3rd = -1;
815    info->y3rd = -1;
816    info->creal = 0;
817    info->cimag = 0;
818    info->videomodeax=255;
819    info->videomodebx=255;
820    info->videomodecx=255;
821    info->videomodedx=255;
822    info->dotmode = 0;
823    info->xdots = (short)filexdots;
824    info->ydots = (short)fileydots;
825    info->colors = (short)filecolors;
826    info->version = 0; /* this forces lots more init at calling end too */
827 
828    /* zero means we won */
829    fclose(fp);
830    return(0);
831 }
832 
load_ext_blk(char far * loadptr,int loadlen)833 static void load_ext_blk(char far *loadptr,int loadlen)
834 {
835    int len;
836    while ((len = fgetc(fp)) > 0) {
837       while (--len >= 0) {
838          if (--loadlen >= 0)
839             *(loadptr++) = (char)fgetc(fp);
840          else
841             fgetc(fp); /* discard excess characters */
842          }
843       }
844 }
845 
skip_ext_blk(int * block_len,int * data_len)846 static void skip_ext_blk(int *block_len, int *data_len)
847 {
848    int len;
849    *data_len = 0;
850    *block_len = 1;
851    while ((len = fgetc(fp)) > 0) {
852       fseek(fp,(long)len,SEEK_CUR);
853       *data_len += len;
854       *block_len += len + 1;
855       }
856 }
857 
858 
859 /* switch obsolete fractal types to new generalizations */
backwardscompat(struct fractal_info * info)860 static void backwardscompat(struct fractal_info *info)
861 {
862    switch(fractype) {
863       case LAMBDASINE:
864          fractype = LAMBDATRIGFP;
865          trigndx[0] = SIN;
866          break;
867       case LAMBDACOS    :
868          fractype = LAMBDATRIGFP;
869          trigndx[0] = COS;
870          break;
871       case LAMBDAEXP    :
872          fractype = LAMBDATRIGFP;
873          trigndx[0] = EXP;
874          break;
875       case MANDELSINE   :
876          fractype = MANDELTRIGFP;
877          trigndx[0] = SIN;
878          break;
879       case MANDELCOS    :
880          fractype = MANDELTRIGFP;
881          trigndx[0] = COS;
882          break;
883       case MANDELEXP    :
884          fractype = MANDELTRIGFP;
885          trigndx[0] = EXP;
886          break;
887       case MANDELSINH   :
888          fractype = MANDELTRIGFP;
889          trigndx[0] = SINH;
890          break;
891       case LAMBDASINH   :
892          fractype = LAMBDATRIGFP;
893          trigndx[0] = SINH;
894          break;
895       case MANDELCOSH   :
896          fractype = MANDELTRIGFP;
897          trigndx[0] = COSH;
898          break;
899       case LAMBDACOSH   :
900          fractype = LAMBDATRIGFP;
901          trigndx[0] = COSH;
902          break;
903       case LMANDELSINE  :
904          fractype = MANDELTRIG;
905          trigndx[0] = SIN;
906          break;
907       case LLAMBDASINE  :
908          fractype = LAMBDATRIG;
909          trigndx[0] = SIN;
910          break;
911       case LMANDELCOS   :
912          fractype = MANDELTRIG;
913          trigndx[0] = COS;
914          break;
915       case LLAMBDACOS   :
916          fractype = LAMBDATRIG;
917          trigndx[0] = COS;
918          break;
919       case LMANDELSINH  :
920          fractype = MANDELTRIG;
921          trigndx[0] = SINH;
922          break;
923       case LLAMBDASINH  :
924          fractype = LAMBDATRIG;
925          trigndx[0] = SINH;
926          break;
927       case LMANDELCOSH  :
928          fractype = MANDELTRIG;
929          trigndx[0] = COSH;
930          break;
931       case LLAMBDACOSH  :
932          fractype = LAMBDATRIG;
933          trigndx[0] = COSH;
934          break;
935       case LMANDELEXP   :
936          fractype = MANDELTRIG;
937          trigndx[0] = EXP;
938          break;
939       case LLAMBDAEXP   :
940          fractype = LAMBDATRIG;
941          trigndx[0] = EXP;
942          break;
943       case DEMM         :
944          fractype = MANDELFP;
945          usr_distest = (info->ydots - 1) * 2;
946          break;
947       case DEMJ         :
948          fractype = JULIAFP;
949          usr_distest = (info->ydots - 1) * 2;
950          break;
951       case MANDELLAMBDA :
952          useinitorbit = 2;
953          break;
954       }
955    curfractalspecific = &fractalspecific[fractype];
956 }
957 
958 /* switch old bifurcation fractal types to new generalizations */
set_if_old_bif(void)959 void set_if_old_bif(void)
960 {
961 /* set functions if not set already, may need to check 'functionpreloaded'
962    before calling this routine.  JCO 7/5/92 */
963 
964    switch(fractype) {
965       case BIFURCATION:
966       case LBIFURCATION:
967       case BIFSTEWART:
968       case LBIFSTEWART:
969       case BIFLAMBDA:
970       case LBIFLAMBDA:
971         set_trig_array(0,s_ident);
972         break;
973 
974       case BIFEQSINPI:
975       case LBIFEQSINPI:
976       case BIFADSINPI:
977       case LBIFADSINPI:
978         set_trig_array(0,s_sin);
979         break;
980    }
981 }
982 
983 /* miscellaneous function variable defaults */
set_function_parm_defaults(void)984 void set_function_parm_defaults(void)
985 {
986    switch(fractype)
987    {
988       case FPPOPCORN:
989       case LPOPCORN:
990       case FPPOPCORNJUL:
991       case LPOPCORNJUL:
992          set_trig_array(0,s_sin);
993          set_trig_array(1,s_tan);
994          set_trig_array(2,s_sin);
995          set_trig_array(3,s_tan);
996          break;
997       case LATOO:
998          set_trig_array(0,s_sin);
999          set_trig_array(1,s_sin);
1000          set_trig_array(2,s_sin);
1001          set_trig_array(3,s_sin);
1002          break;
1003    }
1004 }
1005 
backwards_v18(void)1006 void backwards_v18(void)
1007 {
1008   if(!functionpreloaded)
1009     set_if_old_bif(); /* old bifs need function set, JCO 7/5/92 */
1010   if(fractype==MANDELTRIG && usr_floatflag==1
1011          && save_release < 1800 && bailout == 0)
1012     bailout = 2500;
1013   if(fractype==LAMBDATRIG && usr_floatflag==1
1014          && save_release < 1800 && bailout == 0)
1015     bailout = 2500;
1016 }
1017 
backwards_v19(void)1018 void backwards_v19(void)
1019 {
1020   if(fractype==MARKSJULIA && save_release < 1825) {
1021     if(param[2] == 0)
1022        param[2] = 2;
1023     else
1024        param[2] += 1;
1025   }
1026   if(fractype==MARKSJULIAFP && save_release < 1825) {
1027     if(param[2] == 0)
1028        param[2] = 2;
1029     else
1030        param[2] += 1;
1031   }
1032   if((fractype==FORMULA || fractype==FFORMULA) && save_release < 1824)
1033     inversion[0] = inversion[1] = inversion[2] = invert = 0;
1034   if(fix_bof())
1035     no_mag_calc = 1; /* fractal has old bof60/61 problem with magnitude */
1036   else
1037     no_mag_calc = 0;
1038   if(fix_period_bof())
1039     use_old_period = 1; /* fractal uses old periodicity method */
1040   else
1041     use_old_period = 0;
1042   if(save_release < 1827 && distest)
1043     use_old_distest = 1; /* use old distest code */
1044   else
1045     use_old_distest = 0; /* use new distest code */
1046 }
1047 
backwards_v20(void)1048 void backwards_v20(void)
1049 { /* Fractype == FP type is not seen from PAR file ????? */
1050   if((fractype == MANDELFP || fractype == JULIAFP ||
1051       fractype == MANDEL || fractype == JULIA) &&
1052      (outside <= REAL && outside >= SUM) && save_release <= 1960)
1053     bad_outside = 1;
1054   else
1055     bad_outside = 0;
1056   if((fractype == FORMULA || fractype == FFORMULA) &&
1057       (save_release < 1900 || debugflag == 94))
1058     ldcheck = 1;
1059   else
1060     ldcheck = 0;
1061   if(inside == EPSCROSS && save_release < 1961)
1062     closeprox = 0.01;
1063   if(!functionpreloaded)
1064      set_function_parm_defaults();
1065 }
1066 
check_back(void)1067 int check_back(void) {
1068 /*
1069    put the features that need to save the value in save_release for backwards
1070    compatibility in this routine
1071 */
1072 int ret = 0;
1073    if (fractype == LYAPUNOV ||
1074        fractype == FROTH || fractype == FROTHFP ||
1075        fix_bof() || fix_period_bof() || use_old_distest || decomp[0] == 2 ||
1076        (fractype == FORMULA && save_release <= 1920) ||
1077        (fractype == FFORMULA && save_release <= 1920) ||
1078        (LogFlag != 0 && save_release <= 2001) ||
1079        (fractype == TRIGSQR && save_release < 1900) ||
1080        (inside == STARTRAIL && save_release < 1825) ||
1081        (maxit > 32767 && save_release <= 1950) ||
1082        (distest && save_release <=1950) ||
1083        ((outside <= REAL && outside >= ATAN) &&
1084           save_release <= 1960) ||
1085        (fractype == FPPOPCORN && save_release <= 1960) ||
1086        (fractype == LPOPCORN && save_release <= 1960) ||
1087        (fractype == FPPOPCORNJUL && save_release <= 1960) ||
1088        (fractype == LPOPCORNJUL && save_release <= 1960) ||
1089        (inside == FMODI && save_release <= 2000) ||
1090        ((inside == ATANI || outside == ATAN) && save_release <= 2005) ||
1091        (fractype == LAMBDATRIGFP && trigndx[0] == EXP && save_release <= 2002) ||
1092        ((fractype == JULIBROT || fractype == JULIBROTFP) &&
1093           (neworbittype == QUATFP || neworbittype == HYPERCMPLXFP) &&
1094            save_release <= 2002)
1095        )
1096      ret = 1;
1097    return(ret);
1098 }
1099 
fix_bof(void)1100 static int fix_bof(void)
1101 {
1102 int ret = 0;
1103  if (inside <= BOF60 && inside >= BOF61 && save_release < 1826)
1104     if ((curfractalspecific->calctype == StandardFractal &&
1105         (curfractalspecific->flags & BAILTEST) == 0) ||
1106         (fractype==FORMULA || fractype==FFORMULA))
1107         ret = 1;
1108 return (ret);
1109 }
1110 
fix_period_bof(void)1111 static int fix_period_bof(void)
1112 {
1113 int ret = 0;
1114  if (inside <= BOF60 && inside >= BOF61 && save_release < 1826)
1115     ret = 1;
1116 return (ret);
1117 }
1118 
1119 /* browse code RB*/
1120 
1121 #define MAX_WINDOWS_OPEN 450
1122 
1123   struct window {       /* for fgetwindow on screen browser */
1124      struct coords itl; /* screen coordinates */
1125      struct coords ibl;
1126      struct coords itr;
1127      struct coords ibr;
1128      double win_size;   /* box size for drawindow() */
1129      char name[MAX_NAME];     /* for filename */
1130      int boxcount;      /* bytes of saved screen info */
1131      };
1132 
1133 /* prototypes */
1134 static void drawindow( int, struct window * );
1135 static char is_visible_window
1136             ( struct window *, struct fractal_info *, struct ext_blk_5 * );
1137 static void transform( struct dblcoords * );
1138 static char paramsOK( struct fractal_info * );
1139 static char typeOK( struct fractal_info *, struct ext_blk_3 * );
1140 static char functionOK( struct fractal_info *, int );
1141 static void check_history( char *, char * );
1142 static void bfsetup_convert_to_screen( void );
1143 static void bftransform( bf_t, bf_t, struct dblcoords * );
1144 
1145 char browsename[MAX_NAME]; /* name for browse file */
1146 U16 browsehandle;
1147 U16 boxxhandle;
1148 U16 boxyhandle;
1149 U16 boxvalueshandle;
1150 
1151 /* here because must be visible inside several routines */
1152 static struct affine *cvt;
1153 static bf_t   bt_a, bt_b, bt_c, bt_d, bt_e, bt_f;
1154 static bf_t   n_a, n_b, n_c, n_d, n_e, n_f;
1155 int oldbf_math;
1156 
1157 /* fgetwindow reads all .GIF files and draws window outlines on the screen */
fgetwindow(void)1158 int fgetwindow(void)
1159   {
1160     struct affine stack_cvt;
1161     struct fractal_info read_info;
1162     struct ext_blk_2 blk_2_info;
1163     struct ext_blk_3 blk_3_info;
1164     struct ext_blk_4 blk_4_info;
1165     struct ext_blk_5 blk_5_info;
1166     struct ext_blk_6 blk_6_info;
1167     struct ext_blk_7 blk_7_info;
1168     time_t thistime,lastime;
1169     char mesg[40],newname[60],oldname[60];
1170     int c,i,index,done,wincount,toggle,color_of_box;
1171     struct window winlist;
1172     char drive[FILE_MAX_DRIVE];
1173     char dir[FILE_MAX_DIR];
1174     char fname[FILE_MAX_FNAME];
1175     char ext[FILE_MAX_EXT];
1176     char tmpmask[FILE_MAX_PATH];
1177     int vid_too_big = 0;
1178     int no_memory = 0;
1179     U16 vidlength;
1180     BYTE *winlistptr = (BYTE *)&winlist;
1181     int saved;
1182 #ifdef XFRACT
1183     U32 blinks;
1184 #endif
1185 
1186    oldbf_math = bf_math;
1187    bf_math = BIGFLT;
1188    if (!oldbf_math) {
1189      int oldcalc_status = calc_status; /* kludge because next sets it = 0 */
1190       fractal_floattobf();
1191       calc_status = oldcalc_status;
1192    }
1193    saved = save_stack();
1194    bt_a = alloc_stack(rbflength+2);
1195    bt_b = alloc_stack(rbflength+2);
1196    bt_c = alloc_stack(rbflength+2);
1197    bt_d = alloc_stack(rbflength+2);
1198    bt_e = alloc_stack(rbflength+2);
1199    bt_f = alloc_stack(rbflength+2);
1200 
1201    if ((vidlength = (U16)(sxdots + sydots)) > (U16)4096)
1202       vid_too_big = 2;
1203    /* 4096 based on 4096B in boxx... max 1/4 pixels plotted, and need words */
1204    /* 4096 = 10240/2.5 based on size of boxx+boxy+boxvalues */
1205 #ifdef XFRACT
1206    vidlength = 4; /* Xfractint only needs the 4 corners saved. */
1207 #endif
1208    browsehandle = MemoryAlloc((U16)sizeof(struct window),(long)MAX_WINDOWS_OPEN,FARMEM);
1209    boxxhandle = MemoryAlloc((U16)(vidlength),(long)MAX_WINDOWS_OPEN,EXPANDED);
1210    boxyhandle = MemoryAlloc((U16)(vidlength),(long)MAX_WINDOWS_OPEN,EXPANDED);
1211    boxvalueshandle = MemoryAlloc((U16)(vidlength>>1),(long)MAX_WINDOWS_OPEN,EXPANDED);
1212    if(!browsehandle || !boxxhandle || !boxyhandle || !boxvalueshandle)
1213       no_memory = 1;
1214 
1215      /* set up complex-plane-to-screen transformation */
1216    if (oldbf_math) {
1217         bfsetup_convert_to_screen();
1218         }
1219    else {
1220         cvt = &stack_cvt; /* use stack */
1221         setup_convert_to_screen(cvt);
1222         /* put in bf variables */
1223         floattobf(bt_a, cvt->a);
1224         floattobf(bt_b, cvt->b);
1225         floattobf(bt_c, cvt->c);
1226         floattobf(bt_d, cvt->d);
1227         floattobf(bt_e, cvt->e);
1228         floattobf(bt_f, cvt->f);
1229         }
1230      find_special_colors();
1231      color_of_box = color_medium;
1232 rescan:  /* entry for changed browse parms */
1233      time(&lastime);
1234      toggle = 0;
1235      wincount = 0;
1236      no_sub_images = FALSE;
1237      splitpath(readname,drive,dir,NULL,NULL);
1238      splitpath(browsemask,NULL,NULL,fname,ext);
1239      makepath(tmpmask,drive,dir,fname,ext);
1240      done=(vid_too_big==2) || no_memory || fr_findfirst(tmpmask);
1241                                    /* draw all visible windows */
1242      while (!done)
1243      {
1244        if(keypressed())
1245        {
1246           getakey();
1247           break;
1248        }
1249        splitpath(DTA.filename,NULL,NULL,fname,ext);
1250        makepath(tmpmask,drive,dir,fname,ext);
1251        if( !find_fractal_info(tmpmask,&read_info,&blk_2_info,&blk_3_info,
1252                                      &blk_4_info,&blk_5_info,&blk_6_info,
1253 				     &blk_7_info) &&
1254            (typeOK(&read_info,&blk_3_info) || !brwschecktype) &&
1255            (paramsOK(&read_info) || !brwscheckparms) &&
1256            stricmp(browsename,DTA.filename) &&
1257            blk_6_info.got_data != 1 &&
1258            is_visible_window(&winlist,&read_info,&blk_5_info)
1259          )
1260          {
1261            far_strcpy(winlist.name,DTA.filename);
1262            drawindow(color_of_box,&winlist);
1263            boxcount <<= 1; /*boxcount*2;*/ /* double for byte count */
1264            winlist.boxcount = boxcount;
1265            MoveToMemory(winlistptr,(U16)sizeof(struct window),1L,(long)wincount,browsehandle);
1266            MoveToMemory((BYTE *)boxx,vidlength,1L,(long)wincount,boxxhandle);
1267            MoveToMemory((BYTE *)boxy,vidlength,1L,(long)wincount,boxyhandle);
1268            MoveToMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)wincount,boxvalueshandle);
1269            wincount++;
1270          }
1271 
1272         if(blk_2_info.got_data == 1) /* Clean up any far memory allocated */
1273            MemoryRelease((U16)blk_2_info.resume_data);
1274         if(blk_4_info.got_data == 1) /* Clean up any far memory allocated */
1275            farmemfree(blk_4_info.range_data);
1276         if(blk_5_info.got_data == 1) /* Clean up any far memory allocated */
1277            farmemfree(blk_5_info.apm_data);
1278 
1279         done=(fr_findnext() || wincount >= MAX_WINDOWS_OPEN);
1280       }
1281 
1282       if (no_memory)
1283       {
1284          static FCODE msg[] = {"Sorry...not enough memory to browse."};
1285        texttempmsg(msg);/* doesn't work if NO far memory available, go figure */
1286       }
1287       if (wincount >= MAX_WINDOWS_OPEN)
1288       { /* hard code message at MAX_WINDOWS_OPEN = 450 */
1289          static FCODE msg[] = {"Sorry...no more space, 450 displayed."};
1290        texttempmsg(msg);
1291       }
1292       if (vid_too_big==2)
1293       {
1294          static FCODE msg[] = {"Xdots + Ydots > 4096."};
1295        texttempmsg(msg);
1296       }
1297  c=0;
1298  if (wincount)
1299  {
1300       buzzer(0); /*let user know we've finished */
1301       index=0;done = 0;
1302       MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle);
1303       MoveFromMemory((BYTE *)boxx,vidlength,1L,(long)index,boxxhandle);
1304       MoveFromMemory((BYTE *)boxy,vidlength,1L,(long)index,boxyhandle);
1305       MoveFromMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)index,boxvalueshandle);
1306       showtempmsg(winlist.name);
1307       while ( !done)  /* on exit done = 1 for quick exit,
1308                                  done = 2 for erase boxes and  exit
1309                                  done = 3 for rescan
1310                                  done = 4 for set boxes and exit to save image */
1311       {
1312 #ifdef XFRACT
1313         blinks = 1;
1314 #endif
1315         while (!keypressed())
1316         {
1317           time(&thistime);
1318           if (difftime(thistime,lastime) > .2 ) {
1319              lastime=thistime;
1320              toggle = 1- toggle;
1321           }
1322           if (toggle)
1323              drawindow(color_bright,&winlist);   /* flash current window */
1324           else
1325              drawindow(color_dark,&winlist);
1326 #ifdef XFRACT
1327           blinks++;
1328 #endif
1329         }
1330 #ifdef XFRACT
1331           if ((blinks & 1) == 1)   /* Need an odd # of blinks, so next one leaves box turned off */
1332              drawindow(color_bright,&winlist);
1333 #endif
1334 
1335       c=getakey();
1336       switch (c) {
1337          case RIGHT_ARROW:
1338          case LEFT_ARROW:
1339          case DOWN_ARROW:
1340          case UP_ARROW:
1341            cleartempmsg();
1342            drawindow(color_of_box,&winlist);/* dim last window */
1343            if (c==RIGHT_ARROW || c== UP_ARROW) {
1344               index++;                     /* shift attention to next window */
1345               if (index >= wincount) index=0;
1346            }
1347            else {
1348              index -- ;
1349              if ( index < 0 )  index = wincount -1 ;
1350            }
1351            MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle);
1352            MoveFromMemory((BYTE *)boxx,vidlength,1L,(long)index,boxxhandle);
1353            MoveFromMemory((BYTE *)boxy,vidlength,1L,(long)index,boxyhandle);
1354            MoveFromMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)index,boxvalueshandle);
1355            showtempmsg(winlist.name);
1356            break;
1357 #ifndef XFRACT
1358         case CTL_INSERT:
1359           color_of_box += key_count(CTL_INSERT);
1360           for (i=0 ; i < wincount ; i++) {
1361               MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)i,browsehandle);
1362               drawindow(color_of_box,&winlist);
1363           }
1364           MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle);
1365           drawindow(color_of_box,&winlist);
1366           break;
1367 
1368         case CTL_DEL:
1369           color_of_box -= key_count(CTL_DEL);
1370           for (i=0 ; i < wincount ; i++) {
1371               MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)i,browsehandle);
1372               drawindow(color_of_box,&winlist);
1373           }
1374           MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle);
1375           drawindow(color_of_box,&winlist);
1376           break;
1377 #endif
1378         case ENTER:
1379         case ENTER_2:   /* this file please */
1380           far_strcpy(browsename,winlist.name);
1381           done = 1;
1382           break;
1383 
1384         case ESC:
1385         case 'l':
1386         case 'L':
1387 #ifdef XFRACT
1388         /* Need all boxes turned on, turn last one back on. */
1389           drawindow(color_bright,&winlist);
1390 #endif
1391           autobrowse = FALSE;
1392           done = 2;
1393           break;
1394 
1395         case 'D': /* delete file */
1396           cleartempmsg();
1397           strcpy(mesg,"");
1398           strcat(mesg,"Delete ");
1399           far_strcat(mesg,winlist.name);
1400           strcat(mesg,"? (Y/N)");
1401           showtempmsg(mesg);
1402           while (!keypressed()) ;
1403           cleartempmsg();
1404           c = getakey();
1405           if ( c == 'Y' && doublecaution ) {
1406            static FCODE msg[] = {"ARE YOU SURE???? (Y/N)"};
1407            texttempmsg(msg);
1408             if ( getakey() != 'Y') c = 'N';
1409           }
1410           if ( c == 'Y' ) {
1411           splitpath(readname,drive,dir,NULL,NULL);
1412           splitpath(winlist.name,NULL,NULL,fname,ext);
1413           makepath(tmpmask,drive,dir,fname,ext);
1414           if ( !unlink(tmpmask)) {
1415           /* do a rescan */
1416             done = 3;
1417             far_strcpy(oldname,winlist.name);
1418             tmpmask[0] = '\0';
1419             check_history(oldname,tmpmask);
1420             break;
1421             }
1422           else if( errno == EACCES ) {
1423               static FCODE msg[] = {"Sorry...it's a read only file, can't del"};
1424               texttempmsg(msg);
1425               showtempmsg(winlist.name);
1426               break;
1427               }
1428           }
1429           {
1430           static FCODE msg[] = {"file not deleted (phew!)"};
1431           texttempmsg(msg);
1432           }
1433           showtempmsg(winlist.name);
1434           break;
1435 
1436         case 'R':
1437          cleartempmsg();
1438          stackscreen();
1439          newname[0] = 0;
1440          strcpy(mesg,"");
1441          {
1442          static FCODE msg[] = {"Enter the new filename for "};
1443          far_strcat((char far *)mesg,msg);
1444          }
1445          splitpath(readname,drive,dir,NULL,NULL);
1446          splitpath(winlist.name,NULL,NULL,fname,ext);
1447          makepath(tmpmask,drive,dir,fname,ext);
1448          strcpy(newname,tmpmask);
1449          strcat(mesg,tmpmask);
1450          i = field_prompt(0,mesg,NULL,newname,60,NULL);
1451          unstackscreen();
1452          if( i != -1)
1453           if (!rename(tmpmask,newname)) {
1454             if (errno == EACCES)
1455             {
1456                static FCODE msg[] = {"sorry....can't rename"};
1457                 texttempmsg(msg);
1458             }
1459           else {
1460            splitpath(newname,NULL,NULL,fname,ext);
1461            makepath(tmpmask,NULL,NULL,fname,ext);
1462            far_strcpy(oldname,winlist.name);
1463            check_history(oldname,tmpmask);
1464            far_strcpy(winlist.name,tmpmask);
1465            }
1466           }
1467          MoveToMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle);
1468          showtempmsg(winlist.name);
1469          break;
1470 
1471         case 2: /* ctrl B */
1472           cleartempmsg();
1473           stackscreen();
1474           done = abs(get_browse_params());
1475           unstackscreen();
1476           showtempmsg(winlist.name);
1477           break;
1478 
1479         case 's': /* save image with boxes */
1480           autobrowse = FALSE;
1481           drawindow(color_of_box,&winlist); /* current window white */
1482           done = 4;
1483           break;
1484 
1485         case '\\': /*back out to last image */
1486           done = 2;
1487           break;
1488 
1489         default:
1490           break;
1491      } /*switch */
1492     } /*while*/
1493 
1494     /* now clean up memory (and the screen if necessary) */
1495     cleartempmsg();
1496     if (done >= 1 && done < 4) {
1497        for (index=wincount-1;index>=0;index--){ /* don't need index, reuse it */
1498           MoveFromMemory(winlistptr,(U16)sizeof(struct window),1L,(long)index,browsehandle);
1499           boxcount = winlist.boxcount;
1500           MoveFromMemory((BYTE *)boxx,vidlength,1L,(long)index,boxxhandle);
1501           MoveFromMemory((BYTE *)boxy,vidlength,1L,(long)index,boxyhandle);
1502           MoveFromMemory((BYTE *)boxvalues,(U16)(vidlength>>1),1L,(long)index,boxvalueshandle);
1503           boxcount >>= 1;
1504           if (boxcount > 0 )
1505 #ifdef XFRACT
1506         /* Turn all boxes off */
1507              drawindow(color_bright,&winlist);
1508 #else
1509              clearbox();
1510 #endif
1511        }
1512     }
1513     if (done == 3) {
1514        goto rescan; /* hey everybody I just used the g word! */
1515     }
1516  }/*if*/
1517  else {
1518    static FCODE msg[] = {"sorry.. I can't find anything"};
1519    buzzer(1); /*no suitable files in directory! */
1520    texttempmsg(msg);
1521    no_sub_images = TRUE;
1522  }
1523 
1524  MemoryRelease(browsehandle);
1525  MemoryRelease(boxxhandle);
1526  MemoryRelease(boxyhandle);
1527  MemoryRelease(boxvalueshandle);
1528  restore_stack(saved);
1529  if (!oldbf_math)
1530     free_bf_vars();
1531  bf_math = oldbf_math;
1532  floatflag = usr_floatflag;
1533 
1534  return(c);
1535 }
1536 
1537 
drawindow(int colour,struct window * info)1538 static void drawindow(int colour,struct window *info)
1539 {
1540 #ifndef XFRACT
1541    int cross_size;
1542    struct coords ibl,itr;
1543 #endif
1544 
1545    boxcolor=colour;
1546    boxcount = 0;
1547     if (info->win_size >= minbox) {
1548     /* big enough on screen to show up as a box so draw it */
1549     /* corner pixels */
1550 #ifndef XFRACT
1551      addbox(info->itl);
1552      addbox(info->itr);
1553      addbox(info->ibl);
1554      addbox(info->ibr);
1555      drawlines(info->itl,info->itr,info->ibl.x-info->itl.x,info->ibl.y-info->itl.y); /* top & bottom lines */
1556      drawlines(info->itl,info->ibl,info->itr.x-info->itl.x,info->itr.y-info->itl.y); /* left & right lines */
1557 #else
1558      boxx[0] = info->itl.x + sxoffs;
1559      boxy[0] = info->itl.y + syoffs;
1560      boxx[1] = info->itr.x + sxoffs;
1561      boxy[1] = info->itr.y + syoffs;
1562      boxx[2] = info->ibr.x + sxoffs;
1563      boxy[2] = info->ibr.y + syoffs;
1564      boxx[3] = info->ibl.x + sxoffs;
1565      boxy[3] = info->ibl.y + syoffs;
1566      boxcount = 4;
1567 #endif
1568      dispbox();
1569     }
1570     else { /* draw crosshairs */
1571 #ifndef XFRACT
1572     cross_size = ydots / 45;
1573     if (cross_size < 2) cross_size = 2;
1574     itr.x = info->itl.x - cross_size;
1575     itr.y = info->itl.y;
1576     ibl.y = info->itl.y - cross_size;
1577     ibl.x = info->itl.x;
1578     drawlines(info->itl,itr,ibl.x-itr.x,0); /* top & bottom lines */
1579     drawlines(info->itl,ibl,0,itr.y-ibl.y); /* left & right lines */
1580     dispbox();
1581 #endif
1582    }
1583 }
1584 
1585 /* maps points onto view screen*/
transform(struct dblcoords * point)1586 static void transform(struct dblcoords *point)
1587 {
1588   double tmp_pt_x;
1589   tmp_pt_x = cvt->a * point->x + cvt->b * point->y + cvt->e;
1590   point->y = cvt->c * point->x + cvt->d * point->y + cvt->f;
1591   point->x = tmp_pt_x;
1592 }
1593 
is_visible_window(struct window * list,struct fractal_info * info,struct ext_blk_5 * blk_5_info)1594 static char is_visible_window
1595             ( struct window *list, struct fractal_info *info,
1596               struct ext_blk_5 *blk_5_info )
1597 {
1598  struct dblcoords tl,tr,bl,br;
1599  bf_t bt_x, bt_y;
1600  bf_t bt_xmin, bt_xmax, bt_ymin, bt_ymax, bt_x3rd, bt_y3rd;
1601  int saved;
1602  int two_len;
1603  int cornercount, cant_see;
1604  int  orig_bflength,
1605       orig_bnlength,
1606       orig_padding,
1607       orig_rlength,
1608       orig_shiftfactor,
1609       orig_rbflength;
1610  double toobig, tmp_sqrt;
1611  toobig = sqrt(sqr((double)sxdots)+sqr((double)sydots)) * 1.5;
1612   /* arbitrary value... stops browser zooming out too far */
1613  cornercount=0;
1614  cant_see = 0;
1615 
1616    saved = save_stack();
1617     /* Save original values. */
1618    orig_bflength      = bflength;
1619    orig_bnlength      = bnlength;
1620    orig_padding       = padding;
1621    orig_rlength       = rlength;
1622    orig_shiftfactor   = shiftfactor;
1623    orig_rbflength     = rbflength;
1624 /*
1625    if (oldbf_math && info->bf_math && (bnlength+4 < info->bflength)) {
1626       bnlength = info->bflength;
1627       calc_lengths();
1628    }
1629 */
1630    two_len = bflength + 2;
1631    bt_x = alloc_stack(two_len);
1632    bt_y = alloc_stack(two_len);
1633    bt_xmin = alloc_stack(two_len);
1634    bt_xmax = alloc_stack(two_len);
1635    bt_ymin = alloc_stack(two_len);
1636    bt_ymax = alloc_stack(two_len);
1637    bt_x3rd = alloc_stack(two_len);
1638    bt_y3rd = alloc_stack(two_len);
1639 
1640    if (info->bf_math) {
1641     bf_t   bt_t1, bt_t2, bt_t3, bt_t4, bt_t5, bt_t6;
1642     int di_bflength, two_di_len, two_rbf;
1643 
1644       di_bflength = info->bflength + bnstep;
1645       two_di_len = di_bflength + 2;
1646       two_rbf = rbflength + 2;
1647 
1648       n_a     = alloc_stack(two_rbf);
1649       n_b     = alloc_stack(two_rbf);
1650       n_c     = alloc_stack(two_rbf);
1651       n_d     = alloc_stack(two_rbf);
1652       n_e     = alloc_stack(two_rbf);
1653       n_f     = alloc_stack(two_rbf);
1654 
1655       convert_bf(n_a, bt_a, rbflength, orig_rbflength);
1656       convert_bf(n_b, bt_b, rbflength, orig_rbflength);
1657       convert_bf(n_c, bt_c, rbflength, orig_rbflength);
1658       convert_bf(n_d, bt_d, rbflength, orig_rbflength);
1659       convert_bf(n_e, bt_e, rbflength, orig_rbflength);
1660       convert_bf(n_f, bt_f, rbflength, orig_rbflength);
1661 
1662       bt_t1   = alloc_stack(two_di_len);
1663       bt_t2   = alloc_stack(two_di_len);
1664       bt_t3   = alloc_stack(two_di_len);
1665       bt_t4   = alloc_stack(two_di_len);
1666       bt_t5   = alloc_stack(two_di_len);
1667       bt_t6   = alloc_stack(two_di_len);
1668 
1669       far_memcpy((char far *)bt_t1,blk_5_info->apm_data,(two_di_len));
1670       far_memcpy((char far *)bt_t2,blk_5_info->apm_data+two_di_len,(two_di_len));
1671       far_memcpy((char far *)bt_t3,blk_5_info->apm_data+2*two_di_len,(two_di_len));
1672       far_memcpy((char far *)bt_t4,blk_5_info->apm_data+3*two_di_len,(two_di_len));
1673       far_memcpy((char far *)bt_t5,blk_5_info->apm_data+4*two_di_len,(two_di_len));
1674       far_memcpy((char far *)bt_t6,blk_5_info->apm_data+5*two_di_len,(two_di_len));
1675 
1676       convert_bf(bt_xmin, bt_t1, two_len, two_di_len);
1677       convert_bf(bt_xmax, bt_t2, two_len, two_di_len);
1678       convert_bf(bt_ymin, bt_t3, two_len, two_di_len);
1679       convert_bf(bt_ymax, bt_t4, two_len, two_di_len);
1680       convert_bf(bt_x3rd, bt_t5, two_len, two_di_len);
1681       convert_bf(bt_y3rd, bt_t6, two_len, two_di_len);
1682    }
1683 
1684    /* tranform maps real plane co-ords onto the current screen view
1685      see above */
1686    if (oldbf_math || info->bf_math) {
1687       if (!info->bf_math) {
1688          floattobf(bt_x, info->xmin);
1689          floattobf(bt_y, info->ymax);
1690       }
1691       else {
1692          copy_bf(bt_x, bt_xmin);
1693          copy_bf(bt_y, bt_ymax);
1694       }
1695       bftransform(bt_x, bt_y, &tl);
1696    }
1697    else {
1698       tl.x=info->xmin;
1699       tl.y=info->ymax;
1700       transform(&tl);
1701    }
1702    list->itl.x=(int)(tl.x + 0.5);
1703    list->itl.y=(int)(tl.y + 0.5);
1704    if (oldbf_math || info->bf_math) {
1705       if (!info->bf_math) {
1706          floattobf(bt_x, (info->xmax)-(info->x3rd-info->xmin));
1707          floattobf(bt_y, (info->ymax)+(info->ymin-info->y3rd));
1708       }
1709       else {
1710          neg_a_bf(sub_bf(bt_x, bt_x3rd, bt_xmin));
1711          add_a_bf(bt_x, bt_xmax);
1712          sub_bf(bt_y, bt_ymin, bt_y3rd);
1713          add_a_bf(bt_y, bt_ymax);
1714       }
1715       bftransform(bt_x, bt_y, &tr);
1716    }
1717    else {
1718       tr.x=(info->xmax)-(info->x3rd-info->xmin);
1719       tr.y=(info->ymax)+(info->ymin-info->y3rd);
1720       transform(&tr);
1721    }
1722    list->itr.x=(int)(tr.x + 0.5);
1723    list->itr.y=(int)(tr.y + 0.5);
1724    if (oldbf_math || info->bf_math) {
1725       if (!info->bf_math) {
1726          floattobf(bt_x, info->x3rd);
1727          floattobf(bt_y, info->y3rd);
1728       }
1729       else {
1730          copy_bf(bt_x, bt_x3rd);
1731          copy_bf(bt_y, bt_y3rd);
1732       }
1733       bftransform(bt_x, bt_y, &bl);
1734    }
1735    else {
1736       bl.x=info->x3rd;
1737       bl.y=info->y3rd;
1738       transform(&bl);
1739    }
1740    list->ibl.x=(int)(bl.x + 0.5);
1741    list->ibl.y=(int)(bl.y + 0.5);
1742    if (oldbf_math || info->bf_math) {
1743       if (!info->bf_math) {
1744          floattobf(bt_x, info->xmax);
1745          floattobf(bt_y, info->ymin);
1746       }
1747       else {
1748          copy_bf(bt_x, bt_xmax);
1749          copy_bf(bt_y, bt_ymin);
1750       }
1751       bftransform(bt_x, bt_y, &br);
1752    }
1753    else {
1754       br.x=info->xmax;
1755       br.y=info->ymin;
1756       transform(&br);
1757    }
1758    list->ibr.x=(int)(br.x + 0.5);
1759    list->ibr.y=(int)(br.y + 0.5);
1760 
1761    tmp_sqrt = sqrt(sqr(tr.x-bl.x) + sqr(tr.y-bl.y));
1762    list->win_size = tmp_sqrt; /* used for box vs crosshair in drawindow() */
1763    if (tmp_sqrt < toosmall ) cant_see = 1;
1764  /* reject anything too small onscreen */
1765    if (tmp_sqrt > toobig   ) cant_see = 1;
1766  /* or too big... */
1767 
1768  /* restore original values */
1769  bflength      = orig_bflength;
1770  bnlength      = orig_bnlength;
1771  padding       = orig_padding;
1772  rlength       = orig_rlength;
1773  shiftfactor   = orig_shiftfactor;
1774  rbflength     = orig_rbflength;
1775 
1776  restore_stack(saved);
1777  if (cant_see) /* do it this way so bignum stack is released */
1778     return(FALSE);
1779 
1780  /* now see how many corners are on the screen, accept if one or more */
1781  if ( tl.x >=(0-sxoffs) && tl.x <= (sxdots-sxoffs) && tl.y >=(0-syoffs) && tl.y<= (sydots-syoffs) ) cornercount ++;
1782  if ( bl.x >=(0-sxoffs) && bl.x <= (sxdots-sxoffs) && bl.y >=(0-syoffs) && bl.y<= (sydots-syoffs) ) cornercount ++;
1783  if ( tr.x >=(0-sxoffs) && tr.x <= (sxdots-sxoffs) && tr.y >=(0-syoffs) && tr.y<= (sydots-syoffs) ) cornercount ++;
1784  if ( br.x >=(0-sxoffs) && br.x <= (sxdots-sxoffs) && br.y >=(0-syoffs) && br.y<= (sydots-syoffs) ) cornercount ++;
1785 
1786  if (cornercount >=1 ) return( TRUE );
1787     else return( FALSE );
1788  }
1789 
paramsOK(struct fractal_info * info)1790 static char paramsOK( struct fractal_info *info )
1791 {
1792 double tmpparm3, tmpparm4;
1793 double tmpparm5, tmpparm6;
1794 double tmpparm7, tmpparm8;
1795 double tmpparm9, tmpparm10;
1796 #define MINDIF 0.001
1797 
1798    if( info->version > 6) {
1799      tmpparm3 = info->dparm3;
1800      tmpparm4 = info->dparm4;
1801    }
1802    else{
1803      tmpparm3 = info->parm3;
1804      roundfloatd(&tmpparm3);
1805      tmpparm4 = info->parm4;
1806      roundfloatd(&tmpparm4);
1807    }
1808    if( info->version > 8) {
1809      tmpparm5 = info->dparm5;
1810      tmpparm6 = info->dparm6;
1811      tmpparm7 = info->dparm7;
1812      tmpparm8 = info->dparm8;
1813      tmpparm9 = info->dparm9;
1814      tmpparm10 = info->dparm10;
1815    }
1816    else{
1817      tmpparm5 = 0.0;
1818      tmpparm6 = 0.0;
1819      tmpparm7 = 0.0;
1820      tmpparm8 = 0.0;
1821      tmpparm9 = 0.0;
1822      tmpparm10 = 0.0;
1823    }
1824    if( fabs(info->creal - param[0]) < MINDIF &&
1825        fabs(info->cimag - param[1]) < MINDIF &&
1826        fabs(tmpparm3 - param[2]) < MINDIF &&
1827        fabs(tmpparm4 - param[3]) < MINDIF &&
1828        fabs(tmpparm5 - param[4]) < MINDIF &&
1829        fabs(tmpparm6 - param[5]) < MINDIF &&
1830        fabs(tmpparm7 - param[6]) < MINDIF &&
1831        fabs(tmpparm8 - param[7]) < MINDIF &&
1832        fabs(tmpparm9 - param[8]) < MINDIF &&
1833        fabs(tmpparm10 - param[9]) < MINDIF &&
1834        info->invert[0] - inversion[0] < MINDIF)
1835       return(1); /* parameters are in range */
1836    else
1837       return(0);
1838 }
1839 
functionOK(struct fractal_info * info,int numfn)1840 static char functionOK( struct fractal_info *info, int numfn)
1841 {
1842  int i, mzmatch;
1843    mzmatch = 0;
1844    for(i=0; i<numfn; i++){
1845      if( info->trigndx[i] != trigndx[i] )
1846         mzmatch++;
1847    }
1848    if(mzmatch > 0)
1849      return(0);
1850    else
1851      return(1); /* they all match */
1852 }
1853 
typeOK(struct fractal_info * info,struct ext_blk_3 * blk_3_info)1854 static char typeOK( struct fractal_info *info, struct ext_blk_3 *blk_3_info )
1855 {
1856  int numfn;
1857    if( (fractype == FORMULA || fractype == FFORMULA) &&
1858      (info->fractal_type == FORMULA || info->fractal_type == FFORMULA) )
1859    {
1860        if( !stricmp(blk_3_info->form_name,FormName) )
1861        {
1862          numfn = maxfn;
1863          if (numfn>0)
1864            return(functionOK(info, numfn));
1865          else
1866            return(1); /* match up formula names with no functions */
1867        }
1868        else
1869          return(0); /* two formulas but names don't match */
1870    }
1871    else if(info->fractal_type == fractype ||
1872            info->fractal_type == curfractalspecific->tofloat)
1873    {
1874      numfn = (curfractalspecific->flags >> 6) & 7;
1875      if (numfn>0)
1876        return(functionOK(info, numfn));
1877      else
1878        return(1); /* match types with no functions */
1879    }
1880    else
1881        return(0); /* no match */
1882 }
1883 
check_history(char * oldname,char * newname)1884 static void check_history ( char *oldname, char *newname )
1885 {
1886 int i;
1887 
1888 /* file_name_stack[] is maintained in framain2.c.  It is the history */
1889 /*  file for the browser and holds a maximum of 16 images.  The history */
1890 /*  file needs to be adjusted if the rename or delete functions of the */
1891 /*  browser are used. */
1892 /* name_stack_ptr is also maintained in framain2.c.  It is the index into */
1893 /*  file_name_stack[]. */
1894 
1895    for (i=0;i<name_stack_ptr;i++) {
1896       if (stricmp(file_name_stack[i],oldname) == 0) /* we have a match */
1897          strcpy(file_name_stack[i],newname);    /* insert the new name */
1898    }
1899 }
1900 
bfsetup_convert_to_screen(void)1901 static void bfsetup_convert_to_screen(void)
1902 {
1903    /* setup_convert_to_screen() in LORENZ.C, converted to bf_math */
1904    /* Call only from within fgetwindow() */
1905  bf_t   bt_det, bt_xd, bt_yd, bt_tmp1, bt_tmp2;
1906  bf_t   bt_inter1, bt_inter2;
1907  int saved;
1908 
1909    saved = save_stack();
1910    bt_inter1 = alloc_stack(rbflength+2);
1911    bt_inter2 = alloc_stack(rbflength+2);
1912    bt_det = alloc_stack(rbflength+2);
1913    bt_xd  = alloc_stack(rbflength+2);
1914    bt_yd  = alloc_stack(rbflength+2);
1915    bt_tmp1 = alloc_stack(rbflength+2);
1916    bt_tmp2 = alloc_stack(rbflength+2);
1917 
1918    /* xx3rd-xxmin */
1919    sub_bf(bt_inter1, bfx3rd, bfxmin);
1920    /* yymin-yymax */
1921    sub_bf(bt_inter2, bfymin, bfymax);
1922    /* (xx3rd-xxmin)*(yymin-yymax) */
1923    mult_bf(bt_tmp1, bt_inter1, bt_inter2);
1924 
1925    /* yymax-yy3rd */
1926    sub_bf(bt_inter1, bfymax, bfy3rd);
1927    /* xxmax-xxmin */
1928    sub_bf(bt_inter2, bfxmax, bfxmin);
1929    /* (yymax-yy3rd)*(xxmax-xxmin) */
1930    mult_bf(bt_tmp2, bt_inter1, bt_inter2);
1931 
1932    /* det = (xx3rd-xxmin)*(yymin-yymax) + (yymax-yy3rd)*(xxmax-xxmin) */
1933    add_bf(bt_det, bt_tmp1, bt_tmp2);
1934 
1935    /* xd = dxsize/det */
1936    floattobf(bt_tmp1, dxsize);
1937    div_bf(bt_xd, bt_tmp1, bt_det);
1938 
1939    /* a =  xd*(yymax-yy3rd) */
1940    sub_bf(bt_inter1, bfymax, bfy3rd);
1941    mult_bf(bt_a, bt_xd, bt_inter1);
1942 
1943    /* b =  xd*(xx3rd-xxmin) */
1944    sub_bf(bt_inter1, bfx3rd, bfxmin);
1945    mult_bf(bt_b, bt_xd, bt_inter1);
1946 
1947    /* e = -(a*xxmin + b*yymax) */
1948    mult_bf(bt_tmp1, bt_a, bfxmin);
1949    mult_bf(bt_tmp2, bt_b, bfymax);
1950    neg_a_bf(add_bf(bt_e, bt_tmp1, bt_tmp2));
1951 
1952    /* xx3rd-xxmax */
1953    sub_bf(bt_inter1, bfx3rd, bfxmax);
1954    /* yymin-yymax */
1955    sub_bf(bt_inter2, bfymin, bfymax);
1956    /* (xx3rd-xxmax)*(yymin-yymax) */
1957    mult_bf(bt_tmp1, bt_inter1, bt_inter2);
1958 
1959    /* yymin-yy3rd */
1960    sub_bf(bt_inter1, bfymin, bfy3rd);
1961    /* xxmax-xxmin */
1962    sub_bf(bt_inter2, bfxmax, bfxmin);
1963    /* (yymin-yy3rd)*(xxmax-xxmin) */
1964    mult_bf(bt_tmp2, bt_inter1, bt_inter2);
1965 
1966    /* det = (xx3rd-xxmax)*(yymin-yymax) + (yymin-yy3rd)*(xxmax-xxmin) */
1967    add_bf(bt_det, bt_tmp1, bt_tmp2);
1968 
1969    /* yd = dysize/det */
1970    floattobf(bt_tmp2, dysize);
1971    div_bf(bt_yd, bt_tmp2, bt_det);
1972 
1973    /* c =  yd*(yymin-yy3rd) */
1974    sub_bf(bt_inter1, bfymin, bfy3rd);
1975    mult_bf(bt_c, bt_yd, bt_inter1);
1976 
1977    /* d =  yd*(xx3rd-xxmax) */
1978    sub_bf(bt_inter1, bfx3rd, bfxmax);
1979    mult_bf(bt_d, bt_yd, bt_inter1);
1980 
1981    /* f = -(c*xxmin + d*yymax) */
1982    mult_bf(bt_tmp1, bt_c, bfxmin);
1983    mult_bf(bt_tmp2, bt_d, bfymax);
1984    neg_a_bf(add_bf(bt_f, bt_tmp1, bt_tmp2));
1985 
1986    restore_stack(saved);
1987 }
1988 
1989 /* maps points onto view screen*/
bftransform(bf_t bt_x,bf_t bt_y,struct dblcoords * point)1990 static void bftransform(bf_t bt_x, bf_t bt_y, struct dblcoords *point)
1991 {
1992   bf_t   bt_tmp1, bt_tmp2;
1993   int saved;
1994 
1995    saved = save_stack();
1996    bt_tmp1 = alloc_stack(rbflength+2);
1997    bt_tmp2 = alloc_stack(rbflength+2);
1998 
1999 /*  point->x = cvt->a * point->x + cvt->b * point->y + cvt->e; */
2000    mult_bf(bt_tmp1, n_a, bt_x);
2001    mult_bf(bt_tmp2, n_b, bt_y);
2002    add_a_bf(bt_tmp1, bt_tmp2);
2003    add_a_bf(bt_tmp1, n_e);
2004    point->x = (double)bftofloat(bt_tmp1);
2005 
2006 /*  point->y = cvt->c * point->x + cvt->d * point->y + cvt->f; */
2007    mult_bf(bt_tmp1, n_c, bt_x);
2008    mult_bf(bt_tmp2, n_d, bt_y);
2009    add_a_bf(bt_tmp1, bt_tmp2);
2010    add_a_bf(bt_tmp1, n_f);
2011    point->y = (double)bftofloat(bt_tmp1);
2012 
2013    restore_stack(saved);
2014 }
2015