#ifndef __shootpoint
   #define __shootpoint
   typedef struct
   {
      int x;
      int y;
      int GunType;
      int Counter;
   } shootpnt;
#endif

//-------------------------------------
// Structures
//-------------------------------------
typedef struct
{
   int Credits;
   PLAYER Plr1;
   PLAYER Plr2;
} Foreground;

//-------------------------------------
// Global variables
//-------------------------------------
int FrgndClutY[3];
int FrgndTX, FrgndTY;

//-------------------------------------
// Procedures & functions
//-------------------------------------

//-------------------------------------
// Writes a 2 digits number
//-------------------------------------
inline void WriteNumber (int coorx, int coory, int number, DoubleBuffer *db)
{
   int    i;
   SPRT   *sprite;
   int    NumberU[10] = {0,8,16,24,32,40,48,56,64,72};
   int    NumberV[10] = {0,0,0,0,0,0,0,0,0,0};

   if (number > 99)
      number = 99;

   i = number / 10;
   sprite = db->Get_Spr ();
   setXY0 (sprite, coorx, coory);
   setUV0 (sprite, NumberU[i], NumberV[i]);
   sprite->w = 8;
   sprite->h = 16;
   sprite->clut = GetClut (0,FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);

   i = number - i * 10;
   sprite = db->Get_Spr ();
   setXY0 (sprite, coorx + 9,coory);
   setUV0 (sprite, NumberU[i], NumberV[i]);
   sprite->w = 8;
   sprite->h = 16;
   sprite->clut = GetClut (0,FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);
}

//-------------------------------------
// Draw the remaining bullets in the
// gun
//-------------------------------------
void Draw_Bullet (int player, int bullets, DoubleBuffer *db)
{
   int BulletCoorX[2] = {10, 275};
   int BulletCoorY[2] = {200,200};
   int BulletU[] = { 60, 30,  0,210,180,150,120, 90, 60, 30,  0,198};
   int BulletV[] = {138,138,138,108,108,108,108,108,108,108,108, 64};
   SPRT *sprite;

   sprite = db->Get_Spr ();
   setXY0 (sprite, BulletCoorX[player], BulletCoorY[player]);
   sprite->w = 29;
   sprite->h = 29;
   sprite->u0 = BulletU[bullets];
   sprite->v0 = BulletV[bullets];
   sprite->clut = GetClut (0,FrgndClutY[1] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);
}

//-------------------------------------
// Show the player's score
//-------------------------------------
void Show_Score (int player, int score, DoubleBuffer *db)
{
   int         NumberU[10] = {0,8,16,24,32,0,8,16,24,32};
   int         NumberV[10] = {48,48,48,48,48,56,56,56,56,56};
   int         ScoreX[2] = {15, 232};
   int         ScoreY[2] = {15,15};
   int         PlayerSprV[2] = {48,56};
   int         scrx;
   int         i;
   SPRT        *sprite;

   scrx = ScoreX[player];

   sprite = db->Get_Spr ();
   setXY0 (sprite, scrx, ScoreY[player]);
   sprite->w = 16;
   sprite->h = 8;
   sprite->u0 = 40;
   sprite->v0 = PlayerSprV[player];
   sprite->clut = GetClut (0,FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);
   scrx += 25;

   i = score / 100000;
   score -= i * 100000;
   sprite = db->Get_Spr ();
   setXY0 (sprite, scrx, ScoreY[player]);
   sprite->w = 8;
   sprite->h = 8;
   sprite->u0 = NumberU[i];
   sprite->v0 = NumberV[i];
   sprite->clut = GetClut (0,FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);
   scrx += 9;

   i = score / 10000;
   score -= i * 10000;
   sprite = db->Get_Spr ();
   setXY0 (sprite, scrx, ScoreY[player]);
   sprite->w = 8;
   sprite->h = 8;
   sprite->u0 = NumberU[i];
   sprite->v0 = NumberV[i];
   sprite->clut = GetClut (0,FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);
   scrx += 9;

   i = score / 1000;
   score -= i * 1000;
   sprite = db->Get_Spr ();
   setXY0 (sprite, scrx, ScoreY[player]);
   sprite->w = 8;
   sprite->h = 8;
   sprite->u0 = NumberU[i];
   sprite->v0 = NumberV[i];
   sprite->clut = GetClut (0,FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);
   scrx += 9;

   i = score / 100;
   score -= i * 100;
   sprite = db->Get_Spr ();
   setXY0 (sprite, scrx, ScoreY[player]);
   sprite->w = 8;
   sprite->h = 8;
   sprite->u0 = NumberU[i];
   sprite->v0 = NumberV[i];
   sprite->clut = GetClut (0,FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);
   scrx += 9;

   i = score / 10;
   score -= i * 10;
   sprite = db->Get_Spr ();
   setXY0 (sprite, scrx, ScoreY[player]);
   sprite->w = 8;
   sprite->h = 8;
   sprite->u0 = NumberU[i];
   sprite->v0 = NumberV[i];
   sprite->clut = GetClut (0,FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);
   scrx += 9;

   i = score;
   sprite = db->Get_Spr ();
   setXY0 (sprite, scrx, ScoreY[player]);
   sprite->w = 8;
   sprite->h = 8;
   sprite->u0 = NumberU[i];
   sprite->v0 = NumberV[i];
   sprite->clut = GetClut (0,FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);
}

