    // include implementation file

    #define snd sound(2500)
    csprite_object  object[2];
    csprite_object  EnemyWave[4];
    char PlayerInvinsible = 0;
    char PlayerBlink      = 0;

    int  Countdown=0;
    int PalChanged=0;

 /////////////////////////////////////////////////////////////////////////
 //jet statistics
  int StartingJetEnergy = 5;
 /////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////
 //control statistics
  int Continue=10;
 /////////////////////////////////////////////////////////////////////////

 /////////////////////////////////////////////////////////////////////////
 //game statistics
  int WavesPassed = 0;
  int WaveType    = 0;
  int WaveStatus  = 0;
  int ShipStatus  = 0;
 /////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////
   int y_stack[100];
   int x_stack[100];

    char ControlMechanism= 1;
 /////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////
  // wave implementation
    void LoadWaveSprites (void)
    {
    //grab the wave a sprites
	for (int k=0;k<4 ;k++)
	{
	EnemyWave[k].initialize(100,100);
	bmp_grab("D:\\bitmaps\\rocketb.bmp", &EnemyWave[k].sprite,0);
	bmp_grab("D:\\bitmaps\\enemya.bmp",  &EnemyWave[k].sprite,0);
	bmp_grab("D:\\bitmaps\\enemyc.bmp",  &EnemyWave[k].sprite,0);

	}
     }

  void Wave (void)
  {
	 //wave control
   if (WaveStatus==SPRITE_DEAD)
   {
  WaveStatus = 1;

	for (int k=0; k<=4 ;k++)
	{
	EnemyWave[k].sprite.x     = 320+(30)*random(10);
	EnemyWave[k].sprite.y     = 30*(k+1);
	EnemyWave[k].sprite.state = 5;//SPRITE_ALIVE;
	}

   }
  }
	int k;
    int WaveCall (void)
		{

	  int AllKilled=0;

	  //
	  //WaveType=WavesPassed;

	if (WaveStatus == SPRITE_DEAD)return(0);

	for( k=0;k<4;k++)
	{


////////////////////////////////////////////////////////////////////////////
// for the first kind of wave
   if (WaveType==0)
   {
	EnemyWave[k].sprite.curr_frame=0;
	EnemyWave[k].Homer.speed  =  1;
	EnemyWave[k].sprite.speed =  1;


	EnemyWave[k].sprite.x-=1;

	if (random(200) == 1 && EnemyWave[k].sprite.state)
	EnemyWave[k].Home(&object[0]);

	if (random(20) == 1)
	 {
	  if (EnemyWave[k].sprite.y > y_stack[0])
	  {EnemyWave[k].sprite.y--;}
	  else {EnemyWave[k].sprite.y++;}
	 }
   }
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// for the second kind of wave
   if (WaveType==1)
   {
	EnemyWave[k].sprite.curr_frame=1;
	EnemyWave[k].Homer.speed = 6;
	EnemyWave[k].sprite.speed = 1;

	if (EnemyWave[k].sprite.x < x_stack[k<<4]  )
	    {EnemyWave[k].sprite.x++;}
	    else{EnemyWave[k].sprite.x--;}

	if (EnemyWave[k].sprite.y < y_stack[k<<4]  )
	    {EnemyWave[k].sprite.y++;}
	    else{EnemyWave[k].sprite.y--;}

	if (random(200) == 1 && EnemyWave[k].sprite.state)
	EnemyWave[k].Home(&object[0]);

   }
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// for the third kind of wave
   if (WaveType==2)
   {
	EnemyWave[k].sprite.curr_frame=2;
	EnemyWave[k].sprite.speed = 6;
	EnemyWave[k].Homer.speed = 1;

	EnemyWave[k].sprite.x-=(6);

	if (random(20) == 1)
	 {
	  if (EnemyWave[k].sprite.y > y_stack[0])
	  {EnemyWave[k].sprite.y--;}
	  else {EnemyWave[k].sprite.y++;}
	 }


   }
////////////////////////////////////////////////////////////////////////////
// for the fourth kind of wave
   if (WaveType==3)
   {
	EnemyWave[k].sprite.curr_frame=0;

	EnemyWave[k].sprite.speed = 6;
	EnemyWave[k].Homer.speed = 1;

	EnemyWave[k].sprite.x-=(1);


	EnemyWave[k].VerticalVibration(10);
	EnemyWave[k].HorizontalVibration(10);






   }
////////////////////////////////////////////////////////////////////////////
	//check collision

	 if (PlayerInvinsible == 0)
	 {

	 if(EnemyWave[k].sprite.collision(&object[0].sprite))
	 {
	 snd;// sound protocol
	 EnemyWave[k].Explode();
	 EnemyWave[k].sprite.state-=5;
	 object[0].sprite.state-=1;
	 PlayerInvinsible=1;
	 PlayerBlink=1;
	 Countdown=300;

	 }

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
	//check collision

	 if(EnemyWave[k].sprite.collision(&object[0].fire))
	 {
	 snd;// sound protocol
	 EnemyWave[k].Explode();
	 EnemyWave[k].sprite.state-=1;
	 object[0].fire.state-=1;

	 }
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
	//check collision
	 if(EnemyWave[k].sprite.collision(&object[0].HomingFire))
	 {
	 snd;// sound protocol
	 EnemyWave[k].Explode();
	 EnemyWave[k].sprite.state-=1;
	 object[0].HomingFire.state-=1;

	 }
////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
	//check collision
	 if(EnemyWave[k].HomingFire.collision(&object[0].sprite))
	 {
	 snd;// sound protocol
	 object[0].Explode();
	 EnemyWave[k].HomingFire.state=0;
	 object[0].sprite.state-=1;
	 PlayerInvinsible=1;
	 PlayerBlink=1;
	 Countdown=300;
	 }

	 }



      // invisibility
	 if (PlayerInvinsible)
	 {
	 object[0].Smoulder();
	 object[0].Explode();
	 if (Countdown-- < 0)
	 PlayerInvinsible = NULL;
	 PlayerBlink=NULL;
	 }


////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

	EnemyWave[k].sprite.paste_x_db   ();
	EnemyWave[k].HomeCall            ();
	EnemyWave[k].ExplodeCall         ();


	if (EnemyWave[k].sprite.LeftBehindScreen())
	 {
	  EnemyWave[k].sprite.state=SPRITE_DEAD;
	 //snd;

	 }

	 if(EnemyWave[k].sprite.state <= 0)
	   AllKilled++;

	} //end second if
	if (AllKilled == 4)
	{
	WavesPassed++;
	WaveStatus=SPRITE_DEAD;
	return(1);
	}
	return(0);
	} //end wave
  /////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////
  // mother implementation

    void LoadMotherSprites (void)
    {
    // initialize
    object[1].initialize(350,100);
    // fuel up
    object[1].sprite.state=StartingJetEnergy*3;
    //set homing fire speed
    object[1].Homer.speed = 1;
    // sprite speed
    object[1].SpriteSpeed = 1;
    bmp_grab("D:\\bitmaps\\mother_1.bmp",&object[1].sprite,0);

    }

    void Mother (void)
  {
	 //wave control
   if (object[1].sprite.state<=SPRITE_DEAD)
   {
  object[1].sprite.state = 1;

	object[1].sprite.x     = 320;
	object[1].sprite.y     = 30;
	object[1].sprite.state = SPRITE_ALIVE;
   }
  }
	 int MotherCall (void)
	 {
	 char StringBuffer[50];
	 if (object[0].sprite.state<=SPRITE_DEAD)return(0);


    //PrintRomString something to screen

    sprintf(StringBuffer,"Boss-Energy:> %d       ",object[1].sprite.state);
    PrintRomString(1,20,248,StringBuffer,1);


	 //check collision


	 if (PlayerInvinsible == 0)
	 {
	 if(object[0].sprite.collision(&object[1].HomingFire))
	 {
	 snd;// sound protocol
	 object[0].Explode();
	 object[0].Smoulder();
	 object[1].HomingFire.state=SPRITE_DEAD;
	 object[0].sprite.state-=1;
	 PlayerInvinsible=1;
	 PlayerBlink=1;
	 Countdown=300;
	 }

	 if(object[0].HomingFire.collision(&object[1].sprite))
	 {
	 snd;// sound protocol
	 object[0].HomingFire.state=0;
	 object[1].ClassInteger++;
	 object[1].ClassInteger2++;
	 object[1].sprite.state-=1;
	 object[1].Smoulder();
	 object[1].Explode();

	 }

	 if(object[0].fire.collision(&object[1].sprite))
	 {
	 snd;// sound protocol
	 object[0].fire.state=0;
	 object[1].ClassInteger++;
	 object[1].ClassInteger2++;
	 object[1].sprite.state-=1;
	 object[1].Smoulder();

	 }

	 if(object[0].sprite.collision(&object[1].sprite))
	 {
	 snd;// sound protocol
	 object[1].Explode();
	 object[0].sprite.state-=1;
	 object[1].Smoulder();
	 PlayerInvinsible =1;
	 PlayerBlink=1;
	 Countdown=30;

	 }
	 }// end if


	 if (PlayerInvinsible)
	 {
	 object[0].Smoulder();
	 object[0].Explode();

	 if (Countdown-- < 0)
	 PlayerInvinsible = NULL;
	 PlayerBlink=NULL;
	 }


    // bring him nearer
       if (object[1].sprite.x > 220)
	object[1].sprite.x--;


    // home into the bastard
	if (random(6)==0)
	{
	 object[1].Home(&object[0]);
	 object[1].Aim (&object[0]);
	}

    // vertically vibrate it
    object[1].VerticalVibration(0);

    // horizontally vibrate it
    object[1].HorizontalVibration(0);

    // paste the sprite
	 object[1].sprite.paste_x_db();

     //see if anything is to aim
	   object[1].AimCall();
     // exhaust the homing fire
	   if (object[1].HomingFire.state)
	   object[1].HomingFire.RExhaustAir();
     // exhaust sprite air
	   object[1].sprite.RExhaustAir();

     // yeah baby , bust me in my !@#$
	   object[1].ExplodeCall();
     // burn me up
	   object[1].SmoulderCall();
     //see if anything is to home
	   object[1].HomeCall();

	   if (object[1].sprite.state <= 0)
	   return(1);

	  return(0);


	 }
  /////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////
