/***************************************************/
/*	 			Visual  Sound  version 1.0 				*/
/*			  Copyright©1995 Colin Hannah 				*/
/* This program may be freely distributed so long  */
/* as it is altered in no way and spread in its		*/
/* entirity. 													*/
/* This source file MAY altered in any way by the  */
/* user for research purposes ONLY. NO claim may	*/
/* be made to the original source except by myself	*/
/* You may NOT distribute altered versions of this */
/* source or make claim to it in any other way. 	*/
/*		-See documentation for program details-		*/
/***************************************************/

#include <stdio.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <math.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/copper.h>
#include <hardware/custom.h>

#define VERTADJ 30
#define YHUGE    1 /* Vertical heights          */
#define YBIG    0.5 
#define YNORM   0.25 
#define YSMALL  0.12
#define YTINY   0.05
#define YWIDTH 120 /* Menu width 					*/
#define AHIGH    1 /* Levels of sample accuracy */
#define AMID     2
#define ALOW     4
#define SWIDTH 130 /* Menu width 					*/
#define CPULOW   1
#define CPUHIGH  0
#define CWIDTH 100 /* Menu Width						*/
	/***** Menus *****/
#define MQUIT  0xf800	
#define MABOUT 0x0010	
#define MSLOW  0x1001
#define MSMID  0x0801
#define MSHI   0x0001
#define MHUGE  0x0021
#define MBIG   0x0821
#define MNORM  0x1021
#define MSMALL 0x1821
#define MTINY  0x2021
#define MCPU   0xf841
#define MWIN	0xf861

/* Copper List Data */
#define NUMCOLORS      256
#define NUMLINES_EACH  1 
UWORD colors[] =
{
	0x0FFF,0x0FFF,0x0FFF,0x0FFF,0x0FFF,0x0FFF,0x0EEF,0x0EEF,
	0x0EEE,0x0EEE,0x0DDE,0x0DDE,0x0DDE,0x0DDE,0x0DDE,0x0DDE,
	0x0CCE,0x0CCE,0x0CCE,0x0CCD,0x0CCD,0x0BBD,0x0BBD,0x0BBD,
	0x0BBD,0x0BBD,0x0AAD,0x0AAD,0x0AAD,0x0AAC,0x0AAC,0x0AAC,
	0x0AAC,0x099C,0x099C,0x099C,0x099C,0x099C,0x099C,0x088C,
	0x088B,0x088B,0x088B,0x088B,0x088B,0x078B,0x077B,0x077B,
	0x077B,0x077B,0x077B,0x077A,0x067A,0x066A,0x066A,0x066A,
	0x066A,0x066A,0x066A,0x066A,0x056A,0x0559,0x0559,0x0559,
	0x0559,0x0559,0x0559,0x0559,0x0449,0x0449,0x0449,0x0449,
	0x0449,0x0449,0x0339,0x0339,0x0339,0x0339,0x0338,0x0338,
	0x0338,0x0228,0x0228,0x0228,0x0228,0x0228,0x0228,0x0118,
	0x0118,0x0118,0x0118,0x0118,0x0118,0x0118,0x0118,0x0008,
	0x0008,0x0008,0x0008,0x0007,0x0007,0x0007,0x0007,0x0006,
	0x0006,0x0006,0x0006,0x0005,0x0005,0x0005,0x0005,0x0004,
	0x0004,0x0004,0x0004,0x0004,0x0003,0x0003,0x0003,0x0003,
	0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
	0x0000,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
	0x0002,0x0003,0x0003,0x0003,0x0003,0x0004,0x0004,0x0004,
	0x0004,0x0005,0x0005,0x0005,0x0005,0x0006,0x0006,0x0006,
	0x0006,0x0007,0x0007,0x0007,0x0007,0x0008,0x0008,0x0008,
	0x0008,0x0118,0x0118,0x0118,0x0118,0x0118,0x0118,0x0118,
	0x0118,0x0228,0x0228,0x0228,0x0228,0x0228,0x0228,0x0228,
	0x0338,0x0338,0x0338,0x0339,0x0339,0x0339,0x0449,0x0449,
	0x0449,0x0449,0x0449,0x0449,0x0459,0x0559,0x0559,0x0559,
	0x0559,0x0559,0x0559,0x055A,0x066A,0x066A,0x066A,0x066A,
	0x066A,0x066A,0x066A,0x066A,0x077A,0x077A,0x077B,0x077B,
	0x077B,0x077B,0x077B,0x088B,0x088B,0x088B,0x088B,0x088B,
	0x088C,0x088C,0x099C,0x099C,0x099C,0x099C,0x099C,0x099C,
	0x0AAC,0x0AAC,0x0AAC,0x0AAD,0x0AAD,0x0AAD,0x0BBD,0x0BBD,
	0x0BBD,0x0BBD,0x0BBD,0x0BBD,0x0CCD,0x0CCD,0x0CCE,0x0CCE,
	0x0CCE,0x0DDE,0x0DDE,0x0DDE,0x0DDE,0x0DDE,0x0EEE,0x0EEE,
	0x0EEF,0x0EEF,0x0EEF,0x0FFF,0x0FFF,0x0FFF,0x0FFF,0x0FFF
};
extern struct Custom far custom;

