#include <io.h>
#include <system.h>
#include <stdio.h>
#include <time.h>

#include "back.h"
/*
 * sram distribution
 * (31) 0,1 for differnt face (2,13) for player
 * (3,12) (4,11) (5,10) for enemies
 * (30) 0,1,2 for different face (0,15) for boss
 * (1,14) for bullet
 * (7,8) for firework
 * 19 -- 0 normal --1 begin -- 2 A -- 3 B -- C 4
 * 9 16 17 18 score from thousand
 * 27 28 29 for lifes
 * 20 21 for box
 *
 */
#define IOWR_SRAM_DATA(base, offset, data) \
  IOWR_16DIRECT(base, (offset) * 2, data)
#define IORD_SRAM_DATA(base, offset) \
  IORD_16DIRECT(base, (offset) * 2)



int vadd = 0;
void newBackGroundMusic ()
	{
	  int i =1;
	  while (i < 32){
	        IOWR_16DIRECT (AUDIO_BASE, i*2  , value[vadd]);
	        vadd++;
	        if (vadd >= 131805){
	            vadd = 0;
	        }
	    i++;
	  }
	}


int main()
{
	//////////////////////////////////////////////////////////////////////////////
	//every time want to use the sound effect :piu , use the following two
	//sentences together;
	//			//Sound for dead:
	//		IOWR_16DIRECT (AUDIO_BASE, 0 , 1);
	//		IOWR_16DIRECT (AUDIO_BASE, 0 , 2);
	//
	//		//Sound for hitting:
	//		IOWR_16DIRECT (AUDIO_BASE, 0 , 3);
	// 		IOWR_16DIRECT (AUDIO_BASE, 0 , 4);
	//
	//		//Sound for laughing:
	//		IOWR_16DIRECT (AUDIO_BASE, 0 , 5);
	//		IOWR_16DIRECT (AUDIO_BASE, 0 , 6);
	//////////////////////////////////////////////////////////////////////////


	alt_irq_register(AUDIO_IRQ, NULL, (void*)newBackGroundMusic );
	//define all the variable
    int flag = 0;   // use to determine what state we are

    int gameTime = 0;   // time count
    int score = 0;  // score count
	int finalScore = 0;

    int deadFlag;  //indicates player has been created
    int playerXCoordinate;   //player's leftmost upmost coordinate
    int playerYCoordinate;
    int life;   //indicate how many life still left
    int openMouthTime;	//time period for open mouth animation

    int bossFlag;    //indicates boss has been created
    int bossXCoordinate; //boss's leftmost upmost coordinate
    int bossYCoordinate;
    int bossLife;	//indicate how many life boss still left

    int enemyCount; // number of enemies in the screen up to 8 enemies
    int enemyFlag[9];	//indicate whethor enemy exists max to 10
    int enemyXCoordinate[9];  //enemies' leftmost upmost coordinate
    int enemyYCoordinate[9];
    int fireworkTime;	//time period for firework animation

    int bulletFlag; //indicate bullet created
    int bulletXCoordinate;	//bullet leftmost upmost coordinate
    int bulletYCoordinate;
    int bulletNumber;

    int boxFlag;	//indicate box created
    int boxXCoordinate;
    int boxYCoordinate;

    int playerXSpeed;	//speed for everything
    int playerYSpeed;
    int enemyXSpeed;
    int enemyYSpeed;
    int bossXSpeed;
    int bossYSpeed;
    int bulletXSpeed;
    int boxXSpeed;

    int xLowBound = 0;		// bound for the screen pixels
    int xHighBound = 640;
    int yLowBound = 0;
    int yHighBound = 480;

    int counterTime;	// raise the clock to make a loop longer
    int counterFly;
    int	counterDrop;
    int counterNormal;
    int shine =0;	// variable for dead effect


    IOWR_SRAM_DATA(VGA_BASE,19,1); // init begin display


    //init display all out the screen
    IOWR_SRAM_DATA(VGA_BASE,0,800);
    IOWR_SRAM_DATA(VGA_BASE,1,800);
    IOWR_SRAM_DATA(VGA_BASE,2,800);
    IOWR_SRAM_DATA(VGA_BASE,3,800);
    IOWR_SRAM_DATA(VGA_BASE,4,800);
    IOWR_SRAM_DATA(VGA_BASE,5,800);
    IOWR_SRAM_DATA(VGA_BASE,7,800);
	IOWR_SRAM_DATA(VGA_BASE,20, 800);
    IOWR_SRAM_DATA(VGA_BASE,9,0);
    IOWR_SRAM_DATA(VGA_BASE,16,0);
    IOWR_SRAM_DATA(VGA_BASE,17,0);
    IOWR_SRAM_DATA(VGA_BASE,18,0);
	IOWR_SRAM_DATA(LEDS_BASE, 0, 0);
	IOWR_SRAM_DATA(LEDS_BASE, 1, 0);
	IOWR_SRAM_DATA(LEDS_BASE, 2, 0);
	IOWR_SRAM_DATA(LEDS_BASE, 3, 0);

	int startFlag = 0;
    while(IORD_SRAM_DATA(VGA_BASE, 19) != 0){
		int beginSound = IORD_16DIRECT(AUDIOSLAVE_BASE,0);
		if( beginSound < 20000 || beginSound >46535 || (beginSound>32000 && beginSound< 33000)){
			// threshold move up 1000
			startFlag = 0;
		}else{
			startFlag++;
			if(startFlag > 25){
				startFlag = 0;
				IOWR_SRAM_DATA(VGA_BASE,19,0);
			}
		}
    }


    playerXCoordinate = 40;		// init positions
	playerYCoordinate = 360;
	bossXCoordinate = 550;
	bossYCoordinate = 400;
	bulletXCoordinate = 600;
	bulletYCoordinate = 480;
	boxXCoordinate = 800;
	boxYCoordinate = 800;

	playerYSpeed = 1;	//init speeds
	enemyXSpeed = 1;
	bossXSpeed = 0;
	bossYSpeed = 0;
	bulletXSpeed = 4;
	boxXSpeed = 2;

	deadFlag = 0;	//int flags
	bossFlag = 0;
	bulletFlag = 0;
	boxFlag = 0;
	life = 3;	//init lifes
	bulletNumber = 5;

	int i = 0;	//init for enemyflags
	int j = 0;
	for(i = 0; i < 10; i++){
		enemyFlag[i] = 0;
		enemyXCoordinate[i] = 800;
		enemyYCoordinate[i] = 800;
	}
	enemyCount = 0;

	counterTime = 500;	//init counters
	counterDrop = 500;
	counterFly = 500;
	counterNormal = 500;

	srand(time(NULL));	//init rand seed

	IOWR_SRAM_DATA(VGA_BASE,31, 0);	// init player and boss initial faces
	IOWR_SRAM_DATA(VGA_BASE,30, 0);

	openMouthTime = 0;	//init animation time
	fireworkTime = 0;



	for (; ; ){
		////printf("dfsadfsdfsad");
		// get sound from avalon bus
		int sound = IORD_16DIRECT(AUDIOSLAVE_BASE,0);

		counterTime--;
		//simulate real time
		if(counterTime == 0){
			counterTime = 50000;	//215000 times the clock time
			gameTime = gameTime + 1;
			score = score + 2;
			if(score > 9999){
				score = 9999;
			}
			if(gameTime%10 == 0){
				//printf("%d seconds since game starts \n", gameTime);
			}

			IOWR_SRAM_DATA(LEDS_BASE, 0, score%10);
			IOWR_SRAM_DATA(LEDS_BASE, 1, (score%100)/10);
			IOWR_SRAM_DATA(LEDS_BASE, 2, (score%1000)/100);
			IOWR_SRAM_DATA(LEDS_BASE, 3, score/1000);

			IOWR_SRAM_DATA(VGA_BASE, 18, score%10);
			IOWR_SRAM_DATA(VGA_BASE, 17, (score%100)/10);
			IOWR_SRAM_DATA(VGA_BASE, 16, (score%1000)/100);
			IOWR_SRAM_DATA(VGA_BASE, 9, score/1000);
			// vga score
		}

		//main function
		if( sound < 1700 || sound >64235 || (sound>32000 && sound< 33000)){
			// no sound input case
			counterDrop--;
			//counterFly = 10000;	//problem
			if(counterDrop == 0){
				counterDrop = 500;
				if(flag > 4 && flag <= 13){
					// warning flag is now between 4 to 10
					// shot case
					flag = 0;	//problem
					//printf("shot at %d ------------------- \n", playerYCoordinate);

					// create bullet
					if(bulletFlag == 0 && bulletNumber > 0){
						bulletXCoordinate = 70;
						bulletYCoordinate = playerYCoordinate + 50;
						bulletFlag = 1;
						bulletNumber = bulletNumber - 1;
					}
					//open mouth
					IOWR_SRAM_DATA(VGA_BASE,31, 1);
					openMouthTime = gameTime;
				}else{
					// drop case
					flag = 0;	//problem
					////printf("drop >>>>>>>>>>>>>>>>>>>>\n");

					//player moving ----  drop
					playerYSpeed = 1;
					if(yHighBound - playerYCoordinate >= 90){
						playerYCoordinate = playerYCoordinate + playerYSpeed;
					}
				}
			}

		}else{
			//got sound input case = fly case
			counterFly--;
			counterDrop = 500;	//problem
			if(counterFly == 0){
				////printf("fly <<<<<<<<<<<<<<<<<<<<<<<< \n");
				counterFly = 500;
				flag = flag + 1;

				//printf("%d!!!!!!!!!!!!!!!!!!\n", flag);
				//player moving ----  fly
				playerYSpeed = -3;
				if( (sound > 10000 && sound <30000) || (sound <55535 && sound>35535 )){
					playerYSpeed = -10;
				}
				if(playerYCoordinate - yLowBound >= 100){
					playerYCoordinate = playerYCoordinate + playerYSpeed;
				}
			}
		}


		counterNormal--;
		if(counterNormal == 0){
			//usual event
			counterNormal = 500;

			//shine and super mode after dead
			if(deadFlag == 1){
				if(shine == 10 || shine == 20 || shine == 30 || shine == 40 || shine == 50 || shine == 60 || shine == 70 || shine == 80 || shine == 90 ){
					IOWR_SRAM_DATA(VGA_BASE, 2, 800);
					IOWR_SRAM_DATA(VGA_BASE, 13, 800);
					shine = shine + 1;
				}else if(shine == 100){
					IOWR_SRAM_DATA(VGA_BASE, 2, 800);
					IOWR_SRAM_DATA(VGA_BASE, 13, 800);
					deadFlag = 0;
					shine = 0;
					//printf("super mode over \n");
				}else{

					IOWR_SRAM_DATA(VGA_BASE, 2, playerXCoordinate);
					IOWR_SRAM_DATA(VGA_BASE, 13, playerYCoordinate);
					shine = shine + 1;
				}
			}else{
					IOWR_SRAM_DATA(VGA_BASE, 2, playerXCoordinate);
					IOWR_SRAM_DATA(VGA_BASE, 13, playerYCoordinate);
			}


			//enemy created
			int randNumberSeed = rand()%1000;
			int randNumber = randNumberSeed%100;
			if(randNumber  > 97 && enemyCount < 3){
				//rand is from 0-99, thus 0.01% runs created enemy
				//create enemy of No.(enemyCount + 1)
				i = 0;
				//find the emtpy flag
				while(enemyFlag[i] == 1 && i<5){
					i++;
				}
				//assign random position
				enemyXCoordinate[i] = 620;
				enemyYCoordinate[i] = (randNumberSeed/3) + 10;

				//
				if( enemyYCoordinate[i] >= 100){
					enemyFlag[i] = 1;
					//make sure enemy don't overlap for hardware
					for(j=0; j< i; j++){
						if(abs(enemyYCoordinate[i] - enemyYCoordinate[j]) <= 80 && abs(enemyXCoordinate[i] - enemyXCoordinate[j] <= 60)){
							enemyFlag[i] = 0;
						}
					}
					if(i < 3){
						for(j=i+1; j< 3; j++){
							if(abs(enemyYCoordinate[i] - enemyYCoordinate[j]) <= 80 && abs(enemyXCoordinate[i] - enemyXCoordinate[j] <= 60)){
								enemyFlag[i] = 0;
							}
						}
					}
					if(enemyFlag[i] == 1){
						enemyCount++;
						//printf("an enemy emerge at %d, there are %d enemies \n",enemyYCoordinate[i], enemyCount + 1);
					}
				}
			}


			//enemy engaging
			for(i = 0; i < 3; i++){
				if(enemyFlag[i] == 1){
					enemyXCoordinate[i] = enemyXCoordinate[i] - enemyXSpeed;
					if(enemyXCoordinate[i] < 19){
						enemyFlag[i] = 0;
						enemyCount --;
							IOWR_SRAM_DATA(VGA_BASE, 3+i , 800);
							IOWR_SRAM_DATA(VGA_BASE,12-i, 800);
						//printf("an enemy passed, there are %d enemies \n", enemyCount + 1);
					}else{
							IOWR_SRAM_DATA(VGA_BASE,3+i, enemyXCoordinate[i]);
							IOWR_SRAM_DATA(VGA_BASE,12-i, enemyYCoordinate[i]);
					}
				}
			}



			//boss created
			if(gameTime > 1 && gameTime < 3 && bossFlag == 0){
				//create boss only between a time
				bossFlag = 1;
				//printf("boss created \n");
				bossLife = 1000;
				//assign init position
				bossXCoordinate = 550;
				bossYCoordinate = 400;
				// first face
				IOWR_SRAM_DATA(VGA_BASE,30, 0);
				IOWR_SRAM_DATA(VGA_BASE, 0, 550);
				IOWR_SRAM_DATA(VGA_BASE, 15, 400);
			}
			if(gameTime > 45 && gameTime < 65){
				// second face
				IOWR_SRAM_DATA(VGA_BASE,30, 1);
			}

			if(gameTime > 65 && gameTime < 67){
				//third face and move
				IOWR_SRAM_DATA(VGA_BASE,30, 2);
				bossYSpeed = -2;
				bossXSpeed = 1;
				bossLife = 3;
				//IOWR_16DIRECT (AUDIO_BASE, 0 , 5);
				//IOWR_16DIRECT (AUDIO_BASE, 0 , 6);
			}
			//boss engaging
			if(bossFlag == 1){
				if(bossYCoordinate - yLowBound <= 100){
					bossYSpeed = -bossYSpeed;
				}
				if(yHighBound - bossYCoordinate <= 79){
					bossYSpeed = -bossYSpeed;
				}
				bossXCoordinate = bossXCoordinate - bossXSpeed;
				bossYCoordinate = bossYCoordinate + bossYSpeed;
				if(bossXCoordinate < 20){
					bossFlag = 0;
					//printf("boss passed \n");
					IOWR_SRAM_DATA(VGA_BASE, 0, 800);
					IOWR_SRAM_DATA(VGA_BASE, 15, 800);
					bossXCoordinate = 550;
					bossYCoordinate = 400;
				}else{
					//give it to hardware
					IOWR_SRAM_DATA(VGA_BASE, 0, bossXCoordinate);
					IOWR_SRAM_DATA(VGA_BASE, 15, bossYCoordinate);
				}
			}


			// close mouth
			if(gameTime - openMouthTime > 0){
				//openMouthTime = 10000;
				IOWR_SRAM_DATA(VGA_BASE, 31, 0);

			}


			//bullet engaging
			if(bulletFlag == 1){
				bulletXCoordinate = bulletXCoordinate + bulletXSpeed;
				if(bulletXCoordinate > xHighBound + 10){
					bulletFlag = 0;
				}
				IOWR_SRAM_DATA(VGA_BASE, 1, bulletXCoordinate);
				IOWR_SRAM_DATA(VGA_BASE, 14, bulletYCoordinate);
			}
			//bullet count
			switch(bulletNumber){
			case 0 : {
				IOWR_SRAM_DATA(VGA_BASE,26,800);
				IOWR_SRAM_DATA(VGA_BASE,25,800);
				IOWR_SRAM_DATA(VGA_BASE,24,800);
				IOWR_SRAM_DATA(VGA_BASE,23,800);
				IOWR_SRAM_DATA(VGA_BASE,22,800);
			}break;
			case 1 : {
				IOWR_SRAM_DATA(VGA_BASE,26,430);
				IOWR_SRAM_DATA(VGA_BASE,25,800);
				IOWR_SRAM_DATA(VGA_BASE,24,800);
				IOWR_SRAM_DATA(VGA_BASE,23,800);
				IOWR_SRAM_DATA(VGA_BASE,22,800);
			}break;
			case 2 : {
				IOWR_SRAM_DATA(VGA_BASE,26,430);
				IOWR_SRAM_DATA(VGA_BASE,25,450);
				IOWR_SRAM_DATA(VGA_BASE,24,800);
				IOWR_SRAM_DATA(VGA_BASE,23,800);
				IOWR_SRAM_DATA(VGA_BASE,22,800);
			}break;
			case 3 : {
				IOWR_SRAM_DATA(VGA_BASE,26,430);
				IOWR_SRAM_DATA(VGA_BASE,25,450);
				IOWR_SRAM_DATA(VGA_BASE,24,470);
				IOWR_SRAM_DATA(VGA_BASE,23,800);
				IOWR_SRAM_DATA(VGA_BASE,22,800);
			}break;
			case 4 : {
				IOWR_SRAM_DATA(VGA_BASE,26,430);
				IOWR_SRAM_DATA(VGA_BASE,25,450);
				IOWR_SRAM_DATA(VGA_BASE,24,470);
				IOWR_SRAM_DATA(VGA_BASE,23,490);
				IOWR_SRAM_DATA(VGA_BASE,22,800);
			}break;
			case 5 : {
				IOWR_SRAM_DATA(VGA_BASE,26,430);
				IOWR_SRAM_DATA(VGA_BASE,25,450);
				IOWR_SRAM_DATA(VGA_BASE,24,470);
				IOWR_SRAM_DATA(VGA_BASE,23,490);
				IOWR_SRAM_DATA(VGA_BASE,22,510);
			}break;
			}

			//BOX created
			int randNumberSeed2 = rand()%1000;
			int randNumber2 = randNumberSeed2%100;
			if(randNumber2  > 97 && boxFlag == 0){
				//assign random position
				boxXCoordinate = 620;
				boxYCoordinate = (randNumberSeed/3) + 10;

				if( boxYCoordinate >= 100){
					boxFlag = 1;
					//make sure enemy don't overlap for hardware
					for(j=0; j< 3; j++){
						if(abs(IORD_SRAM_DATA(VGA_BASE, 12-j) - boxYCoordinate) <= 80 && abs(IORD_SRAM_DATA(VGA_BASE, 3+j) - boxXCoordinate <= 60)){
							boxFlag = 0;
						}
					}
					if(boxFlag == 1){
						//printf("an box emerge at %d \n _______________________",boxYCoordinate);
					}
				}
			}
			//box engaging
			if(boxFlag == 1){
				boxXCoordinate = boxXCoordinate - boxXSpeed;
				if(boxXCoordinate < 19){
					boxFlag = 0;
					IOWR_SRAM_DATA(VGA_BASE, 20 , 800);
					IOWR_SRAM_DATA(VGA_BASE,21, 800);
					//printf("a box passed \n");
				}else{
					IOWR_SRAM_DATA(VGA_BASE,20, boxXCoordinate);
					IOWR_SRAM_DATA(VGA_BASE,21, boxYCoordinate);
				}
			}


			//hit boss happens
			if(bulletFlag == 1 && bossFlag == 1 && abs(bulletXCoordinate-bossXCoordinate) <= 40 && bulletYCoordinate - bossYCoordinate <= 80 && bulletYCoordinate - bossYCoordinate >= -25) {
					//assign hit position
					//printf("hit boss happen \n");
					bossLife = bossLife - 1;
					if(bossLife == 0){
						// boss died
						bossFlag = 0;
						IOWR_SRAM_DATA(VGA_BASE,30, 0);
						// provide firework
						IOWR_SRAM_DATA(VGA_BASE, 7 , bossXCoordinate);
						IOWR_SRAM_DATA(VGA_BASE, 8 , bossYCoordinate);
						fireworkTime = gameTime;
						score = score + 200;
					}
						bulletFlag = 0;
						IOWR_SRAM_DATA(VGA_BASE, 1, 800);
						IOWR_SRAM_DATA(VGA_BASE, 14, 800);
						IOWR_SRAM_DATA(VGA_BASE, 0, 800);
						IOWR_SRAM_DATA(VGA_BASE, 15, 800);
						score = score + 30;
						IOWR_16DIRECT (AUDIO_BASE, 0 , 3);
						IOWR_16DIRECT (AUDIO_BASE, 0 , 4);
			}
			//hit enemy happens
			for(i=0; i<3; i++){
				if(bulletFlag == 1 && enemyFlag[i] == 1 && abs(bulletXCoordinate-enemyXCoordinate[i]) <= 40 && bulletYCoordinate - enemyYCoordinate[i] <= 80 && bulletYCoordinate - enemyYCoordinate[i] >= -25) {
						//assign hit position
						//printf("hit enemy happen , there are now %d enemies \n", enemyCount);
						enemyFlag[i] = 0;
						bulletFlag = 0;
						enemyCount--;
						IOWR_SRAM_DATA(VGA_BASE, 1, 800);
						IOWR_SRAM_DATA(VGA_BASE, 14, 800);

						IOWR_SRAM_DATA(VGA_BASE, 3+i , 800);
						IOWR_SRAM_DATA(VGA_BASE,12-i, 800);
						score = score + 20;
						// provide firework
						IOWR_SRAM_DATA(VGA_BASE, 7 , enemyXCoordinate[i]);
						IOWR_SRAM_DATA(VGA_BASE, 8 , enemyYCoordinate[i]);
						IOWR_16DIRECT (AUDIO_BASE, 0 , 3);
						IOWR_16DIRECT (AUDIO_BASE, 0 , 4);
						fireworkTime = gameTime;
				}
			}
			//hit box
			if(bulletFlag == 1 && boxFlag== 1 && abs(bulletXCoordinate-boxXCoordinate) <= 40 && bulletYCoordinate - boxYCoordinate <= 80 && bulletYCoordinate - boxYCoordinate >= -25) {
					//assign hit position
					//printf("hit box happen \n");
					boxFlag = 0;
					bulletFlag = 0;
					bulletNumber = 5;
					IOWR_SRAM_DATA(VGA_BASE, 1, 800);
					IOWR_SRAM_DATA(VGA_BASE, 14, 800);

					IOWR_SRAM_DATA(VGA_BASE, 20 , 800);
					IOWR_SRAM_DATA(VGA_BASE, 21, 800);
			}

			// shutdown firework
			if(gameTime - fireworkTime > 0){
				IOWR_SRAM_DATA(VGA_BASE, 7 , 800);
				IOWR_SRAM_DATA(VGA_BASE, 8 , 800);
			}


			//collision boss happens
			if(deadFlag == 0 && bossFlag == 1 && bossXCoordinate - playerXCoordinate>0 && bossXCoordinate - playerXCoordinate <= 40 && abs(bossYCoordinate - playerYCoordinate) <= 60){
				//assign collision happens
				deadFlag = 1;
				life = life - 1;

		//		IOWR_16DIRECT (AUDIO_BASE, 0 , 1);
		//		IOWR_16DIRECT (AUDIO_BASE, 0 , 2);
				//printf("player is dead contacting boss, has life %d \n", life);
			}
			//collision enemy happens
			for(i=0; i < 3; i++){
				if(deadFlag == 0 && enemyFlag[i] == 1 && enemyXCoordinate[i] - playerXCoordinate>0 && enemyXCoordinate[i] - playerXCoordinate <= 40 && abs(enemyYCoordinate[i] - playerYCoordinate) <= 60){
					//assign collision happens
					deadFlag = 1;
					enemyFlag[i] = 0;
					enemyCount--;
					life = life - 1;

			//		IOWR_16DIRECT (AUDIO_BASE, 0 , 1);
			//		IOWR_16DIRECT (AUDIO_BASE, 0 , 2);
					//printf("player is dead contacting enemy, has life %d \n", life);
					IOWR_SRAM_DATA(VGA_BASE, 3 + i, 800);
					IOWR_SRAM_DATA(VGA_BASE, 12 - i, 800);
				}
			}
			//collision box happens
			if(boxFlag == 1 && boxXCoordinate - playerXCoordinate>0 && boxXCoordinate - playerXCoordinate <= 40 && abs(boxYCoordinate - playerYCoordinate) <= 60){
				//assign collision happens
				boxFlag = 0;
				bulletNumber = bulletNumber + 3;
				if(bulletNumber > 5){
					bulletNumber = 5;
				}
				IOWR_SRAM_DATA(VGA_BASE, 20 , 800);
				IOWR_SRAM_DATA(VGA_BASE, 21, 800);
				//printf("player get bullet, has bullet %d \n", bulletNumber);
			}

			if(life == 3){
				IOWR_SRAM_DATA(VGA_BASE,29,270);
				IOWR_SRAM_DATA(VGA_BASE,28,300);
				IOWR_SRAM_DATA(VGA_BASE,27,330);
			}
			if(life == 2){
				IOWR_SRAM_DATA(VGA_BASE,27,800);
			}
			if(life == 1){
				IOWR_SRAM_DATA(VGA_BASE,28,800);
			}


			//game over happen
			if(life == 0){
				int loop = 0;
                for(loop = 0; loop < 100000; loop++){
                    //create game over
                    IOWR_SRAM_DATA(VGA_BASE,29,800);

                    IOWR_SRAM_DATA(VGA_BASE,0,800);
                    IOWR_SRAM_DATA(VGA_BASE,1,800);
                    IOWR_SRAM_DATA(VGA_BASE,2,800);
                    IOWR_SRAM_DATA(VGA_BASE,3,800);
                    IOWR_SRAM_DATA(VGA_BASE,4,800);
                    IOWR_SRAM_DATA(VGA_BASE,5,800);
                    IOWR_SRAM_DATA(VGA_BASE,7,800);
                    IOWR_SRAM_DATA(VGA_BASE,20, 800);
                    if(finalScore == 0){
                        finalScore = score;
                    }
                    if(finalScore > 200){
                        IOWR_SRAM_DATA(VGA_BASE, 19, 2);
                    }else if(finalScore <= 200 && finalScore > 100){
                        IOWR_SRAM_DATA(VGA_BASE, 19, 3);
                    }else if(finalScore <=100 && finalScore >= 0){
                        IOWR_SRAM_DATA(VGA_BASE, 19, 4);
                    }

                }



                IOWR_SRAM_DATA(VGA_BASE,19,1); // init begin display


                    //init display all out the screen
                    IOWR_SRAM_DATA(VGA_BASE,0,800);
                    IOWR_SRAM_DATA(VGA_BASE,1,800);
                    IOWR_SRAM_DATA(VGA_BASE,2,800);
                    IOWR_SRAM_DATA(VGA_BASE,3,800);
                    IOWR_SRAM_DATA(VGA_BASE,4,800);
                    IOWR_SRAM_DATA(VGA_BASE,5,800);
                    IOWR_SRAM_DATA(VGA_BASE,7,800);
                	IOWR_SRAM_DATA(VGA_BASE,20, 800);
                    IOWR_SRAM_DATA(VGA_BASE,9,0);
                    IOWR_SRAM_DATA(VGA_BASE,16,0);
                    IOWR_SRAM_DATA(VGA_BASE,17,0);
                    IOWR_SRAM_DATA(VGA_BASE,18,0);
                	IOWR_SRAM_DATA(LEDS_BASE, 0, 0);
                	IOWR_SRAM_DATA(LEDS_BASE, 1, 0);
                	IOWR_SRAM_DATA(LEDS_BASE, 2, 0);
                	IOWR_SRAM_DATA(LEDS_BASE, 3, 0);
                	IOWR_SRAM_DATA(VGA_BASE,26,800);
					IOWR_SRAM_DATA(VGA_BASE,25,800);
					IOWR_SRAM_DATA(VGA_BASE,24,800);
					IOWR_SRAM_DATA(VGA_BASE,23,800);
					IOWR_SRAM_DATA(VGA_BASE,22,800);

                    while(IORD_SRAM_DATA(VGA_BASE, 19) != 0){
                		int beginSound = IORD_16DIRECT(AUDIOSLAVE_BASE,0);
                		if( beginSound < 4500 || beginSound >61035 || (beginSound>32000 && beginSound< 33000)){
                			// threshold move up 1000
                			startFlag = 0;
                		}else{
                			startFlag++;
                			if(startFlag > 25){
                				startFlag = 0;
                				IOWR_SRAM_DATA(VGA_BASE,19,0);
                			}
                		}
                    }


                    playerXCoordinate = 40;		// init positions
                	playerYCoordinate = 360;
                	bossXCoordinate = 550;
                	bossYCoordinate = 400;
                	bulletXCoordinate = 600;
                	bulletYCoordinate = 480;
                	boxXCoordinate = 800;
                	boxYCoordinate = 800;

                	playerYSpeed = 1;	//init speeds
                	enemyXSpeed = 1;
                	bossXSpeed = 0;
                	bossYSpeed = 0;
                	bulletXSpeed = 4;
                	boxXSpeed = 2;

                	deadFlag = 0;	//int flags
                	bossFlag = 0;
                	bulletFlag = 0;
                	boxFlag = 0;
                	life = 3;	//init lifes
                	bulletNumber = 5;

                	int i = 0;	//init for enemyflags
                	int j = 0;
                	for(i = 0; i < 10; i++){
                		enemyFlag[i] = 0;
                		enemyXCoordinate[i] = 800;
                		enemyYCoordinate[i] = 800;
                	}
                	enemyCount = 0;

                	counterTime = 500;	//init counters
                	counterDrop = 500;
                	counterFly = 500;
                	counterNormal = 500;

                	srand(time(NULL));	//init rand seed

                	IOWR_SRAM_DATA(VGA_BASE,31, 0);	// init player and boss initial faces
                	IOWR_SRAM_DATA(VGA_BASE,30, 0);

                	openMouthTime = 0;	//init animation time
                	fireworkTime = 0;
                	gameTime = 0;
					openMouthTime = 0;
					bossYSpeed = 0;
					bossXSpeed = 0;
					finalScore = 0;
					score = 0;

            }



			//finish game
			if(gameTime > 50){
				// player survive
				gameTime = 0;
				openMouthTime = 0;
				bossYSpeed = 0;
				bossXSpeed = 0;
				enemyXSpeed = enemyXSpeed * 2;
				bossYSpeed = bossYSpeed * 2;
				bossLife = 1000;
				//printf("time out . next round speed * 2 \n");
				//printf("score is %d", score);
			}


		}
	}
}
