//----------------------------------------------------------------------------------------------
// scene replay, with shadows particles and lensflares, this part use heavily directgem lib
// hmm look like i coded this, surprising aint it :) ( i = acid/z51 of coz :)
//----------------------------------------------------------------------------------------------
// this file is part of source code from intertia³ demo (c)zone51 `2000
//----------------------------------------------------------------------------------------------
#define  D3D_OVERLOADS
#include "particle.h"
#include "PsychoScene.h"
#include "directgem.h"
#include "volumetric.h"
#include "object3d.h"
#include "enum.h"
#include "extrastuff.h"

static	gem_Scene				scene;

static	OBJECT3D				object[8];
static	OBJECT3D				transform[8];

static	LPWORD					ccdata[8];

static	D3DVERTEX				vol1[8][5000];
static	DWORD					volnbr1[8];

static	D3DVERTEX				vol2[8][5000];
static	DWORD					volnbr2[8];

static	D3DVERTEX				vol3[8][5000];
static	DWORD					volnbr3[8];

static	D3DLVERTEX				Flare[4];

static	D3DTLVERTEX				Plate1[4];
static	D3DTLVERTEX				Plate2[4];
static	D3DTLVERTEX				Plate3[4];
static	D3DTLVERTEX				Plate4[4];
static	WORD					p1ON = 0;
static	WORD					p2ON = 0;
static	WORD					p3ON = 0;
static	WORD					p4ON = 0;

static	gem_Vector				litpos[3];
static	gem_Vector				center;

static	gem_Material*			roory;

static	gem_Map*				map1;
static	gem_Map*				map2;

static	ParticleSystem			particles( 2000 );

static	D3DTLVERTEX				FadeV[4];
static	DWORD					Fade = 1;

static	DWORD					banner = 0;
static	FLOAT					x, y, sizex, sizey;
static	DWORD					alpha;

static	FLOAT					lastGenTime = 0;

static	D3DMATRIX				matBackLocal[10];
static	D3DLVERTEX				Plain[4];

static	DWORD					efxon = 0;
static	DWORD					renderScene = 1;

static	DWORD					_3 = 0;
static	FLOAT					_3x, _3y, _3sizex, _3sizey;
static	DWORD					_3alpha;

static	DWORD					circle = 0;
static	DWORD					line = 0;
static	FLOAT					s1, s2, s3, s4;
static	FLOAT					cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
static	DWORD					calpha;

static	FLOAT					lx1, ly1, lx2, ly2, lx3, ly3;
static	FLOAT					lx4, ly4, lx5, ly5, lx6, ly6;