/*	Global Pointers/Structures 								*/
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct UCopList *uCopList = NULL;
struct Screen *my_screen;
struct NewScreen new_screen = {/* For Custom Screen   */
	0,0,320,256,1,	/* Position , Width, Height, depth	*/
	1,0,				/* Fore & Back Pens						*/
	NULL,				/* View modes								*/
	CUSTOMSCREEN,	/* Screen Type								*/
	NULL,				/*	Font										*/
	NULL,				/* Title										*/
	NULL,				/* Gadgets									*/
	NULL				/* Bitmap									*/
};
struct Window *my_window;
struct NewWindow new_window = {/* Window on Workbench */
	40,30,			/* start point 							*/
	210,60,			/* initial size							*/
	1,2,				/* Pen colour registers					*/
	CLOSEWINDOW|	/* IDCMP Flags, resize and close		*/
	NEWSIZE|MENUPICK,	/* Flags, sys gadgets				*/
	WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG|WINDOWSIZING
	|GIMMEZEROZERO| SUPER_BITMAP,
	NULL,				/* custom gadgets 						*/
	NULL,				/* image										*/
	"-Visual Sound-",	/* Title									*/
	NULL,				/* screen to point to					*/
	NULL,				/* bitmap									*/
	77,22,			/* min size									*/
	600,260,			/* max size									*/
	WBENCHSCREEN	/* attatch to Workbench					*/
};
struct NewWindow cust_window = { /* Window in Custom screen */
	0,2,			/* start point 								*/
	320,254,		/* initial size								*/
	0,0,			/* Pen colour registers						*/
	BORDERLESS|BACKDROP| /* IDCMP Flags						*/
	MENUPICK,			/* Flags, sys gadgets				*/
	 SUPER_BITMAP,
	NULL,				/* custom gadgets 						*/
	NULL,				/* image										*/
	NULL,				/* Title										*/
	NULL,				/* will set tpoint to screen later	*/
	NULL,				/* bitmap									*/
	320,254,			/* min size									*/
	320,254,			/* max size									*/
	CUSTOMSCREEN	/* attatch to custom	screen			*/
};
/************************   Menus   *************************/
/***** Options ->Size->Tiny ****/
struct IntuiText Tiny_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM1, 			/* Do Not erase background 					*/
	COMMWIDTH,0,	/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Tiny",			/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem STiny= {
	NULL,				/* next Item										*/
	130,40,SWIDTH,10,	/* Pos, width,height							*/
	ITEMTEXT|HIGHCOMP|CHECKIT|
	ITEMENABLED|COMMSEQ,	/* Flags: 									*/
	0x0000000f,		/* Mutual Exclude all but this				*/
	&Tiny_Text,		/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	't',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->Size->Small ****/
struct IntuiText Small_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM1, 			/* Do Not erase background 					*/
	COMMWIDTH,0,	/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Small",			/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem SSmall= {
	&STiny,				/* next Item									*/
	130,30,SWIDTH,10,	/* Pos, width,height							*/
	ITEMTEXT|HIGHCOMP|CHECKIT|
	ITEMENABLED|COMMSEQ,	/* Flags: 									*/
	0x00000017,		/* Mutual Exclude none							*/
	&Small_Text,	/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	's',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->Size->Normal ****/