//-------------------------------------
// Draw a player's life points
//-------------------------------------
inline void Show_LifePoints (int player, int lifepnt, DoubleBuffer *db)
{
   int    starx[2] = {15,292};
   int    deltax[2] = {17,-17};
   int    lifepntx[2] = {32,274};
   int    lifepnty[2] = {25,25};
   int    scrx;
   int    i;
   SPRT   *sprite;

   if (lifepnt < 6)
   {
      scrx = starx[player];
      for (i = 0; i < lifepnt; i++)
      {
         sprite = db->Get_Spr ();
         setXY0 (sprite, scrx,lifepnty[player]);
         setUV0 (sprite, 80,80);
         sprite->w = 16;
         sprite->h = 16;
         sprite->clut = GetClut (0,FrgndClutY[0] + 480);
         SetSemiTrans (sprite, 0);
         db->Add_Spr (sprite, 15);

         scrx += deltax[player];
      }
   }
   else
   {
      sprite = db->Get_Spr ();
      setXY0 (sprite, starx[player],lifepnty[player]);
      setUV0 (sprite, 80,80);
      sprite->w = 16;
      sprite->h = 16;
      sprite->clut = GetClut (0,FrgndClutY[0] + 480);
      SetSemiTrans (sprite, 0);
      db->Add_Spr (sprite, 15);
      WriteNumber (lifepntx[player], lifepnty[player], lifepnt, db);
   }
}

//-------------------------------------
// Draw the remaining bullets in the
// gun (any other than the one by
// default)
//-------------------------------------
void Draw_Remain_Bullet (int plr, int bulltype, int bull, DoubleBuffer *db)
{
   int BulletW[6] = {6,12,12,8,10,8};
   int BulletH[6] = {15,27,32,32,28,21};
   int BulletU[6] = {150,138,96,110,126,118};
   int BulletV[6] = {65,69,64,64,68,75};
   int BulletDeltaX[6] = {7,13,14,9,17,9};
   int BulletCoorX[2] = {12, 296};
   int DeltaX[2] = {1, -1};
   int Delta;
   SPRT *sprite;
   int i;
   int scrx;

   bulltype--;
   Delta = (BulletDeltaX[bulltype]) * DeltaX[plr];

   scrx = BulletCoorX[plr];

   for (i = 0; i < bull; i++)
   {
      sprite = db->Get_Spr ();
      if (i == 18)
         scrx = BulletCoorX[plr];
      if (i >= 18)
         setXY0 (sprite, scrx, 202 - BulletH[bulltype]);
      else
         setXY0 (sprite, scrx, 228 - BulletH[bulltype]);
      sprite->w = BulletW[bulltype];
      sprite->h = BulletH[bulltype];
      sprite->u0 = BulletU[bulltype];
      sprite->v0 = BulletV[bulltype];
      sprite->clut = GetClut (0,FrgndClutY[0] + 480);
      SetSemiTrans (sprite, 0);
      db->Add_Spr (sprite, 15);

      scrx += Delta;
   }
}