// imagery

      void LoadConstantBitmaps (void)
      {

      // load secondary object graphics
      bitmap_load("D:\\bitmaps\\fire1.bmp",   &BasicFire[0]);
      bitmap_load("D:\\bitmaps\\fire2.bmp",   &BasicFire[1]);
      bitmap_load("D:\\bitmaps\\fire3.bmp",   &BasicFire[2]);
      bitmap_load("D:\\bitmaps\\fire4.bmp",   &BasicFire[3]);
      bitmap_load("D:\\bitmaps\\fire5.bmp",   &BasicFire[4]);
      bitmap_load("D:\\bitmaps\\fire6.bmp",   &BasicFire[5]);



      // the explosion frames
      bitmap_load("D:\\bitmaps\\firea.bmp",  &Explosion[0]);
      bitmap_load("D:\\bitmaps\\fireb.bmp",  &Explosion[1]);
      bitmap_load("D:\\bitmaps\\firec.bmp",  &Explosion[2]);

      // the smoky frames
      bitmap_load("D:\\bitmaps\\smokea.bmp",  &Smoke[0]);
      bitmap_load("D:\\bitmaps\\smokeb.bmp",  &Smoke[1]);
      bitmap_load("D:\\bitmaps\\smokec.bmp",  &Smoke[2]);

      // the plane exhaust
      bitmap_load("D:\\bitmaps\\exhaustl.bmp",  &Exhaust[0]);
      bitmap_load("D:\\bitmaps\\exhaustr.bmp",  &Exhaust[1]);
      // the homing fire frames
      bitmap_load("D:\\bitmaps\\fire_2.bmp",&HFire);

      }

     void LoadCharacterSprites (void)
     {
	 // initialize objects
	 object[0].initialize(100,100);


	 // fill up the energy jet
	 object[0].sprite.state=StartingJetEnergy;

	 // feed objects
	 bmp_grab("D:\\bitmaps\\jet2.bmp",     &object[0].sprite,1);
	 bmp_grab("D:\\bitmaps\\jet2u.bmp",    &object[0].sprite,0);
	 bmp_grab("D:\\bitmaps\\jet2d.bmp",    &object[0].sprite,0);


	 // set objects speed
	 object[0].SpriteSpeed = 4;
	 object[0].FireSpeed =  10;
	 object[0].Homer.speed =  8;
     }


     int AskForContinueScreen (void)
       {
       BITMAP MenuMap;


    nosound();
    FadeAway();
    bitmap_load("D:\\bitmaps\\world.bmp",&MenuMap);

    bitmap_show_buffer_db(&MenuMap,
    (SCREEN_WIDTH-MenuMap.width) >>1,
    (SCREEN_HEIGHT-MenuMap.height) >>1);


    show_double_buffer();
    FadeIn(&MenuMap);

    waitretrace();
    show_double_buffer();
    int TextColor=248;
    char buffer[128];	// HACK
    for (int i=180; i>=100 ; i--)
    {

    bitmap_show_buffer_db(&MenuMap,
    (SCREEN_WIDTH-MenuMap.width) >>1,
    (SCREEN_HEIGHT-MenuMap.height) >>1);
    PrintRomString(10,i-90,TextColor,"game over,",1);

    PrintRomString(10,i-70,TextColor,"your vehicle was totalled due to your,",1);
    PrintRomString(10,i-60,TextColor,"worthless and incompetent skills,",1);

    PrintRomString(10,i-40,TextColor,"do you want to continue?,",1);
    PrintRomString(10,i-30,TextColor,"bang the START button to do so,",1);
    PrintRomString(10,i-20,TextColor,"want to do something stupid ?,",1);
    PrintRomString(10,i-10,TextColor,"bash at BACK button to die,",1);
    sprintf(buffer,                  "you have %d lives left",Continue);
    PrintRomString(10,i,TextColor,buffer,1);
    waitretrace();
    show_double_buffer();
    }

    farfree(MenuMap.data);
    i=100;
    int choice=0;
    #define beep delay(50);sound(4500);delay(50);nosound();
    while(!key_SPACEBAR)
    {
    beep;
    sprintf(buffer," Time Left ::::> %d               ",i);
    PrintRomString(10,190,TextColor,buffer,0);
    if ((key_ESC) || (Continue==0)){choice=1;break;}
    if (i--<0){choice=1;break;}
    else {choice=0;object[0].sprite.state=10;}
    waitretrace();
    show_double_buffer();

    }

   FadeAway();
   bitmap_load("D:\\bitmaps\\Loading.bmp",&MenuMap);
   bitmap_show_buffer_db(&MenuMap,
   (SCREEN_WIDTH-MenuMap.width) >>1,
   (SCREEN_HEIGHT-MenuMap.height) >>1);
   show_double_buffer();
   FadeIn(&MenuMap);


	 if (PalChanged)
	 {ChangePalette('b');}



   farfree(MenuMap.data);
   if (!choice){Continue--;}
   return(choice);

       }






    void ControlSpriteCharacters (void)
    {
    char StringBuffer[20];
    int  FireSelect;

    FireSelect = object[0].sprite.state;
    if (FireSelect > 5)
    FireSelect=5;

    // reset frames
    object[0].sprite.curr_frame=0;
    object[0].Homer.speed   =11-object[0].sprite.state;
    object[0].FireSpeed     =11-object[0].sprite.state;
    object[0].fire.width    =BasicFire[FireSelect].width;
    object[0].fire.height   =BasicFire[FireSelect].height;
    object[0].fire.frames[0]=BasicFire[FireSelect].data;


    //PrintRomString something to screen
    sprintf(StringBuffer,"Jet-Energy ::> %d.",object[0].sprite.state);
    PrintRomString(1,1,248,StringBuffer,1);


    // control this with a keyboard
    if     (ControlMechanism== 1) object[0].KeyboardControl2();
    else if(ControlMechanism== 2) object[0].MouseScanControl2();
    else if(ControlMechanism== 3) object[0].MouseFeelControl2();

/////////////////////////////////////////////////////////////////////////////
//priority queue implementation

     for (int count = 0 ; count < 99 ; count++)
     {x_stack[count]=x_stack[count+1];}
     for (count = 0 ; count < 99  ; count++)
     {y_stack[count]=y_stack[count+1];}
     x_stack[99]=object[0].sprite.x;
     y_stack[99]=object[0].sprite.y;

/////////////////////////////////////////////////////////////////////////////

    // dont let this get out of the screen
	   object[0].InBoundary     ();

    //show the sprites currently alive

    if (PlayerInvinsible)
    {
	if (GameLoopCount%8==1)
	{
	Compliment(PlayerBlink);
	}

	if (PlayerBlink)
	object[0].sprite.paste_x_db();
    }
    else
    {object[0].sprite.paste_x_db();}



	  if (key_Alt || GetButton())
	      {
    // fire into the bastard
	 object[0].Fire();
	      }

	  if (key_Ctrl || GetButton())
	      {
    // fire into the bastard
	 if (object[1].sprite.state==1)
	     object[0].Home(&object[1]);

	   else if (WaveStatus)
	      {
	      object[0].Home(&EnemyWave[random(4)]);
	      }

	      }
	    object[0].sprite.LExhaustAir();


    //see if anything is to explode or smoulder

	   object[0].ExplodeCall();
	   object[0].SmoulderCall();

    //see if anything is to home
	   object[0].HomeCall();

    //see if anything has to fire
	   object[0].RFireCall();
    }


