#include	<clib/all_protos.h>
#include	<math.h>
#include	<float.h>
#include	<string.h>
#include	<exec/memory.h>
#include	<exec/tasks.h>
#include	<iffp/packer.h>
#include	<iff/iff.h>
#include	<iff/ilbm.h>
#include	<exec/execbase.h>
#include	<graphics/gfxbase.h>
#include	<devices/timer.h>
#include	<utility/tagitem.h>


#include	<powerpc/powerpc.h>
#include	<powerpc/tasksPPC.h>
#include	<clib/powerpc_protos.h>



#include	<clib/cybergraphics_protos.h>
#include	<cybergraphx/cybergraphics.h>


#define SETRGB(s,cn,r,g,b)     SetRGB4(&((s)->ViewPort),cn,r,g,b)

double Pi;

ULONG Time1Hi,Time2Hi,Time1Lo,Time2Lo;

extern void FndFnc(void);
extern void Save(void);

extern void	TimeGet(void);
extern void TimeGet2(void);

double ClkFrq,BusFrq;

LONG TimeHi,TimeLo;

extern void UseLibP2(double);
extern void UseLibP3(double);
extern void UseLibP4(double);
extern void UseLibP5(double);
extern void UseLibP6(double);
extern void UseLibP7(double);


#define MemMode MEMF_FAST | MEMF_CLEAR | MEMF_REVERSE
UWORD *OldColorTable,*NewColorTable;
ULONG	ThisMode,TableSize;
ULONG	BFactor = 16777216;
ULONG ColorsOld[4];
ULONG ColorsNext[4];
ULONG *LPixelBuf;
UBYTE *WindowBuf;


UWORD *POTGOR;
UBYTE *DDRAV,*SDRV,*PDRAAV;


struct Library *WarpBase;
struct Library *TimerBase;
struct MsgPort *TimerPort;
struct timerequest *tr;
/*struct TaskPPC *MyTask;*/
struct	Task *MyTask;

UBYTE *PixelBuf;
char CPUStrBuf[256];
char MyStringBuf[256];

UWORD ShortOld[4];
UWORD ShortNext[4];
UBYTE OldColors[4];
UBYTE NextColors[4];
UBYTE *ColorTable32;


UWORD	LastMax,Color;
ULONG NumColors,TopCol,Secs,Micros,LSec;
double ElTime;
int	NumPubs,BPP,MWWidth;
int		PalSize;

UBYTE *BoardMem;
extern int Selected;
int	TotNum;

SHORT	VertPos;
SHORT	PolyTab[10];
SHORT	*PolyPnt;
SHORT	DeltaX,DeltaY; SHORT	x1,y1,x2,y2;
SHORT	Power;
double	PowerF,DeltaP;	/*Fractional power */
double	DX;
struct CyberModeNode *CyberTags;

double Two,Limit,XWidth,XHeight,Pi,XCenter,YCenter,HWidth,HHeight,Factor,Pi,TwoPi,PowerN;
double LastX,LastY,LastFactor,PiD2;
LONG	xtemp,ytemp,MaxCnt,CurCnt,XC,YC,LeftEdge,RightEdge,NearEdge,FarEdge;
ULONG	MltPlr;
ULONG	*PlnPtr;
LONG 	BLeft,BTop,InfBLeft,InfBTop;
WORD	WWidth,WHeight,WDepth,SDepth,PFMT;
BPTR	FileHandle;
UWORD	FontHeight,MenWidth,LeftPos;
SHORT	TFHeight;
USHORT	IWHeight,IWWidth,TwoSpace;
UWORD	LinBuf[1600];
BOOL IsChunk,IsVilScreen,IsCyberScreen,SaveIFF;


struct TextAttr		DefBold;
struct	TextAttr	*DefFont;
struct	TextFont	*DFont;
struct	TextFont	*BFont;
struct TextFont *CWFont;

struct	TextExtent	TextUsed;

struct TextAttr topaz8 =
  {
  (STRPTR)"topaz.font",	/* ta_Name */
  8,	/* ta_YSize */
  FS_NORMAL,	/* ta_Style */
  0x0	/* ta_Flags */
  };


struct TextAttr topaz9 =
  {
  (STRPTR)"topaz.font",	/* ta_Name */
  9,	/* ta_YSize */
  FSB_BOLD,	/* ta_Style */
  0x0	/* ta_Flags */
  };


#define	ChdFlg	DefFlg | CHECKIT | CHECKED
#define	ChkFlg	DefFlg | CHECKIT

ULONG	CmpFlg	= MOUSEBUTTONS | MENUPICK ;
ULONG	MyFlag	 =	NOCAREREFRESH|REPORTMOUSE|BORDERLESS;
ULONG	MenFlg	 =	MENUENABLED | MIDRAWN;
ULONG	DefFlg	 =	ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP;

extern	struct DosLibrary *DOSBase;
struct GfxBase *GfxBase;
struct Library *DiskfontBase;
struct IntuitionBase *IntuitionBase;
struct Library *GadToolsBase;
struct Library *UtilityBase;
struct CyberGfxBase *CyberGfxBase;
struct Library *CyberIntuit;
struct Library *CyberLayer;
struct Library *CgxSystemBase;

extern	struct ExecBase	*SysBase;
struct	Gadget	*GadStuff;
struct	NewScreen	ns;
struct	NewWindow	nw;
BYTE	CurrentXOffset;
BYTE	CurrentYOffset;
UBYTE	Title[] = " Information about this Fractal";
UBYTE	TitleM[] = "  Exploring the Julia Sets";

UBYTE	*WindowName;
SHORT	SWidth,SHeight,CPU;
USHORT	MyView,SysFlag,MenVal;
ULONG	IMClass;
struct	Screen	*WBScreen;
struct	Window	*InfoWindow;
struct	Window	*IntWindow;

struct	MsgPort	*MyPort,*IntPort,*MWPort;
struct	RastPort	*WBRast,*CWRast,*MWRast,*WBSRast;
struct	ViewPort	VPorta,VPortb;
struct	Preferences	MyNewPrefs,*CurPrefs;
struct	Menu		ProjMenu,CountMenu,ChangeMenu,PowerMenu;
struct	MenuItem	*MIStruct;
struct	IntuiText	*ITStruct;

/*	The following structures are for temporary non-displayable rastors for use in
saving the image to an iff file */
struct RastPort VTmpRast,MainWRast;
struct BitMap *TmpBitMap,*MWBitMap;
struct BitMap *NWBitMap;
struct RastPort NWRast;


struct	MenuItem	MI11,MI12,MI13,MI14,MI15,MI16,MI17;
struct	MenuItem	MI31,MI32,MI33,MI34,MI35,MI36;
struct	MenuItem	MI41,MI42,MI43,MI44,MI45,MI46,MI47;
struct	MenuItem	MI21,MI22,MI23,MI24,MI25,MI26;
struct	IntuiText	IT11,IT12,IT13,IT14,IT15,IT16,IT17;
struct	IntuiText	IT31,IT32,IT33,IT34,IT35,IT36;
struct	IntuiText	IT41,IT42,IT43,IT44,IT45,IT46,IT47;
struct	IntuiText	IT21,IT22,IT23,IT24,IT25,IT26;
struct	IntuiText	DummyText;

struct	PLANEPTR	*PlanePtrA;
UBYTE	PalOpt;
UBYTE	Comma[] = {0x2c};
static	char	Mesag3[]	= "System Hardware: ";
static	char	Mesag4[]	= "Use the menu options on the Julia Window to change the following parameters!";
static	char	Mesag5[]	= "Click on the Close Gadget to bring the Julia Window forward!";
static	char	Mesag6[]	= "(Note:  This window won't be closed, but perhaps hidden.)";
static	char	Mesag7[]	= "To bring the Information Window forward, select 'About' from the Project menu!";
static	char	Mesag8[]	= "The Window 'Exploring the Juila Sets' is on the screen                       ";
static	char	ScrMsg[]	= "Window center is at ";
static	char	MandMsg[]	= "The algorithm is z  + z -> z, where z = x + iy.";
static	char	MandMsgG[]	= "The algorithm is z   + z -> z, where z = x + iy.";
static	char	MandMsgP[]	= "The algorithm is z                 + z -> z, where z = R*exp(i0).";
static	char	MandMsgPG[]	= "The algorithm is z                  + z -> z, where z = R*exp(i0).";
static	char	ChpMsg[]	= "Chip Memory Free = ";
static	char	ChpEnd[]	= "                ";
static	char	FstMsg[]	= "Fast Memory Free = ";
static	char	FstEnd[]	= "                        ";
static	char	WdtMsg[]	= "Image Width =  ";
static	char	WdtEnd[]	= "        ";
static	char	HgtMsg[]	= "Image Height = ";
static	char	HgtEnd[]	= "        ";
static	char	MagMsg[]	= "Magnification =               ";
static	char	XPos[]		= "x = ";
static	char	XPsEnd[]	= "                              ";
static	char	YPos[]		= "y = ";
static	char	YPsEnd[]	= "                              ";
static	char	CntMsg[]	= "Maximum Count = ";
static	char	CntEnd[]	= "             ";
static	char	St882[]		= " 68882";

extern void FncFnd(double);


WORD GetLength(UBYTE *);
WORD GethPos(UBYTE *);
WORD LengthDescript(void);
void InitVS(void);
void LibsOpen(void);
void TrueToggle(UWORD,UWORD,UWORD,UWORD);
void LibsClose(void);
void LineToggle(UWORD,UWORD,UWORD,UWORD);
void WriteStuff(void);
void WindowSet(void);
void CheckMsg(void);
void CheckIntMsg(void);
void ITInit(struct IntuiText *,UBYTE *);
void ErrorDisplay(void);
void MIInit(struct MenuItem *,struct MenuItem *,SHORT,BYTE,APTR,SHORT);
void CheckCOPP(void);
void MenuInit(struct Menu *,struct Menu *,BYTE *,SHORT,SHORT);
void PowerChange(void);
void MyFill(UWORD,UWORD,UWORD,UWORD,UWORD);
void DescribeSystem(void);
void ScreenSet(void);
void CountChange(void);
void ScreenClose(void);
void Palette32(void);
void ScreensClose(void);
void GetWindowSize(void);
int  OpenWrite(UBYTE *);
void FullSurface(void);
void FullSurface2(void);
void FullSurface3(void);

int  WriteFile(UBYTE *,ULONG);
void Status(void);
void CloseWrite(void);
void RestoreOrigColors(void);
int ShowPalette(void);
UBYTE *GetColors(UBYTE *,ULONG);
ULONG LongSwap(ULONG);
void MySetRGB(SHORT,USHORT);

void StorePalette(UBYTE *);

void DisLine(struct RastPort *,char *,int);

struct timeval CurTime;


void InitVS(void)
{
	BPP = GetCyberIDAttr(CYBRIDATTR_BPPIX,ThisMode);

	SDepth = GetCyberIDAttr(CYBRIDATTR_DEPTH,ThisMode);
	SWidth = GetCyberIDAttr(CYBRIDATTR_WIDTH,ThisMode);
	SHeight = GetCyberIDAttr(CYBRIDATTR_HEIGHT,ThisMode);
	PFMT = GetCyberIDAttr(CYBRIDATTR_PIXFMT,ThisMode);
}


struct timerequest *CreateTimer(ULONG unit)
{
LONG error;
struct timerequest *TimerMsg;

	TimerPort = CreatePort("MyTimer",32);
	TimerMsg = (struct timerequest *)	CreateIORequest(TimerPort,sizeof(struct timerequest ));
	if (!TimerMsg) return(NULL);
	error = OpenDevice("timer.device",UNIT_MICROHZ,(struct IORequest *) TimerMsg,0L);
	if (error)	{
		DeletePort(TimerPort);
		return(NULL);
		}
	return(TimerMsg);
}


