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(¶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
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