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
335 if (keychk++ > 500) 336 { 337 keychk = 0; 338 if (keypressed()) 339 return (-1); 340 }
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