void OpenTimer(void)
{
	tr = CreateTimer(1);
	TimerBase = (struct Library *)tr->tr_node.io_Device;
}

void CloseTimer(void)
{
	if (TimerPort) DeletePort(TimerPort);
	if (TimerBase) TimerBase = (struct Library *)(-1);
}


void TrueToggle(x,y,xe,ye)
UWORD x, y, xe, ye;
{
ULONG tmpVal;
ULONG color;
UWORD Lft,Top;
	Lft = IntWindow->LeftEdge;
	Top = IntWindow->TopEdge;
	if (y > ye)	{
		tmpVal = y;
		y = ye;
		ye = tmpVal;
		}
	if (y == ye)	{
		if (x > xe) {
			tmpVal = x;
			x = xe;
			xe = tmpVal;
			}
		while(x < xe) {
			color = ReadRGBPixel(&WBScreen->RastPort,x + Lft,y + Top);
			color = 0xffffff - color;
			color = color & 0xffffff;
			WriteRGBPixel(&WBScreen->RastPort,x+Lft,y+Top,color);
			x++;
			}
		}
	else while (y < ye)	{
		color = 0xffffff - ReadRGBPixel(&WBScreen->RastPort,x + Lft,y + Top);
		color = color & 0xffffff;
		WriteRGBPixel(&WBScreen->RastPort,x+Lft,y+Top,color);
		y++;
		}
}

void LineToggle(x,y,xe,ye)
UWORD x, y, xe, ye;
{
UWORD tmpVal;
UBYTE color;
	if (SDepth > 8)	{
		TrueToggle(x,y,xe,ye);
		return;
		}
	if (y > ye)	{
		tmpVal = y;
		y = ye;
		ye = tmpVal;
		}
	if (y == ye)	{
		if (x > xe) {
			tmpVal = x;
			x = xe;
			xe = tmpVal;
			}
		while(x < xe) {
			color = ReadPixel(CWRast,x,y);
			color = 255 - color;
			SetAPen(CWRast,color);
			WritePixel(CWRast,x,y);
			x++;
			}
		}
	else while (y < ye)	{
		color = 255 - ReadPixel(CWRast,x,y);
		SetAPen(CWRast,color);
		WritePixel(CWRast,x,y);
		y++;
		}
}

void TruePixel(UWORD x,UWORD y,ULONG color)
{
ULONG *DstBuf,*Src;
	DstBuf = (ULONG *)WindowBuf;
	DstBuf = DstBuf + WWidth*(ULONG)y;
	DstBuf = DstBuf + (ULONG)x;
	Src = (ULONG *)ColorTable32 + color;
	*DstBuf = *Src;
}

void SetTrueColor(UWORD x, UWORD y, ULONG color)
{
ULONG *ColLng;
UWORD Lft,Top;
UBYTE *Src;
	Lft = IntWindow->LeftEdge;
	Top = IntWindow->TopEdge;
	Lft = Lft + BLeft;
	Top = Top + BTop;
	if (x  + BLeft >= IntWindow->Width - IntWindow->BorderRight) return;
	if (color < 0xfffe)	color = color + 4;
	Src = ColorTable32 + 4*color;
	ColLng = (ULONG *)Src;
	*LPixelBuf++ = *ColLng;
}

void ReadPackedLine(struct Screen *s,UWORD xs,UWORD y,UWORD lWidth,UBYTE *Dest)
{
UWORD pCnt;
	register ULONG	offset = (s->Width*y + xs);
	pCnt = 0;
	while (pCnt < lWidth)	{
		*Dest++ = *(BoardMem+offset);
		offset++;
		pCnt++;
	}
}

void ITInit(Item,NamePtr)
struct	IntuiText	*Item;
UBYTE	*NamePtr;
{
	Item -> IText = NamePtr;
	Item -> BackPen = 0;
	Item -> FrontPen = 3;
	Item -> DrawMode = JAM1;
}

void MIInit(Item,NxtItem,TEdge,Cmd,ITItem,Width)
struct	MenuItem	*Item,*NxtItem;
APTR	ITItem;
SHORT	TEdge,Width;
BYTE	Cmd;
{
	Item -> Command = Cmd;
	Item -> TopEdge = TEdge;
	Item -> NextItem = NxtItem;
	Item -> ItemFill = (APTR)ITItem;
	Item -> Flags = (USHORT)DefFlg;
	Item -> Height = FontHeight;
	Item -> Width = Width;
}

void MenuInit(MenuStruct,NxtMenu,NamePtr,LEdge,MWidth)
struct Menu	*MenuStruct,*NxtMenu;
SHORT	LEdge,MWidth;
BYTE	*NamePtr;
{
	MenuStruct -> NextMenu = NxtMenu;
	MenuStruct -> Width = MWidth;
	MenuStruct -> Height = FontHeight;	/*9;*/
	MenuStruct -> LeftEdge = LEdge;
	MenuStruct -> TopEdge = 0;
	MenuStruct -> MenuName = NamePtr;
	MenuStruct -> Flags = MenFlg;

}


void MyFill(color,xl,yt,xr,yb)
UWORD color,xl,yt,xr,yb;
{
UWORD x,y;
	x = xl;
	y = yt;
	while (y < yb) {
		while (x < xr) {
			TruePixel(x,y,(ULONG)color);
			x++;
			}
		x = xl;
		y++;
		}
}


ULONG	LngColor(int TableCnt)
{
ULONG RGBColor;
UBYTE *Src;
UBYTE Red, Green, Blue;
	Src = (UBYTE *)NewColorTable;
	Src = Src + 4*TableCnt;
	Blue = *Src++;
	Green = *Src++;
	Red = *Src++;
	RGBColor = (ULONG)Red;
	RGBColor <<= 8;
	RGBColor = RGBColor | (ULONG)Green;
	RGBColor <<= 8;
	RGBColor = RGBColor | (ULONG)Blue;
	return(RGBColor);

}

int ShowPicPalette(void)
{
int TmpCol,TopCol;
UWORD xPos,yPos,deltaX,deltaY;
	if (BPP == 1)	{
		yPos = ShowPalette();
		return(yPos);
	}
	deltaX = 4;
	deltaY = 4;
	TmpCol = 0;
	xPos = 20;
	yPos = 2;
	if (BPP == 1) TopCol = 256;
	else TopCol = 3*4096;
	TmpCol = 0;
	while ((TmpCol < TopCol)&&(yPos+20 < IntWindow->Height))	{
		MyFill((UWORD)TmpCol,xPos,yPos,xPos+deltaX,yPos+deltaY);
		xPos = xPos + deltaX;
		TmpCol = TmpCol + 2;
		if (xPos+40 > IntWindow->Width)	{
			xPos = 20;
			yPos = yPos + deltaY;
			}
		}
	return((int)yPos);
}

ShowPalette(void)
{
int TmpCol;
UWORD xPos,yPos,deltaX,deltaY;
	deltaX = 16;
	deltaY = 16;
	TmpCol = 4;
	if (NumColors == 16) {
		TmpCol = 0;
		}
	xPos = BLeft;
	yPos = BTop;
	while (TmpCol < TopCol)	{
		SetAPen(CWRast,TmpCol);
		RectFill(CWRast,xPos,yPos,xPos+deltaX,yPos+deltaY);
		if (xPos > WWidth - 80)	{
			xPos = BLeft - deltaX;
			yPos = yPos + deltaY;
			yPos++;
			}
		xPos = xPos + deltaX;
		TmpCol++;
		if (TmpCol == 17) TmpCol = 20;
		}
		SetAPen(CWRast,TmpCol);
		RectFill(CWRast,xPos,yPos,xPos+deltaX,yPos+deltaY);
	return(yPos);
}

void ScreenSet()
{
WORD	xPos,yPos;
nw.Title = &TitleM[0];
nw.LeftEdge		=	0;
nw.TopEdge		=	0;

nw.Width		=	600;
nw.Height		=	400;

nw.Width		=	534;
nw.Height		=	400;

nw.Width		=	345;
nw.Height		=	272;

nw.BlockPen		=	WBScreen->BlockPen;
nw.DetailPen	=	WBScreen->DetailPen;
nw.IDCMPFlags	=	CmpFlg | IDCMP_NEWSIZE | CLOSEWINDOW ;
nw.Flags		=	WINDOWDRAG|WINDOWDEPTH|SMART_REFRESH|WINDOWCLOSE|ACTIVATE|REPORTMOUSE | WFLG_NEWLOOKMENUS | WFLG_SIZEGADGET;
nw.Screen		= 	WBScreen;
nw.FirstGadget	=	NULL;
nw.CheckMark	=	NULL;
nw.BitMap		=	NULL;
nw.MinWidth		=	100;
nw.MinHeight	=	75;
nw.MaxWidth		=	WBScreen->Width;
nw.MaxHeight	=	WBScreen->Height;

	if (NumColors == 16)	PalSize = 16;
	else PalSize = TopCol - 6;
	if ((WBScreen->Width < 400)||(WBScreen->Height < 300))	{
		nw.Width		=	WBScreen->Width;
		nw.Height		=	WBScreen->Height;
	}
	IntWindow = (struct Window *)OpenWindow( &nw );
	BLeft = (LONG)IntWindow->BorderLeft;
	BTop = (LONG)IntWindow->BorderTop;
	RightEdge = IntWindow->GZZWidth;
	FarEdge = IntWindow->GZZHeight;
	WWidth = RightEdge;
	WHeight = FarEdge;
	XC = RightEdge/2;
	YC = FarEdge/2;
/* Get associated information about Int window */
	CWRast = IntWindow -> RPort;
	IntPort	= IntWindow -> UserPort;
	MWPort	= IntWindow -> UserPort;
	xPos = BLeft;
	yPos = BTop;
	DummyText.ITextFont = DefFont;
	DummyText.IText = (UBYTE *)"Project__";
	MenWidth = IntuiTextLength(&DummyText);


	MenuInit(&ProjMenu,&CountMenu,"Project",20,MenWidth);
	DummyText.IText = (UBYTE *)"Redraw(Same P)___________";
	MenWidth = IntuiTextLength(&DummyText);
	ProjMenu.FirstItem = &MI11;
	MIInit(&MI11,&MI12,0,0x41,&IT11,MenWidth);
	MIInit(&MI12,&MI13,FontHeight,0x50,&IT12,MenWidth);
	MIInit(&MI13,&MI14,2*FontHeight,0x53,&IT13,MenWidth);
	MIInit(&MI14,&MI15,3*FontHeight,0x49,&IT14,MenWidth);
	MIInit(&MI15,&MI16,4*FontHeight,0x4c,&IT15,MenWidth);
	MIInit(&MI16,&MI17,5*FontHeight,0x4e,&IT16,MenWidth);
	MIInit(&MI17,0,6*FontHeight,0x51,&IT17,MenWidth);

	ITInit(&IT11,"About");
	ITInit(&IT12,"Redraw(Same P)");
	ITInit(&IT13,"Save Image (bmp)");
	ITInit(&IT14,"Save Image (iff)");
	ITInit(&IT15,"Save Parm");
	ITInit(&IT16,"Load Parm");
	ITInit(&IT17,"Quit");
	LeftPos = MenWidth;
	DummyText.IText = (UBYTE *)"Maximum Count__";
	MenWidth = IntuiTextLength(&DummyText);

	MenuInit(&CountMenu,&ChangeMenu,"Maximum Count",LeftPos,MenWidth);
	DummyText.IText = (UBYTE *)"Decrease by 8_________";
	MenWidth = IntuiTextLength(&DummyText);

	CountMenu.FirstItem = &MI31;
	MIInit(&MI31,&MI32,0,43,&IT31,MenWidth);
	MIInit(&MI32,&MI33,FontHeight,45,&IT32,MenWidth);
	MIInit(&MI33,&MI34,2*FontHeight,0x44,&IT33,MenWidth);
	MIInit(&MI34,0,3*FontHeight,0x48,&IT34,MenWidth);

	ITInit(&IT31,"Increase by 8");
	ITInit(&IT32,"Decrease by 8");
	ITInit(&IT33,"Double");
	ITInit(&IT34,"Halve");

	LeftPos = LeftPos + MenWidth;
	DummyText.IText = (UBYTE *)"Changes___";
	MenWidth = IntuiTextLength(&DummyText);

	MenuInit(&ChangeMenu,&PowerMenu,"Changes",LeftPos,MenWidth);
	DummyText.IText = (UBYTE *)"Power down_________";
	MenWidth = IntuiTextLength(&DummyText);

	ChangeMenu.FirstItem = &MI41;
	MIInit(&MI41,&MI42,0,0x5a,&IT41,MenWidth);
	MIInit(&MI42,&MI43,FontHeight,0x52,&IT42,MenWidth);
	MIInit(&MI43,&MI44,2*FontHeight,0x3e,&IT43,MenWidth);
	MIInit(&MI44,&MI45,3*FontHeight,0x3c,&IT44,MenWidth);
	MIInit(&MI45,&MI46,4*FontHeight,0x55,&IT45,MenWidth);
	MIInit(&MI46,&MI47,5*FontHeight,0x45,&IT46,MenWidth);
	MIInit(&MI47,0,6*FontHeight,0x59,&IT47,MenWidth);

	ITInit(&IT41,"Zoom");
	ITInit(&IT42,"Restore");
	ITInit(&IT43,"Power Down");
	ITInit(&IT44,"Power Up");
	ITInit(&IT45,"Magnify");
	ITInit(&IT46,"Reduce");
	ITInit(&IT47,"Palette");

	LeftPos = LeftPos + MenWidth;
	DummyText.IText = (UBYTE *)"Fractional Power_____";
	MenWidth = IntuiTextLength(&DummyText);

	MenuInit(&PowerMenu,0,"Fractional Power",LeftPos,MenWidth);
	DummyText.IText = (UBYTE *)"Multiply increment size by 10_________";
	MenWidth = IntuiTextLength(&DummyText);

	PowerMenu.FirstItem = &MI21;
	MIInit(&MI21,&MI22,0,0x2e,&IT21,MenWidth);
	MIInit(&MI22,&MI23,FontHeight,0x30,&IT22,MenWidth);
	MIInit(&MI23,&MI24,2*FontHeight,0x2f,&IT23,MenWidth);
	MIInit(&MI24,&MI25,3*FontHeight,0x78,&IT24,MenWidth);
	MIInit(&MI25,&MI26,4*FontHeight,0x5e,&IT25,MenWidth);
	MIInit(&MI26,0,5*FontHeight,0x5c,&IT26,MenWidth);

	ITInit(&IT21,"Set Increment Size to 0.1");
	ITInit(&IT22,"Set Increment Size to 0");
	ITInit(&IT23,"Divide Increment Size by 10");
	ITInit(&IT24,"Multiply Increment Size by 10");
	ITInit(&IT25,"Increment Fraction by Size");
	ITInit(&IT26,"Decrement Fraction by Size");

	SetMenuStrip(IntWindow,&ProjMenu);
	MenVal = 0;;
}

