#define  D3D_OVERLOADS
#include "extrastuff.h"

VOID CreatePlain( LONG nX, LONG nY, LPD3DLVERTEX vert, LPWORD ind, LPD3DLVERTEX bound )
{
	FLOAT			dx, dy;
	LPD3DLVERTEX	v = vert;
	LONG			i, j;

	for( i = 0 ; i<=nY ; i++ )
		for( j = 0 ; j<=nX ; j++, v++ )
		{
			v->color = bound[0].color;

			dx = (FLOAT)j/(FLOAT)nX;
			dy = (FLOAT)i/(FLOAT)nY;			

			v->x  = (1-dy)*((1-dx)*bound[0].x+dx*bound[1].x)+dy*((1-dx)*bound[2].x+dx*bound[3].x);
			v->y  = (1-dy)*((1-dx)*bound[0].y+dx*bound[1].y)+dy*((1-dx)*bound[2].y+dx*bound[3].y);
			v->z  = (1-dy)*((1-dx)*bound[0].z+dx*bound[1].z)+dy*((1-dx)*bound[2].z+dx*bound[3].z);

			v->tu = (1-dy)*((1-dx)*bound[0].tu+dx*bound[1].tu)+dy*((1-dx)*bound[2].tu+dx*bound[3].tu);
			v->tv = (1-dy)*((1-dx)*bound[0].tv+dx*bound[1].tv)+dy*((1-dx)*bound[2].tv+dx*bound[3].tv);
		}

	for( i = 0 ; i<nY ; i++ )
		for( j = 0 ; j<nX ; j++ )
		{
			WORD		nbr = j + i*(nX+1);

			*ind++ = nbr;
			*ind++ = nbr + 1;
			*ind++ = nbr + nX + 1;

			*ind++ = nbr + nX + 1;
			*ind++ = nbr + 1;
			*ind++ = nbr + nX + 2;
		}
}


HRESULT ApplySphereMap( D3DVERTEX* pvVertices, DWORD dwNumVertices, LPDIRECT3DDEVICE7 pd3dDev )
{
    // Get the current world-view matrix
    D3DMATRIX matWorld, matView, matWV;
    pd3dDev->GetTransform( D3DTRANSFORMSTATE_VIEW,  &matView );
    pd3dDev->GetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld );

	matWV = matWorld*matView;
   
    // Extract world-view matrix elements for speed
    FLOAT m11 = matWV._11,   m21 = matWV._21,   m31 = matWV._31;
    FLOAT m12 = matWV._12,   m22 = matWV._22,   m32 = matWV._32;
    FLOAT m13 = matWV._13,   m23 = matWV._23,   m33 = matWV._33;

    // Loop through the vertices, transforming each one and calculating
    // the correct texture coordinates.
    for( WORD i = 0; i < dwNumVertices; i++ )
    {
        FLOAT nx = pvVertices[i].nx;
        FLOAT ny = pvVertices[i].ny;
        FLOAT nz = pvVertices[i].nz;
        
        // Assign the spheremap's texture coordinates
        pvVertices[i].tu = 0.5f * ( 1.0f + ( nx*m11 + ny*m21 + nz*m31 ) );
        pvVertices[i].tv = 0.5f * ( 1.0f - ( nx*m12 + ny*m22 + nz*m32 ) );
    }

    return S_OK;
}

HRESULT ApplySphereMap( D3DVERTEX* pvVertices, DWORD dwNumVertices, gem_Matrix& mtx )
{    
    // Get the current world-view matrix
    D3DMATRIX matWV = (D3DMATRIX)mtx;	
   
    // Extract world-view matrix elements for speed
    FLOAT m11 = matWV._11,   m21 = matWV._21,   m31 = matWV._31;
    FLOAT m12 = matWV._12,   m22 = matWV._22,   m32 = matWV._32;
    FLOAT m13 = matWV._13,   m23 = matWV._23,   m33 = matWV._33;

    // Loop through the vertices, transforming each one and calculating
    // the correct texture coordinates.
    for( WORD i = 0; i < dwNumVertices; i++ )
    {
        FLOAT nx = pvVertices[i].nx;
        FLOAT ny = pvVertices[i].ny;
        FLOAT nz = pvVertices[i].nz;
        
        // Assign the spheremap's texture coordinates
        pvVertices[i].tu = 0.5f * ( 1.0f + ( nx*m11 + ny*m21 + nz*m31 ) );
        pvVertices[i].tv = 0.5f * ( 1.0f - ( nx*m12 + ny*m22 + nz*m32 ) );
    }

    return S_OK;
}

VOID SetAlphaValue( LPD3DLVERTEX v, DWORD nbr, DWORD alpha )
{
	DWORD alphaVal = alpha<<24;

	for( DWORD i = 0 ; i<nbr ; i++ )
	{
		v[i].dcColor &= 0x00ffffff;
		v[i].dcColor |= alphaVal;
	}
}