//-------------------------------------
// Draw the entire foreground
//-------------------------------------
inline void Draw_Foreground (Foreground *frgnd, DoubleBuffer *db, int select, int vabnbr)
{
   int      i;
   SPRT     *sprite;
   int      lifepnt;
   DR_MODE  *drmode;

   //----------------------------------
   if ((frgnd->Plr1.Bullets == 0) && (frgnd->Plr1.Lifepnt))
   {
      if (VSync (-1) & 16)
      {
         sprite = db->Get_Spr ();          // Write "RELOAD YOUR GUN" for
         setXY0 (sprite, 40, 98);          // player 1 if necessary
         setUV0 (sprite, 0,64);
         sprite->w = 80;
         sprite->h = 44;
         sprite->clut = GetClut (0, FrgndClutY[0] + 480);
         SetSemiTrans (sprite, 0);
         db->Add_Spr (sprite, 15);
      }
   }

   if ((frgnd->Plr2.Bullets == 0) && (frgnd->Plr2.Lifepnt))
   {
      if (!(VSync (-1) & 16))
      {
         sprite = db->Get_Spr ();          // Write "RELOAD YOUR GUN" for
         setXY0 (sprite, 200, 98);         // player 2 if necessary
         setUV0 (sprite, 0,64);
         sprite->w = 80;
         sprite->h = 44;
         sprite->clut = GetClut (0, FrgndClutY[0] + 480);
         SetSemiTrans (sprite, 0);
         db->Add_Spr (sprite, 15);
      }
   }

   //----------------------------------
   sprite = db->Get_Spr ();             // Show the credits
   setXY0 (sprite, 160 - 48 / 2, 15);   //
   setUV0 (sprite, 194,40);
   sprite->w = 48;
   sprite->h = 8;
   sprite->clut = GetClut (0, FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 15);
   WriteNumber (160 - 9,25, frgnd->Credits, db);

   //----------------------------------
   Show_Score (0, frgnd->Plr1.Score, db);   // Show the players's scores
   Show_Score (1, frgnd->Plr2.Score, db);   //

   //----------------------------------
   if (frgnd->Plr1.Lifepnt)             // Show the player 1's life points
   {                                    //
      lifepnt = frgnd->Plr1.Lifepnt;
      if (lifepnt > 99)
         lifepnt = 99;
      Show_LifePoints (0, lifepnt, db);
      frgnd->Plr1.Counter = 20 * 60;
   }
   else
   {
      if ((frgnd->Credits) && (frgnd->Plr1.Counter > 59))
      {
         sprite = db->Get_Spr ();       // Player 1 is dead... but there are
         setXY0 (sprite, 15,25);        // still credits!  So write CONTINUE n
         setUV0 (sprite, 56,48);
         sprite->w = 68;
         sprite->h = 16;
         sprite->clut = GetClut (0,FrgndClutY[0] + 480);
         SetSemiTrans (sprite, 0);
         db->Add_Spr (sprite, 15);

         WriteNumber (92,25, frgnd->Plr1.Counter / 60, db);
         if ((frgnd->Plr1.Counter-- % 60) == 0)
            PlaySFX (vabnbr, 5, 127,0);

         if ((frgnd->Plr2.Lifepnt > 0) && (!(VSync (-1) & 16)))
         {                              
            sprite = db->Get_Spr ();    // If player 2 is still playing, also
            setXY0 (sprite, 48,104);    // write "PLAYER 1 TERMINATED"
            setUV0 (sprite, 206,16);
            sprite->w = 48;
            sprite->h = 16;
            sprite->clut = GetClut (0,FrgndClutY[0] + 480);
            SetSemiTrans (sprite, 0);
            db->Add_Spr (sprite, 15);

            sprite = db->Get_Spr ();
            setXY0 (sprite, 105,104);
            setUV0 (sprite, 0,32);
            sprite->w = 8;
            sprite->h = 16;
            sprite->clut = GetClut (0,FrgndClutY[0] + 480);
            SetSemiTrans (sprite, 0);
            db->Add_Spr (sprite, 15);

            sprite = db->Get_Spr ();
            setXY0 (sprite, 37,121);
            setUV0 (sprite, 120,16);
            sprite->w = 86;
            sprite->h = 16;
            sprite->clut = GetClut (0,FrgndClutY[0] + 480);
            SetSemiTrans (sprite, 0);
            db->Add_Spr (sprite, 15);
         }
      }
      else
      {
         if (frgnd->Plr1.Counter-- > -120)
         {
            SetFontColor (1);           // Player 1 is dead and there's no
            FontLeftOn (15,25);         // credit left.
            Print ("GAME OVER");
            frgnd->Plr1.Counter--;
         }
         else
         {
            if (PleaseWait[0])
            {
               SetFontColor (1);
               FontLeftOn (15,25);
               Print ("PLEASE WAIT");
            }
            else
            {
               sprite = db->Get_Spr ();    // Player 1 is dead and there's no
               setXY0 (sprite, 15,25);     // credit left.  Write PRESS START...
               setUV0 (sprite, 16,32);
               sprite->w = 90;
               sprite->h = 16;
               sprite->clut = GetClut (0,FrgndClutY[0] + 480);
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);
            }
         }
      }
   }

   if (frgnd->Plr2.Lifepnt)             // Show the player 2's life points
   {                                    //
      lifepnt = frgnd->Plr2.Lifepnt;
      if (lifepnt > 99)
         lifepnt = 99;
      Show_LifePoints (1, lifepnt, db);
      frgnd->Plr2.Counter = 20 * 60;
   }
   else
   {
      if ((frgnd->Credits) && (frgnd->Plr2.Counter > 59))
      {
         sprite = db->Get_Spr ();       // Player 2 is dead... but there are
         setXY0 (sprite, 215,25);       // still credits!  So write CONTINUE n
         setUV0 (sprite, 56,48);
         sprite->w = 68;
         sprite->h = 16;
         sprite->clut = GetClut (0,FrgndClutY[0] + 480);
         SetSemiTrans (sprite, 0);
         db->Add_Spr (sprite, 15);

         WriteNumber (293,25, frgnd->Plr2.Counter / 60, db);
         if ((frgnd->Plr2.Counter-- % 60) == 0)
            PlaySFX (vabnbr, 5, 0,127);

         if ((frgnd->Plr1.Lifepnt > 0) && (!(VSync (-1) & 16)))
         {
            sprite = db->Get_Spr ();    // If player 2 is still playing, also
            setXY0 (sprite, 208,104);   // write "PLAYER 1 TERMINATED"
            setUV0 (sprite, 206,16);
            sprite->w = 48;
            sprite->h = 16;
            sprite->clut = GetClut (0,FrgndClutY[0] + 480);
            SetSemiTrans (sprite, 0);
            db->Add_Spr (sprite, 15);

            sprite = db->Get_Spr ();
            setXY0 (sprite, 265,104);
            setUV0 (sprite, 8,32);
            sprite->w = 8;
            sprite->h = 16;
            sprite->clut = GetClut (0,FrgndClutY[0] + 480);
            SetSemiTrans (sprite, 0);
            db->Add_Spr (sprite, 15);

            sprite = db->Get_Spr ();
            setXY0 (sprite, 197,121);
            setUV0 (sprite, 120,16);
            sprite->w = 86;
            sprite->h = 16;
            sprite->clut = GetClut (0,FrgndClutY[0] + 480);
            SetSemiTrans (sprite, 0);
            db->Add_Spr (sprite, 15);
         }
      }
      else
      {
         if (frgnd->Plr2.Counter-- > -120)
         {
            SetFontColor (1);           // Player 2 is dead and there's no
            FontLeftOn (227,25);        // credit left.
            Print ("GAME OVER");
            frgnd->Plr2.Counter--;
         }
         else
         {
            if (PleaseWait[1])
            {
               SetFontColor (1);
               FontRightOn (305,25);
               Print ("PLEASE WAIT");
            }
            else
            {
               sprite = db->Get_Spr ();    // Player 2 is dead and there's no
               setXY0 (sprite, 219,25);    // credit left.  Write PRESS START...
               setUV0 (sprite, 16,32);
               sprite->w = 90;
               sprite->h = 16;
               sprite->clut = GetClut (0,FrgndClutY[0] + 480);
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);
            }
         }
      }
   }

   //----------------------------------
   if (!select)
   {
      if ((frgnd->Plr1.Lifepnt) || (DemoMode))
      {
         if (frgnd->Plr1.BulletType)
            Draw_Remain_Bullet (0, frgnd->Plr1.BulletType, frgnd->Plr1.Bullets, db);
         else
         {
            Draw_Bullet (0, frgnd->Plr1.Bullets >> 1, db);
            if ((frgnd->Plr1.Bullets) && ((frgnd->Plr1.Bullets & 3) != 2))
               frgnd->Plr1.Bullets--;
         }
      }

      if ((frgnd->Plr2.Lifepnt) || (DemoMode))
      {
         if (frgnd->Plr2.BulletType)
            Draw_Remain_Bullet (1, frgnd->Plr2.BulletType, frgnd->Plr2.Bullets, db);
         else
         {
            Draw_Bullet (1, frgnd->Plr2.Bullets >> 1, db);
            if ((frgnd->Plr2.Bullets) && ((frgnd->Plr2.Bullets & 3) != 2))
               frgnd->Plr2.Bullets--;
         }
      }
   }

   drmode = db->Get_DrMode ();
   RECT tww = {FrgndTX,FrgndTY, 256,256};
   SetDrawMode (drmode, 0, 0, GetTPage (1, 0, FrgndTX,FrgndTY), &tww);
   db->Add_DrMode (drmode, 15);
}

