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(¶m[2]);
87 param[3] = read_info.parm4;
88 roundfloatd(¶m[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
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
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
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
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
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
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
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
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
1327 #endif
1328 }
1329 #ifdef XFRACT
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
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
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 */
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