VOID SetColorValue( LPD3DLVERTEX v, DWORD nbr, DWORD col )
{	
	for( DWORD i = 0 ; i<nbr ; i++ )
	{
		v[i].dcColor = col;
	}
}


VOID RenderEfxFace( FLOAT x, FLOAT y, FLOAT sizex, FLOAT sizey, DWORD alpha, LPDIRECTDRAWSURFACE7 text, LPDIRECT3DDEVICE7 pd3dDevice, DWORD orientation )
{
	D3DTLVERTEX		EfxFaces[4];

	if( !orientation )
	{	
		EfxFaces[0] = D3DTLVERTEX( D3DVECTOR( 0, 0, 0.5f ), 0.5f, 0x00ffffff, 0, 0, 0 );
		EfxFaces[1] = D3DTLVERTEX( D3DVECTOR( 0, 0, 0.5f ), 0.5f, 0x00ffffff, 0, 1, 0 );
		EfxFaces[2] = D3DTLVERTEX( D3DVECTOR( 0, 0, 0.5f ), 0.5f, 0x00ffffff, 0, 0, 1 );
		EfxFaces[3] = D3DTLVERTEX( D3DVECTOR( 0, 0, 0.5f ), 0.5f, 0x00ffffff, 0, 1, 1 );
	}
	else
	{
		EfxFaces[0] = D3DTLVERTEX( D3DVECTOR( 0, 0, 0.5f ), 0.5f, 0x00ffffff, 0, 0, 0 );
		EfxFaces[1] = D3DTLVERTEX( D3DVECTOR( 0, 0, 0.5f ), 0.5f, 0x00ffffff, 0, 0, 1 );
		EfxFaces[2] = D3DTLVERTEX( D3DVECTOR( 0, 0, 0.5f ), 0.5f, 0x00ffffff, 0, 1, 0 );
		EfxFaces[3] = D3DTLVERTEX( D3DVECTOR( 0, 0, 0.5f ), 0.5f, 0x00ffffff, 0, 1, 1 );
	}

	EfxFaces[0].sx = x-sizex*0.5f;
	EfxFaces[1].sx = x+sizex*0.5f;
	EfxFaces[2].sx = x-sizex*0.5f;
	EfxFaces[3].sx = x+sizex*0.5f;

	EfxFaces[0].sy = y-sizey*0.5f;
	EfxFaces[1].sy = y-sizey*0.5f;
	EfxFaces[2].sy = y+sizey*0.5f;
	EfxFaces[3].sy = y+sizey*0.5f;

	EfxFaces[0].dcColor = (alpha<<24)|0xffffff;
	EfxFaces[1].dcColor = (alpha<<24)|0xffffff;
	EfxFaces[2].dcColor = (alpha<<24)|0xffffff;
	EfxFaces[3].dcColor = (alpha<<24)|0xffffff;

	pd3dDevice->SetTexture( 0, text );
	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,  D3DBLEND_SRCALPHA );			
	pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );					

	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, EfxFaces, 4, 0 );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
}

#define	ND		1.71f*0.33f