//-------------------------------------
// Draw gun cursors
//-------------------------------------
void Draw_Gun_Cursor (Foreground *frgnd, DoubleBuffer *db, int drawit)
{
   SPRT *sprite;
   DR_MODE *drmode;

   if ((frgnd->Plr1.Lifepnt > 0) && (frgnd->Plr1.Bullets) && ((gun[0]->id == PADID_CON) || (drawit)))
   {
      sprite = db->Get_Spr ();
      setXY0 (sprite, (frgnd->Plr1.GunX) - 12, frgnd->Plr1.GunY - 12);
      setUV0 (sprite, 228,64);
      sprite->w = 24;
      sprite->h = 24;
      sprite->clut = GetClut (0,FrgndClutY[0] + 480);
      SetSemiTrans (sprite, 0);
      db->Add_Spr (sprite, 18);
   }

   if ((frgnd->Plr2.Lifepnt > 0) && (frgnd->Plr2.Bullets) && ((gun[1]->id == PADID_CON) || (drawit)))
   {
      sprite = db->Get_Spr ();
      setXY0 (sprite, frgnd->Plr2.GunX - 12, frgnd->Plr2.GunY - 12);
      setUV0 (sprite, 90,138);
      sprite->w = 24;
      sprite->h = 24;
      sprite->clut = GetClut (0,FrgndClutY[0] + 480);
      SetSemiTrans (sprite, 0);
      db->Add_Spr (sprite, 18);
   }

   drmode = db->Get_DrMode ();
   RECT tww = {FrgndTX,FrgndTY, 256,256};
   SetDrawMode (drmode, 0, 0, GetTPage (1, 0, FrgndTX,FrgndTY), &tww);
   db->Add_DrMode (drmode, 18);
}

//-------------------------------------
// Initialize some foreground shit.
//-------------------------------------
void Init_Foreground (void)
{
   GetFontClutNumber (&FrgndClutY[0], &FrgndClutY[1], &FrgndClutY[2]);
   GetFontTextureCoor (&FrgndTX, &FrgndTY);
}

//---------------------------------------------------------------------------
// Bullet holes management
//---------------------------------------------------------------------------

#define  MAXHOLES  50
shootpnt BulletHoles[MAXHOLES];
int      BulletHolesLayer[MAXHOLES];
int      BulletHolesCtr;

//-------------------------------------
// Reinitialize all the bullet holes
//-------------------------------------
void InitBulletHoles (void)
{
   BulletHolesCtr = 0;
}

//-------------------------------------
// Add a bullet hole in the background
//-------------------------------------
void AddBulletHole (shootpnt *shot, int layer)
{
   int i, j;

   if (shot->GunType != 2)              // Add a bullet hole...
   {                                    //
      i = BulletHolesCtr % MAXHOLES;
      BulletHolesCtr++;
      BulletHoles[i].x = shot->x;
      BulletHoles[i].y = shot->y;
      BulletHoles[i].GunType = shot->GunType;
      BulletHolesLayer[i] = layer;
   }
   else
   {
      for (j = 0; j < 3; j++)           // Or three if the weapon is a
      {                                 // grenade gun.
         i = BulletHolesCtr % MAXHOLES;
         BulletHolesCtr++;
         BulletHoles[i].x = shot->x - 10 + (rand () % 20);
         BulletHoles[i].y = shot->y - 10 + (rand () % 20);
         BulletHoles[i].GunType = shot->GunType;
         BulletHolesLayer[i] = layer;
      }
   }
}

//-------------------------------------
// Draw all the bullet holes
//-------------------------------------
void DrawBulletHoles (DoubleBuffer *db, int bkdx, int bkdy)
{
   int SprU[] = {166,166,166,182,166,176,166};
   int SprV[] = { 66, 66, 92, 75, 66, 66, 66};
   int SprW[] = {  2,  2,  8, 16,  2,  6,  2};
   int SprH[] = {  2,  2,  8, 16,  2,  5,  2};
   SPRT *sprite;
   DR_MODE *dr_mode;
   int i, j, k;

   if (BulletHolesCtr >= MAXHOLES)
      j = MAXHOLES;
   else
      j = BulletHolesCtr;

   for (i = 0; i < j; i++)
   {
      k = BulletHoles[i].GunType;
      sprite = db->Get_Spr ();
      setXY0 (sprite, BulletHoles[i].x + bkdx - (SprW[k] >> 1),
                      BulletHoles[i].y + bkdy - (SprH[k] >> 1));
      sprite->clut = GetClut (0, FrgndClutY[0] + 480);
      sprite->w = SprW[k];
      sprite->h = SprH[k];
      sprite->u0 = SprU[k];
      sprite->v0 = SprV[k];
      SetSemiTrans (sprite, 0);
      db->Add_Spr (sprite, BulletHolesLayer[i]);

      RECT tww = {FrgndTX,FrgndTY, 256,256};
      dr_mode = db->Get_DrMode ();
      SetDrawMode (dr_mode, 0, 0, GetTPage (1, 0, FrgndTX,FrgndTY), &tww);
      db->Add_DrMode (dr_mode, BulletHolesLayer[i]);
   }
}

//---------------------------------------------------------------------------
// Everything that has to do with enemies firing at players
//---------------------------------------------------------------------------

#define  MAXSHOOT  10                   // Draw up to 10 firing at a time
shootpnt ShootPoint[MAXSHOOT];          //
int WhichSide[MAXSHOOT];                //
int RedSpotX[MAXSHOOT];                 // 
int RedSpotY[MAXSHOOT];                 //
int WhichSPoint[2] = {-1,-1};           // Only one damage per player

