
#include "Mandel.h"

#include <libraries/cybergraphics.h>

// use global variables !
extern UBYTE shared_pens[];

void DrawMandelbrot(struct Rect *view, struct DrawMsg *gfxport, int N)
{
	LONG x,y,width,height;
	double cx,cy,dx,dy;
	width = gfxport->xsize;
	height = gfxport->ysize;
	dx = (view->x1 - view->x0) / (double) width;
	dy = (view->y1 - view->y0) / (double) height;
	cy = view->y0;
	for (y = gfxport->offsety; y < height; y++)
	{
		cx = view->x0;
		for (x = gfxport->offsetx; x < width; x++)
		{
			double zx = 0.0;
			double zy = 0.0;
			double h1,h2,g,h3,h4;
			int i = N;
			UBYTE *address;
			double c = 16.0;
			do
			{
				h1 = zx*zx;
				h2 = zy*zy;
				g = zx*zy;
				h3 = h1 - h2;
				h4 = g+g;
				zx = h3 + cx;
				zy = h4 + cy;
				i--;
			} while (h1 + h2 < c && i);
			i = N - i;
			address = gfxport->memptr + y * gfxport->bytesperrow + x * gfxport->bytesperpix;
			switch (gfxport->colormodel)
			{
				case PIXFMT_LUT8:
#ifdef __ORIGINAL__
					if (i < N)
						*address = i*256/N
					else
						*address = 0;
#else
					// use shared palette !
					if (i < N)
						*address = shared_pens[(UBYTE)(i*256/N)];
					else
						*address = shared_pens[0];
#endif
					break;
				case PIXFMT_RGB15:
					if (i < N)
						*((UWORD *) address) = ((i*32/N) << 10) | ((i*32/N) << 5) | (i*32/N)
					else
						*((UWORD *) address) = 0;
					break;
				case PIXFMT_BGR15:
					if (i < N)
						*((UWORD *) address) = ((i*32/N) << 10) | ((i*32/N) << 5) | (i*32/N)
					else
						*((UWORD *) address) = 0;
					break;
				case PIXFMT_RGB15PC:
					if (i < N)
					{
						UWORD c = ((i*32/N) << 10) | ((i*32/N) << 5) | (i*32/N);
						*address++ = c;
						*address = c >> 8;
					}
					else
						*((UWORD *) address) = 0;
					break;
				case PIXFMT_BGR15PC:
					if (i < N)
					{
						UWORD c = ((i*32/N) << 10) | ((i*32/N) << 5) | (i*32/N);
						*address++ = c;
						*address = c >> 8;
					}
					else
						*((UWORD *) address) = 0;
					break;
				case PIXFMT_RGB16:
					if (i < N)
						*((UWORD *) address) = ((i*32/N) << 11) | ((i*64/N) << 5) | (i*32/N)
					else
						*((UWORD *) address) = 0;
					break;
				case PIXFMT_BGR16:
					if (i < N)
						*((UWORD *) address) = ((i*32/N) << 11) | ((i*64/N) << 5) | (i*32/N)
					else
						*((UWORD *) address) = 0;
					break;
				case PIXFMT_RGB16PC:
					if (i < N)
					{
						UWORD c = ((i*32/N) << 11) | ((i*64/N) << 5) | (i*32/N);
						*address++ = c;
						*address = c >> 8;
					}
					else
						*((UWORD *) address) = 0;
					break;
				case PIXFMT_BGR16PC:
					if (i < N)
					{
						UWORD c = ((i*32/N) << 11) | ((i*64/N) << 5) | (i*32/N);
						*address++ = c;
						*address = c >> 8;
					}
					else
						*((UWORD *) address) = 0;
					break;
				case PIXFMT_RGB24:
					if (i < N)
					{
						*((UWORD *) address)++ = ((i*256/N) << 8) | (i*256/N);
						*address = i*256/N;
					}
					else
					{
						*((UWORD *) address)++ = 0;
						*address = 0;
					}
					break;
				case PIXFMT_BGR24:
					if (i < N)
					{
						*((UWORD *) address)++ = ((i*256/N) << 8) | (i*256/N);
						*address = i*256/N;
					}
					else
					{
						*((UWORD *) address)++ = 0;
						*address = 0;
					}
					break;
				case PIXFMT_ARGB32:
					if (i < N)
					{
						*((ULONG *) address) = ((i*256/N) << 16) | ((i*256/N) << 8) | (i*256/N)
					}
					else
					{
						*((ULONG *) address) = 0;
					};
					break;
				case PIXFMT_BGRA32:
					if (i < N)
					{
						*((ULONG *) address) = ((i*256/N) << 24) | ((i*256/N) << 16) | ((i*256/N) << 8)
					}
					else
					{
						*((ULONG *) address) = 0;
					};
					break;
				case PIXFMT_RGBA32:
					if (i < N)
					{
						*((ULONG *) address) = ((i*256/N) << 24) | ((i*256/N) << 16) | ((i*256/N) << 8)
					}
					else
					{
						*((ULONG *) address) = 0;
					};
					break;
			};
			cx += dx;
		};
		cy += dy;
	};
}