HRESULT fxInit_PsychoScene( LPDIRECT3DDEVICE7 pd3dDevice )
{	
	gem_Material*			mat;	
	gem_Mesh*				mesh;		
	gem_Mesh::gem_Group*	group;
	gem_Light*				light;

	TCHAR					namez[] = "Object00";
	DWORD					i;

	LoadTexture( "data\\textures\\part.jpg", pd3dDevice );
	LoadTexture( "data\\textures\\light2.jpg", pd3dDevice );
	LoadTexture( "data\\textures\\envir.jpg", pd3dDevice );
	LoadTexture( "data\\textures\\alien2.jpg", pd3dDevice );	
	LoadTexture( "data\\textures\\roory.jpg", pd3dDevice );		

	LoadTexture( "data\\textures\\acid.jpg", pd3dDevice );	
	LoadTexture( "data\\textures\\beton.jpg", pd3dDevice );	
	LoadTexture( "data\\textures\\juve.jpg", pd3dDevice );	
	LoadTexture( "data\\textures\\nazgul.jpg", pd3dDevice );	

	LoadTexture( "data\\textures\\nopee1.jpg", pd3dDevice );	

	LoadTexture( "data\\lens\\lens05.jpg", pd3dDevice );
	LoadTexture( "data\\lens\\lens01.jpg", pd3dDevice );
	LoadTexture( "data\\lens\\lens02.jpg", pd3dDevice );
	LoadTexture( "data\\lens\\lens03.jpg", pd3dDevice );
	LoadTexture( "data\\lens\\lens04.jpg", pd3dDevice );

	LoadTexture( "data\\textures\\circle.jpg", pd3dDevice );
	LoadTexture( "data\\textures\\inertia.jpg", pd3dDevice );
	LoadTexture( "data\\textures\\3.jpg", pd3dDevice );
	LoadTexture( "data\\textures\\line.jpg", pd3dDevice );

	LoadTexture( "data\\gfx\\beton.jpg", pd3dDevice );
	LoadTexture( "data\\gfx\\acid.jpg", pd3dDevice );
	LoadTexture( "data\\gfx\\naz.jpg", pd3dDevice );
	LoadTexture( "data\\gfx\\juve.jpg", pd3dDevice );

	Flare[0] = D3DLVERTEX( D3DVECTOR(-2, 2, 0 ), 0x80ffffff, 0, 0, 0 );
	Flare[1] = D3DLVERTEX( D3DVECTOR( 2, 2, 0 ), 0x80ffffff, 0, 1, 0 );
	Flare[2] = D3DLVERTEX( D3DVECTOR(-2,-2, 0 ), 0x80ffffff, 0, 0, 1 );
	Flare[3] = D3DLVERTEX( D3DVECTOR( 2,-2, 0 ), 0x80ffffff, 0, 1, 1 );

	Plate1[0] = D3DTLVERTEX( D3DVECTOR( 20, 20, 0 ), 0.5f, 0x00ffffff, 0, 0, 0 );
	Plate1[1] = D3DTLVERTEX( D3DVECTOR( 220, 20, 0 ), 0.5f, 0x00ffffff, 0, 1, 0 );
	Plate1[2] = D3DTLVERTEX( D3DVECTOR( 20, 220, 0 ), 0.5f, 0x00ffffff, 0, 0, 1 );
	Plate1[3] = D3DTLVERTEX( D3DVECTOR( 220, 220, 0 ), 0.5f, 0x00ffffff, 0, 1, 1 );

	Plate2[0] = D3DTLVERTEX( D3DVECTOR( 420, 260, 0 ), 0.5f, 0x00ffffff, 0, 0, 0 );
	Plate2[1] = D3DTLVERTEX( D3DVECTOR( 620, 260, 0 ), 0.5f, 0x00ffffff, 0, 1, 0 );
	Plate2[2] = D3DTLVERTEX( D3DVECTOR( 420, 460, 0 ), 0.5f, 0x00ffffff, 0, 0, 1 );
	Plate2[3] = D3DTLVERTEX( D3DVECTOR( 620, 460, 0 ), 0.5f, 0x00ffffff, 0, 1, 1 );

	Plate3[0] = D3DTLVERTEX( D3DVECTOR( 420, 20, 0 ), 0.5f, 0x00ffffff, 0, 0, 0 );
	Plate3[1] = D3DTLVERTEX( D3DVECTOR( 620, 20, 0 ), 0.5f, 0x00ffffff, 0, 1, 0 );
	Plate3[2] = D3DTLVERTEX( D3DVECTOR( 420, 220, 0 ), 0.5f, 0x00ffffff, 0, 0, 1 );
	Plate3[3] = D3DTLVERTEX( D3DVECTOR( 620, 220, 0 ), 0.5f, 0x00ffffff, 0, 1, 1 );

	Plate4[0] = D3DTLVERTEX( D3DVECTOR( 20, 260, 0 ), 0.5f, 0x00ffffff, 0, 0, 0 );
	Plate4[1] = D3DTLVERTEX( D3DVECTOR( 220, 260, 0 ), 0.5f, 0x00ffffff, 0, 1, 0 );
	Plate4[2] = D3DTLVERTEX( D3DVECTOR( 20, 460, 0 ), 0.5f, 0x00ffffff, 0, 0, 1 );
	Plate4[3] = D3DTLVERTEX( D3DVECTOR( 220, 460, 0 ), 0.5f, 0x00ffffff, 0, 1, 1 );

	Plain[0] = D3DLVERTEX( D3DVECTOR(-11, 11, 3 ), 0x30FFFFFF, 0, 0, 0 );
	Plain[1] = D3DLVERTEX( D3DVECTOR( 11, 11, 3 ), 0x30FFFFFF, 0, 1, 0 );
	Plain[2] = D3DLVERTEX( D3DVECTOR(-11,-11, 3 ), 0x30FFFFFF, 0, 0, 1 );
	Plain[3] = D3DLVERTEX( D3DVECTOR( 11,-11, 3 ), 0x30FFFFFF, 0, 1, 1 );

	D3DVECTOR vFar = D3DVECTOR( 0.0f, 0.0f, 0.5f );
    FadeV[0] = D3DTLVERTEX( vFar, 0.5f, 0x0, 0, 0.01f, 0.99f );
    FadeV[1] = D3DTLVERTEX( vFar, 0.5f, 0x0, 0, 0.01f, 0.01f );
    FadeV[2] = D3DTLVERTEX( vFar, 0.5f, 0x0, 0, 0.99f, 0.99f );
    FadeV[3] = D3DTLVERTEX( vFar, 0.5f, 0x0, 0, 0.99f, 0.01f );

	D3DVIEWPORT7 vp;
    pd3dDevice->GetViewport(&vp);
    FadeV[0].sy = (FLOAT)vp.dwHeight;
    FadeV[2].sy = (FLOAT)vp.dwHeight;
    FadeV[2].sx = (FLOAT)vp.dwWidth;
    FadeV[3].sx = (FLOAT)vp.dwWidth;
	
	scene.Load( "data\\scenes\\psycho.3ds" );	

	particles.Init( 10, gem_Vector( 0.1f, -0.2f, -0.1f ), GetTexture( "data\\textures\\part.jpg" ) );

	scene.SetLightSize( 2.0f );
	scene.SetFlags( GEMFLAGS_SOFTWAREGEOMETRY | GEMFLAGS_RENDERLIGHT );
	//scene.SetFlags( GEMFLAGS_RENDERLIGHT );
	scene.SetViewport( 1.0f, 1000.0f, 0.75f );
	scene.Init( pd3dDevice );

	scene.SetLightFlare( "data\\textures\\light2.jpg" );
	scene.SetActiveCamera( "Camera02" );	

	// manuly set material to meshses...	

	mat = new gem_Material( "data\\textures\\acid.jpg", &scene );		
	mesh = (gem_Mesh*)scene.FindObject( "Plate02" );
	mesh->SetMaterial( mat );

	mat = new gem_Material( "data\\textures\\beton.jpg", &scene );		
	mesh = (gem_Mesh*)scene.FindObject( "Plate01" );
	mesh->SetMaterial( mat );

	mat = new gem_Material( "data\\textures\\juve.jpg", &scene );		
	mesh = (gem_Mesh*)scene.FindObject( "Plate03" );
	mesh->SetMaterial( mat );

	mat = new gem_Material( "data\\textures\\nazgul.jpg", &scene );		
	mesh = (gem_Mesh*)scene.FindObject( "Plate04" );
	mesh->SetMaterial( mat );
	
	roory = new gem_Material( &scene );
	map1 = new gem_Map( "data\\textures\\roory.jpg" );
	map2 = new gem_Map( "data\\textures\\envir.jpg" );

	mesh = (gem_Mesh*)scene.FindObject( "ROORY" );
	mesh->SetMaterial( roory );	
	
	mat = new gem_Material( "data\\textures\\alien2.jpg", &scene );	
	center = gem_Vector( 0, 0, 0 );

	for( i = 0 ; i<mesh->dwVertexCount ; i++ )
	{
		center.x += mesh->pMeshVertexTab[i].x;
		center.y += mesh->pMeshVertexTab[i].y;
		center.z += mesh->pMeshVertexTab[i].z;
	}

	center.x /= (FLOAT)mesh->dwVertexCount;
	center.y /= (FLOAT)mesh->dwVertexCount;
	center.z /= (FLOAT)mesh->dwVertexCount;

	light = (gem_Light*)scene.FindObject( "Light01" );
	litpos[0] = light->position;
	light = (gem_Light*)scene.FindObject( "Light02" );
	litpos[1] = light->position;
	light = (gem_Light*)scene.FindObject( "Light03" );
	litpos[2] = light->position;


	for( i = 1 ; i<=8 ; i++ )
	{
		namez[7] = (char)('0' + i);
		mesh = (gem_Mesh*)scene.FindObject( namez );
		mesh->SetMaterial( mat );
	}	

	// create appropiate data for shadow vol generating (oh doesnt it sound great:)
	for( i = 0 ; i<8 ; i++ )
	{
		namez[7] = (char)('0' + i + 1);

		mesh	= (gem_Mesh*)scene.FindObject( namez );
		group	= mesh->GroupList.GetItem( 0 );

		object[i].vert			= mesh->pTransformVertexTab;
		object[i].vertNbr		= mesh->dwVertexCount;
		object[i].ind			= group->pIndices;
		object[i].indNbr		= group->dwIndicesCount;

		ccdata[i] = new WORD[object[i].indNbr];
		CreateConectivityData( &object[i], ccdata[i] );

		transform[i].vert		= new D3DVERTEX[object[i].vertNbr];
		transform[i].ind		= object[i].ind;
		transform[i].indNbr		= object[i].indNbr;
		transform[i].vertNbr	= object[i].vertNbr;		
	}	

	return S_OK;
}