//-------------------------------------
//
//-------------------------------------
void DumpFiring (void)
{
   char mardure[10];

   itoa (WhichSPoint[0], mardure);
   FontCenterOn (80, 220);
   SetFontColor (1);
   Print (mardure);

   itoa (WhichSPoint[1], mardure);
   FontCenterOn (240, 220);
   SetFontColor (1);
   Print (mardure);
}

//-------------------------------------
// Initialize firing...
//-------------------------------------
void InitFiring (void)
{
   int i;

   for (i = 0; i < MAXSHOOT; i++)
      ShootPoint[i].Counter = 0;
   WhichSPoint[0] = -1;
   WhichSPoint[1] = -1;
}

//-------------------------------------
// Add a new enemy firing
//-------------------------------------
void AddFiring (shootpnt *shot, Foreground *frgnd, int bkdx, int bkdy)
{
   int i, j;
   char counter[23] = {10+50,14+50,10+50,14+50,14+50,50,50,50,14+50,50,50,50,50,50,50,50,50,50,50,50,50,14+50,5+50};

   j = 0;                               // Find a free space. If none, over-
   for (i = 1; i < MAXSHOOT; i++)       // write the oldest one
   {
      if (ShootPoint[i].Counter < ShootPoint[j].Counter)
         j = i;
   }

   if (shot->GunType == 7)      // Grenade's special fuckin' case.
   {
      if (DemoMode)
         return;
      if ((frgnd->Plr1.Lifepnt) && (frgnd->Plr2.Lifepnt))
      {
         if ((shot->x + bkdx) < 160)
            frgnd->Plr1.Lifepnt--;
         else
            frgnd->Plr2.Lifepnt--;
      }
      else if (frgnd->Plr1.Lifepnt)
         frgnd->Plr1.Lifepnt--;
      else
         frgnd->Plr2.Lifepnt--;
      return;
   }

   ShootPoint[j].x = shot->x;
   ShootPoint[j].y = shot->y;
   ShootPoint[j].GunType = shot->GunType;
   ShootPoint[j].Counter = counter[ShootPoint[j].GunType];

   if (((frgnd->Plr1.Lifepnt > 0) && (frgnd->Plr2.Lifepnt > 0)) || (DemoMode))
   {
      if (((ShootPoint[j].x + bkdx) < 160) && (WhichSPoint[0] == -1))
      {
         WhichSPoint[0] = j;
         if (!DemoMode)
            frgnd->Plr1.Lifepnt--;
         if (frgnd->Plr1.BulletType != 0)
         {
            frgnd->Plr1.BulletType = 0;
            frgnd->Plr1.Bullets = 23;
         }
         WhichSide[j] = 1;
         RedSpotX[j] = 80 - ((80 - ShootPoint[j].x) / 2);
         RedSpotY[j] = 180 - ((180 - ShootPoint[j].y) / 2);
      }
      else if (((ShootPoint[j].x + bkdx) > 159) && (WhichSPoint[1] == -1))
      {
         WhichSPoint[1] = j;
         if (!DemoMode)
            frgnd->Plr2.Lifepnt--;
         if (frgnd->Plr2.BulletType != 0)   // When the player is shot, he
         {                                  // looses his weapon
            frgnd->Plr2.BulletType = 0;
            frgnd->Plr2.Bullets = 23;
         }
         WhichSide[j] = 2;
         RedSpotX[j] = 240 - ((240 - ShootPoint[j].x) / 2);
         RedSpotY[j] = 180 - ((180 - ShootPoint[j].y) / 2);
      }
   }
   else
   {
      WhichSide[j] = 0;
      if ((frgnd->Plr1.Lifepnt > 0) && (WhichSPoint[0] == -1))
      {
         WhichSPoint[0] = j;
         frgnd->Plr1.Lifepnt--;
         if (frgnd->Plr1.BulletType != 0)
         {
            frgnd->Plr1.BulletType = 0;
            frgnd->Plr1.Bullets = 23;
         }
         RedSpotX[j] = 160 - ((160 - ShootPoint[j].x) / 2);
         RedSpotY[j] = 180 - ((180 - ShootPoint[j].y) / 2);

      }
      else if ((frgnd->Plr2.Lifepnt > 0) && (WhichSPoint[1] == -1))
      {
         WhichSPoint[1] = j;
         frgnd->Plr2.Lifepnt--;
         if (frgnd->Plr2.BulletType != 0)   // When the player is shot, he
         {                                  // looses his weapon
            frgnd->Plr2.BulletType = 0;
            frgnd->Plr2.Bullets = 23;
         }
         RedSpotX[j] = 160 - ((160 - ShootPoint[j].x) / 2);
         RedSpotY[j] = 180 - ((180 - ShootPoint[j].y) / 2);
      }
   }
}

//-------------------------------------
// Add a new firing
//-------------------------------------
void AddFlash (shootpnt *shot)
{
   int i, j;

   j = 0;                               // Find a free space. If none, over-
   for (i = 1; i < MAXSHOOT; i++)       // write the oldest one
   {
      if (ShootPoint[i].Counter < ShootPoint[j].Counter)
         j = i;
   }

   ShootPoint[j].x = shot->x;
   ShootPoint[j].y = shot->y;
   ShootPoint[j].GunType = 20;  // Flash
   ShootPoint[j].Counter = 64;
}

//-------------------------------------
// Draw all firing
//-------------------------------------
u_char SprUBMG[2] = {174,144};   // For the big machine gun
u_char SprVBMG[2] = {138,153};
u_char SprWBMG[2] = { 16, 32};
u_char SprHBMG[2] = { 15, 31};