void ScreensClose()
{
	if(InfoWindow) {
		CloseWindow(InfoWindow);
		InfoWindow = 0;
		}
	if(IntWindow) ClearMenuStrip(IntWindow);
	if(IntWindow) {
		CloseWindow(IntWindow);
		IntWindow = 0;
		}
}


int OpenWrite(UBYTE *FilNam)
{
	FileHandle = Open(FilNam,MODE_NEWFILE);
	if (!FileHandle)	return(-1);
	return(0);
}

int WriteFile(UBYTE *Source,ULONG FileLength)
{
	Write(FileHandle,(char *)Source,FileLength);
	return(0);
}
void CloseWrite()
{
	Close(FileHandle);
}

UBYTE *GetColors(MyColors,CTSize)
UBYTE *MyColors;
ULONG CTSize;
{
USHORT *CurrentColor,Red,Green,Blue,TCol;
	CurrentColor = WBScreen->ViewPort.ColorMap->ColorTable;
	while (CTSize)	{
		Red = *CurrentColor;
		Red = 0xf00 & Red;
		Red >>= 4;
		TCol = Red;
		TCol >>= 4;
		Red = Red | TCol;
		*MyColors++ = (UBYTE)Red;
		Green = *CurrentColor;
		Green = 0xf0 & Green;
		TCol = Green;
		TCol >>= 4;
		Green = Green | TCol;
		*MyColors++ = (UBYTE)Green;
		Blue = *CurrentColor++;
		Blue = 0xf & Blue;
		TCol = Blue;
		Blue <<= 4;
		Blue = Blue | TCol;
		*MyColors++ = (UBYTE)Blue;
		--CTSize;
		}
	return(MyColors);
}

ULONG LongSwap(LngWrd)
ULONG LngWrd;
{
ULONG LngBuf[1];
UBYTE *ByteBuf;
UBYTE Byte1,Byte2,Byte3,Byte4;
	LngBuf[0] = LngWrd;
	ByteBuf = (UBYTE *)LngBuf;
	Byte1 = *ByteBuf++;
	Byte2 = *ByteBuf++;
	Byte3 = *ByteBuf++;
	Byte4 = *ByteBuf;
	ByteBuf = (UBYTE *)LngBuf;
	*ByteBuf++ = Byte4;
	*ByteBuf++ = Byte3;
	*ByteBuf++ = Byte2;
	*ByteBuf = Byte1;
	LngWrd = LngBuf[0];
	return(LngWrd);
}

void StorePalette(PalPointer)
UBYTE *PalPointer;
{
UBYTE *TabLoc;
int TableCnt;
UBYTE r,g,b,h,LNib,HNib;

	TableCnt = 0;
	TabLoc = (UBYTE *)NewColorTable;
	while (TableCnt < 0x100)	{
		LNib = *TabLoc++;
		HNib = LNib & 0xf0;
		h = HNib;
		h >>= 4;
		h = h | HNib;
		HNib = LNib & 0xf;
		r = HNib;
		r <<= 4;
		r = r | HNib;
		LNib = *TabLoc++;
		HNib = LNib & 0xf0;
		g = HNib;
		g >>= 4;
		g = g | HNib;
		HNib = LNib & 0xf;
        b = HNib;
		b <<= 4;
		b = b | HNib;
		*PalPointer++ = b;
		*PalPointer++ = g;
		*PalPointer++ = r;
		*PalPointer++ = h;
		TableCnt++;
		}

}

void ChangeNW(void)
{
	nw.Width = 180;
	nw.Height = 40;
	nw.LeftEdge = IntWindow->LeftEdge + 40;
	nw.TopEdge = IntWindow->TopEdge + 40;
	nw.Title = "           Saving";
	nw.IDCMPFlags	=	CmpFlg;
	nw.Flags		=	SMART_REFRESH|ACTIVATE;
 }

void DisLine(LineRP,LinMes,LineNum)
struct RastPort *LineRP;
char *LinMes;
int LineNum;
{
		SetAPen(LineRP,0);
		RectFill(LineRP,15,20,130,35);
		SetAPen(LineRP,1);
		Move(LineRP,20,25);
		sprintf(&MyStringBuf[0],LinMes);
		sprintf(&MyStringBuf[strlen(MyStringBuf)],"%d.",(int)(WHeight-LineNum));
		Text(LineRP,&MyStringBuf[0],strlen(MyStringBuf)-1);
}

void SaveBMP(void)
{
UBYTE *BMPHdrBuffer;

UBYTE *LineBuff;
UBYTE *BMPBodyBuffer;
ULONG *BMPLPointer;
UWORD *BMPWPointer;
struct Window *SavingWnd;
ULONG BMPBodyLength,BPPix;
UWORD WAHL,WAHH;
BPTR BMHandle;
LONG PixCount;

UWORD LBufLength,LinePos,DstMode;
int LineNum,HdrSize,WDepth;
char *FilNam;
UBYTE r,g,b;

	WDepth = IntWindow->RPort->BitMap->Depth;
	if (BPP == 1) {
		HdrSize = 0x436;
		FilNam = "Mand8.bmp";
		WAHL = WWidth;
		BPPix = 0x00080001;
		if (WDepth == 4) FilNam = "Mand4.bmp";
		if (WDepth == 5) FilNam = "Mand5.bmp";
		}
	else {
		HdrSize = 0x36;
		FilNam = "Mand.bmp";
		WAHL = 3*WWidth;
		BPPix = 0x00180001;
		}
	BMPHdrBuffer = AllocMem(HdrSize,MemMode);
	BMPWPointer = (UWORD *)BMPHdrBuffer;
	*BMPWPointer++ = 0x424d;	/* 'BM' */
	BMPLPointer = (ULONG *)BMPWPointer;
	WAHH = WAHL;
	WAHL >>= 2;  /* Divide by 4 */
	WAHL <<= 2;  /* Multiply by 4 */
    while (WAHH - WAHL) {
		WAHH++;
		WAHL = WAHH;
		WAHL >>= 2;
		WAHL <<= 2;
		}
	WAHL = WAHH;
	LBufLength = WAHH;
	LineBuff = AllocMem(LBufLength+4,MemMode);
	BMPBodyLength = WAHH*WHeight;
	*BMPLPointer++ = LongSwap(BMPBodyLength + HdrSize);
	*BMPLPointer++ = 0;
	*BMPLPointer++ = LongSwap(HdrSize);	/* 0x36 or 0x436 bytes of header.*/
	*BMPLPointer++ = LongSwap(0x28);	/* 0x28 = 40 bytes remaining before palette (if any).*/
	*BMPLPointer++ = LongSwap((ULONG)WWidth);
	*BMPLPointer++ = LongSwap((ULONG)WHeight);
    *BMPLPointer++ = LongSwap(BPPix);
	*BMPLPointer++ = 0;
	*BMPLPointer++ = LongSwap(BMPBodyLength);
	*BMPLPointer++ = 0;
	*BMPLPointer++ = 0;
	*BMPLPointer++ = 0;
	*BMPLPointer++ = 0;
	if (BPP == 1) StorePalette((UBYTE *)BMPLPointer);
	LineNum = WHeight - 1;
	ChangeNW();
	SavingWnd = OpenWindow(&nw);
	BMHandle = Open(FilNam,MODE_NEWFILE);
	Write(BMHandle,BMPHdrBuffer,HdrSize);
	DstMode = (UWORD)(3*WWidth);
	SetFont(SavingWnd->RPort,CWFont);
	while (LineNum >= 0)	{
		BMPBodyBuffer = LineBuff + LBufLength - 1;
		*BMPBodyBuffer-- = 0;
		*BMPBodyBuffer-- = 0;
		*BMPBodyBuffer-- = 0;
		*BMPBodyBuffer = 0;
		LinePos = (UWORD)IntWindow->BorderTop + (UWORD)LineNum;
    	if (BPP == 1)	{
			ReadPixelLine8(IntWindow->RPort,IntWindow->BorderLeft,LinePos,WWidth,LineBuff,&MainWRast);
			}
		else	{
			PixCount = ReadPixelArray((APTR*)LineBuff,0,0,DstMode,IntWindow->RPort,IntWindow->BorderLeft,LinePos,(UWORD)WWidth,1,RECTFMT_RGB);
			PixCount = WWidth;
			BMPBodyBuffer = LineBuff;
			while (PixCount)	{
        		r = *BMPBodyBuffer++;
				g = *BMPBodyBuffer++;
				b = *BMPBodyBuffer;
				--BMPBodyBuffer;
				--BMPBodyBuffer;
				*BMPBodyBuffer++ = b;
				*BMPBodyBuffer++ = g;
				*BMPBodyBuffer++ = r;
				--PixCount;
				}
    		}
		Write(BMHandle,LineBuff,LBufLength);
		DisLine(SavingWnd->RPort,"Line ",LineNum);
		--LineNum;
		}
	Close(BMHandle);
    if (SavingWnd) CloseWindow(SavingWnd);
	if (LineBuff) FreeMem(LineBuff,LBufLength+4);
	if (BMPHdrBuffer) FreeMem(BMPHdrBuffer,HdrSize);
}

