//---------------------------------------------------------------------------
// Module that takes care of the options and the related topics
//---------------------------------------------------------------------------

#define GUN1 (_PadRead (&p) & 0xFFFF)
#define GUN2 (_PadRead (&p) >> 16)

void Options (Foreground *frgnd, DoubleBuffer *db, int vabnbr, u_long memoryp);
void Calibrate_Guns (int whichgun, DoubleBuffer *db, u_long memoryp);
void Control_Config (Background *bkd, DoubleBuffer *db, u_long memoryp);

//-------------------------------------
// Show the options screen
//-------------------------------------
void Options (Foreground *frgnd, DoubleBuffer *db, int vabnbr, u_long memoryp)
{
   Background bkd;
   POLY_F4  *plain;
   int i, trig, buttons = 0;
   int nbroptions[7] = {1,1,99,99,7,0,0};
   int optionnbr = 0;
   int oldoptionnbr = 0;
   int optiony[8] = {50,70,90,110,130,160,180,200};
   char *difficulties[8] = {"Easiest","Very easy","Easy","Medium",
                            "Medium hard","Hard","Very hard","Hardest"};
   char *optionname[7] = {"Game Mode","Bloody Mode","Sound FX Volume",
                          "Music Volume","Difficulty Level",
                          "Gun Calibration", "Controll configuration"};
   int options[5];
   char exiting = 0;
   POLY_G4 sfxvol;
   POLY_G4 musicvol;

   options[0] = GameMode;               // Put the global option values into
   options[1] = BloodyMode;             // local variables
   options[2] = SfxVol * 99 / 127;      //
   options[3] = MusicVol * 99 / 127;    //
   options[4] = Difficulty;             //

   if (memoryp & 3)
      memoryp = (u_long)((memoryp + 4) & 0xFFFFFFFC);
   bkd.Load ("\\BACKGRND\\MISCELLA\\CHICAGO.BKD", &memoryp);
   bkd.SetLocation (0,0);

   #ifdef TARGETCD
      #ifdef PLAY_CDXAS
         CDXAId = AudioPlayCue (SD_stagesel);
         AudioChangeVolume (CDXAId, MusicVol);
      #endif
   #endif

   while (!exiting)
   {
      if (debug)
         FntPrint ("OptionNbr: %d\n", optionnbr);

      if ((optionnbr == 5) && (gun[0]->id != PADID_GUN) &&
          (gun[1]->id != PADID_GUN))
      {
         if (optionnbr < oldoptionnbr)
            optionnbr--;
         else
            optionnbr++;
      }

      oldoptionnbr = optionnbr;

      SetFontColor (1);
      FontCenterOn (160,22);
      Print ("Options");

      plain = db->Get_Plain ();         // Draw the transparent black bar
      setRGB0 (plain, 0,0,0);           // behind the selected option
      setXYWH (plain, 18,optiony[optionnbr], 284,20);
      SetSemiTrans (plain, 1);          //
      db->Add_Plain (plain, 3);         //

      for (i = 0; i < 5; i++)
      {
         SetFontColor (i == optionnbr);
         FontRightOn (170, optiony[i] + 2);
         Print (optionname[i]);
      }

      if (((gun[0]->id == PADID_GUN) && (gun[0]->result == 0)) ||
          ((gun[1]->id == PADID_GUN) && (gun[1]->result == 0)))
         SetFontColor (optionnbr == 5);
      else
         SetFontColor ((optionnbr == 5) + 2);
      FontCenterOn (160,optiony[5] + 2);
      Print (optionname[5]);
      if (((gun[0]->id == PADID_CON) && (gun[0]->result == 0)) ||
          ((gun[1]->id == PADID_CON) && (gun[1]->result == 0)))
         SetFontColor (optionnbr == 6);
      else
         SetFontColor ((optionnbr == 6) + 2);
      FontCenterOn (160,optiony[6] + 2);
      Print (optionname[6]);
      SetFontColor (optionnbr == 7);
      FontCenterOn (160,optiony[7]);
      Print ("Exit");

      // Game mode
      if (((optionnbr == 0) && (VSync (-1) & 16)) || (optionnbr != 0))
      {
         SetFontColor (0);
         FontLeftOn (180,optiony[0] + 2);
         if (options[0] == 0)
            Print ("Arcade");
         else
            Print ("Street");
      }

      // Bloody mode
      if (((optionnbr == 1) && (VSync (-1) & 16)) || (optionnbr != 1))
      {
         SetFontColor (0);
         FontLeftOn (180,optiony[1] + 2);
         if (options[1] == 0)
            Print ("Off");
         else
            Print ("On");
      }

      // Sound FX volume
      plain = db->Get_Plain ();         // Draw the black bar behind the
      setRGB0 (plain, 0,0,80);          // volume bar
      setXYWH (plain, 180,optiony[2], 102,16); //
      SetSemiTrans (plain, 0);          //
      db->Add_Plain (plain, 6);         //
      SetPolyG4 (&sfxvol);              //
      setRGB0 (&sfxvol, 255,255,0);     // Draw the colored bar
      setRGB2 (&sfxvol, 255,255,0);     //
      setRGB1 (&sfxvol, 255,255 - options[2] * 255 / 99,0);
      setRGB3 (&sfxvol, 255,255 - options[2] * 255 / 99,0);
      setXYWH (&sfxvol, 181,optiony[2] + 1, options[2],14);
      SetSemiTrans (&sfxvol, 0);        //
      db->Add_Gouraud (&sfxvol, 7);     //

      // Music volume
      plain = db->Get_Plain ();         // Draw the black bar behind the
      setRGB0 (plain, 0,0,80);          // volume bar
      setXYWH (plain, 180,optiony[3], 102,16); //
      SetSemiTrans (plain, 0);          //
      db->Add_Plain (plain, 6);         //
      SetPolyG4 (&musicvol);            //
      setRGB0 (&musicvol, 255,255,0);   // Draw the colored bar
      setRGB2 (&musicvol, 255,255,0);   //
      setRGB1 (&musicvol, 255,255 - options[3] * 255 / 99,0);
      setRGB3 (&musicvol, 255,255 - options[3] * 255 / 99,0);
      setXYWH (&musicvol, 181,optiony[3] + 1, options[3],14);
      SetSemiTrans (&musicvol, 0);      //
      db->Add_Gouraud (&musicvol, 7);   //

      // Game difficulty
      if (((optionnbr == 4) && (VSync (-1) & 16)) || (optionnbr != 4))
      {
         SetFontColor (0);
         FontLeftOn (180,optiony[4] + 2);
         Print (difficulties[options[4]]);
      }

      bkd.Draw (db, 0);
      Control_Read (&trig, frgnd, -1, &buttons);

      //-------------------------------
      if (buttons & 2048)           // X button for changing an option
      {
         if ((optionnbr != 2) && (optionnbr != 3))
            PlaySFX (vabnbr, 32, 127,127);
         buttons &= ~2048;
         if ((optionnbr == 0) || (optionnbr == 1) || (optionnbr == 4))
         {
            if (++options[optionnbr] > nbroptions[optionnbr])
               options[optionnbr] = 0;
         }
         else if (optionnbr == 5)
         {
            if ((gun[0]->id == PADID_GUN) || (gun[1]->id == PADID_GUN))
               Calibrate_Guns (0, db, memoryp);
         }
         else if (optionnbr == 6)
         {
            Control_Config (&bkd, db, memoryp);
            #ifdef TARGETCD
               #ifdef PLAY_CDXAS
                  AudioStop (CDXAId);
               #endif
            #endif
         }
         else
            exiting = 1;
      }

      if (buttons & 192)                // Down button to select the next
      {                                 // option
         PlaySFX (vabnbr, 32, 127,127);
         buttons &= ~192;
         if (++optionnbr >= 8)
            optionnbr = 0;
      }

      if (buttons & 256)                // Up button to select the previous
      {                                 // option
         PlaySFX (vabnbr, 32, 127,127); //
         buttons &= ~256;
         if (--optionnbr < 0)
            optionnbr = 7;
      }

      if (buttons & 1024)               // Gun Select button...
      {
         buttons &= ~1024;
         if ((optionnbr == 2) || (optionnbr == 3))
         {
            if (options[optionnbr] < 99)
               options[optionnbr] += 1;
         }
      }

      if (buttons & 32)
      {
         buttons &= ~32;
         PlaySFX (vabnbr, 32, 127,127);
         if (optionnbr < 5)
         {
            if (++options[optionnbr] > nbroptions[optionnbr])
               options[optionnbr] = 0;
         }
         else if (optionnbr == 5)
         {
            if ((gun[0]->id == PADID_GUN) || (gun[1]->id == PADID_GUN))
               Calibrate_Guns (0, db, memoryp);
         }
         else if (optionnbr == 6)
         {
            #ifdef TARGETCD
               #ifdef PLAY_CDXAS
                  AudioStop (CDXAId);
               #endif
            #endif
            Control_Config (&bkd, db, memoryp);
         }
         else
            exiting = 1;
      }

      if (buttons & 8)                  // Left arrow
      {
         buttons &= ~8;
         if ((optionnbr == 2) || (optionnbr == 3))
         {
            if (options[optionnbr] > 0)
               options[optionnbr]--;
            #ifdef TARGETCD
               #ifdef PLAY_CDXAS
                  AudioChangeVolume (CDXAId, options[3] * 127 / 99);
               #endif
            #endif
         }
      }

      if (buttons & 16)                 // Right arrow
      {
         buttons &= ~16;
         if ((optionnbr == 2) || (optionnbr == 3))
         {
            if (options[optionnbr] < nbroptions[optionnbr])
               options[optionnbr]++;
            #ifdef TARGETCD
               #ifdef PLAY_CDXAS
                  AudioChangeVolume (CDXAId, options[3] * 127 / 99);
               #endif
            #endif
         }
      }

      if (buttons & 4096)               // Left arrow
      {
         buttons &= ~4096;
         if ((optionnbr == 0) || (optionnbr == 1) || (optionnbr == 4))
         {
            if (options[optionnbr] > 0)
            {
               options[optionnbr]--;
               PlaySFX (vabnbr, 32, 127,127);
            }
         }
      }

      if (buttons & 8192)               // Right arrow
      {
         buttons &= ~8192;
         if ((optionnbr == 0) || (optionnbr == 1) || (optionnbr == 4))
         {
            if (options[optionnbr] < nbroptions[optionnbr])
            {
               options[optionnbr]++;
               PlaySFX (vabnbr, 32, 127,127);
            }
         }
      }

      SfxVol = options[2] * 127 / 99;

      db->Swap (debug);
   }

   db->ClearDrawArea (0,0,0);           // Turn the screen to black
   db->Swap (debug);                    //
   db->Swap (debug);                    //

   Init_Player (&frgnd->Plr1);          //
   Init_Player (&frgnd->Plr2);          //

   GameMode = options[0];               // Put the option values in the global
   BloodyMode = options[1];             // variables
   SfxVol = options[2] * 127 / 99;      //
   MusicVol = options[3] * 127 / 99;    //
   Difficulty = options[4];             //

   #ifdef TARGETCD
      #ifdef PLAY_CDXAS
         AudioStop (CDXAId);
      #endif
   #endif

   bkd.Clear ();
}