void DrawFiring (DoubleBuffer *db, int bkdx, int bkdy, int vabnbr)
{
   int i, j;
   POLY_F4  *plain;
   SPRT *sprite;
   POLY_FT4 *polygon;
   DR_MODE *dr_mode;
   int x1,y1;
   u_char SprUSG[2] = {114,130};    // For the shotgun
   u_char SprVSG[2] = {138,138};
   u_char SprWSG[2] = {  6, 14};
   u_char SprHSG[2] = {  5, 13};
   u_char SprUMG[2] = {120,144};    // For the machine gun
   u_char SprVMG[2] = {138,138};
   u_char SprWMG[2] = { 10, 16};
   u_char SprHMG[2] = {  9, 13};

   for (i = 0; i < MAXSHOOT; i++)
   {
      if ((ShootPoint[i].Counter == 59) && (ShootPoint[i].GunType != 8) &&
          (ShootPoint[i].GunType != 20))
      {                                     // Time for the player to say
         if (RedSpotX[i] < 160)             // "arghhh" ?
            PlaySFX (vabnbr, 14, 127,0);
         else
            PlaySFX (vabnbr, 14, 0,127);
      }

      if (ShootPoint[i].Counter > 0)
      {
         if ((((ShootPoint[i].Counter % 5) == 0) ||         // Turn screen
             (((ShootPoint[i].Counter + 1) % 5) == 0)) &&   // to red ?
             (ShootPoint[i].GunType != 20) &&
             ((i == WhichSPoint[0]) || (i == WhichSPoint[1])))
         {
            plain = db->Get_Plain ();
            if (WhichSide[i] == 0)
               setXY4 (plain, 0,0, 319,0, 0,239, 319,239);
            else if (WhichSide[i] == 1)
               setXY4 (plain, 0,0, 159,0, 0,239, 159,239);
            else
               setXY4 (plain, 160,0, 319,0, 160,239, 319,239);
            setRGB0 (plain, 128,0,0);
            db->Add_Plain (plain, 15);
         }

         if (ShootPoint[i].Counter > 50)
         {
            if (ShootPoint[i].GunType == 22)
            {
               POLY_F4 *plain;
               plain = db->Get_Plain ();        // Draw the laser beam
               setRGB0 (plain, 255,255,255);
               setXY4 (plain, ShootPoint[i].x + bkdx, ShootPoint[i].y + bkdy,
                              ShootPoint[i].x + bkdx, ShootPoint[i].y + bkdy,
                              ShootPoint[i].x - 5 + bkdx, 460 + bkdy,
                              ShootPoint[i].x + 5 + bkdx, 460 + bkdy);
               db->Add_Plain (plain, 14);
            }
            if (ShootPoint[i].GunType == 21)
            {
               j = ShootPoint[i].Counter % 2;
               sprite = db->Get_Spr ();
               setXY0 (sprite, ShootPoint[i].x - (SprWBMG[j] >> 1) + bkdx,
                       ShootPoint[i].y - (SprHBMG[j] >> 1) + bkdy);
               sprite->clut = GetClut (0, FrgndClutY[0] + 480);
               sprite->w = SprWBMG[j];
               sprite->h = SprHBMG[j];
               sprite->u0 = SprUBMG[j];
               sprite->v0 = SprVBMG[j];
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);
            }
            else if (ShootPoint[i].GunType == 4)
            {
               j = ShootPoint[i].Counter % 2;
               sprite = db->Get_Spr ();
               setXY0 (sprite, ShootPoint[i].x - (SprWMG[j] >> 1) + bkdx,
                       ShootPoint[i].y - (SprHMG[j] >> 1) + bkdy);
               sprite->clut = GetClut (0, FrgndClutY[0] + 480);
               sprite->w = SprWMG[j];
               sprite->h = SprHMG[j];
               sprite->u0 = SprUMG[j];
               sprite->v0 = SprVMG[j];
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);
            }
            else if ((ShootPoint[i].GunType == 1) ||
                     (ShootPoint[i].GunType == 3))
            {
               if (ShootPoint[i].Counter > 55)
                  j = 0;
               else
                  j = 1;
               sprite = db->Get_Spr ();
               setXY0 (sprite, ShootPoint[i].x - (SprWSG[j] >> 1) + bkdx,
                               ShootPoint[i].y - (SprHSG[j] >> 1) + bkdy);
               sprite->clut = GetClut (0, FrgndClutY[0] + 480);
               sprite->w = SprWSG[j];
               sprite->h = SprHSG[j];
               sprite->u0 = SprUSG[j];
               sprite->v0 = SprVSG[j];
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);
            }
            else if ((ShootPoint[i].GunType == 2) || (ShootPoint[i].GunType == 20))
            {
               if (ShootPoint[i].Counter > 55)
                  j = 0;
               else
                  j = 1;
               sprite = db->Get_Spr ();
               setXY0 (sprite, ShootPoint[i].x - (SprWSG[j] >> 1) + bkdx,
                               ShootPoint[i].y - (SprHSG[j] >> 1) + bkdy);
               sprite->clut = GetClut (0, FrgndClutY[0] + 480);
               sprite->w = SprWSG[j];
               sprite->h = SprHSG[j];
               sprite->u0 = SprUSG[j];
               sprite->v0 = SprVSG[j];
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);
            }
         }
         else
         {
            if ((ShootPoint[i].GunType != 8) && (ShootPoint[i].GunType != 20)
                && ((i == WhichSPoint[0]) || (i == WhichSPoint[1])))
            {
               polygon = db->Get_Poly ();
               setUV4 (polygon, 0,168, 52,168, 0,218, 52,218);
               polygon->clut = GetClut (0, FrgndClutY[0] + 480);
               polygon->tpage = GetTPage (1, 0, FrgndTX,FrgndTY);
               setXY4 (polygon, RedSpotX[i] - 52,RedSpotY[i] - 50,
                                RedSpotX[i],RedSpotY[i] - 50,
                                RedSpotX[i] - 52,RedSpotY[i],
                                RedSpotX[i],RedSpotY[i]);
               SetSemiTrans (polygon, 0);
               db->Add_Poly (polygon, 15);

               polygon = db->Get_Poly ();
               setUV4 (polygon, 0,168, 52,168, 0,218, 52,218);
               polygon->clut = GetClut (0, FrgndClutY[0] + 480);
               polygon->tpage = GetTPage (1, 0, FrgndTX,FrgndTY);
               setXY4 (polygon, RedSpotX[i] + 52,RedSpotY[i] - 50,
                                RedSpotX[i],RedSpotY[i] - 50,
                                RedSpotX[i] + 52,RedSpotY[i],
                                RedSpotX[i],RedSpotY[i]);
               SetSemiTrans (polygon, 0);
               db->Add_Poly (polygon, 15);

               polygon = db->Get_Poly ();
               setUV4 (polygon, 0,168, 52,168, 0,218, 52,218);
               polygon->clut = GetClut (0, FrgndClutY[0] + 480);
               polygon->tpage = GetTPage (1, 0, FrgndTX,FrgndTY);
               setXY4 (polygon, RedSpotX[i] - 52,RedSpotY[i] + 50,
                                RedSpotX[i],RedSpotY[i] + 50,
                                RedSpotX[i] - 52,RedSpotY[i],
                                RedSpotX[i],RedSpotY[i]);
               SetSemiTrans (polygon, 0);
               db->Add_Poly (polygon, 15);

               polygon = db->Get_Poly ();
               setUV4 (polygon, 0,168, 52,168, 0,218, 52,218);
               polygon->clut = GetClut (0, FrgndClutY[0] + 480);
               polygon->tpage = GetTPage (1, 0, FrgndTX,FrgndTY);
               setXY4 (polygon, RedSpotX[i] + 52,RedSpotY[i] + 50,
                                RedSpotX[i],RedSpotY[i] + 50,
                                RedSpotX[i] + 52,RedSpotY[i],
                                RedSpotX[i],RedSpotY[i]);
               SetSemiTrans (polygon, 0);
               db->Add_Poly (polygon, 15);
            }
            else if ((ShootPoint[i].GunType != 20) &&
                    ((i == WhichSPoint[0]) || (i == WhichSPoint[1])))
            {
               int coorx, coory;

               coorx = ShootPoint[i].x + bkdx;
               coory = ShootPoint[i].y + bkdy;

               sprite = db->Get_Spr ();
               setUV0 (sprite, 98,162);
               setWH (sprite, 14,22);
               sprite->clut = GetClut (0, FrgndClutY[0] + 480);
               setXY0 (sprite, coorx + 11, coory - 47);
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);

               sprite = db->Get_Spr ();
               setUV0 (sprite, 198,172);
               setWH (sprite, 16,12);
               sprite->clut = GetClut (0, FrgndClutY[0] + 480);
               setXY0 (sprite, coorx + 3, coory - 25);
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);

               sprite = db->Get_Spr ();
               setUV0 (sprite, 178,171);
               setWH (sprite, 18,13);
               sprite->clut = GetClut (0, FrgndClutY[0] + 480);
               setXY0 (sprite, coorx - 5, coory - 13);
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);

               sprite = db->Get_Spr ();
               setUV0 (sprite, 54,167);
               setWH (sprite, 18,17);
               sprite->clut = GetClut (0, FrgndClutY[0] + 480);
               setXY0 (sprite, coorx - 13, coory);
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);

               sprite = db->Get_Spr ();
               setUV0 (sprite, 28,219);
               setWH (sprite, 24,37);
               sprite->clut = GetClut (0, FrgndClutY[0] + 480);
               setXY0 (sprite, coorx - 28, coory + 17);
               SetSemiTrans (sprite, 0);
               db->Add_Spr (sprite, 15);
            }
         }

         ShootPoint[i].Counter--;

         // The player can take another hit if the actual hit is done...
         if ((ShootPoint[i].Counter <= 0) && (WhichSPoint[0] == i))
            WhichSPoint[0] = -1;
         else if ((ShootPoint[i].Counter <= 0) && (WhichSPoint[1] == i))
            WhichSPoint[1] = -1;
      }
   }

   RECT tww = {FrgndTX,FrgndTY, 256,256};
   dr_mode = db->Get_DrMode ();
   SetDrawMode (dr_mode, 0, 0, GetTPage (1, 0, FrgndTX,FrgndTY), &tww);
   db->Add_DrMode (dr_mode, 15);
}

