#include <stdlib.h>
#include <math.h>
#include "tap.h"

#define ID_PLASMA 0x80000105

TAP_ID( ID_PLASMA );
TAP_PROGRAM_NAME("PLASMA");
TAP_AUTHOR_NAME("TOPFIELD");
TAP_DESCRIPTION("Simple PLASMA");
TAP_ETCINFO(__DATE__);

bool _exitFlag = FALSE;

word _c1555[256];

word *_vAddr[576];

#define PEL_write 0x3c8
#define PEL_read 0x3c7
#define PEL_data 0x3c9
#define box_w 160
#define box_h 100
#define pi 3.1415926L

//#define max(a,b) ((a) > (b) ? (a) : (b))
//-------------------------------------------------
byte body[box_w*box_h];	// buffer for the bitmap body
byte colors[256];			// color table
byte tab1[64000];			// table one for thr plasma
byte tab2[64000];			// table two for the plasma
//-------------------------------------------------

void CalcTab1()   // calculate table 1 for plasma
{
	long i=0,j=0;
	while(i<box_h*2)
	{
        j=0;
		while(j<box_w*2)
		{
			tab1[(i*box_w*2)+j]=(byte) (( sqrt(16.0+(box_h-i)*(box_h-i)+(box_w-j)*(box_w-j))-4) *5 );
			j++;
		}
		i++;
	}
}

void CalcTab2()   // calculate table 2 for plasma
{
	long i=0,j=0;
	float temp;
	while(i<box_h*2)
	{
		j=0;
		while(j<box_w*2)
		{
			temp=sqrt(16.0+(box_h-i)*(box_h-i)+(box_w-j)*(box_w-j))-4;
			tab2[(i*box_w*2)+j]=(sin(temp/9.5)+1)*90;
//			tab2[(i*box_w*2)+j]=(sin(sqrt((box_h-i)*(box_h-i)+(box_w-j)*(box_w-j))/9.5)+1)*90;
			j++;
		}
		i++;
	}
}

void CalculateColors()
{
	static double r=1.0/6.0*pi,g=3.0/6.0*pi,b=5.0/6.0*pi;
	int i=0;
	double u,v;
	while(i<256)
	{
		u=2*pi/256*i;
//#define mycol(u,a) (max(0.0,cos((u)+(a))))*63 // try this line instead
#define mycol(u,a) (dword)((cos((u)+(a))+1)*0x1f)
        _c1555[i++] = RGB( mycol(u,r),mycol(u,g), mycol(u,b));
	}
	r+=0.05;
	g-=0.05;
	b+=0.1;
}
void CalculateBody(long x1,long y1,long x2,long y2,long x3,long y3,long x4,long y4,long roll)
{
	long i=0,j=0,k=0;
	char a;
	while(i<box_h)
	{
		j=0;
		k+=box_w;
		while(j<box_w)
		{
								// this is the heart of the plasma
			body[i*box_w+j]=
					tab1[320*(i+y1)+j+x1]+roll+
					tab2[320*(i+y2)+j+x2]+
					tab2[320*(i+y3)+j+x3]+
					tab2[320*(i+y4)+j+x4]
					;
			j++;
		}
		i++;
	}
}

void DisplayObject(int x,int y)
{
    dword i, j;
    byte *p;
    word *dest, *dest2;

    p = &body[0];

    for( j=0; j<box_h; j++ )
    {
        dest  = _vAddr[y+j*2]+x;
        dest2 = _vAddr[y+j*2+1]+x;
        
        for( i=0; i<box_w; i++ )
        {
            *(dest) = _c1555[ *p ];
            *(dest+1) = _c1555[ *p ];
            *(dest2) = _c1555[ *p ];
            *(dest2+1) = _c1555[ *p ];
            p++;
            dest+=2;
            dest2+=2;
        }
    }
}

dword TAP_EventHandler( word event, dword param1, dword param2 )
{
    if( event == EVT_KEY )
    {
        _exitFlag = TRUE;
	    return 0;
    }
    return param1;
}


int TAP_Main(void)
{
	float circle1=0,circle2=0,circle3=0,circle4=0,circle5=0,circle6=0,circle7=0,circle8=0;
	int x1,y1,x2,y2,x3,y3,x4,y4,roll=0;
	int bank=0,i=0;

    word rgn;        
    TYPE_OsdBaseInfo osdBaseInfo;
    TAP_Osd_GetBaseInfo( &osdBaseInfo );

    rgn = TAP_Osd_Create( 0, 0, 720, 576, 0, FALSE );

    TAP_Osd_PutString1926( rgn, 200, 200, -1, "Please Wait..", COLOR_White, COLOR_Blue );

    // set vertical address
    for( i=0; i<576; i+=2 )
    {
        _vAddr[i] = osdBaseInfo.eAddr + 720*i;
        _vAddr[i+1] = osdBaseInfo.oAddr + 720*i;
    }

	CalcTab1();
	CalcTab2();

	CalculateColors();

    while( _exitFlag == FALSE )
	{
        i++;
		circle1+=0.085/6;
		circle2-=0.1/6;
		circle3+=.3/6;
		circle4-=.2/6;
		circle5+=.4/6;
		circle6-=.15/6;
		circle7+=.35/6;
		circle8-=.05/6;
		x2=(box_w/2)+(box_w/2)*sin(circle1);
		y2=(box_h/2)+(box_h/2)*cos(circle2);
		x1=(box_w/2)+(box_w/2)*cos(circle3);
		y1=(box_h/2)+(box_h/2)*sin(circle4);
		x3=(box_w/2)+(box_w/2)*cos(circle5);
		y3=(box_h/2)+(box_h/2)*sin(circle6);
		x4=(box_w/2)+(box_w/2)*cos(circle7);
		y4=(box_h/2)+(box_h/2)*sin(circle8);
        CalculateBody(x1,y1,x2,y2,x3,y3,x4,y4,roll+=5);
        DisplayObject( 200,200 );
        TAP_SystemProc();
    }

    TAP_Osd_Delete( rgn );
    
	return 0;
}