//-------------------------------------
// Gun calibration
//-------------------------------------
void Calibrate_Guns (int whichgun, DoubleBuffer *db, u_long memoryp)
{
   Background bkd;
   PLAYER *player;
   u_long padd = 0;
   u_long padd2 = 0;
   int trig;
   DR_MODE *drmode;
   Foreground dumfrgnd;

   dumfrgnd.Credits = 4;
   if (whichgun == 0)
   {
      dumfrgnd.Plr1.Bullets = 1;
      dumfrgnd.Plr1.Lifepnt = 1;
   }
   else if (whichgun == 1)
   {
      dumfrgnd.Plr2.Bullets = 1;
      dumfrgnd.Plr2.Lifepnt = 1;
   }
   
   if (memoryp & 3)
      memoryp = (u_long)((memoryp + 4) & 0xFFFFFFFC);
   bkd.Load ("\\BACKGRND\\MISCELLA\\CALIBRAT.BKD", &memoryp);
   bkd.SetBKDType (5, &memoryp);

   dumfrgnd.Plr1.GunX = 0;
   dumfrgnd.Plr1.GunY = 0;

   bkd.SetLocation (0,0);

   while (!((padd) & PADstart))
   {
      dumfrgnd.Plr1.GunX = ((IntrusGunX[0][0] - 140 - XGunMiddle) / 5) + 160;
      dumfrgnd.Plr1.GunY = (IntrusGunY[0][0] - YGunMiddle) + 120;
      dumfrgnd.Plr2.GunX = ((IntrusGunX[1][0] - 140 - XGunMiddle) / 5) + 160;
      dumfrgnd.Plr2.GunY = (IntrusGunY[1][0] - YGunMiddle) + 120;

      if ((gun[0]->id == PADID_GUN) && (gun[0]->result == 0) && (whichgun == 0))
      {
         padd = GUN1;
         if (~old_padd & padd & PADRleft)
         {
            XGunMiddle = IntrusGunX[0][0] - 140;
            YGunMiddle = IntrusGunY[0][0];
         }
      }
      else if ((gun[1]->id == PADID_GUN) && (gun[1]->result == 0) && (whichgun == 1))
      {
         padd = GUN2;
         if (~old_padd & padd & PADRleft)
         {
            XGunMiddle = IntrusGunX[1][0] - 140;
            YGunMiddle = IntrusGunY[1][0];
         }
      }
      else
         padd = 0;

      old_padd = padd;
      //-----------

      bkd.Draw (db, 0);
      FontCenterOn (160,25);
      SetFontColor (1);
      Print ("GUN CALIBRATION");
      FontCenterOn (160,205);
      Print ("PRESS START TO EXIT");
      Draw_Gun_Cursor (&dumfrgnd, db, 1);

      FntPrint ("Gun1  X:%d  Y:%d\n", IntrusGunX[0][0], IntrusGunY[0][0]);
      FntPrint ("Gun2  X:%d  Y:%d\n", IntrusGunX[1][0], IntrusGunY[1][0]);
      FntPrint ("GunMiddle  X:%d  Y:%d\n", XGunMiddle, YGunMiddle);

      db->Swap (1);
   }

   bkd.Clear ();

   db->ClearDrawArea (0,0,0);   // Turn the screen to black
   db->Swap (debug);            //
   db->Swap (debug);            //
}