void SaveP(void)
{
DOUBLE *DblPtr;
ULONG	*LngPtr;

UBYTE *DataBuf;
	DataBuf = AllocMem(48,MEMF_CLEAR);
	DblPtr = (DOUBLE *)DataBuf;
	*DblPtr++ = XCenter;
	*DblPtr++ = YCenter;
	*DblPtr++ = HWidth;
	*DblPtr++ = HHeight;
	*DblPtr++ = Factor;
	LngPtr = (LONG *)DblPtr;
	*LngPtr++ = MaxCnt;
	*LngPtr++ = Power;
	OpenWrite((UBYTE *)"Mand.prm");
	WriteFile(DataBuf,48);
	CloseWrite();
	if (DataBuf) FreeMem(DataBuf,48);
}

void LoadP(void)
{
DOUBLE *DblPtr;
ULONG	*LngPtr;

UBYTE *DataBuf;
	DataBuf = AllocMem(48,MEMF_CLEAR);
	FileHandle = Open((UBYTE *)"Mand.prm",MODE_OLDFILE);
	if (!FileHandle)	{
		printf("The file Mand.prm can't be found!\n");
		return;
		}
	Read(FileHandle,DataBuf,48);
	Close(FileHandle);
	LastX = XCenter;
	LastY = YCenter;
	LastFactor = Factor;
	DblPtr = (DOUBLE *)DataBuf;
	XCenter = *DblPtr++;
	YCenter =*DblPtr++;
	HWidth = *DblPtr++;
	HHeight = *DblPtr++;
	Factor = *DblPtr++;
	DX = 1./Factor;
	LngPtr = (LONG *)DblPtr;
	MaxCnt = *LngPtr++;
	Power = *LngPtr++;
	if (DataBuf) FreeMem(DataBuf,48);
	WriteStuff();
}



UBYTE PaletteNumberFind( UBYTE Clr)
{
UBYTE NColor;
	NColor = Clr + 4;
	if (NColor > 16) NColor = NColor + 3;
	return(NColor);
}

void SmallPalette(void)
{
UWORD ColTab[] = {0,0x8,0xc,0xf,0x4c,0xc4,0xf0,0x4f0,0x880,0xc40,0xf00,0xf04,0xf08,0xf0c,0xf0f,0xa0a};
	LoadRGB4(&WBScreen->ViewPort,&ColTab[0],16);
}

void SetPalette(void)
{
UWORD *Src,*Dst;
DOUBLE	RShade;
int Mult1,Mult2,ColMax,BotCol;
ULONG CntCol;
ULONG NColor;
UBYTE	Shade,Shade2;

	if (WBScreen->RastPort.BitMap->Depth == 4)	NumColors = 16;
	if (WBScreen->RastPort.BitMap->Depth == 5)	NumColors = 32;
	if (WBScreen->RastPort.BitMap->Depth == 6)	NumColors = 64;
	if (WBScreen->RastPort.BitMap->Depth == 7)	NumColors = 128;
	if (WBScreen->RastPort.BitMap->Depth == 8)	NumColors = 256;
	TopCol = NumColors - 1;
	if (WBScreen->RastPort.BitMap->Depth < 5) {
		return;
		}
	if (SDepth >= 15) NumColors = 0x10000;
	if (NumColors <= 256) TableSize = 4000;
	else TableSize = 0x40000;
	OldColorTable = WBScreen->ViewPort.ColorMap->ColorTable;
	TopCol = NumColors - 1;
	NewColorTable = AllocMem(TableSize,MemMode);
	ColorTable32 = (UBYTE *)NewColorTable;
	if (!NewColorTable) {
		printf("Failed in allocation!\n");
		return;
		}
	CntCol = 0;
	Dst = (UWORD *)NewColorTable;
	Src = (UWORD *)OldColorTable;
	while (CntCol < NumColors)	{
		*Dst++ = *Src++;
		CntCol++;
		}
	ScreenToFront(WBScreen);
	if (NumColors > 256)	{
		Palette32();
		return;
		}
	WBScreen->ViewPort.ColorMap->ColorTable = NewColorTable;
	Mult1 = 4*256/NumColors;
	Mult2 = 3*Mult1/2;
	ColMax = NumColors/8;
	Mult2 = 6;
	Color = 0;
	BotCol = 4;
	SetRGB32(&(WBScreen->ViewPort),0,0xaa*BFactor,0xaa*BFactor,0xaa*BFactor);
	SetRGB32(&(WBScreen->ViewPort),1,0,0,0);
	SetRGB32(&(WBScreen->ViewPort),2,0xff*BFactor,0xff*BFactor,0xff*BFactor);
	SetRGB32(&(WBScreen->ViewPort),3,0x64*BFactor,0x88*BFactor,0xb8*BFactor);
	Color = 4;
	while (Color < ColMax)	{
		Shade = Mult1*Color + 128;
		Shade2 = Mult2*Color;
		NColor = PaletteNumberFind(Color);
		SetRGB32(&(WBScreen->ViewPort),NColor,0,BFactor*Shade2,BFactor*Shade);
		Color++;
		}
	while (Color < 2*ColMax)	{
        Shade = Color - ColMax;
		Shade2 = Mult2*Shade;
		Shade = Mult1*Shade + 128;
		NColor = PaletteNumberFind(Color);
		SetRGB32(&(WBScreen->ViewPort),NColor,BFactor*Shade,0,BFactor*Shade2);
		Color++;
		}
	while (Color < 3*ColMax)	{
		Shade = Color - 2*ColMax;
		Shade = Mult1*Shade + 128;
		RShade = 2.*Shade/3.;
		Shade2 = RShade;
		NColor = PaletteNumberFind(Color);
		SetRGB32(&(WBScreen->ViewPort),NColor,BFactor*Shade,BFactor*Shade2,0);
		Color++;
		}
	while (Color < 4*ColMax)	{
        Shade = Color - 3*ColMax;
		Shade2 = Mult2*Shade;
		Shade = Mult1*Shade + 128;
		NColor = PaletteNumberFind(Color);
		SetRGB32(&(WBScreen->ViewPort),NColor,BFactor*Shade,BFactor*Shade,BFactor*Shade2);
		Color++;
		}
	while (Color < 5*ColMax)	{
        Shade = Color - 4*ColMax;
		Shade = Mult1*Shade + 128;
		NColor = PaletteNumberFind(Color);
		if (NColor < TopCol)	SetRGB32(&(WBScreen->ViewPort),NColor,BFactor*Shade2,BFactor*Shade,0);
		Color++;
		}
	while (Color < 6*ColMax)	{
        Shade = Color - 5*ColMax;
		Shade2 = Mult2*Shade;
		Shade = Mult1*Shade + 128;
		NColor = PaletteNumberFind(Color);
		if (NColor < TopCol)	SetRGB32(&(WBScreen->ViewPort),NColor,0,BFactor*Shade,BFactor*Shade);
		Color++;
		}
	while (Color < 7*ColMax)	{
		Shade = Color - 6*ColMax;
		Shade = Mult1*Shade + 128;
		NColor = PaletteNumberFind(Color);
		if (NColor < TopCol)	SetRGB32(&(WBScreen->ViewPort),NColor,BFactor*Shade,0,BFactor*Shade);
		Color++;
		}
	while (Color < TopCol - 6)	{
		Shade = Color - 7*ColMax;
		Shade = Mult1*Shade + 96;
		Shade2 = Shade + 59;
		NColor = PaletteNumberFind(Color);
		if (NColor < TopCol)	SetRGB32(&(WBScreen->ViewPort),NColor,BFactor*Shade2,BFactor*Shade,BFactor*Shade2);
		Color++;
		}
	SetRGB32(&(WBScreen->ViewPort),TopCol,120*BFactor,0,120*BFactor);
}


void Palette32(void)
{
LONG C32Cnt;
UBYTE *Begin,*Dst;
UBYTE Red,Green,Blue;
BYTE dRed,dGreen,dBlue;
	Dst = (UBYTE *)NewColorTable;
	Begin = Dst;
	C32Cnt = 0;
	Red = 1;
	Green = 2;
	Blue = 128;
	dRed = 1;
	dGreen = 2;
	dBlue = 4;
	while (C32Cnt < 0xfffe)	{
		*Dst++ = 0;
		if (PalOpt == 0)	{
			*Dst++ = Red;
			*Dst++ = Green;
			*Dst++ = Blue;
			}
		if (PalOpt == 1)	{
			*Dst++ = Green;
			*Dst++ = Blue;
			*Dst++ = Red;
			}
		if (PalOpt == 2)	{
			*Dst++ = Blue;
			*Dst++ = Red;
			*Dst++ = Green;
			}
		if (PalOpt == 3)	{
			*Dst++ = Blue;
			*Dst++ = Green;
			*Dst++ = Red;
			}
		if (PalOpt == 4)	{
			*Dst++ = Green;
			*Dst++ = Red;
			*Dst++ = Blue;
			}
		if (PalOpt == 5)	{
			*Dst++ = Red;
			*Dst++ = Blue;
			*Dst++ = Green;
			}
		C32Cnt++;
		Blue = Blue + dBlue;
		Green = Green + dGreen;
		Red = Red + dRed;
		if ((Blue > 0xfb)||(Blue < 4))	dBlue = - dBlue;
		if ((Green >= 0xfd)||(Green < 2))	dGreen = - dGreen;
		if ((Red >= 0xfe)||(Red < 1))	dRed = - dRed;
		}
	*Dst++ = 0;
	*Dst++ = 0xff;
	*Dst++ = 0xff;
	*Dst++ = 0xff;
	*Dst++ = 0;

	if ((PalOpt == 0)||(PalOpt == 3))	{
		*Dst++ = 120;
		*Dst++ = 0;
		*Dst++ = 120;
		}
	if ((PalOpt == 1)||(PalOpt == 5))	{
		*Dst++ = 120;
		*Dst++ = 120;
		*Dst++ = 0;
		}
	if ((PalOpt == 2)||(PalOpt == 4))	{
		*Dst++ = 0;
		*Dst++ = 120;
		*Dst++ = 120;
		}

	Dst = Begin;
	WBScreen->ViewPort.ColorMap->ColorTable = NewColorTable;
}