VOID CreateCube( LPD3DVERTEX cube, FLOAT size, gem_Vector v )
{
	D3DVECTOR		normal = D3DVECTOR( 0, 0, -1 );

	cube[ 0] = D3DVERTEX( D3DVECTOR( -size+v.x,  size+v.y, -size+v.z ), D3DVECTOR( -ND,  ND, -ND ), 0, 0 );
	cube[ 1] = D3DVERTEX( D3DVECTOR(  size+v.x,  size+v.y, -size+v.z ), D3DVECTOR(  ND,  ND, -ND ), 1, 0 );
	cube[ 2] = D3DVERTEX( D3DVECTOR( -size+v.x, -size+v.y, -size+v.z ), D3DVECTOR( -ND, -ND, -ND ), 0, 1 );

	cube[ 3] = D3DVERTEX( D3DVECTOR( -size+v.x, -size+v.y, -size+v.z ), D3DVECTOR( -ND, -ND, -ND ), 0, 1 );
	cube[ 4] = D3DVERTEX( D3DVECTOR(  size+v.x,  size+v.y, -size+v.z ), D3DVECTOR(  ND,  ND, -ND ), 1, 0 );
	cube[ 5] = D3DVERTEX( D3DVECTOR(  size+v.x, -size+v.y, -size+v.z ), D3DVECTOR(  ND, -ND, -ND ), 1, 1 );


	cube[ 6] = D3DVERTEX( D3DVECTOR( -size+v.x, -size+v.y,  size+v.z ), D3DVECTOR( -ND, -ND,  ND ), 0, 1 );
	cube[ 7] = D3DVERTEX( D3DVECTOR(  size+v.x,  size+v.y,  size+v.z ), D3DVECTOR(  ND,  ND,  ND ), 1, 0 );	
	cube[ 8] = D3DVERTEX( D3DVECTOR( -size+v.x,  size+v.y,  size+v.z ), D3DVECTOR( -ND,  ND,  ND ), 0, 0 );

	cube[ 9] = D3DVERTEX( D3DVECTOR(  size+v.x, -size+v.y,  size+v.z ), D3DVECTOR(  ND, -ND,  ND ), 1, 1 );
	cube[10] = D3DVERTEX( D3DVECTOR(  size+v.x,  size+v.y,  size+v.z ), D3DVECTOR(  ND,  ND,  ND ), 1, 0 );
	cube[11] = D3DVERTEX( D3DVECTOR( -size+v.x, -size+v.y,  size+v.z ), D3DVECTOR( -ND, -ND,  ND ), 0, 1 );


	cube[12] = D3DVERTEX( D3DVECTOR( -size+v.x,  size+v.y, -size+v.z ), D3DVECTOR( -ND,  ND, -ND ), 0, 0 );
	cube[13] = D3DVERTEX( D3DVECTOR(  size+v.x,  size+v.y,  size+v.z ), D3DVECTOR(  ND,  ND,  ND ), 1, 1 );
	cube[14] = D3DVERTEX( D3DVECTOR(  size+v.x,  size+v.y, -size+v.z ), D3DVECTOR(  ND,  ND, -ND ), 1, 0 );

	cube[15] = D3DVERTEX( D3DVECTOR( -size+v.x,  size+v.y, -size+v.z ), D3DVECTOR( -ND,  ND, -ND ), 0, 0 );
	cube[16] = D3DVERTEX( D3DVECTOR( -size+v.x,  size+v.y,  size+v.z ), D3DVECTOR( -ND,  ND,  ND ), 0, 1 );
	cube[17] = D3DVERTEX( D3DVECTOR(  size+v.x,  size+v.y,  size+v.z ), D3DVECTOR(  ND,  ND,  ND ), 1, 1 );


	cube[18] = D3DVERTEX( D3DVECTOR( -size+v.x, -size+v.y, -size+v.z ), D3DVECTOR( -ND, -ND, -ND ), 0, 0 );
	cube[19] = D3DVERTEX( D3DVECTOR(  size+v.x, -size+v.y, -size+v.z ), D3DVECTOR(  ND, -ND, -ND ), 1, 0 );
	cube[20] = D3DVERTEX( D3DVECTOR(  size+v.x, -size+v.y,  size+v.z ), D3DVECTOR(  ND, -ND,  ND ), 1, 1 );

	cube[21] = D3DVERTEX( D3DVECTOR( -size+v.x, -size+v.y, -size+v.z ), D3DVECTOR( -ND, -ND, -ND ), 0, 0 );
	cube[22] = D3DVERTEX( D3DVECTOR(  size+v.x, -size+v.y,  size+v.z ), D3DVECTOR(  ND, -ND,  ND ), 1, 1 );
	cube[23] = D3DVERTEX( D3DVECTOR( -size+v.x, -size+v.y,  size+v.z ), D3DVECTOR( -ND, -ND,  ND ), 0, 1 );


	cube[24] = D3DVERTEX( D3DVECTOR( -size+v.x,  size+v.y, -size+v.z ), D3DVECTOR( -ND,  ND, -ND ), 0, 0 );
	cube[25] = D3DVERTEX( D3DVECTOR( -size+v.x, -size+v.y, -size+v.z ), D3DVECTOR( -ND, -ND, -ND ), 0, 1 );
	cube[26] = D3DVERTEX( D3DVECTOR( -size+v.x, -size+v.y,  size+v.z ), D3DVECTOR( -ND, -ND,  ND ), 1, 1 );	

	cube[27] = D3DVERTEX( D3DVECTOR( -size+v.x,  size+v.y, -size+v.z ), D3DVECTOR( -ND,  ND, -ND ), 0, 0 );
	cube[28] = D3DVERTEX( D3DVECTOR( -size+v.x, -size+v.y,  size+v.z ), D3DVECTOR( -ND, -ND,  ND ), 1, 1 );
	cube[29] = D3DVERTEX( D3DVECTOR( -size+v.x,  size+v.y,  size+v.z ), D3DVECTOR( -ND,  ND,  ND ), 1, 0 );


	cube[30] = D3DVERTEX( D3DVECTOR(  size+v.x, -size+v.y, -size+v.z ), D3DVECTOR(  ND, -ND, -ND ), 0, 1 );
	cube[31] = D3DVERTEX( D3DVECTOR(  size+v.x,  size+v.y, -size+v.z ), D3DVECTOR(  ND,  ND, -ND ), 0, 0 );	
	cube[32] = D3DVERTEX( D3DVECTOR(  size+v.x, -size+v.y,  size+v.z ), D3DVECTOR(  ND, -ND,  ND ), 1, 1 );

	cube[33] = D3DVERTEX( D3DVECTOR(  size+v.x,  size+v.y, -size+v.z ), D3DVECTOR(  ND,  ND, -ND ), 0, 0 );
	cube[34] = D3DVERTEX( D3DVECTOR(  size+v.x,  size+v.y,  size+v.z ), D3DVECTOR(  ND,  ND,  ND ), 1, 0 );	
	cube[35] = D3DVERTEX( D3DVECTOR(  size+v.x, -size+v.y,  size+v.z ), D3DVECTOR(  ND, -ND,  ND ), 1, 1 );
}

