//---------------------------------------------------------------------------
// Sound system class
//---------------------------------------------------------------------------

#include <libsnd.h>

#define  MAXVOICE      24
#define  MAXVAB        3
#define  MAXSFXPERVAB  128
#define  MAXTRACK      30

char     SSseq_table[SS_SEQ_TABSIZ];
VabHdr   SSvabhdr[MAXVAB];
VagAtr   SSvagatr[MAXVAB][MAXSFXPERVAB];
u_long   *SSSEQAddress;
short    SSSEQAccessNbr;
short    SSVabId[MAXVAB];
int      SSVabNbr;
CdlLOC   TOC[MAXTRACK];
CdlLOC   CDTrackSize[MAXTRACK];
int      ActualTrack = -1;
int      NbrCDTrack = 0;
int      LoopTestTime = 60;
char     Voices = 0;

//-------------------------------------
// Play a sound fx
//-------------------------------------
// volr represent, in 1/128 units, the
// percentage of the volume on the
// right.  voll can then be easily
// calculated by 128 - volr.
//-------------------------------------
void PlaySFX (int vabnbr, int sfxnbr, int voll, int volr)
{
   if (!DemoMode)
   {
      SsUtKeyOffV (Voices);
      SsUtKeyOnV (Voices, SSVabId[vabnbr], sfxnbr / 16, sfxnbr % 16,
                  SSvagatr[vabnbr][sfxnbr].min,
                  SSvagatr[vabnbr][sfxnbr].shift * 100 / 127,
                  SSvagatr[vabnbr][sfxnbr].vol * (voll * SfxVol / 127) / 127,
                  SSvagatr[vabnbr][sfxnbr].vol * (volr * SfxVol / 127) / 127);
      if ((++Voices) == MAXVOICE)
         Voices = 0;
   }
}

//-------------------------------------
// Play a sound fx on a specified voice
//-------------------------------------
// volr represent, in 1/128 units, the
// percentage of the volume on the
// right.  voll can then be easily
// calculated by 128 - volr.
//-------------------------------------
void PlaySFXOnV (int vabnbr, int sfxnbr, int voice, int voll, int volr)
{
   if (!DemoMode)
   {
      SsUtKeyOffV (voice);
      SsUtKeyOnV (voice, SSVabId[vabnbr], sfxnbr / 16, sfxnbr % 16,
                  SSvagatr[vabnbr][sfxnbr].min,
                  SSvagatr[vabnbr][sfxnbr].shift * 100 / 127,
                  SSvagatr[vabnbr][sfxnbr].vol * (voll * SfxVol / 127) / 127,
                  SSvagatr[vabnbr][sfxnbr].vol * (volr * SfxVol / 127) / 127);
   }
}

//-------------------------------------
// Initialize the sound system
//-------------------------------------
void SoundInit (void)
{
   int i;

   SsInit ();
   SsSetTableSize (SSseq_table, 1, 1);
   SsSetTickMode (SS_TICK240);
   SsStart ();
   SsSetMVol (127, 127);

   SSVabNbr = 0;

   for (i = 0; i < MAXVAB; i++)
   SSVabId[i] = -1;

   #ifdef TARGETCD
      CdlATV ATV;
      ATV.val0 = 127;
      ATV.val1 = 127;
      ATV.val2 = 127;
      ATV.val3 = 127;
      CdMix (&ATV);

      SsSetSerialAttr (SS_SERIAL_A, SS_MIX, SS_SON);
      SsSetSerialVol (SS_SERIAL_A, 0x7F, 0x7F);

//      NbrCDTrack = CdGetToc (TOC);    // Get the starting pos. of each track
//
//      if (NbrCDTrack > 0)
//      {
//         int start, end, time, i;
//
//         for (i = 0; i < NbrCDTrack; i++)
//         {
//            start = btoi (TOC[i].second) + (btoi (TOC[i].minute) * 60);
//            end = btoi (TOC[i + 1].second) + (btoi (TOC[i + 1].minute) * 60);
//
//            // Compensate for the five second gap between tracks
//            time = end - start - 5;
//
//            CDTrackSize[i].second = itob (time % 60);
//            CDTrackSize[i].minute = itob (time / 60);
//         }
//      }
   #endif
}

//-------------------------------------
// Dump sound system data on the screen
//-------------------------------------
void SoundDumpData (int vabn)
{
   FntPrint ("FSize[%d]: %d\n", vabn, SSvabhdr[vabn].fsize);
}

//-------------------------------------
// Load a library of sound fx (VAB)
//-------------------------------------
// Returns -1 if unsuccessful.
//-------------------------------------
int LoadSFX (char filename[], u_long *memptr)
{
   char *memloc;
   int filesize;
   int i;

   memloc = (char *)*memptr;

   if ((u_long)memloc & 3)
      memloc = (char *)(((u_long)memloc + 4) & 0xFFFFFFFC);

   if (OpenFile (filename) == -1)
      return (-1);

   // Check the filesize
   filesize = FileSize ();

   // Reads the entire file in memory
   if (ReadFile (memloc, filesize) != filesize)
   {
      CloseFile ();
      return (-1);
   }

   // Close the file
   if (CloseFile () == -1)
      return (-1);

   if ((SSVabId[SSVabNbr] = SsVabOpen ((u_char *)memloc, &SSvabhdr[SSVabNbr])) == -1)
      return (-1);
   SsVabTransCompleted (SS_WAIT_COMPLETED);

   if (SsUtGetVabHdr (SSVabId[SSVabNbr], &SSvabhdr[SSVabNbr]))
      return (-1);

   memloc += 0xA10 + 0x200 * SSvabhdr[SSVabNbr].ps;     //filesize;
   *memptr = (u_long)memloc;

   for (i = 0; i < SSvabhdr[SSVabNbr].vs; i++)
      SsUtGetVagAtr (SSVabId[SSVabNbr], i / 16, i % 16, &SSvagatr[SSVabNbr][i]);

   SSVabNbr++;

   return (SSVabNbr - 1);
}

//-------------------------------------
// Close a sound fx bank
//-------------------------------------
int CloseSFX (int vabnbr)
{
   int i;

   SsVabClose (SSVabId[vabnbr]);        // close vab data
   SSVabId[vabnbr] = -1;

   for (i = MAXVAB - 1; i >= 0; i--)
   {
      if (SSVabId[i] == -1)
         SSVabNbr = i;
   }
}

//-------------------------------------
// Return the number of sfx in a read
// VAB
//-------------------------------------
int NbrSFX (int vabnbr)
{
   if (vabnbr > SSVabNbr)
      return (0);
   else
      return (SSvabhdr[vabnbr].vs);
}
