//---------------------------------------------------------------------------
// The Shooting Range main loop!!!
// It's part of the main function, but since the main is already too big, I
// just though it would be easier to read if it was in a file by itself
//---------------------------------------------------------------------------

#define  MAXTARGET  30

ShootingTime = 1159;
int   zeus;
int   OriginX[2];
int   ShootingMode;
char  MinPercentage[] = {60,70,80,90,95,100};
char  IndexPercent = 0;
char  ShootingType[] = {0,1,2,3,4,3,1};     // Last 3 repeats infinitely
signed char ShootingTypeIndex = 0;
char  MaxShootTimePerTarget = 35;
short ActualShootTime[2] = {0,0};
char  NbrTargetShot[2] = {0,0};
short TargetX[2][MAXTARGET];
short TargetY[2][MAXTARGET];
short TargetTime[2][MAXTARGET];
short TargetNbr[2][MAXTARGET];
char  TargetAction[2][MAXTARGET];
char  TargetDirection[2][MAXTARGET];
char  TargetLevel[2][MAXTARGET];
char  TargetXDest[2][MAXTARGET];
char  TargetPos[6][9] = {{1,0,0, 0,1,0, 0,0,1}, {1,0,1, 0,1,0, 0,0,1},
                         {1,0,1, 0,1,0, 1,0,1}, {1,1,0, 0,1,1, 1,1,0},
                         {0,1,1, 1,1,0, 0,1,1}, {0,0,1, 0,0,1, 1,1,1}};
int   NextPattern[2] = {0,0};
bkgnd[0].Load ("\\BACKGRND\\SHOOTING\\SHOOT1.BKD", &MemoryP);
bkgnd[0].SetBKDType (8, &MemoryP);
bkgnd[1].Load ("\\BACKGRND\\SHOOTING\\SHOOT2.BKD", &MemoryP);
bkgnd[1].SetBKDType (8, &MemoryP);
SetPercent (MinPercentage[IndexPercent]);

for (zeus = 0; zeus < 2; zeus++)
{
   for (i = 0; i < MAXTARGET; i++)
      TargetTime[zeus][i] = -1;
}

if ((frgnd.Plr1.Lifepnt != 0) && (frgnd.Plr2.Lifepnt != 0))
{
   ShootingMode = 1;
   OriginX[0] = 6;
   OriginX[1] = 162;
}
else
{
   ShootingMode = 0;
   OriginX[0] = 85;
}