struct IntuiText Norm_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM1, 			/* Do Not erase background 					*/
	COMMWIDTH,0,	/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Normal",		/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem SNorm= {
	&SSmall,				/* next Item									*/
	130,20,SWIDTH,10,	/* Pos, width,height							*/
	ITEMTEXT|HIGHCOMP|CHECKIT|CHECKED| /*  selected startup 	*/
	ITEMENABLED|COMMSEQ,	/* Flags: 									*/
	0x0000001b,		/* Mutual Exclude none							*/
	&Norm_Text,		/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	'n',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->Size->Big ****/
struct IntuiText Big_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM1, 			/* Do Not erase background 					*/
	COMMWIDTH,0,	/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Big",			/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem SBig= {
	&SNorm,				/* next Item									*/
	130,10,SWIDTH,10,		/* Pos, width,height						*/
	ITEMTEXT|HIGHCOMP|CHECKIT|
	ITEMENABLED|COMMSEQ,	/* Flags: 									*/
	0x0000001d,		/* Mutual Exclude none							*/
	&Big_Text,		/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	'b',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->Size->Huge ****/
struct IntuiText Huge_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM1, 			/* Do Not erase background 					*/
	COMMWIDTH,0,	/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Huge",			/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem SHuge= {
	&SBig,				/* next Item									*/
	130,0,SWIDTH,10,	/* Pos, width,height							*/
	ITEMTEXT|HIGHCOMP|CHECKIT|
	ITEMENABLED|COMMSEQ,	/* Flags: 									*/
	0x0000001e,		/* Mutual Exclude none							*/
	&Huge_Text,		/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	'g',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->Sensitivity->Low ****/
struct IntuiText Slow_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM1, 			/* Do Not erase background 					*/
	COMMWIDTH,0,	/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Low",			/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem Slow= {
	NULL,				/* next Item										*/
	130,20,SWIDTH,10,	/* Pos, width,height							*/
	ITEMTEXT|HIGHCOMP|CHECKIT|
	ITEMENABLED|COMMSEQ,	/* Flags: 									*/
	0x00000003,		/* Mutual Exclude none							*/
	&Slow_Text,		/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	'l',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->Sensitivity->Mid ****/
struct IntuiText Mid_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM2, 			/* Do Not erase background 					*/
	COMMWIDTH,0,	/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Mid",			/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem Smid= {
	&Slow,				/* next Item									*/
	130,10,SWIDTH,10,	/* Pos, width,height							*/
	ITEMTEXT|HIGHCOMP|CHECKIT|CHECKED|
	ITEMENABLED|COMMSEQ,	/* Flags: 									*/
	0x00000005,		/* Mutual Exclude none							*/
	&Mid_Text,		/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	'm',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->Sensitivity->Hi ****/