HRESULT fxFrameMove_PsychoScene( LPDIRECT3DDEVICE7 pd3dDevice, LPSYNCINFO sync )
{
	FLOAT			fTimeKey = sync->fTimeKey;
	gem_Light*		light;

	pd3dDevice->LightEnable( 0, FALSE );

	//fTimeKey = 41.999;

	//gem_Vector		g;

	gem_Matrix		mtx;	
	
	scene.Transform( fTimeKey*2000.0f/60.0f );

	gem_Matrix		litmat = TranslationMtx( -center )*
							 RotationMtx( fTimeKey*0.25f, fTimeKey*0.4f, -fTimeKey*0.3f )*
							 TranslationMtx( center );	

	//g = gem_Vector( sin( fTimeKey ), -1.8, cos( fTimeKey ) );
	//particles.Gravity() = g;

	light = (gem_Light*)scene.FindObject( "Light01" );
	light->position = litpos[0]*litmat;
	
	light = (gem_Light*)scene.FindObject( "Light02" );
	light->position = litpos[1]*litmat;	
	
	light = (gem_Light*)scene.FindObject( "Light03" );
	light->position = litpos[2]*litmat;
	

	if( fTimeKey - lastGenTime > 0.20f )
	{
		light = (gem_Light*)scene.FindObject( "Emiter01" );		
		particles.Generate( fTimeKey, light->position );

		light = (gem_Light*)scene.FindObject( "Emiter02" );	
		particles.Generate( fTimeKey, light->position );

		light = (gem_Light*)scene.FindObject( "Emiter03" );	
		particles.Generate( fTimeKey, light->position );				

		lastGenTime = fTimeKey;
	}

	particles.Move( fTimeKey );		
	
	for( int i = 1 ; i<7 ; i++ )
	{
		light = (gem_Light*)scene.FindObject( "Light01" );	

		mtx = CameraMtx( light->position, CalculateCenter( &object[i] ), 0 );
		TransformObject3D( &object[i], &transform[i], mtx );

		volnbr1[i] = CreateShadowVolume( &object[i], &transform[i], ccdata[i], light->position, vol1[i] );

		light = (gem_Light*)scene.FindObject( "Light02" );	

		mtx = CameraMtx( light->position, CalculateCenter( &object[i] ), 0 );
		TransformObject3D( &object[i], &transform[i], mtx );

		volnbr2[i] = CreateShadowVolume( &object[i], &transform[i], ccdata[i], light->position, vol2[i] );

		light = (gem_Light*)scene.FindObject( "Light03" );	

		mtx = CameraMtx( light->position, CalculateCenter( &object[i] ), 0 );
		TransformObject3D( &object[i], &transform[i], mtx );

		volnbr3[i] = CreateShadowVolume( &object[i], &transform[i], ccdata[i], light->position, vol3[i] );
	}

	DWORD		aphCoeff;

	p1ON = 0; p2ON = 0; p3ON = 0; p4ON = 0;

	if( fTimeKey >= 14 && fTimeKey < 19 )
	{
		aphCoeff = (DWORD)255.0f*sin( (fTimeKey-14.0f)*3.14159f*0.2f );
		aphCoeff <<=24;
		Plate1[0].dcColor &= 0xffffff; Plate1[0].dcColor |= aphCoeff;
		Plate1[1].dcColor &= 0xffffff; Plate1[1].dcColor |= aphCoeff;
		Plate1[2].dcColor &= 0xffffff; Plate1[2].dcColor |= aphCoeff;
		Plate1[3].dcColor &= 0xffffff; Plate1[3].dcColor |= aphCoeff;
		p1ON = 1;		
	}	

	if( fTimeKey >= 24 && fTimeKey < 29 )
	{
		aphCoeff = (DWORD)255.0f*sin( (fTimeKey-24.0f)*3.14159f*0.2f );
		aphCoeff <<=24;
		Plate2[0].dcColor &= 0xffffff; Plate2[0].dcColor |= aphCoeff;
		Plate2[1].dcColor &= 0xffffff; Plate2[1].dcColor |= aphCoeff;
		Plate2[2].dcColor &= 0xffffff; Plate2[2].dcColor |= aphCoeff;
		Plate2[3].dcColor &= 0xffffff; Plate2[3].dcColor |= aphCoeff;
		p2ON = 1;		
	}

	if( fTimeKey >= 38 && fTimeKey < 43 )
	{
		aphCoeff = (DWORD)255.0f*sin( (fTimeKey-38.0f)*3.14159f*0.2f );
		aphCoeff <<=24;
		Plate3[0].dcColor &= 0xffffff; Plate3[0].dcColor |= aphCoeff;
		Plate3[1].dcColor &= 0xffffff; Plate3[1].dcColor |= aphCoeff;
		Plate3[2].dcColor &= 0xffffff; Plate3[2].dcColor |= aphCoeff;
		Plate3[3].dcColor &= 0xffffff; Plate3[3].dcColor |= aphCoeff;
		p3ON = 1;
	}	

	if( fTimeKey >= 47 && fTimeKey < 52 )
	{
		aphCoeff = (DWORD)255.0f*sin( (fTimeKey-47.0f)*3.14159f*0.2f );
		aphCoeff <<=24;
		Plate4[0].dcColor &= 0xffffff; Plate4[0].dcColor |= aphCoeff;
		Plate4[1].dcColor &= 0xffffff; Plate4[1].dcColor |= aphCoeff;
		Plate4[2].dcColor &= 0xffffff; Plate4[2].dcColor |= aphCoeff;
		Plate4[3].dcColor &= 0xffffff; Plate4[3].dcColor |= aphCoeff;
		p4ON = 1;
	}

	circle = 0;
	line   = 0;

	if( fTimeKey > 10.0f && fTimeKey < 16.0f )
	{
		circle = 1;
		line   = 1;

		s1 = 100 + ( fTimeKey - 10.0f )*25;
		s2 = 50  + ( fTimeKey - 10.0f )*30;
		s3 = 80  + ( fTimeKey - 10.0f )*25;
		s4 = 90  + ( fTimeKey - 10.0f )*20;

		lx1 = 220 + (fTimeKey - 10.0f )*50;
		lx2 = 230 + (fTimeKey - 10.0f )*50;
		lx3 = 200 + (fTimeKey - 10.0f )*50;

		ly1 = 90;
		ly2 = 110;
		ly3 = 130;

		lx4 = 90; 
		lx5 = 110; 
		lx6 = 130; 

		ly4 = 220 + (fTimeKey - 10.0f )*30;
		ly5 = 230 + (fTimeKey - 10.0f )*30;
		ly6 = 200 + (fTimeKey - 10.0f )*30;

		cx1 = 120; cy1 = 120;		
		cx3 = 113; cy3 = 127;

		cx4 = 30*cos( fTimeKey*0.5 ) - 30*sin( fTimeKey*0.5 ) + 120;
		cy4 = 30*sin( fTimeKey*0.5 ) + 30*cos( fTimeKey*0.5 ) + 120;		

		cx2 = -30*cos( fTimeKey*0.75 ) - 20*sin( fTimeKey*0.75 ) + 120;
		cy2 = -30*sin( fTimeKey*0.75 ) + 20*cos( fTimeKey*0.75 ) + 120;		

		calpha = 150.0f*sin( (fTimeKey - 10.0f)*3.14159f*0.1666f );		
	} 		

	//if( fTimeKey > 10.0f && fTimeKe)

	if( fTimeKey > 20.0f && fTimeKey < 26.0f )
	{
		circle = 1;
		line   = 1;

		s1 = 100 + ( fTimeKey - 20.0f )*25;
		s2 = 80  + ( fTimeKey - 20.0f )*30;
		s3 = 30  + ( fTimeKey - 20.0f )*25;
		s4 = 60  + ( fTimeKey - 20.0f )*20;

		cx1 = 520; cy1 = 360;
		cx2 = 470; cy2 = 360;		
		cx4 = 430; cy4 = 360;		

		lx1 = 420 - (fTimeKey - 20.0f )*50;
		lx2 = 400 - (fTimeKey - 20.0f )*50;
		lx3 = 440 - (fTimeKey - 20.0f )*50;

		ly1 = 330;
		ly2 = 350;
		ly3 = 370;

		lx4 = 490; 
		lx5 = 510; 
		lx6 = 530; 

		ly4 = 260 - (fTimeKey - 20.0f )*30;
		ly5 = 240 - (fTimeKey - 20.0f )*30;
		ly6 = 280 - (fTimeKey - 20.0f )*30;

		cx3 =  33*sinf( fTimeKey*1.7f ) + 520;
		cy3 = -33*cosf( fTimeKey*1.7f ) + 360;		

		calpha = 150.0f*sin( (fTimeKey - 20.0f)*3.14159f*0.1666f );		
	} 		

	if( fTimeKey > 34.0f && fTimeKey < 40.0f )
	{
		circle = 1;
		line   = 1;

		s1 = 100 + ( fTimeKey - 34.0f )*15;
		s2 = 35  + ( fTimeKey - 34.0f )*25;
		s3 = 35  + ( fTimeKey - 34.0f )*25;
		s4 = 35  + ( fTimeKey - 34.0f )*25;

		cx1 = 520; cy1 = 120;		

		cx2 =  23*sinf( fTimeKey ) + 520;
		cy2 = -23*cosf( fTimeKey ) + 120;

		cx3 = -23*cosf( fTimeKey ) - 23*sinf( fTimeKey ) + 520;
		cy3 = -23*sinf( fTimeKey ) + 23*cosf( fTimeKey ) + 120;

		cx4 = 23*cosf( fTimeKey ) - 23*sinf( fTimeKey ) + 520;
		cy4 = 23*sinf( fTimeKey ) + 23*cosf( fTimeKey ) + 120;

		lx1 = 420 - (fTimeKey - 34.0f )*50;
		lx2 = 400 - (fTimeKey - 34.0f )*50;
		lx3 = 440 - (fTimeKey - 34.0f )*50;

		ly1 = 90;
		ly2 = 110;
		ly3 = 130;

		lx4 = 490; 
		lx5 = 510; 
		lx6 = 530;

		ly4 = 220 + (fTimeKey - 34.0f )*30;
		ly5 = 230 + (fTimeKey - 34.0f )*30;
		ly6 = 200 + (fTimeKey - 34.0f )*30;

		calpha = 150.0f*sinf( (fTimeKey - 34.0f)*3.14159f*0.1666f );		
	} 		

	if( fTimeKey > 43.0f && fTimeKey < 49.0f )
	{
		FLOAT		tx, ty;

		circle = 1;
		line   = 1;

		s1 = 100 + ( fTimeKey - 43.0f )*15;
		s2 = 80  + ( fTimeKey - 43.0f )*15;

		s3 = 40  + ( fTimeKey - 43.0f )*10;
		s4 = 10  + ( fTimeKey - 43.0f )*15;

		
		lx1 = 220 + (fTimeKey - 43.0f )*50;
		lx2 = 230 + (fTimeKey - 43.0f )*50;
		lx3 = 200 + (fTimeKey - 43.0f )*50;

		ly1 = 330;
		ly2 = 350;
		ly3 = 370;

		lx4 = 90; 
		lx5 = 110; 
		lx6 = 130;

		ly4 = 260 - (fTimeKey - 43.0f )*30;
		ly5 = 240 - (fTimeKey - 43.0f )*30;
		ly6 = 280 - (fTimeKey - 43.0f )*30;


		cx1 = 120; cy1 = 360;
		cx2 = 120; cy2 = 360;				

		cx3 =  s1*0.5f*sinf( fTimeKey*0.5f ) + 120;
		cy3 = -s1*0.5f*cosf( fTimeKey*0.5f ) + 360;

		tx =  s3*0.5f*sinf( fTimeKey*1.5f ) + 120;
		ty = -s3*0.5f*cosf( fTimeKey*1.5f ) + 360 - s1*0.5;

		cx4 = (tx - 120)*cosf( fTimeKey*0.5f ) - (ty-360)*sinf( fTimeKey*0.5f ) + 120;
		cy4 = (tx - 120)*sinf( fTimeKey*0.5f ) + (ty-360)*cosf( fTimeKey*0.5f ) + 360;

		calpha = 150.0f*sin( (fTimeKey - 43.0f)*3.14159f*0.1666f );		
	} 		

	if( fTimeKey < 2.0f )
	{
		Fade = 1;

		DWORD alpha = (DWORD)( ( 2.0f - fTimeKey )*0.5f*255.0f );

		if( alpha > 255 ) 
			alpha = 255;

		alpha <<= 24;

		FadeV[0].dcColor = alpha | 0x00010101;
		FadeV[1].dcColor = alpha | 0x00010101;
		FadeV[2].dcColor = alpha | 0x00010101;
		FadeV[3].dcColor = alpha | 0x00010101;
	}
	else
		Fade = 0;

	if( fTimeKey > 50.0f )
	{
		Fade = 1;

		DWORD alpha = (DWORD)( ( fTimeKey-50.0f )*0.3333f*255.0f );

		if( alpha > 255 ) 
		{
			alpha = 255;
			renderScene = 0;
		}

		alpha <<= 24;

		FadeV[0].dcColor = alpha | 0x00010101;
		FadeV[1].dcColor = alpha | 0x00010101;
		FadeV[2].dcColor = alpha | 0x00010101;
		FadeV[3].dcColor = alpha | 0x00010101;
	}

	if( fTimeKey < 3.0f )
	{
		banner = 1;

		x = 200 + ( fTimeKey + 3.0f )*20.0f;
		y = 150;		

		sizex = 321;// + ( fTimeKey + 3.0f )*10.0f;
		sizey = 125;// + ( fTimeKey + 3.0f )*10.0f;

		alpha = 0xff;
		
	}
	else
		if( fTimeKey <6.0f )
		{
			banner = 1;

			x = 200 + ( fTimeKey + 3.0f )*20.0f;
			y = 150;
			
			sizex = 321;// + ( fTimeKey + 3.0f )*10.0f;
			sizey = 125;// + ( fTimeKey + 3.0f )*10.0f;

			alpha = (DWORD)( (6.0f - fTimeKey)*0.3333f*255.0f );
		}
		else
			banner = 0;

	if( fTimeKey < 1.0f )
	{
		_3 = 1;

		_3x = 450;
		_3y = 120;		

		_3sizex = 128 + ( fTimeKey + 4.0f )*10.0f;
		_3sizey = 128 + ( fTimeKey + 4.0f )*10.0f;

		_3alpha = 0xff;
		
	}
	else
		if( fTimeKey < 4.0f )
		{
			_3 = 1;

			_3x = 450;
			_3y = 120;
			
			_3sizex = 128 + ( fTimeKey + 4.0f )*10.0f;
			_3sizey = 128 + ( fTimeKey + 4.0f )*10.0f;

			_3alpha = (DWORD)( (4.0f - fTimeKey)*0.3333f*255.0f );
		}
		else
			_3 = 0;


	if( fTimeKey>50.0f )
	{	
		efxon = 1;

		for( i = 0 ; i<10 ; i++ )
		{
			FLOAT	dgr = 3.14159f*0.5f + (i+1)*(0.1f - (fTimeKey-50.0f)*0.45f);
		
			if( dgr > 3.14159f*0.5f )
				dgr = 3.14159f*0.5f;
			else
				if( dgr < 0.0f )
					dgr = 0;

			DWORD	aph = (DWORD)fTimeKey*48.0f;

			if( aph > 48 )
				aph = 48;

			aph <<= 24;

			Plain[0].dcColor = aph | 0xffffff;
			Plain[1].dcColor = aph | 0xffffff;
			Plain[2].dcColor = aph | 0xffffff;
			Plain[3].dcColor = aph | 0xffffff;			

			matBackLocal[i] = (D3DMATRIX)( RotationMtx( dgr, 0.0f, -(1.0f+(FLOAT)i/10.0f)*(fTimeKey-50.0f)*0.275f )*
										   TranslationMtx( 0.0f, 0.0f, 2.0f*i+3) );
		}
	}				

	return S_OK;
}