//-- Main loop for shooting range --
while (((frgnd.Plr1.Lifepnt) || (frgnd.Plr1.Counter > -360) ||
       (frgnd.Plr2.Lifepnt) || (frgnd.Plr2.Counter > -360)) && (!Results))
{
   dbuff.ClearDrawArea (0,0,0);

   // Replaces execscript...
   for (zeus = 0; zeus < (ShootingMode + 1); zeus++)
   {
      if (((ActualShootTime[zeus] == 0) || (NbrTargetShot[zeus] == 0)) &&
          (ShootingTime != 0))
      {                            // Time to start a new sequence of targets
         for (i = 0; i < MAXTARGET; i++)       // First Remove the remaining
         {                                     // target of the screen
            if (TargetTime[zeus][i] != -1)
            {
               Chars[TargetNbr[zeus][i]]->StopAction ();
               TargetTime[zeus][i] = -1;
            }
         }
         if (NbrTargetShot[zeus])
         {
            PlaySFX (commonvab, 3, 127,127);
            if (ShootingMode == 0)
            {
               if (frgnd.Plr1.Lifepnt)
                  frgnd.Plr1.VictimsMiss++;
               else
                  frgnd.Plr2.VictimsMiss++;
            }
            else
               if (zeus == 0)
                  frgnd.Plr1.VictimsMiss++;
               else
                  frgnd.Plr2.VictimsMiss++;
            NbrTargetShot[zeus] = 0;
         }
      
         switch (ShootingType[ShootingTypeIndex])
         {
            //------- White targets ------
            int j;
            case 0: j = MaxShootTimePerTarget * 9;
                    if (ShootingTime < j)
                       j = ShootingTime;
                    ActualShootTime[zeus] = j;
                    j /= MaxShootTimePerTarget;
                    k = 0;
                    NbrTargetShot[zeus] = 0;
                    for (i = 0; (k < j) && (i < 9); i++)
                    {
                       if (TargetPos[NextPattern[zeus]][i] == 1)
                       {
                          TargetTime[zeus][k] = ShootingTime;
                          TargetX[zeus][k] = (i % 3) * 42 + OriginX[zeus] + 33;
                          TargetY[zeus][k] = (i / 3) * 39 + 77;
                          TargetNbr[zeus][k] = i + 30 * zeus;
                          TargetAction[zeus][k] = 8;
                          TargetDirection[zeus][k] = 0;
                          NbrTargetShot[zeus]++;
                          k++;
                       }
                    }
                    while ((i = rand () % 6) == NextPattern[zeus]);
                    NextPattern[zeus] = i;
                    break;
            //-------- Silhouettes -------
            case 1: j = MaxShootTimePerTarget * 9;
                    if (ShootingTime < j)
                       j = ShootingTime;
                    ActualShootTime[zeus] = j;
                    j /= MaxShootTimePerTarget;
                    k = 0;
                    NbrTargetShot[zeus] = 0;
                    for (i = 0; (k < j) && (i < 9); i++)
                    {
                       if (TargetPos[NextPattern[zeus]][i] == 1)
                       {
                          TargetTime[zeus][k] = ShootingTime;
                          if (ShootingMode == 0)
                          {
                             TargetX[zeus][k] = (i % 3) * 42 + 228;
                             TargetDirection[zeus][k] = 1;
                          }
                          else if (zeus == 0)
                          {
                             TargetX[zeus][k] = (i % 3) * 42 - 70;
                             TargetDirection[zeus][i] = 0;
                          }
                          else
                          {
                             TargetX[zeus][k] = (i % 3) * 42 + 305;
                             TargetDirection[zeus][i] = 1;
                          }
                          TargetY[zeus][k] = (i / 3) * 39 + 68;
                          TargetNbr[zeus][k] = i + 30 * zeus;
                          TargetAction[zeus][k] = 3;
                          NbrTargetShot[zeus]++;
                          k++;
                       }
                    }
                    while ((i = rand () % 6) == NextPattern[zeus]);
                    NextPattern[zeus] = i;
                    break;
            //---- Red & white targets ---
            case 2: for (i = 0; i < 28; i++)
                    {
                       TargetTime[zeus][i] = ShootingTime - i * 39;

                       int ruffle;
                       int freud = 1;
                       while (freud)
                       {
                          freud = 0;
                          ruffle = rand () % 6;

                          int stucco;  // Find out if there's a conflict of
                          if ((stucco = i - 4) < 0)    // direction between the
                             stucco = 0;               // actual target & the 4
                          while (stucco < i)           // previous ones
                          {
                             if (((ruffle >> 1) == TargetLevel[zeus][stucco]) &&
                                 ((ruffle & 1) != TargetDirection[zeus][stucco]))
                                freud = 1;
                             stucco++;
                          }
                       }

                       if (ruffle & 1)
                       {
                          TargetX[zeus][i] = OriginX[zeus] + 150;
                          TargetXDest[zeus][i] = OriginX[zeus];
                          TargetDirection[zeus][i] = 1;
                       }
                       else
                       {
                          TargetX[zeus][i] = OriginX[zeus];
                          TargetXDest[zeus][i] = OriginX[zeus] + 150;
                          TargetDirection[zeus][i] = 0;
                       }

                       TargetY[zeus][i] = (ruffle >> 1) * 39 + 68;
                       TargetLevel[zeus][i] = ruffle >> 1;

                       TargetAction[zeus][i] = 6;
                       TargetNbr[zeus][i] = i + 30 * zeus;
                       NbrTargetShot[zeus]++;
                    }

                    ActualShootTime[zeus] = 1159;
                    break;
            //--------- Balloons ---------
            case 3: j = MaxShootTimePerTarget * 9;
                    if (ShootingTime < j)
                       j = ShootingTime;
                    ActualShootTime[zeus] = j;
                    j /= MaxShootTimePerTarget;
                    k = 0;
                    NbrTargetShot[zeus] = 0;
                    for (i = 0; (i < 9) && (k < j); i++)
                    {
                       if (TargetPos[NextPattern[zeus]][i] == 1)
                       {
                          TargetTime[zeus][k] = ShootingTime;
                          TargetX[zeus][k] = (i % 3) * 42 + OriginX[zeus] + 33;
                          TargetY[zeus][k] = (i / 3) * 39 + 76;
                          TargetNbr[zeus][k] = i + 30 * zeus;
                          TargetAction[zeus][k] = 0;
                          TargetDirection[zeus][k] = 0;
                          NbrTargetShot[zeus]++;
                          k++;
                       }
                    }
                    while ((i = rand () % 6) == NextPattern[zeus]);
                    NextPattern[zeus] = i;

                    break;
            //--------- Pictures ---------
            case 4: j = MaxShootTimePerTarget * 9;
                    if (ShootingTime < j)
                       j = ShootingTime;
                    ActualShootTime[zeus] = j;
                    j /= MaxShootTimePerTarget;
                    k = 0;
                    NbrTargetShot[zeus] = 0;
                    for (i = 0; (k < j) && (i < 9); i++)
                    {
                       if (TargetPos[NextPattern[zeus]][i] == 1)
                       {
                          TargetTime[zeus][k] = ShootingTime;
                          TargetX[zeus][k] = (i % 3) * 42 + OriginX[zeus] + 33;
                          TargetY[zeus][k] = (i / 3) * 39 + 77;
                          TargetNbr[zeus][k] = 60 + i + 30 * zeus;
                          TargetAction[zeus][k] = (rand () % 4) * 3;
                          TargetDirection[zeus][k] = 0;
                          if (TargetAction[zeus][k] != 9)
                             NbrTargetShot[zeus]++;
                          k++;
                       }
                    }
                    while ((i = rand () % 6) == NextPattern[zeus]);
                    NextPattern[zeus] = i;
                    break;
        }
      }

      for (i = 0; i < MAXTARGET; i++)          // Start target if time to
      {
         int mule = TargetNbr[zeus][i];
         if (TargetTime[zeus][i] == ShootingTime)
         {
            Chars[mule]->Set_Location (TargetX[zeus][i], TargetY[zeus][i]);
            Chars[mule]->SetDepth (3);
            Chars[mule]->StartAction (TargetAction[zeus][i], TargetDirection[zeus][i]);
         }

         if ((TargetTime[zeus][i] != -1) && (ShootingType[ShootingTypeIndex] == 2))
         {
            if (!Chars[mule]->Dead ())
            {
               if (TargetDirection[zeus][i])
                  Chars[mule]->Move (-1, 0);
               else
                  Chars[mule]->Move (1, 0);
               point popeye = Chars[mule]->Coordinate ();
               if (popeye.x == TargetXDest[zeus][i])
               {
                  Chars[mule]->StopAction ();
                  PlaySFX (commonvab, 3, 127,127);
                  if (ShootingMode == 0)
                  {
                     if (frgnd.Plr1.Lifepnt)
                        frgnd.Plr1.VictimsMiss++;
                     else
                        frgnd.Plr2.VictimsMiss++;
                  }
                  else
                     if (zeus == 0)
                        frgnd.Plr1.VictimsMiss++;
                     else
                        frgnd.Plr2.VictimsMiss++;
               }
            }
         }
      }
   }

   if (!EndRound)
      Control_Read (&trigger, &frgnd, GamePause ? -1 : commonvab, &Buttons);

   if (Flash[0] || Flash[1])
   {
      while (Flash[0] || Flash[1])
      {
         if (Flash[0])
            Flash[0]--;
         if (Flash[1])
            Flash[1]--;
         dbuff.FlashScreen ();
      }
   }

   if (((frgnd.Plr1.Lifepnt != 0) || (frgnd.Plr2.Lifepnt != 0)) &&
       (!GamePause))
   {
      FrameCounter++;
      if (!EndRound)
      {
         ActualShootTime[0]--;
         ActualShootTime[1]--;
         if (--ShootingTime == 0)
         {
            EndRound = 3;
            bkgnd[ShootingMode].BuildDestClut (0);

            for (zeus = 0; zeus < (ShootingMode + 1); zeus++)
            {
               for (i = 0; i < MAXTARGET; i++)     // Remove the remaining target
               {                                   // of the screen
                  if (TargetTime[zeus][i] != -1)
                  {
                     Chars[TargetNbr[zeus][i]]->StopAction ();
                     TargetTime[zeus][i] = -1;
                     NbrTargetShot[zeus]--;
                  }
               }
               if (NbrTargetShot[zeus])
               {
                  PlaySFX (commonvab, 3, 127,127);
                  if (ShootingMode == 0)
                  {
                     if (frgnd.Plr1.Lifepnt)
                        frgnd.Plr1.VictimsMiss++;
                     else
                        frgnd.Plr2.VictimsMiss++;
                  }
                  else
                     if (zeus == 0)
                        frgnd.Plr1.VictimsMiss++;
                     else
                        frgnd.Plr2.VictimsMiss++;
               }
            }
         }
      }
   }

   DrawPercent (&dbuff);
   ShowShootingTime (&dbuff, (ShootingTime + 59) / 60);

   //----------------------------------
   #include "pause.h"

   //-------------------------
   bkgnd[ShootingMode].ChangeClut ();
   bkgnd[ShootingMode].Draw (&dbuff, 0);
   Draw_Foreground (&frgnd, &dbuff, 0, commonvab);
   DrawPlrFiring (&dbuff);

   for (i = 0; i < NbrChars; i++)
   {
      Chars[i]->DrawNextFrame (0,0, &dbuff, &Sfx, &Vab, &posi);
      if (Sfx != -1)    // Play a character's SFX if needed...
      {
         if ((posi > 159) && (posi < 320))      // Right part
         {
            voll = (320 - posi) * 127 / 160;
            PlaySFX (Vab, Sfx, voll,127);
         }
         else if ((posi < 160) && (posi > -1))  // Left part
         {
            volr = posi * 127 / 160;
            PlaySFX (Vab, Sfx, 127,volr);
         }
      }
   }

   if ((!EndRound) && (!GamePause))
      Draw_Gun_Cursor (&frgnd, &dbuff, 0);

   if (trigger)
   {
      if (trigger == 1)
      {
         player = &frgnd.Plr1;
         i = 0;
         trigger--;
         meu = 0;
      }
      else
      {
         player = &frgnd.Plr2;
         i = 3;
         trigger -= 2;
         meu = 1;
      }

      if (player->Counter < 59)
          player->Score = 0;

      if ((player->Bullets > 0) && (player->Lifepnt > 0))
      {                                           // Shoot a bullet
         int SfxGun[6][7] = {{1,1,1,1,1,1,1}, {1,1,2,-1,1,2,4},
                             {1,1,5,-1,1,5,8}, {1,1,2,4,1,2,3},
                             {1,1,-1,-1,1,-1,-1}, {1,1,5,-1,1,5,3}};
         int VabGun[6][7] = {{0,0,0,0,0,0,0}, {0,0,1,1,0,1,1},
                             {0,0,1,1,0,1,1}, {0,0,1,1,0,1,1},
                             {0,0,1,1,0,1,1}, {0,0,1,1,0,1,1}};

         player->Shots++;
         voll = player->PlayerNbr ? 63 : 127;
         volr = player->PlayerNbr ? 127 : 63;
         PlaySFX (VabGun[LevelSelected][player->BulletType],
                  SfxGun[LevelSelected][player->BulletType], voll,volr);
         AddPlrFiring (meu, player->BulletType, player->GunX, player->GunY);
         player->Bullets--;
         if ((!player->BulletType) && (player->Bullets == 1)) //"Reload"
         {
            voll = player->PlayerNbr ? 0 : 127;
            volr = player->PlayerNbr ? 127 : 0;
            PlaySFX (commonvab, 19, voll,volr);
         }

         // Check if the player has shot a guy or a wall or whatever
         Power = GunPower[player->BulletType];
         for (j = 15; (j && Power); j--)
         {
            if ((j == 10) || (j == 5))
            {
               if (bkgnd[ShootingMode].GetHit (j / 5, player->GunX,
                                    player->GunY, &Sfx, &Vab))
               {
                  if (Sfx != -1)
                     PlaySFX (Vab, Sfx, 127,127);
                     Power--;
               }
            }
            else
            {
               if (frgnd.Plr1.Lifepnt && frgnd.Plr2.Lifepnt)
                  zeus = player->PlayerNbr;
               else
                  zeus = 0;
               for (i = 0; (i < MAXTARGET) && (Power); i++)
               {
                  int jui = TargetNbr[zeus][i];
                  if (TargetTime[zeus][i] != -1)
                  {
                     if (Chars[jui]->GetDepth () == j)
                     {
                        if (Chars[jui]->GetHit (player->GunX, player->GunY,
                            player, Power, &bkgnd[ShootingMode], &dbuff))
                        {
                           if ((TargetAction[zeus][i] == 9) &&
                               (ShootingType[ShootingTypeIndex] == 4))
                           {
                              PlaySFX (commonvab, 3, 127,127);
                              player->VictimsMiss++;
                           }
                           else
                              NbrTargetShot[zeus]--;
                           Power = 0;
                           player->Hits++;
                        }
                     }
                  }
               }
            }
         }
      }
   }

   if (EndRound)
   {
      if (shower > 0)
      {
         if (actualvol)
         {
            actualvol -= 2;
            if (actualvol < 0)
               actualvol = 0;
            #ifdef TARGETCD
               #ifdef PLAY_CDXAS
                  AudioChangeVolume (CDXAId, actualvol);
               #endif
            #endif
         }
      }

      shower--;
   }
   else
      shower = 64;

   if ((EndRound) && (shower == 0))
      Init_Score (MemoryP, EndRound, &frgnd.Plr1, &frgnd.Plr2);

   if ((EndRound != 0) && (shower < 0))
   {
      if (Show_Results (&frgnd.Plr1, &frgnd.Plr2, &dbuff))
      {
         bkgnd[ShootingMode].BuildDestClut (4);
         EndRound = 0;
         ShootingTime = 1159;
         FrameCounter = 0;
         if (++IndexPercent > 5)    // Increase the qualify percentage
            IndexPercent = 5;
         SetPercent (MinPercentage[IndexPercent]);
         frgnd.Plr1.Shots = 0;
         frgnd.Plr1.Hits = 0;
         frgnd.Plr1.VictimsMiss = 0;
         frgnd.Plr2.Shots = 0;
         frgnd.Plr2.Hits = 0;
         frgnd.Plr2.VictimsMiss = 0;
         if (MaxShootTimePerTarget > 20)    // Less time to shoot targets...
            MaxShootTimePerTarget -= 3;
         if (++ShootingTypeIndex > 6)
            ShootingTypeIndex = 4;
         ClearScore ();

         if (PleaseWait[0])                 // Time for the player 1 to enter
         {                                  // the game ?
            frgnd.Credits--;
            PlaySFX (commonvab, 17, 127,0);
            Update_Player (&frgnd.Plr1);
            frgnd.Plr1.Lifepnt = 9;
            PleaseWait[0] = 0;
            ActualShootTime[0] = 0;
         }
         if (PleaseWait[1])                 // Time for the player 2 to enter
         {                                  // the game ?
            frgnd.Credits--;
            Update_Player (&frgnd.Plr2);
            frgnd.Plr2.Lifepnt = 9;
            PlaySFX (commonvab, 18, 0,127);
            PleaseWait[1] = 0;
            ActualShootTime[1] = 0;
         }

         if ((frgnd.Plr1.Lifepnt != 0) && (frgnd.Plr2.Lifepnt != 0))
         {
            ShootingMode = 1;
            OriginX[0] = 6;
            OriginX[1] = 162;
         }
         else
         {
            ShootingMode = 0;
            OriginX[0] = 85;
         }
      }
   }

   dbuff.Swap (0);              // swap double buffer
}

PleaseWait[0] = 0;
PleaseWait[1] = 0;
bkgnd[1].Clear ();
