int PlayMovie (char *filename, int start, int end, u_long memoryp,
                      DoubleBuffer *db, int passit);

//-------------------------------------
//
//-------------------------------------
int Select_Screen (u_long memptr, Foreground *frgnd, DoubleBuffer *db, int vabnbr)
{
   u_long     padd = 0, padd2 = 0;
   Background *bkd;
   Character  *Chars[12];
   int        i, j, k;
   int        counter;
   int        levelselect;
   int        trigger = 0;
   PLAYER     *player;
   int        holex = -100, holey = 0;
   SPRT       *sprite;
   DR_MODE    *drmode;
   RECT       tww;
   int        dummy;                     // Dummy...
   int        sfx;                       //
   int        vab;                       //
   u_long     merde;                     //
   char       nbrlevels[2] = {6,5};      //
   int        coorx[2][6] = {{30,118,206, 30,118,206}, {30,118,206, 74,162}};
   int        coory[2][6] = {{75, 75, 75,148,148,148}, {60, 60, 60,140,140}};
   int        actualvol = MusicVol;
   char       *Names[2] = {"\\SPRITES\\SELECT.KRT", "\\SPRITES\\LE2\\SELECT.KRT"};

   #ifdef TARGETCD
      #ifdef PLAY_CDXAS
         AudioChangeVolume (CDXAId, actualvol);
      #endif
   #endif

   memptr = (u_long)((memptr + 3) & 0xFFFFFFFC);
   bkd = (Background *)memptr;
   memptr += sizeof (Background);

   memptr = (u_long)((memptr + 3) & 0xFFFFFFFC);
   Chars[0] = (Character *)memptr;
   memptr += sizeof (Character);

   if (LE1orLE2)
   {
      bkd->Load ("\\BACKGRND\\LE2\\MISCELLA\\LE2STGSL.BKD", &memptr);
      bkd->SetLocation (0,0);
   }

   Chars[0]->Load (Names[LE1orLE2], &memptr);
   for (i = 1; i < (nbrlevels[LE1orLE2] << 1); i++)
      Chars[i] = Chars[0]->Clone_Character (1, &memptr);

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

   for (i = 0; i < nbrlevels[LE1orLE2]; i++)
   {
      Chars[i]->StartAction (i, 0);
      Chars[i]->Set_Location (coorx[LE1orLE2][i] + 42, coory[LE1orLE2][i] + 42);
      Chars[i]->SetDepth (3);
      if (CannotSelect[i] == 1)
      {
         Chars[i + nbrlevels[LE1orLE2]]->StartAction (nbrlevels[LE1orLE2], 0);
         Chars[i + nbrlevels[LE1orLE2]]->Set_Location (coorx[LE1orLE2][i] + 42, coory[LE1orLE2][i] + 42);
         Chars[i + nbrlevels[LE1orLE2]]->SetDepth (4);
      }
   }

   frgnd->Plr1.GunX = 160;
   frgnd->Plr1.GunY = 120;
   frgnd->Plr2.GunX = 160;
   frgnd->Plr2.GunY = 120;

   counter = 900;
   while (counter > 0)
   {
      Control_Read (&trigger, frgnd, vabnbr, &dummy);

      Draw_Gun_Cursor (frgnd, db, 0);
      for (i = 0; i < (nbrlevels[LE1orLE2] << 1); i++)
         Chars[i]->DrawNextFrame (0,0, db, &sfx, &vab, &dummy);

      if (!LE1orLE2)
      {
         SetFontColor (0);
         FontCenterOn (160, 59);
         Print ("STAGE SELECT");
      }
      else
         bkd->Draw (db, 0);

      Draw_Foreground (frgnd, db, 1, vabnbr);

      if (trigger)                      // If fire is pressed, check which
      {                                 // background has been selected
         if (trigger & 1)
            player = &frgnd->Plr1;
         else
            player = &frgnd->Plr2;

         PlaySFXOnV (vabnbr, 1, 0, 127,127);

         trigger = 0;

         for (i = 0; i < nbrlevels[LE1orLE2]; i++)
         {
            if ((player->GunX >= coorx[LE1orLE2][i]) &&
                (player->GunX < coorx[LE1orLE2][i] + 84) &&
                (player->GunY >= coory[LE1orLE2][i]) &&
                (player->GunY < coory[LE1orLE2][i] + 84) &&
                (CannotSelect[i] != 1))
            {
               levelselect = i;
               counter = -1;
               holex = player->GunX;
               holey = player->GunY;
            }
         }

         if (counter != -1)
            PlaySFXOnV (vabnbr, 9, 1, 127,127);
      }

      if ((VSync (-1) & 32) && (!LE1orLE2))
      {
         FontCenterOn (160, 145);
         Print ("SHOOT TO SELECT");
      }

      if (debug)
         FntPrint ("MusicVolume:%d  ActualVolume:%d\n", MusicVol, actualvol);
      db->Swap (debug);
   }

   for (i = 0; i < nbrlevels[LE1orLE2]; i++)
   {
      if (i != levelselect)
         Chars[i]->BuildDestClut (2);
   }

   //----------------------------------
   j = 1;
   while (j || actualvol)
   {
      if (actualvol)
      {
         actualvol--;
         #ifdef TARGETCD
            #ifdef PLAY_CDXAS
               AudioChangeVolume (CDXAId, actualvol);
            #endif
         #endif
      }

      sprite = db->Get_Spr ();
      setXY0 (sprite, holex - 7, holey - 7);
      sprite->w = 14;
      sprite->h = 15;
      sprite->u0 = 186;
      sprite->v0 = 92;
      sprite->clut = GetClut (0, FrgndClutY[0] + 480);
      db->Add_Spr (sprite, 14);

      drmode = db->Get_DrMode ();
      tww.x = FrgndTX;
      tww.y = FrgndTY;
      tww.w = 256;
      tww.h = 256;
      SetDrawMode (drmode, 0, 0, GetTPage (1, 0, FrgndTX,FrgndTY), &tww);
      db->Add_DrMode (drmode, 14);

      for (i = 0; i < nbrlevels[LE1orLE2]; i++)
      {
         if (i != levelselect)
         {
            j = Chars[i]->ChangeClut (0);
            j = Chars[i]->ChangeClut (0);
         }
      }

      if (j == 0)
      {
         for (i = 0; i < nbrlevels[LE1orLE2]; i++)
            if (i != levelselect)
               Chars[i]->StopAction ();

         SetFontColor (0);
         FontCenterOn (160,120);
         Print ("Loading...");
      }

      Draw_Foreground (frgnd, db, 1, vabnbr);

      if (!LE1orLE2)
      {
         SetFontColor (0);
         FontCenterOn (160, 59);
         Print ("STAGE SELECT");
      }

      for (i = 0; i < nbrlevels[LE1orLE2]; i++)
         Chars[i]->DrawNextFrame (0,0, db, &sfx, &vab, &dummy);

      db->Swap (debug);
   }

   for (i = 0; i < (nbrlevels[LE1orLE2] << 1); i++)
      Chars[i]->Clear ();

   if (LE1orLE2)
      bkd->Clear ();

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

   return (levelselect);
}

