int juliabf_per_pixel() { // old.x = xxmin + col*delx + row*delx2 mult_bf_int(bfold.x, bfxdel, (U16)col); mult_bf_int(bftmp, bfxdel2, (U16)row); add_a_bf(bfold.x, bftmp); add_a_bf(bfold.x, bfxmin); // old.y = yymax - row*dely - col*dely2; // note: in next four lines, bfnew is just used as a temporary variable mult_bf_int(bfnew.x, bfydel, (U16)row); mult_bf_int(bfnew.y, bfydel2, (U16)col); add_a_bf(bfnew.x, bfnew.y); sub_bf(bfold.y, bfymax, bfnew.x); // square has side effect - must copy first copy_bf(bfnew.x, bfold.x); copy_bf(bfnew.y, bfold.y); // Square these to rbflength bytes of precision square_bf(bftmpsqrx, bfnew.x); square_bf(bftmpsqry, bfnew.y); return (1); // 1st iteration has been done }
// for aspect ratio debugging void showaspect(char *s) { bf_t bt1, bt2, aspect; char msg[100], str[100]; int saved; saved = save_stack(); bt1 = alloc_stack(rbflength+2); bt2 = alloc_stack(rbflength+2); aspect = alloc_stack(rbflength+2); sub_bf(bt1, bfxmax, bfxmin); sub_bf(bt2, bfymax, bfymin); div_bf(aspect, bt2, bt1); bftostr(str, 10, aspect); sprintf(msg, "aspect %s\nfloat %13.10f\nbf %s\n\n", s, (yymax-yymin)/(xxmax-xxmin), str); if (stopmsg(STOPMSG_NONE, msg) == -1) goodbye(); restore_stack(saved); }
BFComplex *cplxmul_bf(BFComplex *t, BFComplex *x, BFComplex *y) { bf_t tmp1; int saved; saved = save_stack(); tmp1 = alloc_stack(rbflength+2); mult_bf(t->x, x->x, y->x); mult_bf(t->y, x->y, y->y); sub_bf(t->x, t->x, t->y); mult_bf(tmp1, x->x, y->y); mult_bf(t->y, x->y, y->x); add_bf(t->y, tmp1, t->y); restore_stack(saved); return (t); }
static void _fastcall zmo_calcbf(bf_t bfdx, bf_t bfdy, bf_t bfnewx, bf_t bfnewy,bf_t bfplotmx1, bf_t bfplotmx2, bf_t bfplotmy1, bf_t bfplotmy2, bf_t bfftemp) { bf_t btmp1, btmp2, btmp3, btmp4, btempx, btempy ; bf_t btmp2a, btmp4a; int saved; saved = save_stack(); btmp1 = alloc_stack(rbflength+2); btmp2 = alloc_stack(rbflength+2); btmp3 = alloc_stack(rbflength+2); btmp4 = alloc_stack(rbflength+2); btmp2a = alloc_stack(rbflength+2); btmp4a = alloc_stack(rbflength+2); btempx = alloc_stack(rbflength+2); btempy = alloc_stack(rbflength+2); /* calc cur screen corner relative to zoombox, when zoombox co-ords are taken as (0,0) topleft thru (1,1) bottom right */ /* tempx = dy * plotmx1 - dx * plotmx2; */ mult_bf(btmp1,bfdy,bfplotmx1); mult_bf(btmp2,bfdx,bfplotmx2); sub_bf(btempx,btmp1,btmp2); /* tempy = dx * plotmy1 - dy * plotmy2; */ mult_bf(btmp1,bfdx,bfplotmy1); mult_bf(btmp2,bfdy,bfplotmy2); sub_bf(btempy,btmp1,btmp2); /* calc new corner by extending from current screen corners */ /* *newx = sxmin + tempx*(sxmax-sx3rd)/ftemp + tempy*(sx3rd-sxmin)/ftemp; */ sub_bf(btmp1,bfsxmax,bfsx3rd); mult_bf(btmp2,btempx,btmp1); /* show_three_bf("fact1",btempx,"fact2",btmp1,"prod ",btmp2,70); */ div_bf(btmp2a,btmp2,bfftemp); /* show_three_bf("num ",btmp2,"denom",bfftemp,"quot ",btmp2a,70); */ sub_bf(btmp3,bfsx3rd,bfsxmin); mult_bf(btmp4,btempy,btmp3); div_bf(btmp4a,btmp4,bfftemp); add_bf(bfnewx,bfsxmin,btmp2a); add_a_bf(bfnewx,btmp4a); /* *newy = symax + tempy*(sy3rd-symax)/ftemp + tempx*(symin-sy3rd)/ftemp; */ sub_bf(btmp1,bfsy3rd,bfsymax); mult_bf(btmp2,btempy,btmp1); div_bf(btmp2a,btmp2,bfftemp); sub_bf(btmp3,bfsymin,bfsy3rd); mult_bf(btmp4,btempx,btmp3); div_bf(btmp4a,btmp4,bfftemp); add_bf(bfnewy,bfsymax,btmp2a); add_a_bf(bfnewy,btmp4a); restore_stack(saved); }
int mandelbf_per_pixel() { // parm.x = xxmin + col*delx + row*delx2 mult_bf_int(bfparm.x, bfxdel, (U16)col); mult_bf_int(bftmp, bfxdel2, (U16)row); add_a_bf(bfparm.x, bftmp); add_a_bf(bfparm.x, bfxmin); // parm.y = yymax - row*dely - col*dely2; // note: in next four lines, bfold is just used as a temporary variable mult_bf_int(bfold.x, bfydel, (U16)row); mult_bf_int(bfold.y, bfydel2, (U16)col); add_a_bf(bfold.x, bfold.y); sub_bf(bfparm.y, bfymax, bfold.x); copy_bf(bfold.x, bfparm.x); copy_bf(bfold.y, bfparm.y); if ((inside == BOF60 || inside == BOF61) && !nobof) { /* kludge to match "Beauty of Fractals" picture since we start Mandelbrot iteration with init rather than 0 */ floattobf(bfold.x, param[0]); // initial pertubation of parameters set floattobf(bfold.y, param[1]); coloriter = -1; } else { floattobf(bfnew.x, param[0]); floattobf(bfnew.y, param[1]); add_a_bf(bfold.x, bfnew.x); add_a_bf(bfold.y, bfnew.y); } // square has side effect - must copy first copy_bf(bfnew.x, bfold.x); copy_bf(bfnew.y, bfold.y); // Square these to rbflength bytes of precision square_bf(bftmpsqrx, bfnew.x); square_bf(bftmpsqry, bfnew.y); return (1); // 1st iteration has been done }
bool MandelbfSetup() { // this should be set up dynamically based on corners bf_t bftemp1, bftemp2; int saved; saved = save_stack(); bftemp1 = alloc_stack(bflength+2); bftemp2 = alloc_stack(bflength+2); bf_math = bf_math_type::BIGFLT; // bfxdel = (bfxmax - bfx3rd)/(xdots-1) sub_bf(bfxdel, bfxmax, bfx3rd); div_a_bf_int(bfxdel, (U16)(xdots - 1)); // bfydel = (bfymax - bfy3rd)/(ydots-1) sub_bf(bfydel, bfymax, bfy3rd); div_a_bf_int(bfydel, (U16)(ydots - 1)); // bfxdel2 = (bfx3rd - bfxmin)/(ydots-1) sub_bf(bfxdel2, bfx3rd, bfxmin); div_a_bf_int(bfxdel2, (U16)(ydots - 1)); // bfydel2 = (bfy3rd - bfymin)/(xdots-1) sub_bf(bfydel2, bfy3rd, bfymin); div_a_bf_int(bfydel2, (U16)(xdots - 1)); abs_bf(bfclosenuff, bfxdel); if (cmp_bf(abs_bf(bftemp1, bfxdel2), bfclosenuff) > 0) copy_bf(bfclosenuff, bftemp1); if (cmp_bf(abs_bf(bftemp1, bfydel), abs_bf(bftemp2, bfydel2)) > 0) { if (cmp_bf(bftemp1, bfclosenuff) > 0) copy_bf(bfclosenuff, bftemp1); } else if (cmp_bf(bftemp2, bfclosenuff) > 0) copy_bf(bfclosenuff, bftemp2); { int t; t = abs(periodicitycheck); while (t--) half_a_bf(bfclosenuff); } c_exp = (int)param[2]; switch (fractype) { case fractal_type::JULIAFP: copy_bf(bfparm.x, bfparms[0]); copy_bf(bfparm.y, bfparms[1]); break; case fractal_type::FPMANDELZPOWER: init_big_pi(); if ((double)c_exp == param[2] && (c_exp & 1)) // odd exponents symmetry = symmetry_type::XY_AXIS_NO_PARAM; if (param[3] != 0) symmetry = symmetry_type::NONE; break; case fractal_type::FPJULIAZPOWER: init_big_pi(); copy_bf(bfparm.x, bfparms[0]); copy_bf(bfparm.y, bfparms[1]); if ((c_exp & 1) || param[3] != 0.0 || (double)c_exp != param[2]) symmetry = symmetry_type::NONE; break; default: break; } restore_stack(saved); return true; }
void drawbox(int drawit) { struct coords tl,bl,tr,br; /* dot addr of topleft, botleft, etc */ double tmpx,tmpy,dx,dy,rotcos,rotsin,ftemp1,ftemp2; double fxwidth,fxskew,fydepth,fyskew,fxadj; bf_t bffxwidth, bffxskew, bffydepth, bffyskew, bffxadj; int saved; if (zwidth==0) { /* no box to draw */ if (boxcount!=0) { /* remove the old box from display */ clearbox(); /* asm routine */ boxcount = 0; } reset_zoom_corners(); return; } if(bf_math) { saved = save_stack(); bffxwidth = alloc_stack(rbflength+2); bffxskew = alloc_stack(rbflength+2); bffydepth = alloc_stack(rbflength+2); bffyskew = alloc_stack(rbflength+2); bffxadj = alloc_stack(rbflength+2); } ftemp1 = PI*zrotate/72; /* convert to radians */ rotcos = cos(ftemp1); /* sin & cos of rotation */ rotsin = sin(ftemp1); /* do some calcs just once here to reduce fp work a bit */ fxwidth = sxmax-sx3rd; fxskew = sx3rd-sxmin; fydepth = sy3rd-symax; fyskew = symin-sy3rd; fxadj = zwidth*zskew; if(bf_math) { /* do some calcs just once here to reduce fp work a bit */ sub_bf(bffxwidth,bfsxmax,bfsx3rd); sub_bf(bffxskew,bfsx3rd,bfsxmin); sub_bf(bffydepth,bfsy3rd,bfsymax); sub_bf(bffyskew,bfsymin,bfsy3rd); floattobf(bffxadj, fxadj); } /* calc co-ords of topleft & botright corners of box */ tmpx = zwidth/-2+fxadj; /* from zoombox center as origin, on xdots scale */ tmpy = zdepth*finalaspectratio/2; dx = (rotcos*tmpx - rotsin*tmpy) - tmpx; /* delta x to rotate topleft */ dy = tmpy - (rotsin*tmpx + rotcos*tmpy); /* delta y to rotate topleft */ /* calc co-ords of topleft */ ftemp1 = zbx + dx + fxadj; ftemp2 = zby + dy/finalaspectratio; tl.x = (int)(ftemp1*(dxsize+PIXELROUND)); /* screen co-ords */ tl.y = (int)(ftemp2*(dysize+PIXELROUND)); xxmin = sxmin + ftemp1*fxwidth + ftemp2*fxskew; /* real co-ords */ yymax = symax + ftemp2*fydepth + ftemp1*fyskew; if(bf_math) { calc_corner(bfxmin,bfsxmin,ftemp1,bffxwidth,ftemp2,bffxskew); calc_corner(bfymax,bfsymax,ftemp2,bffydepth,ftemp1,bffyskew); } /* calc co-ords of bottom right */ ftemp1 = zbx + zwidth - dx - fxadj; ftemp2 = zby - dy/finalaspectratio + zdepth; br.x = (int)(ftemp1*(dxsize+PIXELROUND)); br.y = (int)(ftemp2*(dysize+PIXELROUND)); xxmax = sxmin + ftemp1*fxwidth + ftemp2*fxskew; yymin = symax + ftemp2*fydepth + ftemp1*fyskew; if(bf_math) { calc_corner(bfxmax,bfsxmin,ftemp1,bffxwidth,ftemp2,bffxskew); calc_corner(bfymin,bfsymax,ftemp2,bffydepth,ftemp1,bffyskew); } /* do the same for botleft & topright */ tmpx = zwidth/-2 - fxadj; tmpy = 0.0-tmpy; dx = (rotcos*tmpx - rotsin*tmpy) - tmpx; dy = tmpy - (rotsin*tmpx + rotcos*tmpy); ftemp1 = zbx + dx - fxadj; ftemp2 = zby + dy/finalaspectratio + zdepth; bl.x = (int)(ftemp1*(dxsize+PIXELROUND)); bl.y = (int)(ftemp2*(dysize+PIXELROUND)); xx3rd = sxmin + ftemp1*fxwidth + ftemp2*fxskew; yy3rd = symax + ftemp2*fydepth + ftemp1*fyskew; if(bf_math) { calc_corner(bfx3rd,bfsxmin,ftemp1,bffxwidth,ftemp2,bffxskew); calc_corner(bfy3rd,bfsymax,ftemp2,bffydepth,ftemp1,bffyskew); restore_stack(saved); } ftemp1 = zbx + zwidth - dx + fxadj; ftemp2 = zby - dy/finalaspectratio; tr.x = (int)(ftemp1*(dxsize+PIXELROUND)); tr.y = (int)(ftemp2*(dysize+PIXELROUND)); if (boxcount!=0) { /* remove the old box from display */ clearbox(); /* asm routine */ boxcount = 0; } if (drawit) { /* caller wants box drawn as well as co-ords calc'd */ #ifndef XFRACT /* build the list of zoom box pixels */ addbox(tl); addbox(tr); /* corner pixels */ addbox(bl); addbox(br); drawlines(tl,tr,bl.x-tl.x,bl.y-tl.y); /* top & bottom lines */ drawlines(tl,bl,tr.x-tl.x,tr.y-tl.y); /* left & right lines */ #else boxx[0] = tl.x + sxoffs; boxy[0] = tl.y + syoffs; boxx[1] = tr.x + sxoffs; boxy[1] = tr.y + syoffs; boxx[2] = br.x + sxoffs; boxy[2] = br.y + syoffs; boxx[3] = bl.x + sxoffs; boxy[3] = bl.y + syoffs; boxcount = 1; #endif dispbox(); /* asm routine to paint it */ } }
void zoomoutbf(void) /* for ctl-enter, calc corners for zooming out */ { /* (xxmin,yymax), etc, are already set to zoombox corners; (sxmin,symax), etc, are still the screen's corners; use the same logic as plot_orbit stuff to first calculate current screen corners relative to the zoombox, as if the zoombox were a square with upper left (0,0) and width/depth 1; ie calc the current screen corners as if plotting them from the zoombox; then extend these co-ords from current real screen corners to get new actual corners */ bf_t savbfxmin,savbfymax,bfftemp; bf_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6,bfplotmx1,bfplotmx2,bfplotmy1,bfplotmy2; int saved; saved = save_stack(); savbfxmin = alloc_stack(rbflength+2); savbfymax = alloc_stack(rbflength+2); bfftemp = alloc_stack(rbflength+2); tmp1 = alloc_stack(rbflength+2); tmp2 = alloc_stack(rbflength+2); tmp3 = alloc_stack(rbflength+2); tmp4 = alloc_stack(rbflength+2); tmp5 = alloc_stack(rbflength+2); tmp6 = alloc_stack(rbflength+2); bfplotmx1 = alloc_stack(rbflength+2); bfplotmx2 = alloc_stack(rbflength+2); bfplotmy1 = alloc_stack(rbflength+2); bfplotmy2 = alloc_stack(rbflength+2); /* ftemp = (yymin-yy3rd)*(xx3rd-xxmin) - (xxmax-xx3rd)*(yy3rd-yymax); */ sub_bf(tmp1,bfymin,bfy3rd); sub_bf(tmp2,bfx3rd,bfxmin); sub_bf(tmp3,bfxmax,bfx3rd); sub_bf(tmp4,bfy3rd,bfymax); mult_bf(tmp5,tmp1,tmp2); mult_bf(tmp6,tmp3,tmp4); sub_bf(bfftemp,tmp5,tmp6); /* plotmx1 = (xx3rd-xxmin); */ ; /* reuse the plotxxx vars is safe */ copy_bf(bfplotmx1,tmp2); /* plotmx2 = (yy3rd-yymax); */ copy_bf(bfplotmx2,tmp4); /* plotmy1 = (yymin-yy3rd); */ copy_bf(bfplotmy1,tmp1); /* plotmy2 = (xxmax-xx3rd); */; copy_bf(bfplotmy2,tmp3); /* savxxmin = xxmin; savyymax = yymax; */ copy_bf(savbfxmin,bfxmin); copy_bf(savbfymax,bfymax); sub_bf(tmp1,bfsxmin,savbfxmin); sub_bf(tmp2,bfsymax,savbfymax); zmo_calcbf(tmp1,tmp2,bfxmin,bfymax,bfplotmx1,bfplotmx2,bfplotmy1, bfplotmy2,bfftemp); sub_bf(tmp1,bfsxmax,savbfxmin); sub_bf(tmp2,bfsymin,savbfymax); zmo_calcbf(tmp1,tmp2,bfxmax,bfymin,bfplotmx1,bfplotmx2,bfplotmy1, bfplotmy2,bfftemp); sub_bf(tmp1,bfsx3rd,savbfxmin); sub_bf(tmp2,bfsy3rd,savbfymax); zmo_calcbf(tmp1,tmp2,bfx3rd,bfy3rd,bfplotmx1,bfplotmx2,bfplotmy1, bfplotmy2,bfftemp); restore_stack(saved); }