/************************************************************************/
/* Fixpoint.c								*/
/*									*/
/* Fix-point version of the mandelbrot genrator. See Float.c for math	*/
/* details. The UPPER CASE variables contain the FXP counterparts of	*/
/* the ones written in lower case.					*/
/************************************************************************/

#include <proto/intuition.h>
#include <proto/graphics.h>
#include <mffp.h>
#include <math.h>

/* -------------------------------------------------------------------- */
/* "Zwei hoch 24" is german for "two, powered by 24" or 2**24.		*/
/* Forgive me, I haven't had the patience to translate all variable	*/
/* names to english.							*/
/* -------------------------------------------------------------------- */

#define ZWEI_HOCH_24	16777216.0

/* -------------------------------------------------------------------- */
/* import externaly defined objects					*/
/* -------------------------------------------------------------------- */

extern struct RastPort	*rp;
extern struct GfxBase	*GfxBase;

extern long __asm Iter_FXP(register __d1 long r, register __d2 long i,register __a2 long divergenz);

extern short __regargs Test(long xx1, long yy1, long xx2, long yy2);

/* -------------------------------------------------------------------- */

long	DIVERGENZ, RMIN, IMIN, DX, DY;
short	MAXITER;

void __regargs Apfel_FXP(long x1, long y1, long x2, long y2)
{
	long xneu, yneu, help1, help2;

	if ( x2 - x1 > 1 && y2 - y1 > 1 ) {
		if ( Test(x1, y1, x2, y2) ) {
			SetAPen(rp, ReadPixel(rp, x1, y1));
			RectFill(rp, x1+1, y1+1, x2-1, y2-1);
		}
		else {
			if ( x2 - x1 + y1 > y2 ) {
				xneu	= (x1 + x2) >> 1;
				help1	= RMIN + xneu * DX;
				help2	= (y1 + 1) * DY + IMIN;
				for ( yneu = y1 + 1; yneu < y2; yneu++ ) {
					SetAPen(rp, Iter_FXP(help1, help2, DIVERGENZ));
					WritePixel(rp, xneu, yneu);
					help2 += DY;
				}
				Apfel_FXP(x1, y1, xneu, y2);
				Apfel_FXP(xneu, y1, x2, y2);
			}
			else {
				yneu	= (y1 + y2) >> 1;
				help1	= IMIN + yneu * DY;
				help2	= (x1 + 1) * DX + RMIN;
				for ( xneu = x1 + 1; xneu < x2; xneu++ ) {
					SetAPen(rp, Iter_FXP(help2, help1, DIVERGENZ));
					WritePixel(rp, xneu, yneu);
					help2 += DX;
				}
				Apfel_FXP(x1, y1, x2, yneu);
				Apfel_FXP(x1, yneu, x2, y2);
			}
		}
	}
}

/* -------------------------------------------------------------------- */
/* Some initializations are needed for the FXP version. 		*/
/* -------------------------------------------------------------------- */

void FixPoint(double rmin, double rmax, double imin, double imax, double dx, double dy,
		int maxiter, double divergenz, int gx, int gy, int depth)
{
	long	help1, help2, help3, help4;
	long	x, y;

	DIVERGENZ	= divergenz	* ZWEI_HOCH_24;
	RMIN		= rmin		* ZWEI_HOCH_24;
	IMIN		= imin		* ZWEI_HOCH_24;
	DX		= dx		* ZWEI_HOCH_24;
	DY		= dy		* ZWEI_HOCH_24;
	MAXITER		= maxiter - 1;

	help1		= RMIN;
	help4		= gy - 1;
	help3		= imax * ZWEI_HOCH_24;

	for ( x = 0; x < gx; x++ ) {
		SetAPen(rp, Iter_FXP(help1, IMIN, DIVERGENZ));
		WritePixel(rp, x, 0);
		SetAPen(rp, Iter_FXP(help1, help3, DIVERGENZ));
		WritePixel(rp, x, help4);
		help1 += DX;
	}

	help1		= IMIN;
	help2		= gx - 1;
	help3		= rmax * ZWEI_HOCH_24;

	for ( y = 0; y < gy; y++ ) {
		SetAPen(rp, Iter_FXP(RMIN, help1, DIVERGENZ));
		WritePixel(rp, 0, y);
		SetAPen(rp, Iter_FXP(help3, help1, DIVERGENZ));
		WritePixel(rp, help2, y);
		help1 += DY;
	}

	Apfel_FXP(0, 0, help2, help4);
}
