
#include <exec/types.h>
#include <math.h>

#ifdef __SASC
	#define M_PI PI
#endif

float rnd(float max);

float wa0[2], wa1[2], wa2[2], wa3[2], wa4[2], wa5[2], wa6[2], wa7[2], wa8[2];
float wb0[2], wb1[2], wb2[2], wb3[2], wb4[2], wb5[2], wb6[2], wb7[2], wb8[2];

extern ULONG TimeWave;
extern WORD	 *PluginSamples;


void InitWave(UBYTE WaveNum, ULONG BufNum) {
	float a0,a1,a2,a3,a4;
	a0=a1=a2=a3=a4=0.0;
	switch(WaveNum) {
		/****************************************/
		case 0:
		break;
		/****************************************/
		case 1:
		break;
		/****************************************/
		case 2:
			a0 = 0.1 + rnd(0.2);
		break;
		/****************************************/
		/** Radar Sweep                        **/
		case 3:
			a0 = 0.7 + rnd(1.1);
		break;
		/****************************************/
		/** Flower Power                       **/
		case 4:
			a0 = 2.0 + (float)((ULONG)(0.99 * rnd(4.0)));
			a1 = M_PI * (float)(2 - (ULONG)a0 % 2);
			a2 = 0.2  + rnd(0.2);
			a3 = 0.65 + rnd(0.22);
		break;
		/****************************************/
		/** Spinit                             **/
		case 5:
			a0 = 0.25 + rnd(0.4);
		break;
		/****************************************/
		/** Sine Waves                         **/
		case 6:
		break;
		/****************************************/
		/** Five                               **/
		case 7:
			a0 = cos(.3 + rnd(.6)) * 0.5;
			a1 = sin(.5 + rnd(.4)) * 0.5;
			a2 = cos(.1 + rnd(.8)) * 0.5;
			a3 = sin(.2 + rnd(.7)) * 0.5;
			a4 = cos(.6 + rnd(.3)) * 0.5;
		break;
		/****************************************/
		/** Rotating Arcs                      **/
		case 8:
			a0 = 0.5 + rnd(0.2);
			a1 = rnd(1.3) + 1.4;
		break;
		/****************************************/
		/** Horizontal Sweep                   **/
		case 9:
		break;
		/****************************************/
		/** NTPU Squared                       **/
		case 10:
			a0 = 0.3 + rnd(0.4);
			a1 = 0.4 * a0;
		break;
		/****************************************/
		/** Particle Pulse                     **/
		case 11:
			a0 = rnd(3)+1;
		break;
		/****************************************/
	}
	wa0[BufNum] = a0;
	wa1[BufNum] = a1;
	wa2[BufNum] = a2;
	wa3[BufNum] = a3;
	wa4[BufNum] = a4;
}

void CalcWave(UBYTE WaveNum, ULONG BufNum) {
	float tf;
	float a0,a1,a2,a3,a4;
	float b0,b1,b2,b3,b4,b5,b6,b7,b8;

	a0 = wa0[BufNum];
	a1 = wa1[BufNum];
	a2 = wa2[BufNum];
	a3 = wa3[BufNum];
	a4 = wa4[BufNum];
	b0 = 0;
	b1 = 0;
	b2 = 0;
	b3 = 0;
	b4 = 0;
	b5 = 0;
	b6 = 0;
	b7 = 0;
	b8 = 0;
	tf=((float)TimeWave) / 10.0;
	switch(WaveNum) {
		/****************************************/
		case 0:
		break;
		/****************************************/
		case 1:
			b0 = tf * 0.0003;
		break;
		/****************************************/
		case 2:
			b0 = cos(tf * 0.2);
			b1 = sin(tf * 0.2);
		break;
		/****************************************/
		/** Radar Sweep                        **/
		case 3:
			b0 = cos(tf * a0);
			b1 = sin(tf * a0);
		break;
		/****************************************/
		/** Flower Power                       **/
		case 4:
			b0 = tf;
		break;
		/****************************************/
		/** Spinit                             **/
		case 5:
			b0 = cos(a0 * tf);
			b1 = sin(a0 * tf);
		break;
		/****************************************/
		/** Sine Waves                         **/
		case 6:
		break;
		/****************************************/
		/** Five                               **/
		case 7:
			b0 = -1.0 * tf;
			b1 = .3 * tf;
			b2 = -.8 * tf + 1.23213;
			b3 = .3 * tf;
			b4 = -1.3 * tf;
			b5 = -1.1 * tf + 4.45245;
			b6 = -.63 * tf + 2.13213;
			b7 = .7 * cos(b1);
			b8 = .7 * sin(b1);
		break;
		/****************************************/
		/** Rotating Arcs                      **/
		case 8:
			b0 = 0.3 * tf;
		break;
		/****************************************/
		/** Horizontal Sweep                   **/
		case 9:
			b0 = sin(0.5*tf);
		break;
		/****************************************/
		/** NTPU Squared                       **/
		case 10:
			b0 = cos(tf * 0.18);
			b1 = sin(tf * 0.18);
		break;
		/****************************************/
		/** Particle Pulse                     **/
		case 11:
			b0 = tf * 0.0003;
		break;
		/****************************************/
	}
	wb0[BufNum] = b0;
	wb1[BufNum] = b1;
	wb2[BufNum] = b2;
	wb3[BufNum] = b3;
	wb4[BufNum] = b4;
	wb5[BufNum] = b5;
	wb6[BufNum] = b6;
	wb7[BufNum] = b7;
	wb8[BufNum] = b8;
}