void RenderLensFlare( gem_Vector& pos, gem_Vector& trg, gem_Matrix& invCam, LPDIRECT3DDEVICE7 pd3dDevice )
{
	D3DMATRIX		lensMtx;	
	FLOAT			focus = Length( trg - pos );
	gem_Vector		dir = Normalize( trg - pos );		

	D3DMATRIX		a1, a2;

	pd3dDevice->GetTransform( D3DTRANSFORMSTATE_VIEW, &a1 );
	pd3dDevice->GetTransform( D3DTRANSFORMSTATE_PROJECTION, &a2 );

	a1 = a1*a2;
	gem_Matrix		trn( a1 );
	gem_Vector		t = pos*trn;

	if( t.x<-1 || t.x>1 || t.y<-1 || t.y>1 )
		return;

	//pd3dDevice->

	pd3dDevice->SetTexture(	0, GetTexture( "data\\lens\\lens03.jpg" ) );			
	lensMtx = (D3DMATRIX)(invCam*TranslationMtx( pos + 0.4f*focus*dir ) );
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &lensMtx );
	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Flare, 4, NULL );
	
	pd3dDevice->SetTexture(	0, GetTexture( "data\\lens\\lens04.jpg" ) );	
	lensMtx = (D3DMATRIX)(invCam*TranslationMtx( pos + 0.2f*dir*focus ) );
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &lensMtx );
	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Flare, 4, NULL );

	pd3dDevice->SetTexture(	0, GetTexture( "data\\lens\\lens05.jpg" ) );	
	lensMtx = (D3DMATRIX)(invCam*TranslationMtx( pos - 0.2f*focus*dir ) );
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &lensMtx );
	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Flare, 4, NULL );

	pd3dDevice->SetTexture(	0, GetTexture( "data\\lens\\lens01.jpg" ) );	
	lensMtx = (D3DMATRIX)(invCam*TranslationMtx( pos + 0.8f*focus*dir ) );
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &lensMtx );
	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Flare, 4, NULL );

	pd3dDevice->SetTexture(	0, GetTexture( "data\\lens\\lens02.jpg" ) );	
	lensMtx = (D3DMATRIX)(invCam*TranslationMtx( pos + 0.6f*focus*dir ) );
	pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &lensMtx );
	pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Flare, 4, NULL );

}