void WindowSet()
{

nw.LeftEdge		=	0;
nw.TopEdge		=	0;			/* Expose screen drag bar */
nw.Width		=	64;
nw.Height		=	30;
nw.DetailPen	=	5;
nw.BlockPen		=	2;
nw.IDCMPFlags	=	CLOSEWINDOW ;
nw.Type			=	WBENCHSCREEN;
nw.Type			=	PUBLICSCREEN;
nw.Flags		=	WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH|ACTIVATE|REPORTMOUSE;
/*nw.Flags		=	WINDOWDRAG|WINDOWDEPTH|SMART_REFRESH|ACTIVATE|REPORTMOUSE | WFLG_NEWLOOKMENUS | WFLG_SIZEGADGET;*/
nw.FirstGadget	=	NULL;
nw.CheckMark	=	NULL;
nw.Screen		=	0;
WindowName 	= &Title[0];
nw.Title		=	(UBYTE *)WindowName;
nw.BitMap		=	NULL;
nw.MinWidth		=	100;
nw.MinHeight	=	75;
nw.MaxWidth		=	SWidth+20;
nw.MaxHeight	=	SHeight+20;
    Delay(10);
	InfoWindow = (struct Window *)OpenWindow( &nw );
	WBScreen = InfoWindow -> WScreen;
	DefFont = WBScreen->Font;
	WBRast = InfoWindow -> RPort;
	MyPort	= InfoWindow -> UserPort;
	WBScreen = InfoWindow->WScreen;
	WDepth = WBScreen->RastPort.BitMap->Depth;
	FontHeight = 1.2*(DefFont->ta_YSize);
	TFHeight = GfxBase->DefaultFont->tf_YSize;
	IWHeight = 21*TFHeight;
	InfBTop = InfoWindow->BorderTop;
	InfBLeft = InfoWindow->BorderLeft;
	IWWidth = TextLength(WBRast,&Mesag7[0],strlen(Mesag7));
	TwoSpace = TextLength(WBRast,(STRPTR)"  ",2);
	IWWidth = IWWidth + 2*TwoSpace;
	if (IWHeight + InfBTop < WBScreen->Height)	ChangeWindowBox(InfoWindow,0,0,IWWidth+InfBLeft+InfoWindow->BorderRight,IWHeight+InfBTop);
	else ChangeWindowBox(InfoWindow,0,0,IWWidth+InfBLeft+InfoWindow->BorderRight,WBScreen->Height);
	SetWindowTitles(InfoWindow,(UBYTE *)" Information about this Fractal",(UBYTE *)-1);
	DFont = GfxBase->DefaultFont;
	if (!CWFont) CWFont = OpenFont(&topaz8);
	DefBold.ta_Name = DFont->tf_Message.mn_Node.ln_Name;
	DefBold.ta_YSize = 14*DFont->tf_YSize/10;
	DefBold.ta_Style = 2;
	if (DiskfontBase) BFont = OpenDiskFont(&DefBold);
	nw.BlockPen = 3;

	nw.Screen = WBScreen;
	IsCyberScreen = FALSE;
	ThisMode = WBScreen->ViewPort.ColorMap->VPModeID;
	BPP = 1;
	if (CyberGfxBase)	{
		if (IsCyberModeID(ThisMode))	{
			IsCyberScreen = TRUE;
			InitVS();
			}
		}
	SetPalette();
}


WORD LengthDescript()
{
WORD chPos;
	if (SysFlag == 0)	chPos = GetLength((STRPTR)" 68000");
	else	{
		if (SysFlag & 0x10) chPos = GetLength((STRPTR)" 68060");
		else if (SysFlag & 0x8) chPos = GetLength((STRPTR)" 68040");
		else if (SysFlag & 0x4) chPos = GetLength((STRPTR)" 68030");
		else if (SysFlag & 0x2) chPos = GetLength((STRPTR)" 68020");
		chPos = chPos + GetLength((STRPTR)"'");
		if (SysFlag & AFF_68882) chPos = chPos + GetLength((STRPTR)St882);
		else if (SysFlag & AFF_68881) chPos = chPos + GetLength((STRPTR)" 68881");
		}
	return(chPos);
}

void CheckCOPP()
{
	if (SysFlag & AFF_68882)	{
		Text(WBRast,(STRPTR)Comma,1);
		Text(WBRast,(STRPTR)&St882[0],strlen(St882));
		}
	else if (SysFlag & AFF_68881)	{
		Text(WBRast,(STRPTR)Comma,1);
		Text(WBRast,(STRPTR)" 68881",6);
		}
}

void DescribeSystem()
{
	Text(WBRast,&CPUStrBuf[0],strlen(CPUStrBuf));
}

WORD GetLength(TempMsg)
UBYTE *TempMsg;
{
WORD chPos;
	chPos = TextLength(WBRast,TempMsg,strlen(TempMsg));
	return(chPos);
}
WORD GethPos(TempMsg)
UBYTE *TempMsg;
{
WORD	chPos;
	chPos = TextLength(WBRast,TempMsg,strlen(TempMsg));
	chPos = IWWidth - chPos;
	chPos >>= 1;
	chPos = chPos + InfBLeft;
	return(chPos);
}


void DisCnt(void)
{
static char	SrtBuf[30];
	Move(WBRast,160,19*TFHeight);
	SetAPen(WBRast,2);
	sprintf(&SrtBuf[0],(STRPTR)"Working on line %d.        ",ytemp);
	Text(WBRast,(STRPTR)SrtBuf,strlen(SrtBuf));
}

void WriteStuff()
{
static	char	Mesage[] 	= "SManMOS Beta 2.0 (3/28/2001)";
static	char	Mesag1[] 	= "by David M. McKinstry";
static	char	Mesag2[]	= "Copyright ";
static	char	Mesag2c[]	= " 1998-2001";
char	StrngBuffer[200];
UBYTE	Mesag2b[]	= {0xa9};
ULONG	MemSize;
char *TmpPtr;
WORD vPos,hPos,chPos,SpcPlus;
	SpcPlus = 3*TFHeight/2;
	--SpcPlus;
	vPos = InfBTop + TFHeight;
	SetAPen(WBRast,1);
	chPos = GethPos(&Mesage[0]);
	Move(WBRast,chPos,vPos);
	Text(WBRast,(STRPTR)Mesage,strlen(Mesage));
	vPos = vPos + TFHeight;
	Mesag1[5] = 0x76;
	chPos = GethPos(&Mesag1[0]);
	Move(WBRast,chPos,vPos);
	Text(WBRast,(STRPTR)Mesag1,strlen(Mesag1));
	hPos = IWWidth/8;
	vPos = vPos + TFHeight;
	SetAPen(WBRast,3);
	chPos = TextLength(WBRast,&Mesag2[0],strlen(Mesag2));
	chPos = chPos + TextLength(WBRast,&Mesag2b[0],1);
	chPos = chPos + TextLength(WBRast,&Mesag2c[0],strlen(Mesag2c));
	chPos = IWWidth - chPos;
	chPos >>= 1;
	Move(WBRast,chPos,vPos);
	Text(WBRast,(STRPTR)Mesag2,strlen(Mesag2));
	Text(WBRast,(STRPTR)Mesag2b,1);
	Text(WBRast,(STRPTR)Mesag2c,strlen(Mesag2c));
	vPos = vPos + SpcPlus;
	SetAPen(WBRast,1);
	chPos = LengthDescript();
	chPos = chPos + GetLength(&Mesag3[0]);
	chPos = IWWidth - chPos;
	chPos >>= 1;
	Move(WBRast,40,vPos);

	Text(WBRast,(STRPTR)Mesag3,strlen(Mesag3));
	DescribeSystem();

	vPos = vPos + TFHeight;
	Move(WBRast,hPos,vPos);
	MemSize = AvailMem(MEMF_CHIP);
	TmpPtr = &ChpEnd[0];
	--TmpPtr;
	sprintf(TmpPtr,"%d",(int)MemSize);
	Text(WBRast,(STRPTR)ChpMsg,strlen(ChpMsg));
	Move(WBRast,61*IWWidth/100,vPos);
	MemSize = AvailMem(MEMF_FAST);
	TmpPtr = &FstEnd[0];
	--TmpPtr;
	sprintf(TmpPtr,"%d",(int)MemSize);
	Text(WBRast,(STRPTR)FstMsg,strlen(FstMsg));

	SetAPen(WBRast,2);
	vPos = vPos + SpcPlus;
	chPos = GethPos(Mesag4);
	Move(WBRast,chPos,vPos);
	Text(WBRast,(STRPTR)Mesag4,strlen(Mesag4));

	SetAPen(WBRast,1);
	vPos = vPos + SpcPlus;

	Move(WBRast,hPos,vPos);
	TmpPtr = &WdtEnd[0];
	sprintf(TmpPtr,"%d",WWidth);
	Text(WBRast,(STRPTR)WdtMsg,strlen(WdtMsg));
	Text(WBRast,(STRPTR)"        ",8);
	Move(WBRast,hPos + TextLength(WBRast,&WdtMsg[0],strlen(WdtMsg)),vPos);
	Text(WBRast,(STRPTR)TmpPtr,strlen(TmpPtr));
	Move(WBRast,61*IWWidth/100,vPos);
	TmpPtr = &HgtEnd[0];
	sprintf(TmpPtr,"%d",WHeight);
	Text(WBRast,(STRPTR)HgtMsg,strlen(HgtMsg));
	Text(WBRast,(STRPTR)"        ",8);
	Move(WBRast,61*IWWidth/100 + TextLength(WBRast,&HgtMsg[0],strlen(HgtMsg)),vPos);
	Text(WBRast,(STRPTR)TmpPtr,strlen(TmpPtr));
	vPos = vPos + SpcPlus;
	SetAPen(WBRast,1);
	TmpPtr = &MagMsg[16];
	sprintf(TmpPtr,"%e",Factor);
	Move(WBRast,hPos,vPos);
	Text(WBRast,(STRPTR)MagMsg,strlen(MagMsg));

	SetAPen(WBRast,1);
	TmpPtr = &CntEnd[0];
	sprintf(TmpPtr,(STRPTR)"%d",MaxCnt);
	Move(WBRast,61*IWWidth/100,vPos);
	Text(WBRast,(STRPTR)CntMsg,strlen(CntMsg));
	Text(WBRast,(STRPTR)"        ",8);
	Move(WBRast,61*IWWidth/100 + TextLength(WBRast,&CntMsg[0],strlen(CntMsg)),vPos);
	Text(WBRast,(STRPTR)TmpPtr,strlen(TmpPtr));

	vPos = vPos + SpcPlus;
	SetAPen(WBRast,3);
	chPos = GethPos(&ScrMsg[0]);
	Move(WBRast,chPos,vPos);
	Text(WBRast,(STRPTR)ScrMsg,strlen(ScrMsg));

	SetAPen(WBRast,1);
	vPos = vPos + TFHeight;
	Move(WBRast,hPos,vPos);
	TmpPtr = &XPsEnd[0];
	sprintf(TmpPtr,"%#.14e",(HWidth-XCenter)/Factor);
	Text(WBRast,(STRPTR)XPos,strlen(XPos));
	Text(WBRast,(STRPTR)"                          ",24);
	Move(WBRast,hPos+TextLength(WBRast,&XPos[0],strlen(XPos)),vPos);
	Text(WBRast,(STRPTR)TmpPtr,strlen(TmpPtr));

	Move(WBRast,61*IWWidth/100,vPos);
	TmpPtr = &YPsEnd[0];
	sprintf(TmpPtr,"%#.14e",(HHeight-YCenter)/Factor);
	Text(WBRast,(STRPTR)YPos,strlen(YPos));
	Text(WBRast,(STRPTR)"                          ",24);
	Move(WBRast,61*IWWidth/100+TextLength(WBRast,&YPos[0],strlen(YPos)),vPos);
	Text(WBRast,(STRPTR)TmpPtr,strlen(TmpPtr));

	SetAPen(WBRast,3);
	vPos = vPos + SpcPlus;
	if (PowerF == 0.) {
		if (Power < 10) chPos = GethPos(&MandMsg[0]);
		else	chPos = GethPos(&MandMsgG[0]);
		}
	else chPos = GethPos(&MandMsgP[0]);
	Move(WBRast,chPos,vPos);
	if (PowerF == 0.)	{
		if (Power < 10) Text(WBRast,(STRPTR)MandMsg,strlen(MandMsg));
		else	Text(WBRast,(STRPTR)MandMsgG,strlen(MandMsgG));
		}
	else {
		Text(WBRast,(STRPTR)MandMsgP,strlen(MandMsgP));
		MandMsgP[strlen(MandMsgP)-3] = 0x2d;
		SetDrMd(WBRast,JAM1);
		Move(WBRast,chPos,vPos);
		Text(WBRast,(STRPTR)MandMsgP,strlen(MandMsgP)-2);
		SetDrMd(WBRast,JAM2);
		MandMsgP[strlen(MandMsgP)-3] = 0x30;
		}
	vPos = vPos - TFHeight/3;
	if (PowerF == 0.) chPos = chPos + TextLength(WBRast,&MandMsg[0],18);
	else chPos = chPos + TextLength(WBRast,&MandMsgP[0],18);
	Move(WBRast,chPos,vPos);
	vPos = vPos + TFHeight/3;

	TmpPtr = &StrngBuffer[0];
	if (PowerF == 0.) {
		sprintf(TmpPtr,"%d",Power);
		if (Power < 10) Text(WBRast,(STRPTR)TmpPtr,1);
		else Text(WBRast,(STRPTR)TmpPtr,2);
		}
	else {

		sprintf(TmpPtr,"%#2.16f",PowerN);
		Text(WBRast,(STRPTR)TmpPtr,16);
		}
	if (((SysFlag & AFF_68881)||(SysFlag & AFF_68882))&&((SysFlag & AFF_68020)||(SysFlag & AFF_68030)))	CPU = 1;

	SetAPen(WBRast,2);

	vPos = vPos + SpcPlus;
	chPos = GethPos(&Mesag5[0]);

	vPos = vPos + 3*TFHeight/2;

	sprintf(&Mesag8[0],(STRPTR)"'Exploring the Julia Sets' is on the %d bit screen with palette option %d!",SDepth,PalOpt);
	chPos = GethPos(&Mesag8[0]);
	SetAPen(WBRast,1);
	Move(WBRast,chPos,vPos);
	Text(WBRast,(STRPTR)Mesag8,strlen(Mesag8));

	vPos = vPos + TFHeight;
	TmpPtr = &StrngBuffer[0];
/*	sprintf(TmpPtr,(STRPTR)"This task is located at %x!",MyTask);
	Move(WBRast,20,vPos);
	Text(WBRast,&StrngBuffer[0],strlen(&StrngBuffer[0]));*/

}

