// Octopus.cpp: implementation of the COctopus class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Octopus.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

COctopus::COctopus( PDIRECT3DDEVICE8 pDevice ) : CEfx( pDevice ),
												 m_pvbSphere( NULL ),
												 m_pibSphere( NULL ),
												 m_pvbWireframeSphere( NULL ),
												 m_pibWireframeSphere( NULL )				
{
	try
	{
		LoadAlphaTexture( "graypart.bmp" );
		LoadAlphaTexture( "display5.bmp" );
	}
	catch( CTextureException )
	{
		throw CSystemException( "unable toload textures" );
	}	

	if( FAILED( m_pDevice->CreateVertexBuffer( 20*10*8*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbSphere ) ) )
		throw CSystemException( "unable to create sphere vertex buffer" );

	if( FAILED( m_pDevice->CreateIndexBuffer( 20*10*36*sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibSphere ) ) )
		throw CSystemException( "unable to create sphere index buffer" );

	if( FAILED( m_pDevice->CreateVertexBuffer( 202*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbWireframeSphere ) ) )
		throw CSystemException( "unable to create wireframe sphere vertex buffer" );

	if( FAILED( m_pDevice->CreateIndexBuffer( (20*11*2 + 10*20*2)*sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibWireframeSphere ) ) )
		throw CSystemException( "unable to create wireframe sphere index buffer" );	

	if( FAILED( m_pDevice->CreateVertexBuffer( 404*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbFxLines ) ) )
		throw CSystemException( "unable to create fx lines vertex buffer" );

	if( FAILED( m_pDevice->CreateVertexBuffer( 404*sizeof(SIMPLEVERTEX), 0, FVF_SIMPLEVERTEX, D3DPOOL_DEFAULT, &m_pvbFxHalo ) ) )
		throw CSystemException( "unable to create fx halo vertex buffer" );

	if( FAILED( m_pDevice->CreateIndexBuffer( (20*11*6 + 10*20*6)*sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibFxHalo ) ) )
		throw CSystemException( "unable to create fx halo index buffer" );


	m_piqFade = new CImageQuad( m_pDevice );
	m_piqDisp = new CImageQuad( m_pDevice, 20, 224, 276, 480 );
	m_piqDisp->SetColor( 0x0 );

	PSIMPLEVERTEX			pVertices;
	LPWORD					pIndices;

	DWORD					dwIndex = 0;

	m_pvbSphere->Lock( 0, 0,(LPBYTE*)&pVertices, 0 );
	
	for( DWORD i = 0 ; i < 20 ; i++ )
		for( DWORD j = 0 ; j < 10 ; j++, dwIndex++ )
		{
			FLOAT			fShift = 1.0f*RAND() + 1.0f;

			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.2f + fShift, (FLOAT)i*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/12.0f ),	  0xa0a0a0 );
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.2f + fShift, (FLOAT)(i+1)*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/12.0f ), 0xa0a0a0 );
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.2f + fShift, (FLOAT)(i+1)*H_2PI/20.0f, (FLOAT)(j+2)*H_PI/12.0f ), 0xa0a0a0 );
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.2f + fShift, (FLOAT)i*H_2PI/20.0f, (FLOAT)(j+2)*H_PI/12.0f ),	  0xa0a0a0 );

			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.0f + fShift, (FLOAT)i*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/12.0f ),	  0x303030 );
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.0f + fShift, (FLOAT)(i+1)*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/12.0f ), 0x303030 );
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.0f + fShift, (FLOAT)(i+1)*H_2PI/20.0f, (FLOAT)(j+2)*H_PI/12.0f ), 0x303030 );
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.0f + fShift, (FLOAT)i*H_2PI/20.0f, (FLOAT)(j+2)*H_PI/12.0f ),	  0x303030 );

			m_vBasePos[dwIndex][0] = Polar2Cartesian3d( 1.2f + fShift, (FLOAT)i*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/12.0f );
			m_vBasePos[dwIndex][1] = Polar2Cartesian3d( 1.2f + fShift, (FLOAT)(i+1)*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/12.0f );
			m_vBasePos[dwIndex][2] = Polar2Cartesian3d( 1.2f + fShift, (FLOAT)(i+1)*H_2PI/20.0f, (FLOAT)(j+2)*H_PI/12.0f );
			m_vBasePos[dwIndex][3] = Polar2Cartesian3d( 1.2f + fShift, (FLOAT)i*H_2PI/20.0f, (FLOAT)(j+2)*H_PI/12.0f );

			m_vBasePos[dwIndex][4] = Polar2Cartesian3d( 1.0f + fShift, (FLOAT)i*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/12.0f );
			m_vBasePos[dwIndex][5] = Polar2Cartesian3d( 1.0f + fShift, (FLOAT)(i+1)*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/12.0f );
			m_vBasePos[dwIndex][6] = Polar2Cartesian3d( 1.0f + fShift, (FLOAT)(i+1)*H_2PI/20.0f, (FLOAT)(j+2)*H_PI/12.0f );
			m_vBasePos[dwIndex][7] = Polar2Cartesian3d( 1.0f + fShift, (FLOAT)i*H_2PI/20.0f, (FLOAT)(j+2)*H_PI/12.0f );

			m_vDir[dwIndex] = Polar2Cartesian3d( 1.0f + fShift, ( (FLOAT)i+0.5f )*H_2PI/20.0f, ( (FLOAT)j + 1.5f )*H_PI/12.0f );
		}

	m_pvbSphere->Unlock();

	m_pibSphere->Lock( 0, 0, (LPBYTE*)&pIndices, 0 );

	for( i = 0, dwIndex = 0 ; i < 20 ; i++ )
		for( DWORD j = 0 ; j < 10 ; j++, dwIndex++ )
		{
			// up
			*(pIndices++) = (WORD)(8*dwIndex + 0 );
			*(pIndices++) = (WORD)(8*dwIndex + 1 );
			*(pIndices++) = (WORD)(8*dwIndex + 2 );

			*(pIndices++) = (WORD)(8*dwIndex + 0 );
			*(pIndices++) = (WORD)(8*dwIndex + 2 );
			*(pIndices++) = (WORD)(8*dwIndex + 3 );

			//down
			*(pIndices++) = (WORD)(8*dwIndex + 4 );
			*(pIndices++) = (WORD)(8*dwIndex + 5 );
			*(pIndices++) = (WORD)(8*dwIndex + 6 );

			*(pIndices++) = (WORD)(8*dwIndex + 4 );
			*(pIndices++) = (WORD)(8*dwIndex + 6 );
			*(pIndices++) = (WORD)(8*dwIndex + 7 );

			//left
			*(pIndices++) = (WORD)(8*dwIndex + 0 );
			*(pIndices++) = (WORD)(8*dwIndex + 3 );
			*(pIndices++) = (WORD)(8*dwIndex + 4 );

			*(pIndices++) = (WORD)(8*dwIndex + 4 );
			*(pIndices++) = (WORD)(8*dwIndex + 3 );
			*(pIndices++) = (WORD)(8*dwIndex + 7 );

			//right
			*(pIndices++) = (WORD)(8*dwIndex + 1 );
			*(pIndices++) = (WORD)(8*dwIndex + 2 );
			*(pIndices++) = (WORD)(8*dwIndex + 5 );

			*(pIndices++) = (WORD)(8*dwIndex + 5 );
			*(pIndices++) = (WORD)(8*dwIndex + 2 );
			*(pIndices++) = (WORD)(8*dwIndex + 6 );

			//front
			*(pIndices++) = (WORD)(8*dwIndex + 2 );
			*(pIndices++) = (WORD)(8*dwIndex + 3 );
			*(pIndices++) = (WORD)(8*dwIndex + 7 );

			*(pIndices++) = (WORD)(8*dwIndex + 7 );
			*(pIndices++) = (WORD)(8*dwIndex + 2 );
			*(pIndices++) = (WORD)(8*dwIndex + 6 );

			//back
			*(pIndices++) = (WORD)(8*dwIndex + 0 );
			*(pIndices++) = (WORD)(8*dwIndex + 1 );
			*(pIndices++) = (WORD)(8*dwIndex + 4 );

			*(pIndices++) = (WORD)(8*dwIndex + 4 );
			*(pIndices++) = (WORD)(8*dwIndex + 1 );
			*(pIndices++) = (WORD)(8*dwIndex + 5 );
		}

	m_pibSphere->Unlock();

	m_pvbWireframeSphere->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 3.5f, 0.0f, 0.0f ), 0x40000000 );
	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 3.5f, 0.0f, H_PI ), 0x40000000 );

	for( i = 0 ; i < 20 ; i++ )
		for( DWORD j = 0 ; j < 10 ; j++ )
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 3.5f,(FLOAT)i*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/11.0f ), 0x40000000 );

	m_pvbWireframeSphere->Unlock();

	m_pibWireframeSphere->Lock( 0, 0, (LPBYTE*)&pIndices, 0 );

	for( i = 0 ; i < 20 ; i++ )
	{
		*(pIndices++) = 0;
		*(pIndices++) = (WORD)(10*i + 2);

		for( DWORD j = 0 ; j < 9 ; j++ )
		{
			*(pIndices++) = (WORD)(10*i + j + 2);
			*(pIndices++) = (WORD)(10*i + j + 1 + 2);
		}

		*(pIndices++) = (WORD)(10*i + 9 + 2);
		*(pIndices++) = 1;
	}

	for( i = 0 ; i < 10 ; i++ )
	{
		for( DWORD j = 0 ; j < 19 ; j++ )
		{
			*(pIndices++) = (WORD)(10*j + i + 2 );
			*(pIndices++) = (WORD)(10*(j+1) + i + 2 );
		}

		*(pIndices++) = (WORD)(10*19 + i + 2 );
		*(pIndices++) = (WORD)(10*0  + i + 2 );
	}

	m_pibWireframeSphere->Unlock();

	m_pvbFxLines->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 3.25f, 0.0f, 0.0f ), 0x40000000 );
	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 4.00f, 0.0f, 0.0f ), 0x40000000 );
	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 3.25f, 0.0f, H_PI ), 0x40000000 );
	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 4.00f, 0.0f, H_PI ), 0x40000000 );

	for( i = 0 ; i < 20 ; i++ )
		for( DWORD j = 0 ; j < 10 ; j++ )
		{
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 3.25f,(FLOAT)i*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/11.0f ), 0x40000000 );
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 4.00f,(FLOAT)i*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/11.0f ), 0x40000000 );
		}

	m_pvbFxLines->Unlock();

	m_pvbFxHalo->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.0f, 0.0f, 0.0f ), 0xa08080ff );
	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.0f, 0.0f, H_PI ), 0xa08080ff );

	for( i = 0 ; i < 20 ; i++ )
		for( DWORD j = 0 ; j < 10 ; j++ )
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 1.0f,(FLOAT)i*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/11.0f ), 0xa08080ff );

	dwIndex = 0;

	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 2.0f, 0.0f, 0.0f ), 0x208080ff );
	m_vHalo[dwIndex++] = Polar2Cartesian3d( 1.0f, 0.0f, 0.0f );

	*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 2.0f, 0.0f, H_PI ), 0x208080ff );
	m_vHalo[dwIndex++] = Polar2Cartesian3d( 1.0f, 0.0f, H_PI );

	for( i = 0 ; i < 20 ; i++ )
		for( DWORD j = 0 ; j < 10 ; j++ )
		{
			*(pVertices++) = SIMPLEVERTEX( Polar2Cartesian3d( 2.0f,(FLOAT)i*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/11.0f ), 0x208080ff );
			m_vHalo[dwIndex++] = Polar2Cartesian3d( 1.0f,(FLOAT)i*H_2PI/20.0f, (FLOAT)(j+1)*H_PI/11.0f );
		}
	
	m_pvbFxHalo->Unlock();

	m_pibFxHalo->Lock( 0, 0, (LPBYTE*)&pIndices, 0 );


	for( i = 0 ; i < 20 ; i++ )
	{
		*(pIndices++) = 0;
		*(pIndices++) = (WORD)(10*i + 2);
		*(pIndices++) = 202;
		
		*(pIndices++) = (WORD)(10*i + 2);
		*(pIndices++) = 202;
		*(pIndices++) = (WORD)(10*i + 204);

		for( DWORD j = 0 ; j < 9 ; j++ )
		{
			*(pIndices++) = (WORD)(10*i + j + 2);
			*(pIndices++) = (WORD)(10*i + j + 1 + 2);
			*(pIndices++) = (WORD)(10*i + j + 204 );

			*(pIndices++) = (WORD)(10*i + j + 1 + 2);
			*(pIndices++) = (WORD)(10*i + j + 204 );
			*(pIndices++) = (WORD)(10*i + j + 1 + 204 );
		}

		*(pIndices++) = (WORD)(10*i + 9 + 2);
		*(pIndices++) = 1;
		*(pIndices++) = (WORD)(10*i + 9 + 204);

		*(pIndices++) = 1;
		*(pIndices++) = (WORD)(10*i + 9 + 204);
		*(pIndices++) = 203;
	}

	for( i = 0 ; i < 10 ; i++ )
	{
		for( DWORD j = 0 ; j < 19 ; j++ )
		{
			*(pIndices++) = (WORD)(10*j + i + 2 );
			*(pIndices++) = (WORD)(10*(j+1) + i + 2 );
			*(pIndices++) = (WORD)(10*j + i + 204 );

			*(pIndices++) = (WORD)(10*(j+1) + i + 2 );
			*(pIndices++) = (WORD)(10*j + i + 204 );
			*(pIndices++) = (WORD)(10*(j+1) + i + 204 );
		}

		*(pIndices++) = (WORD)(10*19 + i + 2 );
		*(pIndices++) = (WORD)(10*0  + i + 2 );
		*(pIndices++) = (WORD)(10*19 + i + 204 );

		*(pIndices++) = (WORD)(10*0  + i + 2 );
		*(pIndices++) = (WORD)(10*19 + i + 204 );
		*(pIndices++) = (WORD)(10*0 + i + 204 );
		
	}

	m_pibFxHalo->Unlock();

	for( i = 0 ; i < 202 ; i++ )
		m_fScaleShift[i] = H_2PI*RAND();	

	for( i = 0 ; i < 200 ; i++ )
		m_dwSyncIndex[i] = rand()%6;

	// sync splines

	m_fSync[0][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[0][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[0][ 2] = FLOATKEY(  2.51f,  0.00f );
	m_fSync[0][ 3] = FLOATKEY(  2.71f,  1.00f );
	m_fSync[0][ 4] = FLOATKEY(  2.91f,  0.00f );
	m_fSync[0][ 5] = FLOATKEY(  6.31f,  0.00f );
	m_fSync[0][ 6] = FLOATKEY(  6.51f,  1.00f );
	m_fSync[0][ 7] = FLOATKEY(  6.71f,  0.00f );
	m_fSync[0][ 8] = FLOATKEY( 11.94f,  0.00f );
	m_fSync[0][ 9] = FLOATKEY( 12.14f,  1.00f );
	m_fSync[0][10] = FLOATKEY( 12.34f,  0.00f );
	m_fSync[0][11] = FLOATKEY( 13.53f,  0.00f );
	m_fSync[0][12] = FLOATKEY( 13.73f,  1.00f );
	m_fSync[0][13] = FLOATKEY( 13.93f,  0.00f );
	m_fSync[0][14] = FLOATKEY( 15.75f,  0.00f );
	m_fSync[0][15] = FLOATKEY( 15.95f,  1.00f );
	m_fSync[0][16] = FLOATKEY( 16.15f,  0.00f );


	InitFloatSpline( 17, m_fSync[0] );

	m_fSync[1][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[1][ 1] = FLOATKEY(  0.16f,  0.00f );
	m_fSync[1][ 2] = FLOATKEY(  0.33f,  1.00f );
	m_fSync[1][ 3] = FLOATKEY(  0.53f,  0.00f );
	m_fSync[1][ 4] = FLOATKEY(  1.82f,  0.00f );
	m_fSync[1][ 5] = FLOATKEY(  2.02f,  1.00f );
	m_fSync[1][ 6] = FLOATKEY(  2.22f,  0.00f );
	m_fSync[1][ 7] = FLOATKEY(  3.62f,  0.00f );
	m_fSync[1][ 8] = FLOATKEY(  3.82f,  1.00f );
	m_fSync[1][ 9] = FLOATKEY(  3.92f,  0.00f );
	m_fSync[1][10] = FLOATKEY(  4.02f,  1.00f );
	m_fSync[1][11] = FLOATKEY(  4.22f,  0.00f );
	m_fSync[1][12] = FLOATKEY(  4.52f,  0.00f );
	m_fSync[1][13] = FLOATKEY(  4.72f,  1.00f );
	m_fSync[1][14] = FLOATKEY(  4.92f,  0.00f );
	m_fSync[1][15] = FLOATKEY(  4.95f,  0.00f );
	m_fSync[1][16] = FLOATKEY(  5.15f,  1.00f );
	m_fSync[1][17] = FLOATKEY(  5.35f,  0.00f );
	m_fSync[1][18] = FLOATKEY(  5.51f,  0.00f );
	m_fSync[1][19] = FLOATKEY(  5.71f,  1.00f );
	m_fSync[1][20] = FLOATKEY(  5.91f,  0.00f );
	m_fSync[1][21] = FLOATKEY(  6.75f,  0.00f );
	m_fSync[1][22] = FLOATKEY(  6.95f,  1.00f );
	m_fSync[1][23] = FLOATKEY(  7.15f,  0.00f );
	m_fSync[1][24] = FLOATKEY(  7.34f,  0.00f );
	m_fSync[1][25] = FLOATKEY(  7.54f,  1.00f );
	m_fSync[1][26] = FLOATKEY(  7.74f,  0.00f );
	m_fSync[1][27] = FLOATKEY(  8.79f,  0.00f );
	m_fSync[1][28] = FLOATKEY(  8.99f,  1.00f );
	m_fSync[1][29] = FLOATKEY(  9.19f,  0.00f );
	m_fSync[1][30] = FLOATKEY(  9.45f,  0.00f );
	m_fSync[1][31] = FLOATKEY(  9.65f,  1.00f );
	m_fSync[1][32] = FLOATKEY(  9.85f,  0.00f );
	m_fSync[1][33] = FLOATKEY( 10.85f,  0.00f );
	m_fSync[1][34] = FLOATKEY( 11.05f,  1.00f );
	m_fSync[1][35] = FLOATKEY( 11.25f,  0.00f );
	m_fSync[1][36] = FLOATKEY( 11.51f,  0.00f );
	m_fSync[1][37] = FLOATKEY( 11.71f,  1.00f );
	m_fSync[1][38] = FLOATKEY( 11.91f,  0.00f );
	m_fSync[1][39] = FLOATKEY( 12.59f,  0.00f );
	m_fSync[1][40] = FLOATKEY( 12.79f,  1.00f );
	m_fSync[1][41] = FLOATKEY( 12.91f,  0.00f );
	m_fSync[1][42] = FLOATKEY( 13.03f,  1.00f );
	m_fSync[1][43] = FLOATKEY( 13.23f,  0.00f );
	m_fSync[1][44] = FLOATKEY( 13.93f,  0.00f );
	m_fSync[1][45] = FLOATKEY( 14.13f,  1.00f );
	m_fSync[1][46] = FLOATKEY( 14.33f,  0.00f );
	m_fSync[1][47] = FLOATKEY( 14.49f,  0.00f );
	m_fSync[1][48] = FLOATKEY( 14.69f,  1.00f );
	m_fSync[1][49] = FLOATKEY( 14.89f,  0.00f );
	m_fSync[1][50] = FLOATKEY( 16.21f,  0.00f );
	m_fSync[1][51] = FLOATKEY( 16.41f,  1.00f );
	m_fSync[1][52] = FLOATKEY( 16.61f,  0.00f );


	InitFloatSpline( 53, m_fSync[1] );

	m_fSync[2][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[2][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[2][ 2] = FLOATKEY(  0.72f,  0.00f );
	m_fSync[2][ 3] = FLOATKEY(  0.92f,  1.00f );
	m_fSync[2][ 4] = FLOATKEY(  1.12f,  0.00f );
	m_fSync[2][ 5] = FLOATKEY(  8.08f,  0.00f );
	m_fSync[2][ 6] = FLOATKEY(  8.28f,  1.00f );
	m_fSync[2][ 7] = FLOATKEY(  8.48f,  0.00f );
	m_fSync[2][ 8] = FLOATKEY(  9.97f,  0.00f );
	m_fSync[2][ 9] = FLOATKEY( 10.17f,  1.00f );
	m_fSync[2][10] = FLOATKEY( 10.27f,  0.00f );
	m_fSync[2][11] = FLOATKEY( 10.37f,  1.00f );
	m_fSync[2][12] = FLOATKEY( 10.57f,  0.00f );
	m_fSync[2][13] = FLOATKEY( 15.09f,  0.00f );
	m_fSync[2][14] = FLOATKEY( 15.29f,  1.00f );
	m_fSync[2][15] = FLOATKEY( 15.49f,  0.00f );
	m_fSync[2][16] = FLOATKEY( 16.66f,  0.00f );
	m_fSync[2][17] = FLOATKEY( 16.86f,  1.00f );
	m_fSync[2][18] = FLOATKEY( 16.97f,  0.00f );
	m_fSync[2][19] = FLOATKEY( 17.08f,  1.00f );
	m_fSync[2][20] = FLOATKEY( 17.28f,  0.00f );
	m_fSync[2][21] = FLOATKEY( 17.34f,  0.00f );
	m_fSync[2][22] = FLOATKEY( 17.54f,  1.00f );
	m_fSync[2][23] = FLOATKEY( 17.74f,  0.00f );
	m_fSync[2][24] = FLOATKEY( 17.84f,  0.00f );
	m_fSync[2][25] = FLOATKEY( 18.04f,  1.00f );
	m_fSync[2][26] = FLOATKEY( 18.24f,  0.00f );
	m_fSync[2][27] = FLOATKEY( 18.28f,  0.00f );
	m_fSync[2][28] = FLOATKEY( 18.49f,  1.00f );
	m_fSync[2][29] = FLOATKEY( 18.69f,  0.00f );
	m_fSync[2][30] = FLOATKEY( 19.10f,  0.00f );
	m_fSync[2][31] = FLOATKEY( 19.30f,  1.00f );
	m_fSync[2][32] = FLOATKEY( 19.50f,  0.00f );
	m_fSync[2][33] = FLOATKEY( 19.62f,  0.00f );
	m_fSync[2][34] = FLOATKEY( 19.82f,  1.00f );
	m_fSync[2][35] = FLOATKEY( 20.02f,  0.00f );
	m_fSync[2][36] = FLOATKEY( 20.07f,  0.00f );
	m_fSync[2][37] = FLOATKEY( 20.27f,  1.00f );
	m_fSync[2][38] = FLOATKEY( 20.47f,  0.00f );


	InitFloatSpline( 39, m_fSync[2] );

	m_fSync[3][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[3][ 1] = FLOATKEY(  0.12f,  0.00f );
	m_fSync[3][ 2] = FLOATKEY(  0.24f,  1.00f );
	m_fSync[3][ 3] = FLOATKEY(  0.35f,  0.00f );
	m_fSync[3][ 4] = FLOATKEY(  0.46f,  1.00f );
	m_fSync[3][ 5] = FLOATKEY(  0.66f,  0.00f );
	m_fSync[3][ 6] = FLOATKEY(  1.59f,  0.00f );
	m_fSync[3][ 7] = FLOATKEY(  1.79f,  1.00f );
	m_fSync[3][ 8] = FLOATKEY(  1.99f,  0.00f );
	m_fSync[3][ 9] = FLOATKEY(  3.16f,  0.00f );
	m_fSync[3][10] = FLOATKEY(  3.36f,  1.00f );
	m_fSync[3][11] = FLOATKEY(  3.56f,  0.00f );
	m_fSync[3][12] = FLOATKEY(  3.67f,  0.00f );
	m_fSync[3][13] = FLOATKEY(  3.87f,  1.00f );
	m_fSync[3][14] = FLOATKEY(  4.07f,  0.00f );
	m_fSync[3][15] = FLOATKEY(  4.30f,  0.00f );
	m_fSync[3][16] = FLOATKEY(  4.50f,  1.00f );
	m_fSync[3][17] = FLOATKEY(  4.70f,  0.00f );
	m_fSync[3][18] = FLOATKEY(  5.43f,  0.00f );
	m_fSync[3][19] = FLOATKEY(  5.63f,  1.00f );
	m_fSync[3][20] = FLOATKEY(  5.74f,  0.00f );
	m_fSync[3][21] = FLOATKEY(  5.84f,  1.00f );
	m_fSync[3][22] = FLOATKEY(  6.04f,  0.00f );
	m_fSync[3][23] = FLOATKEY(  6.54f,  0.00f );
	m_fSync[3][24] = FLOATKEY(  6.74f,  1.00f );
	m_fSync[3][25] = FLOATKEY(  6.94f,  0.00f );
	m_fSync[3][26] = FLOATKEY(  7.19f,  0.00f );
	m_fSync[3][27] = FLOATKEY(  7.39f,  1.00f );
	m_fSync[3][28] = FLOATKEY(  7.49f,  0.00f );
	m_fSync[3][29] = FLOATKEY(  7.60f,  1.00f );
	m_fSync[3][30] = FLOATKEY(  7.80f,  0.00f );
	m_fSync[3][31] = FLOATKEY(  8.29f,  0.00f );
	m_fSync[3][32] = FLOATKEY(  8.49f,  1.00f );
	m_fSync[3][33] = FLOATKEY(  8.61f,  0.00f );
	m_fSync[3][34] = FLOATKEY(  8.73f,  1.00f );
	m_fSync[3][35] = FLOATKEY(  8.93f,  0.00f );
	m_fSync[3][36] = FLOATKEY(  9.01f,  0.00f );
	m_fSync[3][37] = FLOATKEY(  9.21f,  1.00f );
	m_fSync[3][38] = FLOATKEY(  9.33f,  0.00f );
	m_fSync[3][39] = FLOATKEY(  9.45f,  1.00f );
	m_fSync[3][40] = FLOATKEY(  9.65f,  0.00f );
	m_fSync[3][41] = FLOATKEY( 10.35f,  0.00f );
	m_fSync[3][42] = FLOATKEY( 10.55f,  1.00f );
	m_fSync[3][43] = FLOATKEY( 10.75f,  0.00f );
	m_fSync[3][44] = FLOATKEY( 10.85f,  0.00f );
	m_fSync[3][45] = FLOATKEY( 11.05f,  1.00f );
	m_fSync[3][46] = FLOATKEY( 11.13f,  0.00f );
	m_fSync[3][47] = FLOATKEY( 11.21f,  1.00f );
	m_fSync[3][48] = FLOATKEY( 11.41f,  0.00f );
	m_fSync[3][49] = FLOATKEY( 12.18f,  0.00f );
	m_fSync[3][50] = FLOATKEY( 12.38f,  1.00f );
	m_fSync[3][51] = FLOATKEY( 12.58f,  0.00f );
	m_fSync[3][52] = FLOATKEY( 12.67f,  0.00f );
	m_fSync[3][53] = FLOATKEY( 12.87f,  1.00f );
	m_fSync[3][54] = FLOATKEY( 13.07f,  0.00f );
	m_fSync[3][55] = FLOATKEY( 13.74f,  0.00f );
	m_fSync[3][56] = FLOATKEY( 13.94f,  1.00f );
	m_fSync[3][57] = FLOATKEY( 14.14f,  0.00f );
	m_fSync[3][58] = FLOATKEY( 14.44f,  0.00f );
	m_fSync[3][59] = FLOATKEY( 14.64f,  1.00f );
	m_fSync[3][60] = FLOATKEY( 14.75f,  0.00f );
	m_fSync[3][61] = FLOATKEY( 14.86f,  1.00f );
	m_fSync[3][62] = FLOATKEY( 15.06f,  0.00f );
	m_fSync[3][63] = FLOATKEY( 16.41f,  0.00f );
	m_fSync[3][64] = FLOATKEY( 16.61f,  1.00f );
	m_fSync[3][65] = FLOATKEY( 16.81f,  0.00f );


	InitFloatSpline( 66, m_fSync[3] );

	m_fSync[4][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[4][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[4][ 2] = FLOATKEY(  2.69f,  0.00f );
	m_fSync[4][ 3] = FLOATKEY(  2.89f,  1.00f );
	m_fSync[4][ 4] = FLOATKEY(  3.02f,  0.00f );
	m_fSync[4][ 5] = FLOATKEY(  3.14f,  1.00f );
	m_fSync[4][ 6] = FLOATKEY(  3.34f,  0.00f );
	m_fSync[4][ 7] = FLOATKEY(  6.13f,  0.00f );
	m_fSync[4][ 8] = FLOATKEY(  6.33f,  1.00f );
	m_fSync[4][ 9] = FLOATKEY(  6.53f,  0.00f );
	m_fSync[4][10] = FLOATKEY(  9.67f,  0.00f );
	m_fSync[4][11] = FLOATKEY(  9.87f,  1.00f );
	m_fSync[4][12] = FLOATKEY( 10.07f,  0.00f );
	m_fSync[4][13] = FLOATKEY( 13.31f,  0.00f );
	m_fSync[4][14] = FLOATKEY( 13.51f,  1.00f );
	m_fSync[4][15] = FLOATKEY( 13.71f,  0.00f );
	m_fSync[4][16] = FLOATKEY( 15.96f,  0.00f );
	m_fSync[4][17] = FLOATKEY( 16.16f,  1.00f );
	m_fSync[4][18] = FLOATKEY( 16.36f,  0.00f );


	InitFloatSpline( 19, m_fSync[4] );

	m_fSync[5][ 0] = FLOATKEY(  0.00f,  0.00f );
	m_fSync[5][ 1] = FLOATKEY(  0.20f,  0.00f );
	m_fSync[5][ 2] = FLOATKEY(  0.94f,  0.00f );
	m_fSync[5][ 3] = FLOATKEY(  1.14f,  1.00f );
	m_fSync[5][ 4] = FLOATKEY(  1.24f,  0.00f );
	m_fSync[5][ 5] = FLOATKEY(  1.34f,  1.00f );
	m_fSync[5][ 6] = FLOATKEY(  1.44f,  0.00f );
	m_fSync[5][ 7] = FLOATKEY(  1.54f,  1.00f );
	m_fSync[5][ 8] = FLOATKEY(  1.74f,  0.00f );
	m_fSync[5][ 9] = FLOATKEY(  2.00f,  0.00f );
	m_fSync[5][10] = FLOATKEY(  2.20f,  1.00f );
	m_fSync[5][11] = FLOATKEY(  2.40f,  0.00f );
	m_fSync[5][12] = FLOATKEY(  4.72f,  0.00f );
	m_fSync[5][13] = FLOATKEY(  4.92f,  1.00f );
	m_fSync[5][14] = FLOATKEY(  5.12f,  0.00f );
	m_fSync[5][15] = FLOATKEY(  7.86f,  0.00f );
	m_fSync[5][16] = FLOATKEY(  8.06f,  1.00f );
	m_fSync[5][17] = FLOATKEY(  8.26f,  0.00f );
	m_fSync[5][18] = FLOATKEY( 11.71f,  0.00f );
	m_fSync[5][19] = FLOATKEY( 11.91f,  1.00f );
	m_fSync[5][20] = FLOATKEY( 12.11f,  0.00f );
	m_fSync[5][21] = FLOATKEY( 15.27f,  0.00f );
	m_fSync[5][22] = FLOATKEY( 15.47f,  1.00f );
	m_fSync[5][23] = FLOATKEY( 15.58f,  0.00f );
	m_fSync[5][24] = FLOATKEY( 15.68f,  1.00f );
	m_fSync[5][25] = FLOATKEY( 15.88f,  0.00f );
	m_fSync[5][26] = FLOATKEY( 17.14f,  0.00f );
	m_fSync[5][27] = FLOATKEY( 17.34f,  1.00f );
	m_fSync[5][28] = FLOATKEY( 17.54f,  0.00f );
	m_fSync[5][29] = FLOATKEY( 17.57f,  0.00f );
	m_fSync[5][30] = FLOATKEY( 17.77f,  1.00f );
	m_fSync[5][31] = FLOATKEY( 17.97f,  0.00f );
	m_fSync[5][32] = FLOATKEY( 18.07f,  0.00f );
	m_fSync[5][33] = FLOATKEY( 18.27f,  1.00f );
	m_fSync[5][34] = FLOATKEY( 18.47f,  0.00f );
	m_fSync[5][35] = FLOATKEY( 18.95f,  0.00f );
	m_fSync[5][36] = FLOATKEY( 19.15f,  1.00f );
	m_fSync[5][37] = FLOATKEY( 19.35f,  0.00f );
	m_fSync[5][38] = FLOATKEY( 19.36f,  0.00f );
	m_fSync[5][39] = FLOATKEY( 19.56f,  1.00f );
	m_fSync[5][40] = FLOATKEY( 19.76f,  0.00f );
	m_fSync[5][41] = FLOATKEY( 19.79f,  0.00f );
	m_fSync[5][42] = FLOATKEY( 19.99f,  1.00f );
	m_fSync[5][43] = FLOATKEY( 20.19f,  0.00f );
	m_fSync[5][44] = FLOATKEY( 20.76f,  0.00f );
	m_fSync[5][45] = FLOATKEY( 20.96f,  1.00f );
	m_fSync[5][46] = FLOATKEY( 21.16f,  0.00f );


	InitFloatSpline( 47, m_fSync[5] );


	m_dwKeyCount[0] = 17;
	m_dwKeyCount[1] = 53;
	m_dwKeyCount[2] = 39;
	m_dwKeyCount[3] = 66;
	m_dwKeyCount[4] = 19;
	m_dwKeyCount[5] = 47;

}

COctopus::~COctopus()
{
	SAFE_RELEASE( m_pvbSphere );
	SAFE_RELEASE( m_pibSphere );
}

BOOL COctopus::UpdateFrame( FLOAT fTime )
{
	// standard setup

	m_pDevice->SetTransform( D3DTS_PROJECTION, ProjectionMtx( 30.0f, 0.75f, 1.0f, 100.0f ) );
	m_pDevice->SetTransform( D3DTS_VIEW, CameraMtx( he3d_CVector( 0, 0, -10 ), he3d_CVector( 0, 0, 0 ), 0 ) );

	m_mtxSphere = RotationMtx( 0.3f*fTime, -0.4f*fTime, 0.2f*fTime );
	m_mtxFxSphere = ScaleMtx( 0.3f )*RotationMtx( 0.3f*fTime, -0.4f*fTime, 0.2f*fTime )*TranslationMtx( -1.84f, -1.26f, 0.0f );

	FLOAT					fAlpha;

	if( fTime < 2.0f )
	{
		m_bRenderFade = TRUE;

		fAlpha = CLAMPALPHA( 140.0f*( 2.0f - fTime ) );
		m_piqFade->SetAlpha( (DWORD)fAlpha );
	}
	else if( fTime > 18.0f )
	{
		m_bRenderFade = TRUE;

		fAlpha = CLAMPALPHA( 128.0f*( fTime - 18.0f ) );
		m_piqFade->SetAlpha( (DWORD)fAlpha );
	}
	else
		m_bRenderFade = FALSE;


	PSIMPLEVERTEX			pVertices;

	m_pvbFxHalo->Lock( 202*sizeof(SIMPLEVERTEX), 202*sizeof(SIMPLEVERTEX), (LPBYTE*)&pVertices, 0 );

	for( DWORD i = 0 ; i < 202 ; i++ )
		pVertices[i].m_vPos = m_vHalo[i]*( 2.25f + sinf( fTime*2.5f + m_fScaleShift[i] ) );

	m_pvbFxHalo->Unlock();

	FLOAT					fSync[6];

	for( i = 0 ; i < 6 ; i++ )
		fSync[i] = GetFloatSplineValue( fTime, m_dwKeyCount[i], m_fSync[i] );
	
	DWORD					dwIndex = 0;

	m_pvbSphere->Lock( 0, 0, (LPBYTE*)&pVertices, 0 );

	for( i = 0 ; i < 200 ; i++ )
		for( DWORD j = 0 ; j < 8 ; j++, dwIndex++ )
			pVertices[dwIndex].m_vPos = m_vBasePos[i][j] + 0.25f*fSync[m_dwSyncIndex[i]]*m_vDir[i];

	m_pvbSphere->Unlock();

	return TRUE;
}

BOOL COctopus::RenderEfx()
{
	m_pDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffffff, 1.0f, 0 );

	m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
	m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
	m_pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );	

	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxSphere );
	
	m_pDevice->SetVertexShader( FVF_SIMPLEVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbSphere, sizeof(SIMPLEVERTEX) );
	m_pDevice->SetIndices( m_pibSphere, 0 );

	m_pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 20*10*8, 0, 20*10*12 );
	
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

	m_pDevice->SetStreamSource( 0, m_pvbWireframeSphere, sizeof(SIMPLEVERTEX) );
	m_pDevice->SetIndices( m_pibWireframeSphere, 0 );

	m_pDevice->DrawIndexedPrimitive( D3DPT_LINELIST, 0, 202, 0, 20*10 + 20*11 );

	m_pDevice->SetStreamSource( 0, m_pvbFxLines, sizeof(SIMPLEVERTEX) );
	
	m_pDevice->DrawPrimitive( D3DPT_LINELIST, 0, 202 );

	m_pDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_POINTSIZE, FLT2DWORD( 8.0f ) );

	m_pDevice->SetTexture( 0, GetTexture( "graypart.bmp" ) );

	m_pDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 404 );

	m_pDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );
	m_pDevice->SetTexture( 0, NULL );

	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );

	m_pDevice->SetRenderState( D3DRS_ZENABLE, FALSE );

	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

	m_pDevice->SetTexture( 0, GetTexture( "display5.bmp" ) );
	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );

	m_piqDisp->Render( m_pDevice );

	m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );

	m_pDevice->SetTexture( 0, NULL );

	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

	m_pDevice->SetTransform( D3DTS_WORLD, m_mtxFxSphere );

	m_pDevice->SetVertexShader( FVF_SIMPLEVERTEX );
	m_pDevice->SetStreamSource( 0, m_pvbFxHalo, sizeof(SIMPLEVERTEX) );
	m_pDevice->SetIndices( m_pibFxHalo, 0 );

	m_pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 404, 0, 20*11*2 + 10*20*2 );

	
	if( m_bRenderFade )
	{
		m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
		m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

		m_piqFade->Render( m_pDevice );
	}

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

	return TRUE;
}