//---------------------------------------------------------------------------
// Drawing of players gun fire
//---------------------------------------------------------------------------
int PlrFiring[2] = {-1,-1};
int PlrFiringType[2];
int PlrFiringX[2];
int PlrFiringY[2];
const int PlrFiringCounter[7] = {5,5,9,9,5,5,5};    /////////sizeof (SprWS) / sizeof (SprWS[0]),
//                                 sizeof (SprWS) / sizeof (SprWS[0]),
//                                 sizeof (SprWB) / sizeof (SprWB[0]),
//                                 sizeof (SprWB) / sizeof (SprWB[0]),
//                                 sizeof (SprWS) / sizeof (SprWS[0]),
//                                 sizeof (SprWS) / sizeof (SprWS[0]),
//                                 sizeof (SprWS) / sizeof (SprWS[0])};
   
//-------------------------------------
// Add a player's gun fire
//-------------------------------------
void AddPlrFiring (int player, int guntype, int x, int y)
{
   PlrFiring[player] = PlrFiringCounter[guntype] - 1;
   PlrFiringType[player] = guntype;
   PlrFiringX[player] = x;
   PlrFiringY[player] = y;
}

//-------------------------------------
// Draw players's gun fire
//-------------------------------------
void DrawPlrFiring (DoubleBuffer *db)
{
   SPRT *sprite;
   DR_MODE *dr_mode;
   int i,j;
   int SprUS[2][5] = {{240,232,218,208,202},{0,10,14,0,0}};
   int SprVS[2][5] = {{110,94,94,94,94},{236,220,235,226,220}};
   int SprWS[5] = {14,16,14,10,6};
   int SprHS[5] = {14,14,13,9,5};
   int SprUB[9] = {114,114,114,222,222,222,190,190,190};
   int SprVB[9] = {153,153,153,138,138,138,138,138,138};
   int SprWB[9] = {30,30,30,32,32,32,32,32,32};
   int SprHB[9] = {29,29,29,32,32,32,28,28,28};

   for (i = 0; i < 2; i++)
   {
      if (PlrFiring[i] >= 0)
      {
         sprite = db->Get_Spr ();
         sprite->clut = GetClut (0, FrgndClutY[0] + 480);

         if ((PlrFiringType[i] != 2) && (PlrFiringType[i] != 3))
         {
            sprite->w = SprWS[PlrFiring[i]];
            sprite->h = SprHS[PlrFiring[i]];
            sprite->u0 = SprUS[i][PlrFiring[i]];
            sprite->v0 = SprVS[i][PlrFiring[i]];
            setXY0 (sprite, PlrFiringX[i] - (sprite->w >> 1),
                            PlrFiringY[i] - (sprite->h >> 1));
         }
         else
         {
            sprite->w = SprWB[PlrFiring[i]];
            sprite->h = SprHB[PlrFiring[i]];
            sprite->u0 = SprUB[PlrFiring[i]];
            sprite->v0 = SprVB[PlrFiring[i]];
            setXY0 (sprite, PlrFiringX[i] - (sprite->w >> 1),
                            PlrFiringY[i] - (sprite->h >> 1));
         }

         PlrFiring[i]--;
         SetSemiTrans (sprite, 0);
         db->Add_Spr (sprite, 15);
      }
   }

   RECT tww = {FrgndTX,FrgndTY, 256,256};
   dr_mode = db->Get_DrMode ();
   SetDrawMode (dr_mode, 0, 0, GetTPage (1, 0, FrgndTX,FrgndTY), &tww);
   db->Add_DrMode (dr_mode, 15);
}