//-------------------------------------
// Show the title screen
//-------------------------------------
int TitleScreen (u_long memptr, DoubleBuffer *db, Foreground *frgnd, int vabnbr)
{
   int     Black = 1;
   int     i, j, k;
   int     Counter;
   int     sfx;
   POLY_F4 *plain;
   int     tiscclut[3];
   int     tpx[3], tpy[3];
   short   pictvrammemhandle[3];
   RECT    tww;
   DR_MODE *drmode;
   int     spru[16] = {40,0,0,0,154,234,314,394,0,42,84,0,126,216,306,0};
   int     sprv[16] = {0,32,64,0,0,0,0,0,84,84,84,176,126,126,126,0};
   int     sprw[16] = {176,256,256,152,80,80,80,80,40,40,40,70,88,88,88,256};
   int     sprh[16] = {31,31,64,84,126,126,126,126,90,90,90,8,126,126,126,164};
   int     sprstart[16] = {90,90,230,0,0,160,175,200,0,10000,
                           10000,0,10000,10000,10000,230};
   int     sprend[16] = {230,230,600,230,160,175,200,230,
                         230,230,230,230,230,230,230,600};
   int     sprstrtx[16] = {72,32,32,320,512,240,240,240,472,0,0,522,0,0,0,64};
   int     sprstrty[16] = {-45,270,96,50,50,50,50,50,50,0,0,176,0,0,0,20};
   int     sprdestx[16] = {72,32,32,48,240,240,240,240,200,0,0,250,0,0,0,64};
   int     sprdesty[16] = {96,129,96,50,50,50,50,50,50,0,0,176,0,0,0,20};
   int     sprstep[16] = {25,25,1,40,40,1,1,1,40,10,10,40,10,10,10,1};
   int     sprwpage[16] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2};
   int     sprdepth[16] = {14,14,14,5,5,5,5,5,5,5,5,5,5,5,5,5};
   char    *filename[3] = {"\\SPRITES\\TITLE1.TIM",
                           "\\SPRITES\\TITLE2.TIM",
                           "\\SPRITES\\TITLE3.TIM"};
   TIM_IMAGE timimg;
   SPRT    *sprite;
   int     trig;
   int     buttons = 0;

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

   //----------------------------------
   for (i = 0; i < 3; i++)
   {
      if (memptr & 3)
         memptr = (u_long)((memptr + 4) & 0xFFFFFFFC);
      if (ReadFont (filename[i], memptr) == 0)
      {
         while (1)
         {
            return (-1);
            FntPrint ("Unable to load file.\n");
            FntFlush (-1);
         }
      }

      if (OpenTIM ((u_long *)memptr))
         while (1)
         {
            return (-1);
            FntPrint ("Unable to load file.\n");
            FntFlush (-1);
         }

      if (!ReadTIM (&timimg))
         while (1)
         {
            return (-1);
            FntPrint ("Unable to load file.\n");
            FntFlush (-1);
         }

      if ((tiscclut[i] = AllocClut ()) == -1)
         return (-1);
      else
         tiscclut[i] += 480;

      RECT shit = {0,tiscclut[i], 256,1};
      if (timimg.crect)
         LoadImage (&shit, timimg.caddr);

      point po = AllocVram (timimg.prect->w, timimg.prect->h,
                            &pictvrammemhandle[i], 1);

      tpx[i] = po.x;
      tpy[i] = po.y;

      if (timimg.prect)
      {
         RECT shit2 = {po.x, po.y, timimg.prect->w, timimg.prect->h};
         LoadImage (&shit2, timimg.paddr);
         DrawSync (0);
      }
   }

   #ifdef TARGETCD
      #ifdef PLAY_CDXAS
         CDXAId = AudioPlayCue (SD_Tile1);
      #endif
   #endif

   db->ClearDrawArea (255,255,255); // Turn the screen to white
   db->Swap (debug);                //
   db->Swap (debug);                //

   //----------------------------------
   Counter = 0;
   while (Black && (Counter < 550))
   {
      if (VSync (-1) & 32)
      {
         SetFontColor (0);
         FontCenterOn (160,195);
         Print ("Press start to begin\n");
         FontCenterOn (160,213);
         Print ("Press select for options");
      }

      if (Counter == 115)
         PlaySFX (vabnbr, 30, 127,127);

      if (Counter == 230)
         PlaySFX (vabnbr, 1, 127,127);

      if ((Counter < 230) || (Counter > 232))
      {
         plain = db->Get_Plain ();
         setXY4 (plain, 0,0, 319,0, 0,239, 319,239);
         setRGB0 (plain, 230,0,0);
         SetSemiTrans (plain, 0);
         db->Add_Plain (plain, 0);

         for (i = 0; i < 16; i++)
         {
            if ((Counter >= sprstart[i]) && (Counter < sprend[i]))
            {
               sprite = db->Get_Spr ();
               if (Counter >= (sprstart[i] + sprstep[i]))
                  setXY0 (sprite, sprdestx[i], sprdesty[i]);
               else
                  setXY0 (sprite, (sprdestx[i] - sprstrtx[i]) * (Counter -
                                   sprstart[i]) / sprstep[i] + sprstrtx[i],
                                  (sprdesty[i] - sprstrty[i]) * (Counter -
                                   sprstart[i]) / sprstep[i] + sprstrty[i]);
               sprite->w = sprw[i];
               sprite->h = sprh[i];
               sprite->u0 = spru[i] & 127;
               sprite->v0 = sprv[i];
               sprite->clut = GetClut (0, tiscclut[sprwpage[i]]);
               db->Add_Spr (sprite, sprdepth[i]);

               drmode = db->Get_DrMode ();
               tww.x = tpx[sprwpage[i]] + ((spru[i] >> 1) & ~63);
               tww.y = tpy[sprwpage[i]];
               tww.w = 256;
               tww.h = 256;
               SetDrawMode (drmode, 0, 0, GetTPage (1, 0,
                            tpx[sprwpage[i]] + ((spru[i] >> 1) & ~63), tpy[sprwpage[i]]),
                            &tww);
               db->Add_DrMode (drmode, sprdepth[i]);
            }
         }
      }
      else
      {
         plain = db->Get_Plain ();
         setXY4 (plain, 0,0, 319,0, 0,239, 319,239);
         setRGB0 (plain, 255,255,255);
         SetSemiTrans (plain, 0);
         db->Add_Plain (plain, 0);
      }

      Counter++;

      if (buttons == 0)
      {
         Control_Read (&trig, frgnd, vabnbr, &buttons); // Start button ?
         if (buttons & 1)
            Black = 0;
         if (buttons & 544)                             // Select button ?
         {
            db->ClearDrawArea (0,0,0);  // Turn the screen to black
            db->Swap (debug);           //
            db->Swap (debug);           //
            db->Swap (debug);           //
            for (i = 0; i < 3; i++)
            {
               FreeVram (pictvrammemhandle[i]);
               FreeClut (tiscclut[i] - 480);
            }
            #ifdef TARGETCD
               #ifdef PLAY_CDXAS
                  AudioStop (CDXAId);
               #endif
            #endif
            Options (frgnd, db, vabnbr, memptr);
            return (0);
         }
      }

      db->Swap (debug);
   }

   for (i = 0; i < 3; i++)
   {
      FreeVram (pictvrammemhandle[i]);
      FreeClut (tiscclut[i] - 480);
   }

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

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

   return (0);
}