void LibsOpen()
{
	if (!DOSBase)	{
		DOSBase = (struct DosLibrary *)OpenLibrary((UBYTE *)"dos.library",0L);
		}
	DiskfontBase = (struct Library *)OpenLibrary((UBYTE *)"diskfont.library",0);
	GfxBase = (struct GfxBase *)OpenLibrary((UBYTE *)"graphics.library",0L);

	WarpBase = (struct Library *)OpenLibrary((UBYTE *)"powerpc.library",14L);
	IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *)"intuition.library",0L);
	CyberGfxBase = (struct CyberGfxBase *)OpenLibrary((UBYTE *)"cybergraphics.library",40);
}

void LibsClose()
{
	if (WarpBase) CloseLibrary(WarpBase);
	if (DiskfontBase)	CloseLibrary(DiskfontBase);

	if (CyberGfxBase)	CloseLibrary((struct Library *)CyberGfxBase);

	if(GfxBase)			CloseLibrary((struct Library *)GfxBase);

	if(IntuitionBase)	CloseLibrary((struct Library *)IntuitionBase);

	}

void CheckMsg()
{
struct IntuiMessage *MyMsg;
	IMClass = 0;
    MyMsg = (struct IntuiMessage*) GetMsg(MyPort);
	if (MyMsg != NULL) {
  		IMClass = MyMsg -> Class;
		ReplyMsg((struct Message *)MyMsg);
	}
}

void CheckIntMsg()
{
struct IntuiMessage *MyMsg;
	MenVal = 0;
    MyMsg = (struct IntuiMessage*) GetMsg(IntPort);
	if (MyMsg != NULL) {
		MenVal = MyMsg -> Code;
		IMClass = MyMsg -> Class;
		ReplyMsg((struct Message *)MyMsg);
	}
}

void ErrorDisplay()
{
static	char	Err020[]	= "You are running SMan on an Amiga without a math coprocessor!";
static	char	Err021[]	= "Although this is probably working, it must be incredibly slow!";
static	char	Err022[]	= "Please run SMan on an adequate machine!";
static	char	Err023[]	= "Use the Close Gadget to Terminate.";
	SetRast(WBRast,0);
	SetAPen(WBRast,1);
	Move(WBRast,40,80);
	Text(WBRast,(STRPTR)Err020,strlen(Err020));
	Move(WBRast,40,95);
	Text(WBRast,(STRPTR)Err021,strlen(Err021));
	Move(WBRast,40,125);
	Text(WBRast,(STRPTR)Err022,strlen(Err022));
	SetAPen(WBRast,3);
	Move(WBRast,40,155);
	Text(WBRast,(STRPTR)Err023,strlen(Err023));
	WindowToFront(InfoWindow);
	IMClass = 0;
	while (IMClass != CLOSEWINDOW)	{
		CheckMsg();
		Delay(1);
		}
}


void CountChange()
{
	if((MenVal & 0xff) == 1)	MaxCnt = MaxCnt + 8;
	if((MenVal & 0xff) == 0x21)	MaxCnt = MaxCnt - 8;
	if((MenVal & 0xff) == 0x41)	MaxCnt = 2*MaxCnt;
	if((MenVal & 0xff) == 0x61) MaxCnt = MaxCnt/2;
	if (MaxCnt < 8)	MaxCnt = 8;
	WriteStuff();
	ActivateWindow(IntWindow);
}

void Restore(void)
{
	Factor = LastFactor;
	DX = 1./Factor;
	XCenter = LastX;
	YCenter = LastY;
	MenVal = 0xf820;	/* Force Redraw! */
}

void DrawPoly(void)
{
UWORD	xS,yS,xE,yE;
	PolyPnt = &PolyTab[0];
	xS = *PolyPnt++;
	yS = *PolyPnt++;
	xE = *PolyPnt++;
	yE = *PolyPnt++;
	LineToggle(xS,yS,xE,yE);
	xS = xE;
	yS = yE;
	xE = *PolyPnt++;
	yE = *PolyPnt++;
	LineToggle(xS,yS,xE,yE);
	xS = xE;
	yS = yE;
	xE = *PolyPnt++;
	yE = *PolyPnt++;
	LineToggle(xS,yS,xE,yE);
	xS = xE;
	yS = yE;
	xE = *PolyPnt++;
	yE = *PolyPnt++;
	LineToggle(xS,yS,xE,yE);
}

void PolyUpDate(void)
{
	PolyPnt = &PolyTab[0];
	x2 = IntWindow -> MouseX;
	*PolyPnt++ = x1;		/* Upper-Left Corner */
	*PolyPnt++ = y1;
	*PolyPnt++ = x2;		/* Upper-Right Corner */
	*PolyPnt++ = y1;
	DeltaX = x2 - x1;
	DeltaY = WHeight*DeltaX/WWidth;
	y2 = y1 + DeltaY;
	*PolyPnt++ = x2;		/* Lower-Right Corner */
	*PolyPnt++ = y2;
	*PolyPnt++ = x1;		/* Lower-Left Corner */
	*PolyPnt++ = y2;
	*PolyPnt++ = x1;		/* Upper-Left Corner */
	*PolyPnt++ = y1;
	Move(CWRast,x1,y1);
	PolyPnt = &PolyTab[0];
	DrawPoly();
}

/* Clear by reversing again */
void PolyClear(void)
{
	PolyPnt = &PolyTab[0];
	DrawPoly();
}
/*WaitChg will wait until there is at least a difference of 10 between
 the original MouseX value and the new. */

void WaitChg(void)
{
	while ((x2 - x1) < 5)	{
		x2 = IntWindow -> MouseX;
		Delay(1);
		}
}
void DoZoom(void)
{
double Ratio;
	x1 = 0;
	y1 = 0;
	x2 = 0;
	y2 = 0;
	while (MenVal != SELECTDOWN)	{
		x1 = IntWindow -> MouseX;
		y1 = IntWindow -> MouseY;
		CheckIntMsg();
		}
	x1 = IntWindow -> MouseX;
	y1 = IntWindow -> MouseY;

/* Now prep for complementary polygon (i.e. rectangle) */
	SetDrMd(CWRast,2);
	WaitChg();
	PolyUpDate();
	while (MenVal != SELECTUP)	{
		CheckIntMsg();
		PolyClear();
		PolyUpDate();
		Delay(1);
		}
/* Clear Polygon and restore drawing mode */
	PolyClear();
	SetDrMd(CWRast,0);
	LastFactor = Factor;
	LastX = XCenter;
	LastY = YCenter;

	Ratio = XWidth/DeltaX;
	Factor = Ratio*Factor;
	DX = 1./Factor;
	XCenter = XCenter - (double)(x1 - BLeft);
	XCenter = Ratio*XCenter;
	YCenter = YCenter - (double)(y1 - BTop);
	YCenter = Ratio*YCenter;
	MenVal = 0xf820;
}



void Zoom(void)
{
	xtemp = RightEdge;
	if ((MenVal & 0xf0) == 0xc0)	{
		PalOpt++;
        if (PalOpt > 5) PalOpt = 0;
		Palette32();
		}

    if((MenVal & 0xf0) == 0x00)	DoZoom();
	if(MenVal == 0xf822)	Restore();
	if((MenVal & 0xf0) == 0x40)	{
		--Power;
		if (PowerF == 0.)	{
			if (Power < 2) Power = 2;
			}
		else if (Power < 1) Power = 1;
		SetRast(WBRast,0);
		ActivateWindow(InfoWindow);
		}
	if((MenVal & 0xf0) == 0x60)	{
		Power++;
		if (Power > 99) {
			Power = 9;
			}
		SetRast(WBRast,0);
		ActivateWindow(InfoWindow);
		}
	if((MenVal & 0xf0) == 0x80)	{
		LastFactor = Factor;
		LastX = XCenter;
		LastY = YCenter;
		XCenter = 2.*(XCenter - HWidth);
		YCenter = 2.*(YCenter - HHeight);
		XCenter = XCenter + HWidth;
		YCenter = YCenter + HHeight;

		Factor = 2.*Factor;
		DX = 1./Factor;
		MenVal = 0xf820;
		}
	if((MenVal & 0xf0) == 0xa0)	{
		LastFactor = Factor;
		LastX = XCenter;
		LastY = YCenter;
		XCenter  = 0.5*(XCenter - HWidth);
		YCenter = 0.5*(YCenter - HHeight);
		XCenter = XCenter + HWidth;
		YCenter = YCenter + HHeight;
		Factor = Factor/2.;
		DX = 1./Factor;
		MenVal = 0xf820;
	}
	WriteStuff();
}


void SManMen(void)
{
		if (MenVal == 0xf800)	{
			WriteStuff();
			WBenchToFront();
			WindowToFront(InfoWindow);
			ActivateWindow(InfoWindow);
			}
		if (MenVal == 0xf840)	{
			SaveBMP();
			MenVal = 0;
			}
		if (MenVal == 0xf860)	{
			Save();
			MenVal = 0;
			}
		if (MenVal == 0xf880)	{
			SaveP();
			MenVal = 0;
			}
		if (MenVal == 0xf8a0)	{
			LoadP();
			MenVal = 0xf820;
			}
}



