/*
* Starfield Application
*
* University of Abertay Dundee
* May be used for educational purposed only
*
* Author - Dr Henry S Fortuna
*
* $Revision: 1.9 $
* $Date: 2008/01/12 10:35:13 $
*
*/
#include <sps2lib.h>
#include <sps2tags.h>
#include <sps2util.h>
#include <sps2regstructs.h>
#include <assert.h>
#include <memory.h>
#include <signal.h>
#include <sys/time.h>
#include <iostream.h>
#include <stdio.h>
#include "PS2Defines.h"
#include "ps2maths.h"
#include "ps2matrix4x4.h"
#include "pad.h"
#include "sps2wrap.h"
#include "dma.h"
#include "texture.h"
#include "font.h"
#include "primitives.h"
#include "audio.h"


//*** DEFINITIONS
#define OBJECTS 		(100)		// Number of "stars"
#define MAX_Z			(1000.0f) 	// Z values in the game world range from 1 to MAX_Z
#define MIN_Z			(1.0f)
#define MULT			(2)			// Defines how big the game "world is"  in multiples of the screen area.
									// Don't use numbers greater than 6 as this causes visual defects.
									
//***GLOBALS
bool g_bLoop = true;
void sprites();
void GameLogic();
void AnimateSprites();
void GameControls();
void Fire();
void Enemies();
void Collision();
void BackgroundLoad();
void BackgroundRender();
void UserCollision();
void StartLogic();
void MenuLogic();
void InstructionsLogic();
void PauseLogic();
void OverLogic();
void ScoreLogic();
void init();
float x,y,z;
PS2SpriteT Bin[OBJECTS];		//Declare an array of our sprite objects
CTexture Binary;					// The texture for the asteroid
PS2SpriteT Player;
CTexture Ship;
PS2SpriteT Enemy[20];
CTexture Bot;
PS2SpriteT EnemyExplosion[20];
CTexture BotExplosion;
PS2SpriteT UserFire[20];
CTexture UserLaser;
PS2SpriteT EnemyFire[20];
CTexture EnemyLaser;
PS2SpriteT Background;
CTexture BG1;
CTexture BG2;
CTexture BG3;
CTexture BG4;
CTexture BG5;
CTexture BG6;
CTexture BGGame;
CTexture BGPauseCont;
CTexture BGPauseQuit;
CTexture InstrucCont;
CTexture InstrucObj;
CTexture GameOver;
CTexture BGScore;
CFont Font;
CTexture FontTex;
PS2SpriteT Life;
CTexture Lifebar;
AudioDevice DSP0(0), DSP1(1);
SoundSample Explosion("explosion", &DSP0);
SoundSample Laser("laser", &DSP0);
bool fire[20];
bool game;
bool menu;
bool paused;
int bgn;
int score;
int highscore;
int health;
int randenemfire[20];
bool enemyfired[20];
bool enemydeath[20];
bool enemyfire[20];
bool instructions = false;
int firen = 0;
int timer;
int lifeamount;
enum GameState {gamelogic, menulogic, instructionlogic, pauselogic, startlogic, overlogic, scorelogic};
enum GameState GS;

void sig_handle(int sig)
{
	g_bLoop = false;
}