//-------------------------------------
// Intro sequence
//-------------------------------------
// Return 0 if there's a player
// Otherwise, return -1 for a demo
//-------------------------------------
int Intro (u_long memptr, DoubleBuffer *db, Foreground *frgnd, int vabnbr)
{
   int        Black = 1;
   int        OfsWritings;
   int        i, j, k;
   int        Counter;
   Character  *guns[2];
   char       *Number = "     ";
   int        sfx;
   int        vab;
   POLY_F4    *plain;
   int        x1 = -160, x2 = 319;
   shootpnt   *marde;
   int        dummy;
   int        trig, buttons;
   static     KonamiMovie = 5;
   int        Demo = 1;

   if (((frgnd->Plr1.Lifepnt != 0) && (frgnd->Plr1.Score != 0)) ||
       ((frgnd->Plr2.Lifepnt != 0) && (frgnd->Plr2.Score != 0)))

      return (0);

   //----------------------------------
   DynamicDifficulty = 11;

   if (memptr & 3)
      memptr = (u_long)((memptr + 4) & 0xFFFFFFFC);
   guns[0] = (Character *)memptr;
   memptr += sizeof (Character);

   guns[0]->Load ("\\SPRITES\\GUNS.KRT", &memptr);
   guns[1] = guns[0]->Clone_Character (0, &memptr);
   for (i = 0; i < 2; i++)
   {
      guns[i]->Set_Location (-89 + 497 * i,120);
      guns[i]->SetDepth (15);
      guns[i]->StartAction (0, i);
   }

   while ((frgnd->Plr1.Lifepnt == 0) && (frgnd->Plr2.Lifepnt == 0) && (Demo--))
   {
      frgnd->Credits = 99;
      TitleScreen (memptr, db, frgnd, vabnbr);
      if ((frgnd->Plr1.Lifepnt == 0) && (frgnd->Plr2.Lifepnt == 0))
      {
         if (LE1orLE2 == 0)
            Hall_Of_Fame (memptr, db, frgnd, vabnbr);
         else
            Hall_Of_Fame2 (memptr, db, frgnd, vabnbr);
      }
      frgnd->Credits = 99;
      if (--KonamiMovie == 0)
      {
         KonamiMovie = 5;
         #ifdef TARGETCD
            #ifdef PLAY_MOVIES
               PlayMovie ("\\MOVIES\\KONAMI.STR;1", 1, 122, memptr, db, 1);
            #endif
         #endif
      }
   }

   //-------------------------------
   if ((frgnd->Plr1.Lifepnt == 0) && (frgnd->Plr2.Lifepnt == 0))
   {
      guns[0]->Clear ();                   // Enter demo mode!
      guns[1]->Clear ();                   //

      db->ClearDrawArea (0,0,0);
      db->Swap (debug);
      db->Swap (debug);

      return (-1);
   }

   //----------------------------------
   Counter = 100;
   while (Counter--)
   {
      buttons = 0;
      Control_Read (&trig, frgnd, vabnbr, &buttons);

      if (frgnd->Plr1.Lifepnt != 0)
      {
         plain = db->Get_Plain ();
         setXY4 (plain, x1,0, x1 + 159,0, x1,239, x1 + 159,239);
         setRGB0 (plain, 255,0,0);
         SetSemiTrans (plain, 0);
         db->Add_Plain (plain, 0);
         if (x1 < 0)
            x1 += 10;
         marde = guns[0]->DrawNextFrame (0,0, db, &sfx, &vab, &dummy);
         if (marde != NULL)
            PlaySFX (vabnbr, 1, 127,0);
      }

      if (frgnd->Plr2.Lifepnt != 0)
      {
         plain = db->Get_Plain ();
         setXY4 (plain, x2,0, x2 + 159,0, x2,239, x2 + 159,239);
         setRGB0 (plain, 0,0,255);
         SetSemiTrans (plain, 0);
         db->Add_Plain (plain, 0);
         if (x2 > 159)
            x2 -= 10;
         marde = guns[1]->DrawNextFrame (0,0, db, &sfx, &vab, &dummy);
         if (marde != NULL)
            PlaySFX (vabnbr, 1, 0,127);
      }

      if (buttons & 1)
         Counter = 100;

      db->Swap (debug);
   }

   guns[0]->Clear ();
   guns[1]->Clear ();

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

   return (0);
}