void FullCheck(void)
{
USHORT	SavVal;
ULONG	SavCls;

struct IntuiMessage *MyMsg;
		IMClass = 0;
		MenVal = 0;
		CheckMsg();
		if (IMClass == CLOSEWINDOW) {
			ScreenToFront(IntWindow->WScreen);
			WindowToFront(IntWindow);
			}
		CheckIntMsg();
		if (IMClass == CLOSEWINDOW) {
			ScreenToFront(IntWindow->WScreen);
			WindowToFront(IntWindow);
			MenVal = 0xf8c0;
			return;
			}
		if (MenVal)	 {
			SavVal = MenVal;
			SavCls = IMClass;
			while (MenVal == MENUDOWN)	{	/*Was MENUPICK */
				CheckIntMsg();
				}
			MenVal = SavVal;
			IMClass = SavCls;
			if (SavVal == 0xffff)	{
				MenVal = 0;
				}
			}
		if (IMClass == IDCMP_NEWSIZE) {
			while (IMClass == IDCMP_NEWSIZE)	{
				IMClass = 0;
				MyMsg = (struct IntuiMessage*) GetMsg(IntWindow -> UserPort);
				if (MyMsg)	{
					IMClass = MyMsg -> Class;
					ReplyMsg((struct Message *)MyMsg);
					}
				}
			GetWindowSize();
			MenVal = 0xf820;	/* Force a redraw */
			}

		if (MenVal & 0xf800) {
			if ((MenVal & 0xf) == 1) {
				CountChange();
				MenVal = 0;
				}
			if ((MenVal & 0xf) == 3) PowerChange();
			if (MenVal == 0xf800)	{
				WriteStuff();
				WBenchToFront();
				WindowToFront(InfoWindow);
				ActivateWindow(InfoWindow);
				MenVal = 0;
				}
			if (MenVal == 0xf8c0) xtemp = RightEdge;	/* Quit */
			if (MenVal == 0xf840) xtemp = RightEdge;	/* Save BMP */
			if (MenVal == 0xf860) SaveIFF = TRUE;		/* Save iff */
			if (MenVal == 0xf880) xtemp = RightEdge;	/* SaveP */
			if (MenVal == 0xf8a0) xtemp = RightEdge;	/* LoadP */
			if ((MenVal & 0xf80f) == 0xf802) xtemp = RightEdge;	/* Zoom */
			if ((MenVal & 0xf820) == 0xf820) xtemp = RightEdge; /* Redraw */
			}
}



void PlotIt(UWORD Clr)
{
ULONG *ColSrc;
int BotCol,TopCol;
	if (Clr != 0xffff)	{
		if (Clr > LastMax) {
			LastMax = Clr;
			}
		}
		if (NumColors == 16)	{
			BotCol = 0;
			TopCol = 15;
			}
		else {
			BotCol = 4;
			TopCol = NumColors - 1;
			}
		if (Clr == 0xffff) {
                   Clr = TopCol;
			}
		else if (Clr > (TopCol - BotCol)) {
				while (Clr > (TopCol - BotCol)) Clr = Clr - (TopCol - BotCol);
				}
		if (Clr != TopCol) Clr  = Clr + BotCol;
		if (Clr == 17) Clr = 20;
		if (Clr == 18) Clr = 21;
		if (Clr == 19) Clr = 22;

        *PixelBuf++ = (UBYTE)(Clr & 0xff);
}


void GetWindowSize(void)
{
WORD OldWidth,OldHeight;
	OldWidth = WWidth;
	OldHeight = WHeight;
	BLeft = (LONG)IntWindow->BorderLeft;
	BTop = (LONG)IntWindow->BorderTop;
	RightEdge = IntWindow->GZZWidth;
	FarEdge = IntWindow->GZZHeight;
	WWidth = RightEdge;
	WHeight = FarEdge;
	XWidth = WWidth;
	XHeight = WHeight;
	XC = RightEdge/2;
	YC = FarEdge/2;
	HWidth = XC;
	HHeight = YC;
	XCenter = XCenter + 0.5*(double)(WWidth - OldWidth);
	YCenter = YCenter + 0.5*(double)(WHeight - OldHeight);
	WriteStuff();
}

void PowerChange()
{
	if ((MenVal & 0xf0) == 0) {
		DeltaP = 0.1;
		}
	if ((MenVal & 0xf0) == 0x20) {
		DeltaP = 0.0;
		PowerF = 0.;
		}
	if ((MenVal & 0xf0) == 0x40) {
		DeltaP = DeltaP/10.;
		if (DeltaP < 1.e-14) DeltaP = 1.e-14;
		}
	if ((MenVal & 0xf0) == 0x60) {
		DeltaP = 10.0*DeltaP;
		if (DeltaP > 0.1) DeltaP = 0.1;
		}
	if ((MenVal & 0xf0) == 0x80) {
		PowerF = PowerF + DeltaP;
		if (PowerF >= 1.0)	{
			PowerF = PowerF - 1.0;
			Power++;
			if (Power > 99) Power = 9;
			xtemp = RightEdge;
			}
		}
	if ((MenVal & 0xf0) == 0xa0) {
		PowerF = PowerF - DeltaP;
		if (PowerF < 0.)	{
			--Power;
			PowerF = PowerF + 1.0;
			if (Power < 1) {
				Power = 1;
				}
			}
		}
	SetRast(WBRast,0);
	ActivateWindow(InfoWindow);
	WriteStuff();
	ActivateWindow(IntWindow);
	MenVal = 0;
}

int LineCheck(void)
{
		CheckMsg();
		if (IMClass == CLOSEWINDOW)	{
			ScreenToFront(IntWindow->WScreen);
			WindowToFront(IntWindow);
			ActivateWindow(IntWindow);
			}
		if ((!MenVal) && (!IMClass)) CheckIntMsg();
		if (MenVal)	{
			if ((MenVal & 0xf) == 1)	CountChange();
			if (MenVal == 0xf8c0)	return(TRUE);
			if ((MenVal & 0xf) == 2) {
				Zoom();
				if (MenVal == 0xf820) return(TRUE);
				}
			if ((MenVal & 0xf) == 0)	{
				SManMen();
				if((MenVal & 0xff) == 0x20)	return(TRUE);
				}
			if ((MenVal & 0xf) == 3) PowerChange();
			}
}


void WritePixels(ULONG *MyPixelBuf,ULONG Width,ULONG Height)
{
APTR fpp;
ULONG NumPixels,BaseAdr,xOff,yOff,xyOff,xLoc,yLoc;
ULONG *DstBuf,*LastBase;
	NumPixels = Width*Height;
/*	fpp =
LockBitMapTags(&WBScreen->BitMap,LBMI_BASEADDRESS,&BaseAdr,TAG_DONE);*/
	BaseAdr = 0xe0000000;
	xOff = IntWindow->LeftEdge + IntWindow->BorderLeft;
	yOff = IntWindow->TopEdge + IntWindow->BorderTop;
	yOff = yOff*WBScreen->Width;
	xyOff = xOff + yOff;
	DstBuf = (ULONG *)BaseAdr + xyOff;
	LastBase = DstBuf;
	yLoc = 0;
	while (yLoc < Height)	{
		xLoc = 0;
        while (xLoc < Width)	{
			*DstBuf++ = *MyPixelBuf++;
			xLoc++;
			}
		yLoc++;
		DstBuf = LastBase + WBScreen->Width;
		LastBase = DstBuf;
		}
/*     if (fpp) UnLockBitMap(fpp);*/
}

void GreyPixels(ULONG *MyPixelBuf,ULONG Width,ULONG Height)
{
ULONG NumPixels,PixCnt;
	NumPixels = Width*Height;
	PixCnt = 0;
	while (PixCnt < NumPixels)	{
		*MyPixelBuf++ = 0xaaaaaa;
		PixCnt++;
		}
}


BOOL InputCheck(void)
{
UWORD RBVal;
UBYTE Val1,Val2;
    *DDRAV = 3;
	Val1 = *SDRV;
	if (Val1) *SDRV = 0;
	if (Val1 == 0x31) return(TRUE);
	Val2 = *PDRAAV;
	if (!(Val2 & 0x40)) return(TRUE);
    RBVal = ((*POTGOR)& 0x400);
	if (RBVal != 0x400) return(TRUE);
	return(FALSE);
}


void FullSurface()
{
double yRel;
UWORD BorLft,BorTop;
BOOL IPCheck;
int RepCntr;

   	BorLft = IntWindow->BorderLeft;
	BorTop = IntWindow->BorderTop;
	ytemp = NearEdge;
	Limit = Two*Factor;
	Limit = Limit*Limit;
	PixelBuf = WindowBuf;
	LPixelBuf = (ULONG *)PixelBuf;
	PowerN = (double)Power + PowerF;
	GetSysTime(&CurTime);
	Secs = CurTime.tv_secs;
	Micros = CurTime.tv_micro;
	while (ytemp < FarEdge)	{
		yRel = (double)ytemp - YCenter;
		yRel = yRel*DX;
		if ((PowerF != 0.)||(Power > 7))	{
			FncFnd(yRel);
			}

/*		else	{
			switch(Power)	{*/
		else switch(Power)	{

			case 2:
				UseLibP2(yRel);
				break;

			case 3:
				UseLibP3(yRel);
				break;

			case 4:
				UseLibP4(yRel);
				break;

			case 5:
				UseLibP5(yRel);
				break;

			case 6:
				UseLibP6(yRel);
				break;

			case 7:
				UseLibP7(yRel);
				break;
				}
/*			}*/

		IPCheck = FALSE;
		IPCheck = InputCheck();
		if (IPCheck)	{
			FullCheck();
			CheckMsg();
			if (IMClass == CLOSEWINDOW)	{
				ScreenToFront(IntWindow->WScreen);
				WindowToFront(IntWindow);
				ActivateWindow(IntWindow);
				}
			if ((!MenVal) && (!IMClass)) CheckIntMsg();
			if (MenVal)	{
				if ((MenVal & 0xf) == 1)	CountChange();
				if (MenVal == 0xf8c0)	return;
				if ((MenVal & 0xf) == 2) {
					Zoom();
					if (MenVal == 0xf820) return;
					}
				if ((MenVal & 0xf) == 0)	{
					SManMen();
					if((MenVal & 0xff) == 0x20)	return;
					}
				if ((MenVal & 0xf) == 3) PowerChange();
			}
		}
	if (NumColors <= 256)	{
			WritePixelLine8(IntWindow->RPort,BorLft,BorTop+ytemp,WWidth,WindowBuf,&MainWRast);
            PixelBuf = WindowBuf;
            }
		ytemp++;
		if ((ytemp & 0x3f)== 0) {
			 if (MaxCnt > 256) DisCnt();
			}

	}

	GetSysTime(&CurTime);
	if (CurTime.tv_micro < Micros)	{
		CurTime.tv_micro = CurTime.tv_micro + 1000000;
		CurTime.tv_secs = CurTime.tv_secs - 1;
		}
	ElTime = CurTime.tv_secs - Secs + (CurTime.tv_micro - Micros)/1000000.;

	if (NumColors > 256)	{
		WritePixelArray((APTR*)WindowBuf,0,0,4*WWidth,IntWindow->RPort,BorLft,BorTop,WWidth,WHeight,RECTFMT_ARGB);
		LPixelBuf = (ULONG *)WindowBuf;
	}
	SetAPen(WBRast,1);
	sprintf(&MyStringBuf[0],"Time to generate last complete image was %e seconds.",ElTime);
	Move(WBRast,20,InfoWindow->Height - 20);
	Text(WBRast,(STRPTR)&MyStringBuf[0],strlen(MyStringBuf));
	MenVal = 0;
	IMClass = 0;
}

void Status()
{
struct IntuiMessage *MyMsg;
	IMClass = 0;
	MenVal = 0;
	while (!MenVal)	{
		Delay(1);
		CheckMsg();
		if (IMClass == CLOSEWINDOW)	{
			ScreenToFront(IntWindow->WScreen);
			WindowToFront(IntWindow);
			ActivateWindow(IntWindow);
			}
		if (!MenVal) CheckIntMsg();
		if (IMClass == CLOSEWINDOW) MenVal = 0xf8c0;
		if ((MenVal & 0xff7f) == 0x68) MenVal = 0;
		if (MenVal & 0xf800)	{
			if (MenVal == 0xffff) MenVal = 0;
			if ((MenVal & 0xf) == 0)	{
				SManMen();
				if (MenVal == 0xf800) MenVal = 0;
				}
			if ((MenVal & 0xf) == 1)	CountChange();
			if ((MenVal & 0xf) == 2)	Zoom();
			if ((MenVal & 0xf) == 3) PowerChange();
			if (MenVal == 0xf840)	{
				SaveBMP();
				MenVal = 0;
				}
			if (MenVal == 0xf860)	{
				Save();
				MenVal = 0;
				}
			if (MenVal == 0xf880)	{
				SaveP();
				MenVal = 0;
				}
			if (MenVal == 0xf8A0)	{
				LoadP();
				MenVal = 0xf820;	/* Force a redraw */
				}
			}
		if (IMClass == IDCMP_NEWSIZE) {
			while (IMClass == IDCMP_NEWSIZE)	{
				IMClass = 0;
				MyMsg = (struct IntuiMessage*) GetMsg(IntWindow -> UserPort);
				if (MyMsg)	{
					IMClass = MyMsg -> Class;
					ReplyMsg((struct Message *)MyMsg);
					}
				}
			GetWindowSize();
			MenVal = 0xf820;	/* Force a redraw */
			}
	}
}