//---------------------------------------------------------------------------
int EnemyX = -1;
int EnemyLength;
int EnemyStep = 10;
Character *enemychar;

//-------------------------------------
// Initialize some variables for the
// enemy lifepoints bar
//-------------------------------------
void InitEnemyLife (Character *enemy)
{
   if ((EnemyLength = enemy->GetLifePoint () * 10 + 2) > 200)
   {
      EnemyStep = 2000 / EnemyLength;
      EnemyLength = EnemyStep * enemy->GetLifePoint () + 2;
   }
   else
      EnemyStep = 10;

   EnemyX = 160 - ((enemy->GetLifePoint () * EnemyStep + 60) / 2);

   enemychar = enemy;
}

//-------------------------------------
// Clear the enemy's life point bar
//-------------------------------------
void ClearEnemyLife (void)
{
   EnemyX = -1;
}

//-------------------------------------
// Draw an orange bar that shows the
// life points the boss has left
//-------------------------------------
inline void DrawEnemyLife (DoubleBuffer *db)
{
   int lifepnt = enemychar->GetLifePoint ();

   if (EnemyX != -1)
   {
      if (lifepnt <= 0)
      {
         lifepnt = 0;
         EnemyX = -1;
         return;
      }

      SPRT *sprite = db->Get_Spr ();
      sprite->clut = GetClut (0, FrgndClutY[0] + 480);
      sprite->w = 48;
      sprite->h = 16;
      sprite->u0 = 124;
      sprite->v0 = 48;
      setXY0 (sprite, EnemyX, 170);
      SetSemiTrans (sprite, 0);
      db->Add_Spr (sprite, 15);

      RECT tww = {FrgndTX,FrgndTY, 256,256};
      DR_MODE *dr_mode = db->Get_DrMode ();
      SetDrawMode (dr_mode, 0, 0, GetTPage (1, 0, FrgndTX,FrgndTY), &tww);
      db->Add_DrMode (dr_mode, 15);

      POLY_G4 *marde = db->Get_Gouraud ();
      setRGB0 (marde, 255,255,0);       // Draw the colored bar
      setRGB2 (marde, 255,255,0);       //
      setRGB1 (marde, 255,255 - lifepnt * 10 * 255 / EnemyLength,0);
      setRGB3 (marde, 255,255 - lifepnt * 10 * 255 / EnemyLength,0);
      setXYWH (marde, EnemyX + 61,171, lifepnt * EnemyStep,14);
      SetSemiTrans (marde, 0);          //
      db->Add_Gouraud (marde, 15);      //

      POLY_F4 *plain = db->Get_Plain ();// Draw the black bar behind the
      setRGB0 (plain, 0,0,0);           // life points bar
      setXYWH (plain, EnemyX + 60,170, EnemyLength,16);
      SetSemiTrans (plain, 1);          //
      db->Add_Plain (plain, 15);        //
   }
}

//---------------------------------------------------------------------------

//-------------------------------------
// Display the remaining time for the
// shooting range
//-------------------------------------
ShowShootingTime (DoubleBuffer *db, int time)
{
   char su[10] = { 0, 8,16,24,32, 0, 8,16,24,32};
   char sv[10] = {48,48,48,48,48,56,56,56,56,56};
   SPRT *sprite;
   DR_MODE *dr_mode;

   sprite = db->Get_Spr ();                 // "time"
   setXY0 (sprite, 145,40);
   setWH (sprite, 30,8);
   setUV0 (sprite, 224,48);
   sprite->clut = GetClut (0, FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 14);

   sprite = db->Get_Spr ();                 // Tens
   setXY0 (sprite, 152,48);
   setWH (sprite, 8,8);
   setUV0 (sprite, su[time / 10], sv[time / 10]);
   sprite->clut = GetClut (0, FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 14);

   sprite = db->Get_Spr ();                 // Units
   setXY0 (sprite, 160,48);
   setWH (sprite, 8,8);
   setUV0 (sprite, su[time % 10], sv[time % 10]);
   sprite->clut = GetClut (0, FrgndClutY[0] + 480);
   SetSemiTrans (sprite, 0);
   db->Add_Spr (sprite, 14);

   RECT tww3 = {FrgndTX,FrgndTY,256,256};
   dr_mode = db->Get_DrMode ();
   SetDrawMode (dr_mode, 0, 0, GetTPage (1, 0, FrgndTX,FrgndTY), &tww3);
   db->Add_DrMode (dr_mode, 14);
}