void sprites()
{
	if(!Binary.LoadBitmap("images/binarylarge.bmp", true, false))
	{
		printf("Can't load Texture\n");
		g_bLoop = false;
	}
	
	if(!Ship.LoadBitmap("images/shipfireside.bmp", true, false))
	{
		printf("Can't load texture\n");
		g_bLoop = false;
	}	
	Player.ChangeSize(64,64);
	Player.SetSize(100,100);
	Player.SetAnimCount(3 ,2);

	if(!Bot.LoadBitmap("images/spacebotfireside.bmp", true, false))
	{
		printf("Can't load texture\n");
		g_bLoop = false;
	}	
	for(int n=0; n<20; n++){
		Enemy[n].ChangeSize(64,64);
		Enemy[n].SetSize(50,50);
		Enemy[n].SetAnimCount(20,2);
		Enemy[n].animate = true;
	}
	
	if(!BotExplosion.LoadBitmap("images/spacebotdeathside.bmp", true, false))
	{
		printf("Can't load texture\n");
		g_bLoop = false;
	}
	for(int n=0; n<20; n++){
		EnemyExplosion[n].ChangeSize(64,64);
		EnemyExplosion[n].SetSize(50,50);
		EnemyExplosion[n].SetAnimCount(5,4);
	}

	if(!UserLaser.LoadBitmap("images/laserside.bmp", true, false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	for(int n = 0; n<20; n++){
		UserFire[n].ChangeSize(64,64);
		UserFire[n].SetSize(50,50);
		UserFire[n].SetAnimCount(3,2);
		//UserFire[n].ChangePic(0,0);
		UserFire[n].animate = true;
	}

	if(!EnemyLaser.LoadBitmap("images/enemylaserside.bmp", true, false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	for(int n=0; n<20; n++){
		EnemyFire[n].ChangeSize(64,64);
		EnemyFire[n].SetSize(50,50);
		EnemyFire[n].SetAnimCount(3,2);
		EnemyFire[n].animate = true;
	}

	if(!Lifebar.LoadBitmap("images/life.bmp", true, false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	Life.ChangeSize(128,32);
	Life.SetSize(32,128);
	if(!FontTex.LoadBitmap("images/font.bmp",true, true))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	for(int loop=0;loop <OBJECTS; loop++)
	{	
		Bin[loop].MoveTo	((((rand()%SPS2Manager.GetScreenWidth())-SPS2Manager.GetScreenWidth()/2)*MULT), 
			(((rand()%350)-175)*MULT),				
			//(((rand()%(SPS2Manager.GetScreenHeight()-200))-(SPS2Manager.GetScreenHeight()-200)/2)*MULT), 
							1 + (rand()%200));
		Bin[loop].ChangePic (((rand()%2)*64),0);
	}
	for(int n=0; n < 20; n++)Enemy[n].MoveTo((((rand()%SPS2Manager.GetScreenWidth())-SPS2Manager.GetScreenWidth()/2)*MULT), 
		(((rand()%350)-175)*MULT),1);					
		//(((rand()%(SPS2Manager.GetScreenHeight()-200))-(SPS2Manager.GetScreenHeight()-200)/2)*MULT),1);
}
void BackgroundLoad()
{
	//for(int m=0; m<7; m++){
		Background.ChangeSize(256,256);
		//Background.SetSize(SPS2Manager.GetScreenWidth(), SPS2Manager.GetScreenHeight());
		Background.SetSize(512,640);
	//}
	if(!BG1.LoadBitmap("images/start.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!BG2.LoadBitmap("images/start-pause.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!BG3.LoadBitmap("images/start-game.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!BG4.LoadBitmap("images/start-score.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!BG5.LoadBitmap("images/start-instructions.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!BG6.LoadBitmap("images/start-2.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!BGGame.LoadBitmap("images/background-panel.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!BGPauseCont.LoadBitmap("images/pause-continue.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!BGPauseQuit.LoadBitmap("images/pause-quit.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!InstrucCont.LoadBitmap("images/instructions-cont.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!InstrucObj.LoadBitmap("images/instructions-obj.bmp",true,false))
	{
		printf("Can't Load texture\n");
			g_bLoop = false;
	}
		if(!GameOver.LoadBitmap("images/gameover.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
	if(!BGScore.LoadBitmap("images/background.bmp",true,false))
	{
		printf("Can't Load texture\n");
		g_bLoop = false;
	}
}
void BackgroundRender()
{
	if(bgn==0){
		BG1.Upload(TEXBUF496);
		BG1.Select();
	}
	if(bgn==1){
		BG2.Upload(TEXBUF496);
		BG2.Select();
	}
	if(bgn==2){
		BG3.Upload(TEXBUF496);
		BG3.Select();
	}
	if(bgn==3){
		BG4.Upload(TEXBUF496);
		BG4.Select();
	}
	if(bgn==4){
		BG5.Upload(TEXBUF496);
		BG5.Select();
	}
	if(bgn==5){
		BG6.Upload(TEXBUF496);
		BG6.Select();
	}
	if(bgn==6){
		BGGame.Upload(TEXBUF496);
		BGGame.Select();
	}
	if(bgn==7){
		BGPauseCont.Upload(TEXBUF496);
		BGPauseCont.Select();
	}
	if(bgn==8){
		BGPauseQuit.Upload(TEXBUF496);
		BGPauseQuit.Select();
	}
	if(bgn==9){
		InstrucCont.Upload(TEXBUF496);
		InstrucCont.Select();
	}
	if(bgn==10){
		InstrucObj.Upload(TEXBUF496);
		InstrucObj.Select();
	}
	if(bgn==11){
		GameOver.Upload(TEXBUF496);
		GameOver.Select();
	}
	if(bgn==12){
		BGScore.Upload(TEXBUF496);
		BGScore.Select();
	}
	Background.Render();
}
int main(void)
{
	
	timeval time;
	gettimeofday(&time, NULL);
	srand(time.tv_usec);
	
	SPS2Manager.Initialise(1024);	// 1024 * 4K Pages = 4MB Total
	VIFStaticDMA.Initialise(512);	// 512 * 4K Pages = 2MB Static DMA
	VIFDynamicDMA.Initialise(256);	// 256 * 4K Pages * 2 Buffers =
									// 2MB Dynamic DMA	

	// Initialise control pad 0
	if(!pad_init(PAD_0, PAD_INIT_LOCK | PAD_INIT_ANALOGUE | PAD_INIT_PRESSURE))
	{
		printf("Failed to initialise control pad\n");
		pad_cleanup(PAD_0);
		exit(0);
	}
	
	//***Local declarations
	sprites();
	BackgroundLoad();
	score =0;
	health = 5;
	highscore = 100;
	lifeamount = 128;
	for(int n=0; n < 20; n++){
		Enemy[n].ChangePic(0,0);
		Enemy[n].MoveTo((((rand()%576)-288)*MULT), 
		(((rand()%400)-200)*MULT),1);
		randenemfire[n] = rand()%1000;
	}

	//set starting state
	GS = startlogic;
	bgn=1;


	
	// Register our signal function for every possible signal (i.e. ctrl + c)
	for(int sig=0; sig<128; sig++)
		signal(sig, sig_handle);

	// Set up the DMA packet to clear the screen. We want to clear to blue.
	SPS2Manager.InitScreenClear(0, 0x25, 0x10);
	enable_actuator(0,1,1);
	//*** GAME LOOP
	while(g_bLoop)
	{
		VIFDynamicDMA.Fire();
		
		pad_update(PAD_0);
		// Check for exit condition and Input!
		if((pad[0].buttons & PAD_START)&&(pad[0].buttons & PAD_SELECT)) g_bLoop = false;


		SPS2Manager.BeginScene();	//Start frame******************************
		BackgroundRender();
	
		//set gamestate
		switch (GS)
		{
		case gamelogic:
			GameLogic();
			break;
		case instructionlogic:
			InstructionsLogic();
			break;
		case pauselogic:
			PauseLogic();
			break;
		case startlogic:
			StartLogic();
			break;
		case menulogic:
			MenuLogic();
			break;
		case overlogic:
			OverLogic();
			break;
		case scorelogic:
			ScoreLogic();
		}
			//sets the rumble off when the player scores	
		if(timer > 0){
			set_actuator(0,1,0);
			timer = timer + 1;
		}
		//ends the rumble after a set amount of time
		if(timer == 10){
			timer = 0;
			set_actuator(0,0,0);
		}

		SPS2Manager.EndScene();		//End frame*********************************
		if(pad[0].pressed & PAD_SQUARE){
			SPS2Manager.ScreenShot();
		}	

	}//end of game loop

	DSP0.Close();
	DSP1.Close();

	pad_cleanup(PAD_0);
	
	return 0;
}
void GameLogic()
{
	Life.MoveTo(-220,230,1000);
	GameControls();
	Player.MoveTo(x,y,1000);
		//loop through all the objects
		for(int loop=0; loop <OBJECTS; loop++)		
		{	
			// Render the object - RenderPerspective() is where all the scaling is done
			// Best have a look at this! - it is the key to how it all happens ;)
			Binary.Upload(TEXBUF496);
			Binary.Select();
			Bin[loop].RenderPerspective();					
			
			// Increment object in Z (movement towards screen)
			Bin[loop].MoveDeltaZ();
			
			// Check Z is not outwith range 
			if(Bin[loop].GetZ() > MAX_Z)		
			{	
				// Respawn the object as at the start
				Bin[loop].MoveTo	((((rand()%SPS2Manager.GetScreenWidth())-SPS2Manager.GetScreenWidth()/2)*MULT), 
									(((rand()%350)-175)*MULT),		
					//(((rand()%(SPS2Manager.GetScreenHeight()-200))-(SPS2Manager.GetScreenHeight()-200)/2)*MULT), 
							1 + (rand()%200));
			}				
		}
		AnimateSprites();
		Enemies();
		Collision();
		UserCollision();
		Fire();
		Lifebar.Upload(TEXBUF496);
		Lifebar.Select();
		Life.Render();
		Ship.Upload(TEXBUF496);
		Ship.Select();
		Player.Render();
		

		DSP0.HandleAudio();
		DSP1.HandleAudio();

		FontTex.Upload(TEXBUF480);
		FontTex.Select();

		Font.printfC(  230, 220, 127, 0, 0, 127, "%d", score);
		Font.printfC( -200, 220, 127, 0, 0, 127, "%d", health);
}
void AnimateSprites()
{
	if (Player.animate)
	{
		Player.AnimateOnce();
	} 

	for(int i = 0; i<20; i++)
	{
		if (EnemyFire[i].animate) EnemyFire[i].Animate();
		if (EnemyExplosion[i].animate) EnemyExplosion[i].AnimateOnce();
		if (Enemy[i].animate) Enemy[i].Animate();
		if (UserFire[i].animate)UserFire[i].Animate();
	}

}

void GameControls()
{
	//int firen = 0;
	float xaxisval = pad[0].axes[PAD_AXIS_LX];
	float yaxisval = pad[0].axes[PAD_AXIS_LY];

	x = x + xaxisval*2;
	y = y + yaxisval*2;
	if(y > 175)y=175;
	if(y < -224)y=-224;
	if(x < -288)x=-288;
	if(x > 288)x=288;
	if((yaxisval > 0)&&(y < 175))for(int loop=0; loop<OBJECTS; loop++)Bin[loop].MoveDeltaY(-0.010f*Bin[loop].GetZ());
	if((yaxisval < 0)&&(y > -224))for(int loop=0; loop<OBJECTS; loop++)Bin[loop].MoveDeltaY(0.010f*Bin[loop].GetZ());
	if((xaxisval > 0)&&(x < 288))for(int loop=0; loop<OBJECTS; loop++)Bin[loop].MoveDeltaX(-0.010f*Bin[loop].GetZ());
	if((xaxisval < 0)&&(x > -288))for(int loop=0; loop<OBJECTS; loop++)Bin[loop].MoveDeltaX(0.010f*Bin[loop].GetZ());
	if((pad[0].buttons & PAD_UP)/*&&(game == true)*/&&(y> -224))
	{
		y = y -1;
		//if(y < -224)y=-224;
		for(int loop=0; loop<OBJECTS; loop++)Bin[loop].MoveDeltaY(0.010f*Bin[loop].GetZ());
		/*for(int n=0; n<20; n++)Enemy[n].MoveDeltaY(0.010f*Enemy[n].GetZ());
		for(int firen=0; firen<5; firen++){
			if(fire[firen]==true)UserFire[firen].MoveDeltaY(0.010f*UserFire[firen].GetZ());
		}*/
	}
	if((pad[0].buttons & PAD_DOWN)/*&&(game == true)*/&&(y < 175))
	{
		y = y + 1;
		//if(y > 175)y=175;
		for(int loop=0; loop<OBJECTS; loop++)Bin[loop].MoveDeltaY(-0.010f*Bin[loop].GetZ());
		/*for(int n=0; n<20; n++)Enemy[n].MoveDeltaY(-0.010f*Enemy[n].GetZ());
		for(int firen=0; firen<5; firen++){
			if(fire[firen]==true)UserFire[firen].MoveDeltaY(-0.010f*UserFire[firen].GetZ());
		}*/
	}
	if((pad[0].buttons & PAD_LEFT)/*&&(game == true)*/&&(x > -288))
	{
		x = x - 1;
		//if(x < -256)x = -256;
		for(int loop=0; loop<OBJECTS; loop++)Bin[loop].MoveDeltaX(0.010f*Bin[loop].GetZ());
		/*for(int n=0; n<20; n++)Enemy[n].MoveDeltaX(0.010f*Enemy[n].GetZ());
		for(int firen=0; firen<5; firen++){
			if(fire[firen]==true)UserFire[firen].MoveDeltaX(0.010f*UserFire[firen].GetZ());
		}*/
	}
	if((pad[0].buttons & PAD_RIGHT)/*&&(game == true)*/&&(x < 288))
	{
		x = x + 1;
		//if(x > 256) x = 256;
		for(int loop=0; loop<OBJECTS; loop++)Bin[loop].MoveDeltaX(-0.010f*Bin[loop].GetZ());
		/*for(int n=0; n<20; n++)Enemy[n].MoveDeltaX(-0.010f*Enemy[n].GetZ());
		for(int firen=0; firen<5; firen++){
			if(fire[firen]==true)UserFire[firen].MoveDeltaX(-0.010f*UserFire[firen].GetZ());
		}*/
	}
	if((pad[0].released & PAD_START) /*&& (game == true) && (paused == false)*/)
	{
		GS = pauselogic;
		bgn=7;
	}
	
	if((pad[0].pressed & PAD_CROSS)&&(fire[firen] == false)/*&&(game == true)*/)
	{
		Laser.Play();
		Player.animate = true;
		fire[firen] = true;
		UserFire[firen].MoveTo(x,y,MAX_Z);
		firen = firen + 1;
		if(firen > 19)firen = 0;
	}
	
}
void StartLogic()
{
	if((pad[0].released & PAD_START) /*&& (menu == false) && (game ==false)*/){
		GS = menulogic;
		bgn=2;
	}
}
void MenuLogic()
{	
	
	if((pad[0].pressed & PAD_UP))
	{
		bgn = bgn - 1;
		if(bgn < 2)bgn=4;
	}
	if((pad[0].pressed & PAD_DOWN))
	{
		bgn = bgn + 1;
		if(bgn > 4)bgn=2;
	}
	if(((pad[0].released & PAD_CROSS)||(pad[0].released & PAD_START))/* && (menu == true) && (game == false)*/ && (bgn==4))
	{
		GS = instructionlogic;
		bgn=9;
	}
	if((pad[0].pressed & PAD_TRI) /*&& (menu == true) && (game ==false)*/){
		GS = startlogic;
		bgn =1;
	}
	if(((pad[0].released & PAD_CROSS)||(pad[0].released & PAD_START))/* && (menu == true) && (game == false)*/ && (bgn==2))
	{
		GS = gamelogic;
		bgn=6;
	}
	if(((pad[0].released & PAD_CROSS)||(pad[0].released & PAD_START)) && (bgn==3))
	{
		GS = scorelogic;
		bgn = 12;
	}
}
void InstructionsLogic()
{	
	if(((pad[0].released & PAD_RIGHT)||(pad[0].released & PAD_CROSS))/*&& (instructions == true)&&(bgn==9)*/){
		if(bgn==10){
			GS = startlogic;
			bgn = 1;
		}
		if(bgn==9)bgn=10;
		//if(bgn==10)bgn=9;
	}
	if((pad[0].released & PAD_LEFT) /*&& (instructions == true)&& (bgn==10)*/)
	{
		bgn=9;
		//if(bgn==9)bgn=10;
	}
	if((pad[0].released & PAD_TRI) /*&& (instructions == true)*/){
		GS = menulogic;
		bgn = 4;
	}
}
void PauseLogic()
{	
	if((pad[0].pressed & PAD_DOWN) /*&& (game == true) && (paused == true)*/)
	{
		bgn = bgn + 1;
		if (bgn > 8)bgn=7;
	}
	if((pad[0].pressed & PAD_UP) /*&& (game == true) && (paused == true)*/)
	{
		bgn = bgn - 1;
		if (bgn < 7)bgn = 8;
	}
	if((pad[0].released & PAD_CROSS) /*&& (game == true) && (paused == true)*/ && (bgn==7))
	{
		GS = gamelogic;
		bgn = 6;
	}
	if((pad[0].pressed & PAD_CROSS) /*&& (game == true) && (paused == true)*/ && (bgn==8))
	{
		GS = startlogic;

		x = 0;
		y = 0;
		for(int firel=0; firel<20; firel++)fire[firel]=false;
		for(int n=0; n < 20; n++)
		{
			Enemy[n].MoveTo((((rand()%576)-288)*MULT),(((rand()%400)-200)*MULT),1);		
			randenemfire[n] = rand()%1000;
			enemyfire[n] = false;
		}
			//(((rand()%(SPS2Manager.GetScreenHeight()-200))-(SPS2Manager.GetScreenHeight()-200)/2)*MULT),1);
		for(int loop=0;loop <OBJECTS; loop++)
	{	
		Bin[loop].MoveTo	((((rand()%SPS2Manager.GetScreenWidth())-SPS2Manager.GetScreenWidth()/2)*MULT), 
			(((rand()%350)-175)*MULT),				
			//(((rand()%(SPS2Manager.GetScreenHeight()-200))-(SPS2Manager.GetScreenHeight()-200)/2)*MULT), 
							1 + (rand()%200));
		Bin[loop].ChangePic (((rand()%2)*64),0);
	}
		Life.ChangeSize(128,32);
		Life.SetSize(128,32);
		lifeamount = 128;
		if (score > highscore)highscore = score;
		score =0;
		health = 5;
		bgn = 1;
		firen =0;
	}

}
void OverLogic()
{
	if((pad[0].released & PAD_START)||(pad[0].released & PAD_CROSS))
	{
		GS = startlogic;
		bgn = 1;
	}
}
void ScoreLogic()
{
	FontTex.Upload(TEXBUF480);
	FontTex.Select();
	Font.printfC( 0, 0, 127, 0, 0, 127, "high score: %d", highscore);
	if((pad[0].released & PAD_START)||(pad[0].released & PAD_CROSS))
	{
		GS = startlogic;
		bgn = 1;
	}
	if(pad[0].released & PAD_TRI)
	{
		GS = menulogic;
		bgn = 3;
	}
}
void Fire()
{
	for(int firel=0; firel<20; firel++)
		{
			if(fire[firel] == true){
			UserLaser.Upload(TEXBUF496);
			UserLaser.Select();
			UserFire[firel].RenderPerspective();
			
			UserFire[firel].MoveDeltaZBack();
			if(UserFire[firel].GetZ() < MIN_Z)fire[firel] = false;
			}
		}
	for(int enemyn=0; enemyn<20; enemyn++)
	{
		if(enemyfired[enemyn]==true){
			EnemyLaser.Upload(TEXBUF496);
			EnemyLaser.Select();
			EnemyFire[enemyn].RenderPerspective();
			EnemyFire[enemyn].MoveDeltaZ(0.010f*Enemy[enemyn].GetZ());
			EnemyFire[enemyn].MoveDeltaX(0.01f*x);
			EnemyFire[enemyn].MoveDeltaY(0.01f*y);
			if(EnemyFire[enemyn].GetZ() > MAX_Z)enemyfired[enemyn]=false;
		}
	}
}
void Enemies()
{
	int sleep=0;
	for(int enemyn=0; enemyn<20; enemyn++){
		
			/*if(sleep > 25){
				deathpic[enemyn] = deathpic[enemyn] + 64;
				sleep = 0;
			}
			sleep = sleep + 1;
			BotExplosion.Upload(TEXBUF496);
			BotExplosion.Select();
			EnemyExplosion[enemyn].RenderPerspective();
			if(deathpic[enemyn] > 256){
				enemydeath[enemyn] = false;
				deathpic[enemyn] = 64;
			}
			else EnemyExplosion[enemyn].ChangePic(128,deathpic[enemyn]);*/
		
	Bot.Upload(TEXBUF496);
	Bot.Select();
	Enemy[enemyn].RenderPerspective();
	//if(sleep > 10){
	/*if((Enemy[enemyn].GetZ() < 750)||(enemyfired[enemyn]==true))*/Enemy[enemyn].MoveDeltaZ(/*0.020f*Enemy[enemyn].GetZ()*/);
	/*else 
	{
		firing[enemyn] = firing[enemyn] + 1;
	}*/
	if((Enemy[enemyn].GetZ() > randenemfire[enemyn])&&(enemyfire[enemyn] == false))
	{
		enemyfired[enemyn] = true;
		enemyfire[enemyn] = true;
		EnemyFire[enemyn].MoveTo(Enemy[enemyn].GetX(),Enemy[enemyn].GetY(),Enemy[enemyn].GetZ());
	}
	Enemy[enemyn].MoveDeltaX(0.001f*x);
	Enemy[enemyn].MoveDeltaY(0.001f*y);
	//sleep = 0;
	//}
	sleep = sleep + 1;
	if(Enemy[enemyn].GetZ()> MAX_Z){
		Enemy[enemyn].MoveTo((((rand()%576)-288)*MULT),(((rand()%400)-200)*MULT),1);	
		randenemfire[enemyn] = rand()%1000;
		enemyfire[enemyn] = false;
		//(((rand()%(SPS2Manager.GetScreenHeight()-200))-(SPS2Manager.GetScreenHeight()-200)/2)*MULT),1);
	}
	if(enemydeath[enemyn] == true){

				
			
			BotExplosion.Upload(TEXBUF496);
			BotExplosion.Select();
			EnemyExplosion[enemyn].RenderPerspective();
			if(EnemyExplosion[enemyn].animate == false)
			{
			enemydeath[enemyn] = false;
			}
	}
	}
}

void Collision()
{
	float topenemyy=0;
	float bottomenemyy=0;
	float leftenemyx=0;
	float rightenemyx=0;
	float enemyz=0;
	float toplasery=0;
	float bottomlasery=0;
	float leftlaserx=0;
	float rightlaserx=0;
	float laserz=0;
	for(int enemyn=0; enemyn<20; enemyn++){
		for(int firel=0; firel<20; firel++){
			topenemyy = Enemy[enemyn].GetY() - Enemy[enemyn].GetHeight();
			bottomenemyy = Enemy[enemyn].GetY() + Enemy[enemyn].GetHeight();
			leftenemyx = Enemy[enemyn].GetX() - Enemy[enemyn].GetWidth();
			rightenemyx = Enemy[enemyn].GetX() + Enemy[enemyn].GetWidth();
			enemyz = Enemy[enemyn].GetZ();
			toplasery = UserFire[firel].GetY() - UserFire[firel].GetHeight();
			bottomlasery = UserFire[firel].GetY() + UserFire[firel].GetHeight();
			leftlaserx = UserFire[firel].GetX() - UserFire[firel].GetWidth();
			rightlaserx = UserFire[firel].GetX() + UserFire[firel].GetWidth();
			laserz = UserFire[firel].GetZ();
			if((((rightenemyx > UserFire[firel].GetX())&& (UserFire[firel].GetX() > leftenemyx))||((rightlaserx > Enemy[enemyn].GetX())
				&& (Enemy[enemyn].GetX() > leftlaserx))) && (((bottomenemyy > UserFire[firel].GetY()) && (UserFire[firel].GetY() > topenemyy))
				||((bottomlasery > Enemy[enemyn].GetY())&&(Enemy[enemyn].GetY() > toplasery)))&&(enemyz > laserz)&&(fire[firel] == true))
			{
				enemydeath[enemyn] = true;
				EnemyExplosion[enemyn].MoveTo(Enemy[enemyn].GetX(),Enemy[enemyn].GetY(),Enemy[enemyn].GetZ());
				EnemyExplosion[enemyn].animate= true;
					Enemy[enemyn].MoveTo((((rand()%576)-288)*MULT), 
					(((rand()%400)-200)*MULT),1);
					randenemfire[enemyn] = rand()%1000;
					enemyfire[enemyn] = false;
					Explosion.Play();
					timer = 1;
						//(((rand()%(SPS2Manager.GetScreenHeight()-200))-(SPS2Manager.GetScreenHeight()-200)/2)*MULT),1);
					fire[firel] = false;
					
					score = score + 1;
			}
	}
	}
}
void UserCollision()
{
	float topplayery=0;
	float bottomplayery=0;
	float leftplayerx=0;
	float rightplayerx=0;
	float playerz=0;
	float topenemylasery=0;
	float bottomenemylasery=0;
	float leftenemylaserx=0;
	float rightenemylaserx=0;
	float enemylaserz=0;
	topplayery = y - Player.GetHeight();
	bottomplayery = y + Player.GetHeight();
	leftplayerx = x - Player.GetWidth();
	rightplayerx = x + Player.GetWidth();
	playerz = Player.GetZ()-1;
	for(int enemyn=0; enemyn<20; enemyn++){
		topenemylasery = EnemyFire[enemyn].GetY() - EnemyFire[enemyn].GetHeight();
		bottomenemylasery = EnemyFire[enemyn].GetY() + EnemyFire[enemyn].GetHeight();
		leftenemylaserx = EnemyFire[enemyn].GetX() - EnemyFire[enemyn].GetWidth();
		rightenemylaserx = EnemyFire[enemyn].GetX() + EnemyFire[enemyn].GetWidth();
		enemylaserz = EnemyFire[enemyn].GetZ();
		if((((rightplayerx > EnemyFire[enemyn].GetX())
			&&(EnemyFire[enemyn].GetX() > leftplayerx))
			||((rightenemylaserx > x)
			&&(x > leftenemylaserx)))
			&& (((bottomplayery > EnemyFire[enemyn].GetY())
			&&(EnemyFire[enemyn].GetY() > topplayery))
			||((bottomenemylasery > y)
			&&(topenemylasery > y)))
			&&(enemylaserz > playerz)
			&&(enemyfired[enemyn] == true))
		{
			enemyfired[enemyn] = false;
			health = health - 1;
			Explosion.Play();
			lifeamount = lifeamount - 26;
			if(lifeamount < 0)lifeamount = 0;
			Life.ChangeSize(lifeamount,32);
			Life.SetSize(32,lifeamount);
		}
	}
	if(health < 0)
	{
		GS = overlogic;
		x = 0;
		y = 0;
		for(int firel=0; firel<20; firel++)fire[firel]=false;
		for(int n=0; n < 20; n++)
		{
			Enemy[n].MoveTo((((rand()%576)-288)*MULT),(((rand()%400)-200)*MULT),1);		
			randenemfire[n] = rand()%1000;
			enemyfire[n] = false;
		}
			//(((rand()%(SPS2Manager.GetScreenHeight()-200))-(SPS2Manager.GetScreenHeight()-200)/2)*MULT),1);
		for(int loop=0;loop <OBJECTS; loop++)
	{	
		Bin[loop].MoveTo	((((rand()%SPS2Manager.GetScreenWidth())-SPS2Manager.GetScreenWidth()/2)*MULT), 
			(((rand()%350)-175)*MULT),				
			//(((rand()%(SPS2Manager.GetScreenHeight()-200))-(SPS2Manager.GetScreenHeight()-200)/2)*MULT), 
							1 + (rand()%200));
		Bin[loop].ChangePic (((rand()%2)*64),0);
	}
		Life.ChangeSize(128,32);
		Life.SetSize(128,32);
		lifeamount = 128;
		if (score > highscore)highscore = score;
		score =0;
		health = 5;
		bgn = 11;
		firen = 0;
	}
}