HRESULT fxRender_PsychoScene( LPDIRECT3DDEVICE7 pd3dDevice )
{
	DWORD				i = 0;
	gem_Object*			obj;	
	gem_Light*			light;

	TCHAR*				name;

	gem_Matrix			invCam;
	gem_Matrix			cammtx;
	gem_Vector			pos1, pos2, pos3;

	light = (gem_Light*)scene.FindObject( "Light01" );
	pos1 = light->position;
	light = (gem_Light*)scene.FindObject( "Light02" );
	pos2 = light->position;
	light = (gem_Light*)scene.FindObject( "Light03" );
	pos3 = light->position;
	
	invCam = InvCameraMtx( scene.currentCam->position, scene.currentCam->target, scene.currentCam->roll );
	//cammtx = CameraMtx( scene.currentCam->position, scene.currentCam->target, scene.currentCam->roll );	
	cammtx = IdentMtx();

	pd3dDevice->SetTexture( 0, GetTexture( "data\\textures\\alien2.jpg" ) );

	pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );
	pd3dDevice->SetRenderState( D3DRENDERSTATE_SHADEMODE, D3DSHADE_FLAT );  

	pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR );	
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_ANISOTROPIC );	
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_ANISOTROPIC );
	pd3dDevice->SetTextureStageState( 0, D3DTSS_MAXANISOTROPY, 2 );	
	
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, D3DZB_USEW );

	pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0x00000000, 1.0f, 0L );

	scene.currentCam->SetGeometry( pd3dDevice );

	pd3dDevice->BeginScene();

	if( renderScene )
	{
		while( obj = scene.ObjectList.GetItem( i ) )
		{
			name = scene.ObjectList.GetName( i++ );

			if( !strncmp( name, "Plate00", 5 ) )
			{
				pd3dDevice->SetRenderState( D3DRENDERSTATE_WRAP0, 0 );
				pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
				pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,  D3DBLEND_ONE );			
				pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );			
				pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE );
				pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
			}
			else
			{
				if( !strcmp( name, "ROORY" ) )
				{
					pd3dDevice->SetRenderState( D3DRENDERSTATE_WRAP0, D3DWRAPCOORD_0 | D3DWRAPCOORD_1 );
					pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );
					pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE );
					pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
					gem_Mesh* mesh = (gem_Mesh*)obj;																
					roory->texture1 = map1;
					obj->Render();			
					roory->texture1 = map2;															
					ApplySphereMap( mesh->pTransformVertexTab, mesh->dwVertexCount, pd3dDevice );
					pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
					pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,  D3DBLEND_ONE );			
					pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );
					pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE );
				}
				else
				{
					pd3dDevice->SetRenderState( D3DRENDERSTATE_WRAP0, 0 );
					pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );
					pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, TRUE );
					pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_CCW );
				}
			}					

			obj->Render();			
		}

		for( i = 1 ; i<7 ; i++ )
		{
			RenderShadowVolume( volnbr1[i], vol1[i], pd3dDevice );
			RenderShadowVolume( volnbr2[i], vol2[i], pd3dDevice );
			RenderShadowVolume( volnbr3[i], vol3[i], pd3dDevice );
		}	

		RenderShadow( pd3dDevice );		

		pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,  D3DBLEND_ONE );			
		pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );	
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE );		

		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, D3DZB_FALSE );
		RenderLensFlare( pos1, scene.currentCam->position + (-scene.currentCam->position + scene.currentCam->target)*0.3f, invCam, pd3dDevice );
		RenderLensFlare( pos2, scene.currentCam->position + (-scene.currentCam->position + scene.currentCam->target)*0.3f, invCam, pd3dDevice );
		RenderLensFlare( pos3, scene.currentCam->position + (-scene.currentCam->position + scene.currentCam->target)*0.3f, invCam, pd3dDevice );		
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, D3DZB_USEW );

		pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,  D3DBLEND_SRCALPHA );			
		pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );	
		particles.Render( invCam, pd3dDevice );	

		pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );

		if( p1ON )
		{
			pd3dDevice->SetTexture( 0, GetTexture( "data\\gfx\\naz.jpg" ) );	
			pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, Plate1, 4, 0 );
		}

		if( p2ON )
		{
			pd3dDevice->SetTexture( 0, GetTexture( "data\\gfx\\beton.jpg" ) );
			pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, Plate2, 4, 0 );
		}

		if( p3ON )
		{
			pd3dDevice->SetTexture( 0, GetTexture( "data\\gfx\\juve.jpg" ) );
			pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, Plate3, 4, 0 );
		}

		if( p4ON )
		{
			pd3dDevice->SetTexture( 0, GetTexture( "data\\gfx\\acid.jpg" ) );
			pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, Plate4, 4, 0 );
		}	

		pd3dDevice->SetTexture( 0, NULL );

		pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,  D3DBLEND_SRCALPHA );			
		pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );			
		
		if( Fade )
		{
			pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, FadeV, 4, 0 );				
		}
		
		pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );

		pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,  D3DBLEND_SRCALPHA );			
		pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );			

		if( banner )
		{
			RenderEfxFace( x, y, sizex, sizey, alpha, GetTexture( "data\\textures\\inertia.jpg" ), pd3dDevice );
		}

		if( _3 )
		{
			RenderEfxFace( _3x, _3y, _3sizex, _3sizey, _3alpha, GetTexture( "data\\textures\\3.jpg" ), pd3dDevice );
		}

		if( circle )
		{
			RenderEfxFace( cx1, cy1, s1, s1, calpha, GetTexture( "data\\textures\\circle.jpg" ), pd3dDevice );
			RenderEfxFace( cx2, cy2, s2, s2, calpha, GetTexture( "data\\textures\\circle.jpg" ), pd3dDevice );
			RenderEfxFace( cx3, cy3, s3, s3, calpha, GetTexture( "data\\textures\\circle.jpg" ), pd3dDevice );
			RenderEfxFace( cx4, cy4, s4, s4, calpha, GetTexture( "data\\textures\\circle.jpg" ), pd3dDevice );
		}

		if( line )
		{
			RenderEfxFace( lx1, ly1, 200, 80, calpha, GetTexture( "data\\textures\\line.jpg" ), pd3dDevice );
			RenderEfxFace( lx2, ly2, 200, 80, calpha, GetTexture( "data\\textures\\line.jpg" ), pd3dDevice );
			RenderEfxFace( lx3, ly3, 200, 80, calpha, GetTexture( "data\\textures\\line.jpg" ), pd3dDevice );			

			RenderEfxFace( lx4, ly4, 80, 200, calpha, GetTexture( "data\\textures\\line.jpg" ), pd3dDevice, 1 );
			RenderEfxFace( lx5, ly5, 80, 200, calpha, GetTexture( "data\\textures\\line.jpg" ), pd3dDevice, 1 );
			RenderEfxFace( lx6, ly6, 80, 200, calpha, GetTexture( "data\\textures\\line.jpg" ), pd3dDevice, 1 );			
		}

		pd3dDevice->SetTexture( 0, NULL );
	}		

	if( efxon )
	{
	
		D3DMATRIX matView = CameraMtx( gem_Vector( 0, 0, -10 ), gem_Vector( 0, 0, 20 ), 0 );//mat;	
		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );
		D3DMATRIX matProj = GetD3DMATRIX( ProjectionMtx( 45.0f, 0.5f, 1000.0f, 0.70f ) );

		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );		
		pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION, &matProj );			

		pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, FALSE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, D3DZB_FALSE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,  D3DBLEND_SRCALPHA );			
		pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );					
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE, FALSE );		
		pd3dDevice->SetRenderState( D3DRENDERSTATE_WRAP0, 0 );
		
		pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );		

		pd3dDevice->SetTexture( 0, GetTexture( "data\\textures\\nopee1.jpg" ) );
		
		for( i = 0 ; i<7 ; i++ )
		{		
			pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matBackLocal[i] );		
			pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Plain, 4, NULL );
		}	

		pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
		pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, D3DZB_USEW );
		
	}	
	
	pd3dDevice->EndScene();

	return S_OK;
}

VOID fxDelete_PsychoScene( LPDIRECT3DDEVICE7 pd3dDevice )
{
}


