/* * MandelVroom 2.0 * * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA * * All rights reserved. * * Permission is hereby granted to distribute this program's source * executable, and documentation for non-comercial purposes, so long as the * copyright notices are not removed from the sources, executable or * documentation. This program may not be distributed for a profit without * the express written consent of the author Kevin L. Clague. * * This program is not in the public domain. * * Fred Fish is expressly granted permission to distribute this program's * source and executable as part of the "Fred Fish freely redistributable * Amiga software library." * * Permission is expressly granted for this program and it's source to be * distributed as part of the Amicus Amiga software disks, and the * First Amiga User Group's Hot Mix disks. * * contents: this file contains functions to calculate and draw orbits for * fixed point (scaled int) math mode. */ #include "mandp.h" #include "parms.h" static double x_scale, y_scale; static int x_center, y_center; static int rightedge,botedge; static struct RastPort *Rp; extern SHORT MaxOrbit; #define ORBSHIFT 27 #define ORBINT(f) ((int)((f)*(double)(1<RPort; width = (Window->Width-LEFTMARG-RIGHTMARG); height = (Window->Height-TOPMARG-BOTMARG); rightedge = width + LEFTMARG - 1; botedge = height + TOPMARG - 1; x_scale = y_scale = (float) height / (2.0 * (double)(1<RealLow + (MouseX-Pict->LeftMarg) * Pict->RealGap ); cimag = ORBINT( Pict->ImagLow + (MouseY-Pict->TopMarg) * Pict->ImagGap ); sreal = ORBINT( Pict->Real ); simag = ORBINT( Pict->Imag ); if ( Pict->pNode.ln_Type == MANDPICT ) { Parms.C_Real = creal; Parms.C_Imag = cimag; Parms.ScreenReal = sreal; Parms.ScreenImag = simag; } else { Parms.C_Real = sreal; Parms.C_Imag = simag; Parms.ScreenReal = creal; Parms.ScreenImag = cimag; } Parms.MaxIteration = MaxOrbit; /* Clear the window for next display plot */ SetAPen(Rp, 0); RectFill(Rp, LEFTMARG,TOPMARG, rightedge, botedge); SetAPen(Rp, HIGHLIGHTPEN); first_flag = 0; Orbit3216( &Parms ); } PlotIntOrbit( zreal, zimag ) LONG zreal, zimag; { int x,y; x = x_center + (int)((double) zreal * x_scale); y = y_center + (int)((double) zimag * y_scale); if (x >= LEFTMARG && x <= rightedge && y >= TOPMARG && y <= botedge && first_flag == 1 ) { WritePixel( Rp, x, y ); } first_flag = 1; } /* * Orbit display for 32 bit math using 16 bit multiplies. * It is written for the 68000 instruction set. */ Orbit3216( Parms ) struct IntPotParms *Parms; { LONG Height; register struct IntPotParms *P = Parms; register LONG cura, curb, cura2, curb2; #asm height equ -4 Bits2Shift equ 5 ; ; ; d1 - BITS2SHIFT ; d2 - k ; d4 - a ; d5 - b ; d6 - a2 ; d7 - b2 ; screenr equ 0 screeni equ 4 curx equ 8 cury equ 12 maxi equ 16 ; move.l #Bits2Shift,d1 move.l screenr(a2),d4 move.l screeni(a2),d5 move.w maxi(a2),d2 bra Fposa2 ; FKLoop ; ; cura = cura2 - curb2 + curx; exg d6,d4 ; exchange cura and cura2 sub.l d7,d4 ; subtract curb add.l curx(a2),d4 ; add curx ; ; curb = cura * curb >> 12; move.l d6,d7 ; get copy of op1 sign bit bpl Fpos1 ; get absolute value of op1 neg.l d6 Fpos1 eor.l d5,d7 ; calculate result sign tst.l d5 ; get absolute value of op2 bpl Fpos2 neg.l d5 Fpos2 move.l d6,d0 ; get a copy of op1 swap d0 ; get high half of op1 move.w d0,d7 ; save a copy of high half mulu d5,d0 ; multiply op2 low by op1 high clr.w d0 ; clear least significant part swap d0 ; put it in it's place swap d5 ; get high half of op2 mulu d5,d6 ; multiply op2 high with op1 low clr.w d6 ; clear least significant part swap d6 ; put it in its place mulu d7,d5 ; multiply op2 high by op1 high add.l d0,d5 ; add partial results add.l d6,d5 ; add partial results tst.l d7 ; is the result negative? bpl Fpos3 neg.l d5 ; yes, better negate it. Fpos3 asl.l d1,d5 ; now, rescale it. ; ; curb += curb + cury; add.l d5,d5 ; double it and add cury add.l cury(a2),d5 Fposa2 ; ; cura2 = cura * cura; move.l d4,d0 ; get absolute value of a in d0 bpl Fposa neg.l d0 Fposa move.l d0,d6 ; copy absolute value into d6 swap d6 ; get high part in d6 mulu d6,d0 ; multiply high and low destroying low clr.w d0 ; clear the least significant part swap d0 ; put most sig. part in low half mulu d6,d6 ; multiply high and high destroing high add.l d0,d6 ; add in lower half twice add.l d0,d6 asl.l d1,d6 ; get radix point back in correct place bvs Fbailout ; ; curb2 = curb * curb; move.l d5,d0 ; get absolute value of a in d0 bpl Fposb neg.l d0 Fposb move.l d0,d7 ; copy absolute value into d7 swap d7 ; get high part in d7 mulu d7,d0 ; multiply high and low destroying low clr.w d0 ; clear the least significant part swap d0 ; put most sig. part in low half mulu d7,d7 ; multiply high and high destroing high add.l d0,d7 ; add in lower half twice add.l d0,d7 asl.l d1,d7 ; get radix point back in correct place bvs Fbailout ; movem.l .saveregs,-(sp) ; #endasm PlotIntOrbit(cura,curb); #asm ; movem.l (sp)+,.saveregs ; move.l d6,d0 ; if (cura2 + curb2 >= 4) goto bailout; add.l d7,d0 bvs Fbailout ; dbra d2,FKLoop ; addq #1,d2 Fbailout move.w maxi(a2),d0 sub.w d2,d0 sub.w #1,d0 ext.l d0 #endasm ;; } #asm .saveregs reg d0-d3/a2 #endasm