home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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<<ORBSHIFT)))
-
- InitIntOrbit()
- {
- register struct Window *Window;
- register int width, height;
-
- Window = OrbitWind;
- Rp = Window->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<<ORBSHIFT));
-
- x_center = width/2 + LEFTMARG;
- y_center = height/2 + TOPMARG;
- }
-
- static char first_flag;
-
- DrawOrbitInt( Pict )
- struct Picture *Pict;
- {
- struct IntPotParms Parms;
- LONG creal, cimag;
- LONG sreal, simag;
-
- InitIntOrbit();
-
- creal = ORBINT( Pict->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
-
-
-
-