File: common\jb.c
1
2 /* see Fractint.c for a description of the "include" hierarchy */
3 #include "port.h"
4 #include "prototyp.h"
5 #include "helpdefs.h"
6 #include "fractype.h"
7
8 /* these need to be accessed elsewhere for saving data */
9 double mxminfp = -.83;
10 double myminfp = -.25;
11 double mxmaxfp = -.83;
12 double mymaxfp = .25;
13
14 static long mxmin, mymin;
15 static long x_per_inch, y_per_inch, inch_per_xdot, inch_per_ydot;
16 static double x_per_inchfp, y_per_inchfp, inch_per_xdotfp, inch_per_ydotfp;
17 static int bbase;
18 static long xpixel, ypixel;
19 static double xpixelfp, ypixelfp;
20 static long initz, djx, djy, dmx, dmy;
21 static double initzfp, djxfp, djyfp, dmxfp, dmyfp;
22 static long jx, jy, mx, my, xoffset, yoffset;
23 static double jxfp, jyfp, mxfp, myfp, xoffsetfp, yoffsetfp;
24
25 struct Perspective
26 {
27 long x, y, zx, zy;
28 };
29
30 struct Perspectivefp
31 {
32 double x, y, zx, zy;
33 };
34
35 struct Perspective LeftEye, RightEye, *Per;
36 struct Perspectivefp LeftEyefp, RightEyefp, *Perfp;
37
38 _LCMPLX jbc;
39 _CMPLX jbcfp;
40
41 #ifndef XFRACT
42 static double fg, fg16;
43 #endif
44 int zdots = 128;
45
46 float originfp = (float)8.0;
47 float heightfp = (float)7.0;
48 float widthfp = (float)10.0;
49 float distfp = (float)24.0;
50 float eyesfp = (float)2.5;
51 float depthfp = (float)8.0;
52 float brratiofp = (float)1.0;
53 static long width, dist, depth, brratio;
54 #ifndef XFRACT
55 static long eyes;
56 #endif
57 int juli3Dmode = 0;
58
59 int neworbittype = JULIA;
60
61 int
62 JulibrotSetup(void)
63 {
64 #ifndef XFRACT
65 long origin;
66 #endif
67 int r = 0;
68 char *mapname;
69
70 #ifndef XFRACT
71 if (colors < 255)
72 {
73 static FCODE msg[] =
74 {"Sorry, but Julibrots require a 256-color video mode"};
75 stopmsg(0, msg);
76 return (0);
77 }
78 #endif
79
80 xoffsetfp = (xxmax + xxmin) / 2; /* Calculate average */
81 yoffsetfp = (yymax + yymin) / 2; /* Calculate average */
82 dmxfp = (mxmaxfp - mxminfp) / zdots;
83 dmyfp = (mymaxfp - myminfp) / zdots;
84 floatparm = &jbcfp;
85 x_per_inchfp = (xxmin - xxmax) / widthfp;
86 y_per_inchfp = (yymax - yymin) / heightfp;
87 inch_per_xdotfp = widthfp / xdots;
88 inch_per_ydotfp = heightfp / ydots;
89 initzfp = originfp - (depthfp / 2);
90 if(juli3Dmode == 0)
91 RightEyefp.x = 0.0;
92 else
93 RightEyefp.x = eyesfp / 2;
94 LeftEyefp.x = -RightEyefp.x;
95 LeftEyefp.y = RightEyefp.y = 0;
96 LeftEyefp.zx = RightEyefp.zx = distfp;
97 LeftEyefp.zy = RightEyefp.zy = distfp;
98 bbase = 128;
99
100 #ifndef XFRACT
101 if (fractalspecific[fractype].isinteger > 0)
102 {
103 long jxmin, jxmax, jymin, jymax, mxmax, mymax;
104 if (fractalspecific[neworbittype].isinteger == 0)
105 {
106 static FCODE msg[] = {"Julibrot orbit type isinteger mismatch"};
107 stopmsg(0, (char far *)msg);
108 }
109 if (fractalspecific[neworbittype].isinteger > 1)
110 bitshift = fractalspecific[neworbittype].isinteger;
111 fg = (double) (1L << bitshift);
112 fg16 = (double) (1L << 16);
113 jxmin = (long) (xxmin * fg);
114 jxmax = (long) (xxmax * fg);
115 xoffset = (jxmax + jxmin) / 2; /* Calculate average */
116 jymin = (long) (yymin * fg);
117 jymax = (long) (yymax * fg);
118 yoffset = (jymax + jymin) / 2; /* Calculate average */
119 mxmin = (long) (mxminfp * fg);
120 mxmax = (long) (mxmaxfp * fg);
121 mymin = (long) (myminfp * fg);
122 mymax = (long) (mymaxfp * fg);
123 origin = (long) (originfp * fg16);
124 depth = (long) (depthfp * fg16);
125 width = (long) (widthfp * fg16);
126 dist = (long) (distfp * fg16);
127 eyes = (long) (eyesfp * fg16);
128 brratio = (long) (brratiofp * fg16);
129 dmx = (mxmax - mxmin) / zdots;
130 dmy = (mymax - mymin) / zdots;
131 longparm = &jbc;
132
133 x_per_inch = (long) ((xxmin - xxmax) / widthfp * fg);
134 y_per_inch = (long) ((yymax - yymin) / heightfp * fg);
135 inch_per_xdot = (long) ((widthfp / xdots) * fg16);
136 inch_per_ydot = (long) ((heightfp / ydots) * fg16);
137 initz = origin - (depth / 2);
138 if(juli3Dmode == 0)
139 RightEye.x = 0l;
140 else
141 RightEye.x = eyes / 2;
142 LeftEye.x = -RightEye.x;
143 LeftEye.y = RightEye.y = 0l;
144 LeftEye.zx = RightEye.zx = dist;
145 LeftEye.zy = RightEye.zy = dist;
146 bbase = (int) (128.0 * brratiofp);
147 }
148 #endif
149
150 if (juli3Dmode == 3)
151 {
152 savedac = 0;
153 mapname = Glasses1Map;
154 }
155 else
156 mapname = GreyFile;
157 if(savedac != 1)
158 {
159 if (ValidateLuts(mapname) != 0)
160 return (0);
161 spindac(0, 1); /* load it, but don't spin */
162 if(savedac == 2)
163 savedac = 1;
164 }
165 return (r >= 0);
166 }
167
168
169 int
170 jb_per_pixel(void)
171 {
172 jx = multiply(Per->x - xpixel, initz, 16);
173 jx = divide(jx, dist, 16) - xpixel;
174 jx = multiply(jx << (bitshift - 16), x_per_inch, bitshift);
175 jx += xoffset;
176 djx = divide(depth, dist, 16);
177 djx = multiply(djx, Per->x - xpixel, 16) << (bitshift - 16);
178 djx = multiply(djx, x_per_inch, bitshift) / zdots;
179
180 jy = multiply(Per->y - ypixel, initz, 16);
181 jy = divide(jy, dist, 16) - ypixel;
182 jy = multiply(jy << (bitshift - 16), y_per_inch, bitshift);
183 jy += yoffset;
184 djy = divide(depth, dist, 16);
185 djy = multiply(djy, Per->y - ypixel, 16) << (bitshift - 16);
186 djy = multiply(djy, y_per_inch, bitshift) / zdots;
187
188 return (1);
189 }
190
191 int
192 jbfp_per_pixel(void)
193 {
194 jxfp = ((Perfp->x - xpixelfp) * initzfp / distfp - xpixelfp) * x_per_inchfp;
195 jxfp += xoffsetfp;
196 djxfp = (depthfp / distfp) * (Perfp->x - xpixelfp) * x_per_inchfp / zdots;
197
198 jyfp = ((Perfp->y - ypixelfp) * initzfp / distfp - ypixelfp) * y_per_inchfp;
199 jyfp += yoffsetfp;
200 djyfp = depthfp / distfp * (Perfp->y - ypixelfp) * y_per_inchfp / zdots;
201
202 return (1);
203 }
204
205 static int zpixel, plotted;
206 static long n;
207
208 int
209 zline(long x, long y)
210 {
211 xpixel = x;
212 ypixel = y;
213 mx = mxmin;
214 my = mymin;
215 switch(juli3Dmode)
216 {
217 case 0:
218 case 1:
219 Per = &LeftEye;
220 break;
221 case 2:
222 Per = &RightEye;
223 break;
224 case 3:
225 if ((row + col) & 1)
226 Per = &LeftEye;
227 else
228 Per = &RightEye;
229 break;
230 }
231 jb_per_pixel();
232 for (zpixel = 0; zpixel < zdots; zpixel++)
233 {
234 lold.x = jx;
235 lold.y = jy;
236 jbc.x = mx;
237 jbc.y = my;
238 if (keypressed())
239 return (-1);
240 ltempsqrx = multiply(lold.x, lold.x, bitshift);
241 ltempsqry = multiply(lold.y, lold.y, bitshift);
242 for (n = 0; n < maxit; n++)
243 if (fractalspecific[neworbittype].orbitcalc())
244 break;
245 if (n == maxit)
246 {
247 if (juli3Dmode==3)
248 {
249 color = (int) (128l * zpixel / zdots);
250 if ((row + col) & 1)
251 {
252
253 (*plot) (col, row, 127 - color);
254 }
255 else
256 {
257 color = (int) (multiply((long) color << 16, brratio, 16) >> 16);
258 if (color < 1)
259 color = 1;
260 if (color > 127)
261 color = 127;
262 (*plot) (col, row, 127 + bbase - color);
263 }
264 }
265 else
266 {
267 color = (int) (254l * zpixel / zdots);
268 (*plot) (col, row, color + 1);
269 }
270 plotted = 1;
271 break;
272 }
273 mx += dmx;
274 my += dmy;
275 jx += djx;
276 jy += djy;
277 }
278 return (0);
279 }
280
281 int
282 zlinefp(double x, double y)
283 {
284 #ifdef XFRACT
285 static int keychk = 0; 286 #endif
287 xpixelfp = x;
288 ypixelfp = y;
289 mxfp = mxminfp;
290 myfp = myminfp;
291 switch(juli3Dmode)
292 {
293 case 0:
294 case 1:
295 Perfp = &LeftEyefp;
296 break;
297 case 2:
298 Perfp = &RightEyefp;
299 break;
300 case 3:
301 if ((row + col) & 1)
302 Perfp = &LeftEyefp;
303 else
304 Perfp = &RightEyefp;
305 break;
306 }
307 jbfp_per_pixel();
308 for (zpixel = 0; zpixel < zdots; zpixel++)
309 {
310 /* Special initialization for Mandelbrot types */
311 if ((neworbittype == QUATFP || neworbittype == HYPERCMPLXFP)
312 && save_release > 2002)
313 {
314 old.x = 0.0;
315 old.y = 0.0;
316 jbcfp.x = 0.0;
317 jbcfp.y = 0.0;
318 qc = jxfp;
319 qci = jyfp;
320 qcj = mxfp;
321 qck = myfp;
322 }
323 else
324 {
325 old.x = jxfp;
326 old.y = jyfp;
327 jbcfp.x = mxfp;
328 jbcfp.y = myfp;
329 qc = param[0];
330 qci = param[1];
331 qcj = param[2];
332 qck = param[3];
333 }
334 #ifdef XFRACT
341 #else
342 if (keypressed())
343 return (-1);
344 #endif
345 tempsqrx = sqr(old.x);
346 tempsqry = sqr(old.y);
347
348 for (n = 0; n < maxit; n++)
349 if (fractalspecific[neworbittype].orbitcalc())
350 break;
351 if (n == maxit)
352 {
353 if (juli3Dmode == 3)
354 {
355 color = (int) (128l * zpixel / zdots);
356 if ((row + col) & 1)
357 (*plot) (col, row, 127 - color);
358 else
359 {
360 color = (int)(color * brratiofp);
361 if (color < 1)
362 color = 1;
363 if (color > 127)
364 color = 127;
365 (*plot) (col, row, 127 + bbase - color);
366 }
367 }
368 else
369 {
370 color = (int) (254l * zpixel / zdots);
371 (*plot) (col, row, color + 1);
372 }
373 plotted = 1;
374 break;
375 }
376 mxfp += dmxfp;
377 myfp += dmyfp;
378 jxfp += djxfp;
379 jyfp += djyfp;
380 }
381 return (0);
382 }
383
384 int
385 Std4dFractal(void)
386 {
387 long x, y;
388 int xdot, ydot;
389 c_exp = (int)param[2];
390 if(neworbittype == LJULIAZPOWER)
391 {
392 if(c_exp < 1)
393 c_exp = 1;
394 if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
395 fractalspecific[neworbittype].orbitcalc = longZpowerFractal;
396 else
397 fractalspecific[neworbittype].orbitcalc = longCmplxZpowerFractal;
398 }
399
400 for (y = 0, ydot = (ydots >> 1) - 1; ydot >= 0; ydot--, y -= inch_per_ydot)
401 {
402 plotted = 0;
403 x = -(width >> 1);
404 for (xdot = 0; xdot < xdots; xdot++, x += inch_per_xdot)
405 {
406 col = xdot;
407 row = ydot;
408 if (zline(x, y) < 0)
409 return (-1);
410 col = xdots - col - 1;
411 row = ydots - row - 1;
412 if (zline(-x, -y) < 0)
413 return (-1);
414 }
415 if (plotted == 0)
416 {
417 if (y == 0)
418 plotted = -1; /* no points first pass; don't give up */
419 else
420 break;
421 }
422 }
423 return (0);
424 }
425 int
426 Std4dfpFractal(void)
427 {
428 double x, y;
429 int xdot, ydot;
430 c_exp = (int)param[2];
431
432 if(neworbittype == FPJULIAZPOWER)
433 {
434 if(param[3] == 0.0 && debugflag != 6000 && (double)c_exp == param[2])
435 fractalspecific[neworbittype].orbitcalc = floatZpowerFractal;
436 else
437 fractalspecific[neworbittype].orbitcalc = floatCmplxZpowerFractal;
438 get_julia_attractor (param[0], param[1]); /* another attractor? */
439 }
440
441 for (y = 0, ydot = (ydots >> 1) - 1; ydot >= 0; ydot--, y -= inch_per_ydotfp)
442 {
443 plotted = 0;
444 x = -widthfp / 2;
445 for (xdot = 0; xdot < xdots; xdot++, x += inch_per_xdotfp)
446 {
447 col = xdot;
448 row = ydot;
449 if (zlinefp(x, y) < 0)
450 return (-1);
451 col = xdots - col - 1;
452 row = ydots - row - 1;
453 if (zlinefp(-x, -y) < 0)
454 return (-1);
455 }
456 if (plotted == 0)
457 {
458 if (y == 0)
459 plotted = -1; /* no points first pass; don't give up */
460 else
461 break;
462 }
463 }
464 return (0);
465 }
466