void RestoreOrigColors()
{
UWORD *MyTable;
SHORT CCount;
	MyTable = OldColorTable;
	CCount = 0;
	while (CCount < NumColors) {
		MySetRGB(CCount,*MyTable++);
		CCount++;
		}
}

void MySetRGB(Color,Value)
SHORT Color;
USHORT Value;
{
UBYTE Red,Green,Blue;
USHORT SRed,SGreen,SBlue;
	SRed = Value;
	SRed >>=8;
	Red = (UBYTE)SRed;
	SGreen = 0xf0 & Value;
	SGreen >>=4;
	Green = (UBYTE)SGreen;
	SBlue = 0xf & Value;
	Blue = (UBYTE)SBlue;
	SETRGB(WBScreen,Color,Red,Green,Blue);
}


void CPUStuff(void)
{

int StrLength;
	sprintf(&CPUStrBuf[0],"PowerPC ");	/* Well duh!! it's running on MorphOS isn't it.*/
	StrLength = strlen(CPUStrBuf);
	sprintf(&CPUStrBuf[StrLength],"CPU at %#.2f MHz ",ClkFrq/1.e6);
	StrLength = strlen(CPUStrBuf);
	sprintf(&CPUStrBuf[StrLength],"with bus clock of %#.2f MHz. ",BusFrq/1.e6);
}


void ClockGet(void)
{
LONG OldPri;
double TotTic,Freq,Multip;
int IMult;

	OldPri = SetTaskPri(MyTask,20);
	TimeGet();
	GetSysTime(&CurTime);
	Secs = CurTime.tv_secs;
	Micros = CurTime.tv_micro;
	Time1Hi = TimeHi;
	Time1Lo = TimeLo;
	Delay(20);
    TimeGet();
	GetSysTime(&CurTime);
	if (CurTime.tv_micro < Micros)	{
		CurTime.tv_micro = CurTime.tv_micro + 1000000;
		CurTime.tv_secs = CurTime.tv_secs - 1;
		}
	Time2Hi = TimeHi;
	Time2Lo = TimeLo;
	ElTime = CurTime.tv_secs - Secs + (CurTime.tv_micro - Micros)/1000000.;
	TotTic = (double)(Time2Lo - Time1Lo);
	if (TotTic < 0.)	{
		TotTic = TotTic + (65536.*65536.);
		Time2Hi--;
		TotTic = TotTic + 655536.*65536.*(double)(Time2Hi - Time1Hi);
		}
	else	{
		TotTic = TotTic + 655536.*65536.*(double)(Time2Hi - Time1Hi);
		}

	ClkFrq = TotTic/ElTime;
	BusFrq = 4*ClkFrq;

	GetSysTime(&CurTime);
	Secs = CurTime.tv_secs;
	Micros = CurTime.tv_micro;
/* Note that within TimeGet2, it's assumed that each floating point
multiplication is 3 clock cycles.  This is the basis for the kludged
determination of the CPU frequency. */
	TimeGet2();
	GetSysTime(&CurTime);
	if (CurTime.tv_micro < Micros)	{
		CurTime.tv_micro = CurTime.tv_micro + 1000000;
		CurTime.tv_secs = CurTime.tv_secs - 1;
		}
	OldPri = SetTaskPri(MyTask,OldPri);

	ElTime = CurTime.tv_secs - Secs + (CurTime.tv_micro - Micros)/1000000.;
	TotTic = (double)(Time2Lo - Time1Lo);
	if (TotTic < 0.)	{
		TotTic = TotTic + (65536.*65536.);
		Time2Hi--;
		TotTic = TotTic + 655536.*65536.*(double)(Time2Hi - Time1Hi);
		}
	else	{
		TotTic = TotTic + 655536.*65536.*(double)(Time2Hi - Time1Hi);
		}
	Freq = 600*32768/ElTime;	/*About 600 cycles per pass */
	Freq = 2.1*Freq;
	Multip = Freq/BusFrq;
	IMult = (int)Multip;
	Freq = (double)IMult*BusFrq/2.;
	ClkFrq = Freq;

}



int main(void)
{
ULONG WindowBufSize;
ULONG BMAttr;
char	StrBuf[100];
int VPos,KeyCnt;

UBYTE KeyVal;
	SDRV =	(UBYTE *)0xbfec01;
	DDRAV =	(UBYTE *)0xbfe201;
	PDRAAV = (UBYTE *)0xbfe001;
	POTGOR = (UWORD *)0xdff016;
	PalOpt = 3;
	Pi = 2*atan(1.);
	Two = 2.;
	SaveIFF = FALSE;
	LastMax = 0;
	PowerF = 0.;
	DeltaP = 0.;
	WindowBuf = 0;
	SysFlag = SysBase -> AttnFlags;
	LibsOpen();
	MyTask = FindTask(0);
	OpenTimer();
	ClockGet();
	CPUStuff();
	Pi = 4.*atan(1.);
	TwoPi = 2.*Pi;
	PiD2 = Pi/2.;
	Power = 2;
	PowerN = 2.;
	CPU = 0;
	MaxCnt = 256;
	MaxCnt = 64;
	MltPlr = 0x80;
	WindowSet();
	if (SysFlag)	{
		SysFlag = SysBase -> AttnFlags;
		SWidth = 600;
		SHeight = 400;
		XC = SWidth/2;
		YC = SHeight/2;

		if (WBScreen->Width < 600) MltPlr = 0x40;
		Factor = (double)MltPlr;
		DX = 1./Factor;
		LastFactor = Factor;
		if (NumColors)	MaxCnt = NumColors;
		ScreenSet();
		WindowToFront(IntWindow);
		if (NumColors > 256) MaxCnt = 256;
		if (NumColors <= 256) {
			WindowBufSize = WBScreen->Width*WBScreen->Height;
			WindowBuf = AllocMem(WindowBufSize,MemMode);
			VPos = ShowPalette();
			VPos = VPos - 100;
			}
		else {
			WindowBufSize = 4*WBScreen->Width*WBScreen->Height;
			WindowBuf = AllocMem(WindowBufSize,MemMode);
			GreyPixels((ULONG *)WindowBuf,(ULONG)WWidth,(ULONG)WHeight);
			VPos = 16 + ShowPicPalette();
			WritePixelArray((APTR*)WindowBuf,0,0,4*WWidth,IntWindow->RPort,BLeft,BTop,WWidth,WHeight,RECTFMT_ARGB);
			VPos = WHeight - 60;
        	}
        MaxCnt = 32;
		SetFont(CWRast,CWFont);
		SetAPen(CWRast,1);
		Move(CWRast,10,VPos);
		VPos = VPos + 15;
		Move(CWRast,10,VPos);
		if (NumColors <= 256)	{
			if(IntWindow->Width > 320)	{
				sprintf(&StrBuf[0],"This display shows the %d colors of",PalSize);
				Text(CWRast,&StrBuf[0],strlen(StrBuf));
				VPos = VPos + 15;
				Move(CWRast,10,VPos);
				Text(CWRast,(STRPTR)"the palette being used for the",30);
				VPos = VPos + 15;
				Move(CWRast,10,VPos);
				Text(CWRast,"Mandelbrot Images! The palette for",34);
				VPos = VPos + 15;
				Move(CWRast,10,VPos);
				Text(CWRast,(STRPTR)"this screen may have changed, but will be",38);
				VPos = VPos + 15;
				Move(CWRast,10,VPos);
				Text(CWRast,"restored when SMan is done!",27);
				VPos = VPos + 15;
				Move(CWRast,20,VPos);
				}
				MWBitMap = (struct BitMap *)AllocBitMap((ULONG)WBScreen->Width,WBScreen->Height,WDepth,BMF_CLEAR|BMF_DISPLAYABLE,WBScreen->RastPort.BitMap);
				if (!MWBitMap) {
					printf("Couldn't allocate the 1st BitMap!\n");
					}
			InitRastPort(&MainWRast);
			MainWRast.Layer = NULL;
			MainWRast.BitMap = MWBitMap;
			Text(CWRast,(STRPTR)"Press Left Mouse Button to Continue!",36);
			OffMenu(IntWindow,0xf8c2); /* Turn off palette option*/
		}
		else	{
			PalSize = 256;

			if (BPP > 1) {
				OffMenu(IntWindow,0xf860);	/* Turn off Save Image (iff). */
				PalSize = 0x8000;
				if (SDepth >= 16) PalSize = 0x10000;
				}
			VPos = VPos - 32;
			Move(CWRast,20,VPos);
			SetAPen(CWRast,2);
			sprintf(&StrBuf[0],"This display above shows some of the");
			Text(CWRast,&StrBuf[0],strlen(StrBuf));

			VPos = VPos + 15;
			Move(CWRast,20,VPos);
			sprintf(&StrBuf[0],"nearly %d colors of the palette",PalSize);
			Text(CWRast,&StrBuf[0],strlen(StrBuf));

			VPos = VPos + 15;
			Move(CWRast,20,VPos);

			Text(CWRast,(STRPTR)"used for the Mandelbrot Images!",31);

			VPos = VPos + 15;
			VPos = VPos + 15;
			Move(CWRast,20,VPos);
			SetAPen(CWRast,2);
			Text(CWRast,(STRPTR)"Press Left Mouse Button to Continue!",36);
		}


		MenVal = 0;
		while ((MenVal != SELECTDOWN)&&(MenVal != 0xf8c0)) {
			 CheckIntMsg();
			if (IMClass == CLOSEWINDOW) MenVal = 0xf8C0;
			 Delay(1);
			}
		XWidth = WWidth;
		XHeight = WHeight;
		HWidth = XC;
		XCenter = XC;
		HHeight = YC;
		YCenter = YC;
		LastX = XCenter;
		LastY = YCenter;
		WriteStuff();
		ActivateWindow(InfoWindow);
		MenVal = 0xf801;
		while (MenVal != 0xf8c0)	{
			FullSurface();
			while ((!MenVal) && (!IMClass))	{
				Status();
				}
			}
		}
	if (((SysFlag & AFF_68881)||(SysFlag & AFF_68882))&&((SysFlag & AFF_68020)||(SysFlag & AFF_68030))||(SysFlag & AFF_68040))	{
		BPP = BPP;
		}
	else {
		ErrorDisplay();
		}
	if (WBScreen->RastPort.BitMap->Depth >= 5) {
		WBScreen->ViewPort.ColorMap->ColorTable = OldColorTable;
		if (NumColors <= 256) RestoreOrigColors();
	}
	if (!WindowBuf) {
		if (MWBitMap) FreeBitMap(TmpBitMap);
		}
	Delay(25);

	if (NewColorTable)	{
		FreeMem(NewColorTable,TableSize);
		NewColorTable = 0;
		}
	if (WindowBuf) {
		FreeMem(WindowBuf,WindowBufSize);
		WindowBuf = 0;
		}
	ScreensClose();
	CloseTimer();
	LibsClose();
	return(0);
}