void DrawWave(LONG *WaveX, LONG *WaveY, ULONG Width, ULONG Height, UBYTE WaveNum, ULONG BufNum) {
	LONG i,xs,ys,xd,yd;
	LONG k;
	LONG minx,maxx,miny,maxy;

	float scales,scaled,greater;
	float xsf,ysf;
	float xdf0,ydf0,xdf1,ydf1,xdf2,ydf2;
	float wf,hf,tf;

	float a0, a1, a2, a3, a4;
	float b0, b1, b2, b3, b4, b5, b6, b7, b8;
	float c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10;

	a0 = wa0[BufNum];
	a1 = wa1[BufNum];
	a2 = wa2[BufNum];
	a3 = wa3[BufNum];
	a4 = wa4[BufNum];

	b0 = wb0[BufNum];
	b1 = wb1[BufNum];
	b2 = wb2[BufNum];
	b3 = wb3[BufNum];
	b4 = wb4[BufNum];
	b5 = wb5[BufNum];
	b6 = wb6[BufNum];
	b7 = wb7[BufNum];
	b8 = wb8[BufNum];

	wf=(float)Width;
	hf=(float)Height;
	tf=((float)TimeWave) / 10.0;

	minx = -(Width/2)  + 1;
	maxx =  (Width/2)  - 1;
	miny = -(Height/2) + 1;
	maxy =  (Height/2) - 1;

	greater=1.0;
	if(wf > greater) greater = wf;
	if(hf > greater) greater = hf;

	scales = 1.0 / greater;
	scaled = 1.0 / (greater/2.0);

	k=0;
	for(xs=0; xs<(Width); xs++) {
		ys = (PluginSamples[k++] >> 10) + (PluginSamples[k++] >> 10);

		xsf = ((float)xs) * scales;
		ysf = ((float)ys) / 256.0;

		switch(WaveNum) {
			/****************************************/
			case 0:
				xdf0 = 2*xsf-1;
				ydf0 = ysf * 0.75;
				xdf1 = xdf0;
				ydf1 = ydf0;
			break;
			/****************************************/
			case 1:
				c0 = ysf * 0.2 + .2;
				c1 = xsf * 6.28318530 + b0;
				xdf0 = c0 * cos(c1);
				ydf0 = c0 * sin(c1);
				xdf1 = xdf0;
				ydf1 = ydf0;
			break;
			/****************************************/
			case 2:
				c0 = ysf * 0.25 + .2;
				c1 = 2.1 * (xsf-0.5);
				xdf0 =  b0 * c1 + b1 * c0;
				ydf0 = -b0 * c0 + b1 * c1;
				xdf1 =  b0 * c1 - b1 * c0;
				ydf1 =  b0 * c0 + b1 * c1;
			break;
			/****************************************/
			/** Radar Sweep                        **/
			case 3:
				c0   = ysf * 0.4 * xsf;
				xdf0 = -b0 * xsf - b1 * c0;
				ydf0 =  b0 * c0  - b1 * xsf;
				xdf1 = xdf0;
				ydf1 = ydf0;
			break;
			/****************************************/
			/** Flower Power                       **/
			case 4:
				c0   = a1 * xsf;
				c1   = a3 * cos(a0*c0) + 0.18 * ysf;
				xdf0 = c1 * cos(c0+a2*b0);
				ydf0 = c1 * sin(c0+a2*b0);
				xdf1 = xdf0;
				ydf1 = ydf0;
			break;
			/****************************************/
			/** Spinit                             **/
			case 5:
				c0   = 2 * xsf - 1;
				c1   = ysf * 0.6 + c0;
				xdf0 = - b0 * c0 - b1 * c1;
				ydf0 =   b0 * c1 - b1 * c0;
				xdf1 = - b0 * c0 + b1 * c1;
				ydf1 =   b0 * c1 + b1 * c0;
			break;
			/****************************************/
			/** Sine Waves                         **/
			case 6:
				c0   = - sin(6.2831853 * xsf);
				c1   = 0.4 * ysf;
				xdf0 = 2.0 * xsf - 1 - c0 * c1;
				ydf0 = 0.7 * cos( 6.2831853 * xsf ) + sqrt( 1 - c0*c0 ) * c1;
				xdf1 = xdf0;
				ydf1 = -ydf0;
			break;
			/****************************************/
			/** Five                               **/
			case 7:
				c0   = b7 * ( xsf - .1 ) + a0;
				c1   = b8 * ( xsf - .1 ) + a0;
				c2   = .7 * ( xsf - .1 ) * sin( b3 ) + a1;
				c3   = .7 * ( xsf - .1 ) * cos( b3 ) + a1;
				c4   = b7 * ( xsf - .1 ) + a2;
				c5   = b8 * ( xsf - .1 ) + a2;
				c6   = b7 * ( xsf - .1 ) + a3;
				c7   = b8 * ( xsf - .1 ) + a3;
				c8   = b7 * ( xsf - .1 ) + a4;
				c9   = b8 * ( xsf - .1 ) + a4;
				c10  = .7 * ysf;

				switch(xs%5) {
					case 0:
						xdf0 = c0 * cos(b0) - c1 * sin(b0);
						ydf0 = c1 * sin(b0) + c0 * cos(b0) * c10;
					break;
					case 1:
						xdf0 = -(c0 * sin(b2) - c1 * cos(b2));
						ydf0 = -(c1 * cos(b2) + c0 * sin(b2) * c10);
					break;
					case 2:
						xdf0 = -(c4 * sin(b4) - c5 * cos(b4));
						ydf0 = -(c5 * cos(b4) + c4 * sin(b4) * c10);
					break;
					case 3:
						xdf0 = c6 * cos(b5) - c7 * sin(b5);
						ydf0 = c7 * sin(b5) + c6 * cos(b5) * c10;
					break;
					case 4:
						xdf0 = -c8 * cos(b6) - c9 * sin(b6);
						ydf0 = -c9 * sin(b6) + c8 * cos(b6) * c10;
					break;
				}
				xdf1 = xdf0;
				ydf1 = ydf0;
			break;
			/****************************************/
			/** Rotating Arcs                      **/
			case 8:
				c0   = a0 + .025 * ysf;
				c1   = b0 + a1 * xsf;

				xdf0 = c0 * cos(c1);
				ydf0 = c0 * sin(c1);
				xdf1 = c0 * cos(c1 + 3.14159);
				ydf1 = c0 * sin(c1 + 3.14159);
			break;
			/****************************************/
			/** Horizontal Sweep                   **/
			case 9:
				c0   = 2 * (xsf - 0.5);
				c1   = 0.7 * b0 + ysf * 0.25;

				xdf0 =  c1;
				ydf0 =  c0;
				xdf1 = -c1;
				ydf1 =  c0;
			break;
			/****************************************/
			/** NTPU Squared                       **/
			case 10:
				c0   = a1 * ysf + a0;
				c1   = 2.0 * a0 * (xsf - 0.5);

				switch(xs%2) {
					case 0:
						xdf0 =   b0 * c1 + b1 * c0;
						ydf0 = - b0 * c0 + b1 * c1;
						xdf1 =   b0 * c1 - b1 * c0;
						ydf1 =   b0 * c0 + b1 * c1;
					break;
					case 1:
						xdf0 = - b0 * c1 - b1 * c0;
						ydf0 = - b0 * c0 + b1 * c1;
						xdf1 = - b0 * c1 + b1 * c0;
						ydf1 =   b0 * c0 + b1 * c1;
					break;
				}
			break;
			/****************************************/
			/** NTPU Squared                       **/
			case 11:
				c0   = fabs(ysf) * 0.85 + 0.05;
				c1   = xsf * 43.766877 - b0;

				switch(xs%2) {
					case 0:
						xdf0 = c0 * cos(c1);
						ydf0 = c0 * sin(c1);
						xdf1 = c0 * cos(c1)+scaled;
						ydf1 = c0 * sin(c1);
					break;
					case 1:
						xdf0 = c0 * cos(c1);
						ydf0 = c0 * sin(c1)+scaled;
						xdf1 = c0 * cos(c1)+scaled;
						ydf1 = c0 * sin(c1)+scaled;
					break;
				}
			break;
			/****************************************/
		}

		xd = xdf0/scaled;
		yd = ydf0/scaled;
		/**
		if(xd < minx) xd = minx;
		if(xd > maxx) xd = maxx;
		if(yd < miny) yd = miny;
		if(yd > maxy) yd = maxy;
		**/
		WaveX[xs] = xd;
		WaveY[xs] = yd;

		xd = xdf1/scaled;
		yd = ydf1/scaled;
		/**
		if(xd < minx) xd = minx;
		if(xd > maxx) xd = maxx;
		if(yd < miny) yd = miny;
		if(yd > maxy) yd = maxy;
		**/
		WaveX[xs+Width] = xd;
		WaveY[xs+Width] = yd;
	}
}