//-------------------------------------
// Buttons configuration for joypads
//-------------------------------------
void Control_Config (Background *bkd, DoubleBuffer *db, u_long memoryp)
{
   int          dummy, i, j, trig, button = 0;
   Foreground   frgnd;
   int          padder[2], oldpadder[2] = {0,0};
   Character    *joypad[2];
   Character    *buttons[2][9];
   Character    *buttonlight[2][8];
   int          ActualSelection[2] = {0,0};
   int          Preset[3][3] = {{6,1,4},{0,1,4},{0,4,6}};
   int          flag = -1;
   POLY_F4      *plain;
   int          exiting = 0;

   //----------------------------------
   memoryp = (memoryp + 3) & 0xFFFFFFFC;        // Load the joypad image
   joypad[0] = (Character *)memoryp;            //
   memoryp += sizeof (Character);
   joypad[0]->Load ("\\SPRITES\\OPTIONS\\JOYPAD.KRT", &memoryp);
   joypad[0]->Scale (3000);
   joypad[1] = joypad[0]->Clone_Character (0, &memoryp);
   joypad[1]->Scale (3000);

   //----------------------------------
   memoryp = (memoryp + 3) & 0xFFFFFFFC;        // Load the buttons
   buttons[0][0] = (Character *)memoryp;        //
   memoryp += sizeof (Character);
   buttons[0][0]->Load ("\\SPRITES\\OPTIONS\\BUTTONS.KRT", &memoryp);
   buttons[1][0] = buttons[0][0]->Clone_Character (0, &memoryp);
   for (i = 0; i < 2; i++)
      for (j = 1; j < 9; j++)
         buttons[i][j] = buttons[0][0]->Clone_Character (0, &memoryp);
   for (i = 0; i < 2; i++)
   {
      for (j = 0; j < 6; j++)
      {
         buttons[i][j]->Set_Location (60, 50 + (i * 100) + (j * 12));
         buttons[i][j]->StartAction (j, 0);
         buttons[i][j]->SetDepth (17);
      }
   }

   for (i = 0; i < 2; i++)
   {
      for (j = 6; j < 9; j++)
      {
         buttons[i][j]->SetCharacteristics (128);
         buttons[i][j]->Set_Location (120, 50 + (i * 100) + ((j - 6) * 12));
         buttons[i][j]->StartAction (ButtonSelection[i][j - 6] + 6, 0);
         buttons[i][j]->SetDepth (17);
      }
   }

   //----------------------------------
   memoryp = (memoryp + 3) & 0xFFFFFFFC;        // Load the buttons light
   buttonlight[0][0] = (Character *)memoryp;    //
   memoryp += sizeof (Character);
   buttonlight[0][0]->Load ("\\SPRITES\\OPTIONS\\LITEBTN.KRT", &memoryp);
   buttonlight[1][0] = buttonlight[0][0]->Clone_Character (0, &memoryp);
   for (i = 0; i < 2; i++)
      for (j = 1; j < 8; j++)
         buttonlight[i][j] = buttonlight[0][0]->Clone_Character (0, &memoryp);

   for (i = 0; i < 2; i++)
   {
      for (j = 0; j < 8; j++)
      {
         short butx[8] = {262,275,285,273,195,195,272,272};
         short buty[8] = { 60, 70, 60, 49, 34, 34, 34, 34};
         buttonlight[i][j]->Set_Location (butx[j], buty[j] + 100 * i);
         if (j > 3)
            buttonlight[i][j]->StartAction (0, 0);
         else
            buttonlight[i][j]->StartAction (1, 0);
         buttonlight[i][j]->SetDepth (17);
         buttonlight[i][j]->SetCharacteristics (8);
      }
   }

   //----------------------------------
   joypad[0]->Set_Location (235, 75);       // Joypad images
   joypad[0]->StartAction (0, 0);           //
   joypad[0]->SetDepth (16);                //
   joypad[1]->Set_Location (235, 175);      //
   joypad[1]->StartAction (0, 0);           //
   joypad[1]->SetDepth (16);                //

   while (!exiting)
   {
      //-------------------------------
      padder[0] = GUN1;
      padder[1] = GUN2;

      for (i = 0; i < 2; i++)
      {
         if ((padder[i] & ~oldpadder[i] & PADL1) &&         // L1
             (ActualSelection[i] < 3))
            flag = 4;

         if ((padder[i] & ~oldpadder[i] & PADL2) &&         // L2
             (ActualSelection[i] < 3))
            flag = 5;

         if ((padder[i] & ~oldpadder[i] & PADR1) &&         // R1
             (ActualSelection[i] < 3))
            flag = 6;

         if ((padder[i] & ~oldpadder[i] & PADR2) &&         // R2
             (ActualSelection[i] < 3))
            flag = 7;

         if ((padder[i] & ~oldpadder[i] & PADRleft) &&      // Square
             (ActualSelection[i] < 3))
            flag = 0;

         if ((padder[i] & ~oldpadder[i] & PADRdown) &&      // Cross
             (ActualSelection[i] < 3))
            flag = 1;

         if ((padder[i] & ~oldpadder[i] & PADRright) &&     // Circle
             (ActualSelection[i] < 3))
            flag = 2;

         if ((padder[i] & ~oldpadder[i] & PADRup) &&        // Triangle
             (ActualSelection[i] < 3))
            flag = 3;

         if (flag != -1)
         {
            if ((ActualSelection[i] == 0) && (flag != ButtonSelection[i][1]) &&
                (flag != ButtonSelection[i][2]))
            {
               PlaySFX (commonvab, 32, 127,127);
               ButtonSelection[i][0] = flag;
               buttons[i][6]->StartAction (flag + 6, 0);
               flag = -1;
            }
            else if ((ActualSelection[i] == 1) && (flag != ButtonSelection[i][0]) &&
                (flag != ButtonSelection[i][2]))
            {
               PlaySFX (commonvab, 32, 127,127);
               ButtonSelection[i][1] = flag;
               buttons[i][7]->StartAction (flag + 6, 0);
               flag = -1;
            }
            else if ((ActualSelection[i] == 2) && (flag != ButtonSelection[i][0]) &&
                (flag != ButtonSelection[i][1]))
            {
               PlaySFX (commonvab, 32, 127,127);
               ButtonSelection[i][2] = flag;
               buttons[i][8]->StartAction (flag + 6, 0);
               flag = -1;
            }
            else
            {
               PlaySFX (commonvab, 32, 127,127);
               flag = -1;
            }
         }

         if (padder[i] & ~oldpadder[i] & PADLdown)          // Down
         {
            PlaySFX (commonvab, 32, 127,127);
            if ((++ActualSelection[i]) > 5)
               ActualSelection[i] = 0;
         }

         if (padder[i] & ~oldpadder[i] & PADLup)            // Up
         {
            PlaySFX (commonvab, 32, 127,127);
            if ((--ActualSelection[i]) < 0)
               ActualSelection[i] = 5;
         }

         if ((padder[i] & ~oldpadder[i] & PADselect) &&     // Select
             (ActualSelection[i] > 2))
         {
            PlaySFX (commonvab, 32, 127,127);
            int grui = ActualSelection[i] - 3;
            ButtonSelection[i][0] = Preset[grui][0];
            ButtonSelection[i][1] = Preset[grui][1];
            ButtonSelection[i][2] = Preset[grui][2];
            buttons[i][6]->StartAction (ButtonSelection[i][0] + 6, 0);
            buttons[i][7]->StartAction (ButtonSelection[i][1] + 6, 0);
            buttons[i][8]->StartAction (ButtonSelection[i][2] + 6, 0);
         }

         if ((padder[i] & ~oldpadder[i] & PADRdown) &&      // Cross
             (ActualSelection[i] > 2))
         {
            PlaySFX (commonvab, 32, 127,127);
            int grui = ActualSelection[i] - 3;
            ButtonSelection[i][0] = Preset[grui][0];
            ButtonSelection[i][1] = Preset[grui][1];
            ButtonSelection[i][2] = Preset[grui][2];
            buttons[i][6]->StartAction (ButtonSelection[i][0] + 6, 0);
            buttons[i][7]->StartAction (ButtonSelection[i][1] + 6, 0);
            buttons[i][8]->StartAction (ButtonSelection[i][2] + 6, 0);
         }

         if (padder[i] & ~oldpadder[i] & PADstart)          // Start
            exiting = 1;
      }

      //-------------------------------
      plain = db->Get_Plain ();             // Draw the transparent blue bar
      setRGB0 (plain, 0,128,255);           // behind the selected option plr1
      setXYWH (plain, 12,44 + 12 * ActualSelection[0], 125,12);
      SetSemiTrans (plain, 1);              //
      db->Add_Plain (plain, 16);            //

      plain = db->Get_Plain ();             // Draw the transparent blue bar
      setRGB0 (plain, 0,128,255);           // behind the selected option plr2
      setXYWH (plain, 12,144 + 12 * ActualSelection[1], 125,12);
      SetSemiTrans (plain, 1);              //
      db->Add_Plain (plain, 16);            //

      SetFontColor (1);
      FontCenterOn (160, 25);
      Print ("Player 1");
      FontCenterOn (160, 125);
      Print ("Player 2");

      joypad[0]->DrawNextFrame (0,0, db, &dummy, &dummy, &dummy);
      joypad[1]->DrawNextFrame (0,0, db, &dummy, &dummy, &dummy);
      for (i = 0; i < 2; i++)
         for (j = 0; j < 9; j++)
            buttons[i][j]->DrawNextFrame (0,0, db, &dummy, &dummy, &dummy);
      bkd->Draw (db, 0);

      for (i = 0; i < 2; i++)
      {
         if (ActualSelection[i] < 3)
            buttonlight[i][ButtonSelection[i][ActualSelection[i]]]->DrawNextFrame (0,0, db, &dummy, &dummy, &dummy);
         else
         {
            for (j = 0; j < 3; j++)
               buttonlight[i][Preset[ActualSelection[i] - 3][j]]->DrawNextFrame (0,0, db, &dummy, &dummy, &dummy);
         }
      }

      db->Swap (0);

      oldpadder[0] = padder[0];
      oldpadder[1] = padder[1];
   }

   joypad[0]->Clear ();                 // Clear all the shit out of memory
   joypad[1]->Clear ();                 //
   for (i = 0; i < 2; i++)              //
   {                                    //
      for (j = 0; j < 6; j++)           //
         buttons[i][j]->Clear ();       //
      for (j = 0; j < 8; j++)           //
         buttonlight[i][j]->Clear ();   //
   }                                    //
}