VOID CreateLCube( LPD3DLVERTEX cube, FLOAT size, gem_Vector v )
{
	D3DVECTOR		normal = D3DVECTOR( 0, 0, -1 );

	cube[ 0] = D3DLVERTEX( D3DVECTOR( -size+v.x,  size+v.y, -size+v.z ), 0x0, 0, 0, 0 );
	cube[ 1] = D3DLVERTEX( D3DVECTOR(  size+v.x,  size+v.y, -size+v.z ), 0x0, 0, 1, 0 );

	cube[ 2] = D3DLVERTEX( D3DVECTOR( -size+v.x,  size+v.y,  size+v.z ), 0x0, 0, 0, 1 );
	cube[ 3] = D3DLVERTEX( D3DVECTOR(  size+v.x,  size+v.y,  size+v.z ), 0x0, 0, 0, 1 );

	cube[ 4] = D3DLVERTEX( D3DVECTOR( -size+v.x, -size+v.y, -size+v.z ), 0x0, 0, 1, 0 );
	cube[ 5] = D3DLVERTEX( D3DVECTOR(  size+v.x, -size+v.y, -size+v.z ), 0x0, 0, 1, 1 );

	cube[ 6] = D3DLVERTEX( D3DVECTOR( -size+v.x, -size+v.y,  size+v.z ), 0x0, 0, 0, 1 );
	cube[ 7] = D3DLVERTEX( D3DVECTOR(  size+v.x, -size+v.y,  size+v.z ), 0x0, 0, 1, 0 );	

	cube[ 8] = D3DLVERTEX( D3DVECTOR(  size+v.x, -size+v.y,  size+v.z ), 0x0, 0, 0, 0 );
	cube[ 9] = D3DLVERTEX( D3DVECTOR(  size+v.x,  size+v.y,  size+v.z ), 0x0, 0, 1, 1 );

	cube[10] = D3DLVERTEX( D3DVECTOR( -size+v.x, -size+v.y,  size+v.z ), 0x0, 0, 1, 0 );
	cube[11] = D3DLVERTEX( D3DVECTOR( -size+v.x,  size+v.y,  size+v.z ), 0x0, 0, 0, 1 );
	
	cube[12] = D3DLVERTEX( D3DVECTOR(  size+v.x, -size+v.y, -size+v.z ), 0x0, 0, 0, 0 );
	cube[13] = D3DLVERTEX( D3DVECTOR(  size+v.x,  size+v.y, -size+v.z ), 0x0, 0, 1, 1 );

	cube[14] = D3DLVERTEX( D3DVECTOR( -size+v.x, -size+v.y, -size+v.z ), 0x0, 0, 1, 0 );
	cube[15] = D3DLVERTEX( D3DVECTOR( -size+v.x,  size+v.y, -size+v.z ), 0x0, 0, 0, 0 );

	cube[16] = D3DLVERTEX( D3DVECTOR(  size+v.x,  size+v.y, -size+v.z ), 0x0, 0, 0, 1 );
	cube[17] = D3DLVERTEX( D3DVECTOR(  size+v.x,  size+v.y,  size+v.z ), 0x0, 0, 1, 1 );

	cube[18] = D3DLVERTEX( D3DVECTOR( -size+v.x,  size+v.y, -size+v.z ), 0x0, 0, 0, 0 );
	cube[19] = D3DLVERTEX( D3DVECTOR( -size+v.x,  size+v.y,  size+v.z ), 0x0, 0, 1, 0 );

	cube[20] = D3DLVERTEX( D3DVECTOR(  size+v.x, -size+v.y, -size+v.z ), 0x0, 0, 1, 1 );
	cube[21] = D3DLVERTEX( D3DVECTOR(  size+v.x, -size+v.y,  size+v.z ), 0x0, 0, 0, 0 );

	cube[22] = D3DLVERTEX( D3DVECTOR( -size+v.x, -size+v.y, -size+v.z ), 0x0, 0, 1, 1 );
	cube[23] = D3DLVERTEX( D3DVECTOR( -size+v.x, -size+v.y,  size+v.z ), 0x0, 0, 0, 1 );	
}