struct IntuiText Shigh_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM2, 			/* Do Not erase background 					*/
	COMMWIDTH,0,	/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"High",			/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem Shigh= {
	&Smid,				/* next Item									*/
	130,0,SWIDTH,10,	/* Pos, width,height							*/
	ITEMTEXT|HIGHCOMP|CHECKIT|
	ITEMENABLED|COMMSEQ,	/* Flags: 									*/
	0x00000006,		/* Mutual Exclude none							*/
	&Shigh_Text,	/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	'h',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->Window ****/
struct IntuiText Win_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM1, 			/* Do Not erase background 					*/
	COMMWIDTH,0,	/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Window",		/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem Wind= {
	NULL,				/* next Item										*/
	0,30,140,10,	/* Pos, width,height								*/
	ITEMTEXT|HIGHCOMP|CHECKIT|CHECKED|COMMSEQ|
	ITEMENABLED,	/* Flags: 											*/
	0x00000000,		/* Mutual Exclude none							*/
	&Win_Text,		/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	'w',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->CPU ****/
struct IntuiText Cpu_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM1, 			/* Do Not erase background 					*/
	COMMWIDTH,0,	/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Low CPU",		/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem Cpu= {
	&Wind,				/* next Item									*/
	0,20,140,10,		/* Pos, width,height							*/
	ITEMTEXT|HIGHCOMP|CHECKIT|COMMSEQ|
	ITEMENABLED,	/* Flags: 											*/
	0x00000000,		/* Mutual Exclude none							*/
	&Cpu_Text,		/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	'c',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->Size ****/
struct IntuiText Size_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM2, 			/* Do Not erase background 					*/
	0,0,				/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Size",			/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem Size= {
	&Cpu,				/* next Item										*/
	0,10,140,10,	/* Pos, width,height								*/
	ITEMTEXT|HIGHCOMP|
	ITEMENABLED,	/* Flags: 											*/
	0x00000000,		/* Mutual Exclude none							*/
	&Size_Text,		/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	0,					/* Command short cut								*/
	&SHuge,			/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/***** Options ->Sensitivity ****/
struct IntuiText Sensitivity_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM2, 			/* Do Not erase background 					*/
	0,0,				/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Sensitivity",	/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem Sensitivity= {
	&Size,			/* next Item										*/
	0,0,140,10,		/* Pos, width,height								*/
	ITEMTEXT|HIGHCOMP|
	ITEMENABLED,	/* Flags: 											*/
	0x00000000,		/* Mutual Exclude none							*/
	&Sensitivity_Text,/* pointer to IntuiText struct			*/
	NULL,				/* SelectFill - no fill text					*/
	0,					/* Command short cut								*/
	&Shigh,			/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/*****    Project ->About->3     ****/
struct IntuiText About3_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM2, 			/* Do Not erase background 					*/
	0,0,				/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"          FREEWARE!",/* Name										*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem About3= {
	NULL,				/* next Item										*/
	80,24,200,10,	/* Pos, width,height								*/
	ITEMTEXT|HIGHNONE|
	ITEMENABLED,	/* Flags: 											*/
	0x00000000,		/* Mutual Exclude none							*/
	&About3_Text,	/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	0,					/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/*****    Project ->About->2     ****/
struct IntuiText About2_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM2, 			/* Do Not erase background 					*/
	0,0,				/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"CopyWrite 1995 Colin Hannah",/* Name							*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem About2= {
	&About3,				/* next Item									*/
	80,12,200,10,		/* Pos, width,height							*/
	ITEMTEXT|HIGHNONE|
	ITEMENABLED,	/* Flags: 											*/
	0x00000000,		/* Mutual Exclude none							*/
	&About2_Text,	/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	0,					/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/*****    Project ->About->1     ****/
struct IntuiText About1_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM2, 			/* Do Not erase background 					*/
	0,0,				/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"    - Visual Sound V1.0 - ",/* Name									*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem About1= {
	&About2,			/* next Item										*/
	80,0,200,10,	/* Pos, width,height								*/
	ITEMTEXT|HIGHNONE|
	ITEMENABLED,	/* Flags: 											*/
	0x00000000,		/* Mutual Exclude none							*/
	&About1_Text,	/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	0,					/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/*****    Project ->About     ****/
struct IntuiText About_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM2, 			/* Do Not erase background 					*/
	0,0,				/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"About",			/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem About= {
	NULL,				/* next Item										*/
	0,12,75,10,		/* Pos, width,height								*/
	ITEMTEXT|HIGHCOMP|
	ITEMENABLED,	/* Flags: 											*/
	0x00000000,		/* Mutual Exclude none							*/
	&About_Text,	/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	0,					/* Command short cut								*/
	&About1,			/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/*****    Project ->Quit     ****/
struct IntuiText Quit_Text = {
	1,2,				/* Fore & back pens 								*/
	JAM2, 			/* Do Not erase background 					*/
	0,0,				/* Position offset 								*/
	NULL,				/* No text attributes							*/
	"Quit",			/* Name												*/
	NULL,				/* next IntuiText struct						*/
};
struct MenuItem Quit= {
	&About,			/* next Item										*/
	0,0,75,10,		/* Pos, width,height								*/
	ITEMTEXT|HIGHCOMP|
	ITEMENABLED|COMMSEQ,	/* Flags: 									*/
	0x00000000,		/* Mutual Exclude none							*/
	&Quit_Text,		/* pointer to IntuiText struct				*/
	NULL,				/* SelectFill - no fill text					*/
	'q',				/* Command short cut								*/
	NULL,				/* pointer to sub items							*/
	MENUNULL,		/* pointer to next selection					*/
};
/**** Options Menu ****/
struct Menu Options_Menu = {
	NULL,
	80,0,140,0,
	MENUENABLED,
	"Options",
	&Sensitivity,
	0,0,0,0
};
/**** Project Menu ****/
struct Menu Project_Menu = {
	&Options_Menu,	/* next Menu 										*/
	0,0,75,0,		/* Position, width, height						*/
	MENUENABLED,	/* switch menu on									*/
	"Project",		/* Name												*/
	&Quit,			/* Pointer to first item						*/
	0,0,0,0
};

/************************ Functions *************************/
/* Generates Copper List for the custom screen 					*/
BOOL loadCopper(VOID)
{
register USHORT i;
/* Allocate memory for the Copper list 							*/
/* Make certain that the initial memory is cleared.  			*/
	uCopList = (struct UCopList *)
	AllocMem(sizeof(struct UCopList), MEMF_PUBLIC|MEMF_CLEAR);
	if (uCopList == NULL)
	    return(FALSE);

	CINIT(uCopList, NUMCOLORS);   /* Initialize the Copper list buffer. */
	for (i=0; i<NUMCOLORS; i++)    /* Load in each color. */
    { 
	    CWAIT(uCopList, (i*NUMLINES_EACH), 0);
	    CMOVE(uCopList, custom.color[1], colors[i]);
    }
	CEND(uCopList);    /* End the Copper list */

	/*  Forbid task switching while changing the Copper list. */
	Forbid();
	my_screen->ViewPort.UCopIns=uCopList;
	Permit();    /* Permit task switching again. */
	RethinkDisplay();    /* Display the new Copper list. */
	return(TRUE);
}
/* Erases old bar with color0 then draws new with color1		*/
void draw(int Xpos, SHORT Ycent, SHORT height, SHORT width)
{
	SetAPen(my_window->RPort,0);
	RectFill(my_window->RPort,Xpos,0,Xpos+width,400);
	SetAPen(my_window->RPort,1);
	RectFill(my_window->RPort,Xpos,Ycent-height,Xpos+width,Ycent+height);
}
/* Opens or Close Custom screen for display						*/
BOOL ScreenChange(BOOL *CustScreen) 
{
	/* Close old window */
	ClearMenuStrip(my_window);
	CloseWindow(my_window);
	if(*CustScreen==FALSE) {
		/* Open Custom screen and set colours*/
		if(!(my_screen= (struct Screen*) OpenScreen(&new_screen))) 
			return(TRUE);
		SetRGB4(&my_screen->ViewPort,0,0,0,0);
		SetRGB4(&my_screen->ViewPort,1,0xf,0xf,0xf);
		cust_window.Screen = my_screen;  /* now attatch to screen */
		if(!(my_window= (struct Window*) OpenWindow(&cust_window))) 
			return(TRUE);
		*CustScreen=TRUE;
		loadCopper();		/* Draw Copper List */
	} else {
		/* Close Custom Screen */
	   FreeVPortCopLists(my_screen->ViewPort);
		CloseScreen(my_screen);
		/* Reopen window on workbench screen */
		if(!(my_window= (struct Window*) OpenWindow(&new_window))) 
			return(TRUE);
		*CustScreen=FALSE;
	}
	/* Switch on Menus */
	SetMenuStrip(my_window,&Project_Menu);
	return(FALSE);
}
/***************************  MAIN  ************************/

main ()
{
	BOOL close,LowCpu,CustScreen;
	ULONG class;
	USHORT code;
	struct IntuiMessage *my_message;
	SHORT offset,Ycent,accuracy,Yadjust;
	SHORT *sound;
	int i,Xpos=2;
	float size;

	/* Initialise */
	close=FALSE;
	CustScreen=FALSE;
	size=YNORM;
	offset=8;
	accuracy=AMID;
	Ycent = 23;
	sound = (SHORT *) 0xbfe100; /* sound = base address of audio input */
	LowCpu=CPUHIGH;
	Yadjust= 2;

	/* Open Intuition and Gfx Libraries */
	if(!(IntuitionBase= (struct IntuitionBase*) OpenLibrary("intuition.library",0)))
		exit();	/* intuition couldn't be opened - this will NEVER happen!!! */

	if(!(GfxBase = (struct GfxBase*) OpenLibrary("graphics.library",0))) {
		CloseLibrary(IntuitionBase);
		exit();
	}
	/* Open Window on Workbench screen */
	if(!(my_window= (struct Window*) OpenWindow(&new_window))) {
		CloseLibrary( IntuitionBase );
		CloseLibrary( GfxBase );
		exit(); 		/* Can't open window mem problems? close intuition, exit */
	}

	SetMenuStrip(my_window,&Project_Menu);	/* Menus On */

	/************* LOOOOOOOOOP! *************/
	while(!close) {	
	Xpos = 0;  /* must reinitialise each time */

	if(LowCpu)  /* delay if user wants low cpu usage */
		Delay(1);

		/* read in audio and update screen*/
		for(i=0;i<0x30;i+=accuracy) 
		{
			SHORT data; 
			data = abs(*(sound + i)+100); /* get new reading */
			if(data==1) /* Remove any rouge data */
				data=0;
			if(data>100) /* Remove any rouge data */
				data=0;		
			/* Rescale reading for window size and users size request */
			data=data*Yadjust*size;
			draw(Xpos,Ycent,data,offset); /* Draw this Bar */		
			Xpos+=offset; /* increment to find initial Xcord of next bar */
		}
		
		/* Check For User Interuptions/ Messages. ie Sys Gadgets and Menus */
		while(my_message= (struct IntuiMessage*) GetMsg(my_window->UserPort)) {
				/* Gather New Message data then reply QUICKLY */
				class = my_message->Class; 	
				code  = my_message->Code;
				ReplyMsg( my_message ); /* free message and OS */
			
				/* Check for and process any Sys gadget messages */
				switch(class) {
					case CLOSEWINDOW: close=TRUE; break;
					case NEWSIZE: {
						/* Calculate new data after Window size change */
						Ycent=my_window->Height/2-7; 
						offset=(my_window->Width)/(44/accuracy);
						/* Large division value generates lots of rescales */
						Yadjust= (SHORT) ((my_window->Height)/VERTADJ);
								if(Yadjust<1) /* Prevent any division by zero */
									Yadjust=1;
						} break;
					default: /* Some other message */ break;
				}

			/***** Check for menu selections ****/
				if(class==MENUPICK) {
					int num;
					struct MenuItem *item_p;			
					num=code;
					while(num!=MENUNULL) {
						item_p = (struct MenuItem*)ItemAddress(&Project_Menu,num);
						/* Right. What was the menu selection: */
						switch(num) {
							case MQUIT: close=TRUE; 	break;
							case MSLOW: accuracy=ALOW; break;
							case MSMID: accuracy=AMID; break;
							case MSHI:  accuracy=AHIGH;break;
							case MHUGE: size=YHUGE; 	break;
							case MBIG:  size=YBIG; 		break;
							case MNORM: size=YNORM; 	break;
							case MSMALL:size=YSMALL;	break;
							case MTINY: size=YTINY;		break;
							case MCPU:  { /* Toggle */
								if(LowCpu==CPUHIGH) {
									LowCpu=CPULOW;
								} else {
									LowCpu=CPUHIGH;
								}
							}									break;
							case MWIN:	{
							/* Custom Screen Toggle (lots of recalculation) */
								close=ScreenChange(&CustScreen); 
								Ycent=my_window->Height/2-1; 
								accuracy=AHIGH;
								/* If closeing Custom Screen: */
								if(CustScreen==FALSE) {
									Ycent=my_window->Height/2-7; 
									accuracy=AMID;
								}
							}	break;
							default: /* some other menu */ 		break;
						}
						/* more calculations as a result of users choices */
						offset=(my_window->Width)/(44/accuracy);
						Yadjust= (SHORT) ((my_window->Height)/VERTADJ);
						if(Yadjust<1)
							Yadjust=1;
					num=item_p->NextSelect; /* check for other menu selections */
					}
				}
			/* continue reading messages until NULL returned */				
			}
		}
	/* Clean up and end program */
	ClearMenuStrip(my_window);
	CloseWindow( my_window );
	if(CustScreen==TRUE) {
		FreeVPortCopLists(my_screen->ViewPort);
		CloseScreen( my_screen );
	}
	CloseLibrary( IntuitionBase );
	CloseLibrary( GfxBase );
}