
typedef struct {
       UWORD Period;
       UWORD Volume;
       UWORD Cycles;
       UBYTE *Data;
       ULONG Length;
       UBYTE Init_Priority;
       UBYTE Second_Priority;
       UBYTE Flags;
       UBYTE *Channel_Select;
       UBYTE NoOfSelect;
} SOUNDSTRUCT;

       extern void     *OpenLibrary(), *AllocRaster(), *AllocMem(), 
                       *CreatePort();

       extern long     OpenDevice(), DoIO();


#define LEFT0F    1
#define RIGHT0F   2
#define RIGHT1F   4
#define LEFT1F    8

UBYTE Left_Right[]     = { LEFT0F,LEFT1F,RIGHT0F,RIGHT1F };
UBYTE Right_Left[]     = { RIGHT1F,RIGHT0F,LEFT1F,LEFT0F };
UBYTE Left_Only[]      = { LEFT1F,LEFT0F };
UBYTE Right_Only[]     = { RIGHT0F,RIGHT1F };
UBYTE Left0[]	= { LEFT0F };
UBYTE Right0[]	= { RIGHT0F };
UBYTE Left1[]	= { LEFT1F };
UBYTE Right1[]	= { RIGHT1F };

BOOL AudioDevice = FALSE;

struct IOAudio *Audio[7];
struct MsgPort *RpyPort[7];

/***********************************************************************/

SOUNDSTRUCT Entrance_Sound[2] = {
{
   1200,   /* Period */
   64,   /* Volume */
   1,     /* Cycles */
   NULL,  /* Data   */
   0,     /* Length */
   -2,    /* Sound effect Priority */
   -3,    /* Want Entrances to always fire if possible */
   NULL,
   Left0, /* This is the Left tank Only want the Left Speaker. */
   1          /* Thats two cannels to choose from */
},
{
   1800,   /* Period */
   64,   /* Volume */
   1,     /* Cycles */
   NULL,  /* Data   */
   0,     /* Length */
   -2,    /* Sound effect Priority */
   -3,    /* Want Entrances to always fire if possible */
   NULL,
   Right0, /* This is the Left tank Only want the Left Speaker. */
   1          /* Thats two cannels to choose from */
}
	};


BOOL AudioExtra[2];

SoundSetup()
{
   short i;
   
   /* First allocate memory for Audio IO */
   for (i = 0;i<7;i++) {
       if (!(Audio[i]=(struct IOAudio *)AllocMem(sizeof(struct IOAudio),
               MEMF_PUBLIC | MEMF_CLEAR))) {
           printf("Unable to create Audio IO port\n");
           _abort();
       }
   }
   if (!(RpyPort[0] = CreatePort("p0",0))) _abort();
   if (!(RpyPort[1] = CreatePort("p1",0))) _abort();
   if (!(RpyPort[2] = CreatePort("p2",0))) _abort();
   if (!(RpyPort[3] = CreatePort("p3",0))) _abort();
   if (!(RpyPort[4] = CreatePort("p4",0))) _abort();
   if (!(RpyPort[5] = CreatePort("p4",0))) _abort();
   if (!(RpyPort[6] = CreatePort("p4",0))) _abort();
   for (i = 0;i<7;i++) {
       Audio[i]->ioa_Request.io_Message.mn_ReplyPort = RpyPort[0];
   }

   
   if((OpenDevice(AUDIONAME,0L,Audio[0],0L))!=NULL)
      {
      printf("Can't open Audio Device!\n");
      _abort();
      }
   AudioDevice = TRUE;
   
   *Audio[1] = *Audio[0];
   *Audio[2] = *Audio[0];
   *Audio[3] = *Audio[0];
   *Audio[4] = *Audio[0];
   *Audio[5] = *Audio[0];
   *Audio[6] = *Audio[0];
   for (i = 0;i<7;i++) {
       Audio[i]->ioa_Request.io_Message.mn_ReplyPort = RpyPort[i];
   }

   /* Now all Audio[] must be replyed */
   for (i = 0;i<5;i++) {
       ReplyMsg(Audio[i]);
   }
   AudioExtra[0] = FALSE;
   AudioExtra[1] = FALSE;
}

FreeSound()
{                       
   int i;
   

   for(i=0;i<7;i++) {
       if (!(CheckIO(Audio[i]))) AbortIO(Audio[i]);
   }
   if (AudioDevice) CloseDevice(Audio[0]);
   for(i=0;i<7;i++) {
       if (RpyPort[i]) DeletePort(RpyPort[i]);
   }
   for(i=0;i<7;i++) {
       if (Audio[i]) FreeMem(Audio[i],sizeof(struct IOAudio));
   }
}

BOOL PlaySound(Sound)
   SOUNDSTRUCT *Sound;
{
   register struct IOAudio *ad;
   short i;
   
   ad = NULL;
   for(i=0;i<5;i++) {
       if (CheckIO(Audio[i])) {
           ad = Audio[i];
           if (ad->ioa_Request.io_Command == CMD_WRITE) {
               ad->ioa_Request.io_Command = ADCMD_FREE;
               ad->ioa_Request.io_Message.mn_Node.ln_Pri= -127;
               BeginIO(ad);
           }
       }
   }
   if (ad == NULL) return(FALSE);
   WaitIO(ad);
   ad->ioa_Request.io_Command = ADCMD_ALLOCATE;
   ad->ioa_Request.io_Flags   = ADIOF_NOWAIT;
   ad->ioa_Data = Sound->Channel_Select;
   ad->ioa_Length = Sound->NoOfSelect;
   ad->ioa_Request.io_Message.mn_Node.ln_Pri=Sound->Init_Priority;
   ad->ioa_AllocKey = 0;
   BeginIO(ad);
   if (WaitIO(ad)) return(FALSE);
   
   if (Sound->Init_Priority != Sound->Second_Priority) {
       ad->ioa_Request.io_Command = ADCMD_SETPREC;
       ad->ioa_Request.io_Message.mn_Node.ln_Pri=Sound->Second_Priority;
       BeginIO(ad);
       WaitIO(ad);
   }
   
   ad->ioa_Request.io_Command=CMD_WRITE;
   ad->ioa_Request.io_Flags=ADIOF_PERVOL|IOF_QUICK;
   ad->ioa_Data=Sound->Data;
   ad->ioa_Cycles=Sound->Cycles;
   ad->ioa_Length=Sound->Length;
   ad->ioa_Period=Sound->Period;
   ad->ioa_Volume=Sound->Volume;
   BeginIO(ad);
   return(TRUE);
}

struct IOAudio *PlayBack(Sound)
   SOUNDSTRUCT *Sound;
{
   register struct IOAudio *ad;
   short i;
   
   ad = NULL;
   for(i=0;i<5;i++) {
       if (CheckIO(Audio[i])) {
           ad = Audio[i];
           if (ad->ioa_Request.io_Command == CMD_WRITE) {
               ad->ioa_Request.io_Command = ADCMD_SETPREC;
               ad->ioa_Request.io_Message.mn_Node.ln_Pri= -127;
               BeginIO(ad);
           }
       }
   }
   if (ad == NULL) return(FALSE);
   WaitIO(ad);
   ad->ioa_Request.io_Command = ADCMD_ALLOCATE;
   ad->ioa_Request.io_Flags   = ADIOF_NOWAIT;
   ad->ioa_Data = Sound->Channel_Select;
   ad->ioa_Length = Sound->NoOfSelect;
   ad->ioa_Request.io_Message.mn_Node.ln_Pri=Sound->Init_Priority;
   BeginIO(ad);
   if (WaitIO(ad)) return(FALSE);
   
   if (Sound->Init_Priority != Sound->Second_Priority) {
       ad->ioa_Request.io_Command = ADCMD_SETPREC;
       ad->ioa_Request.io_Message.mn_Node.ln_Pri=Sound->Second_Priority;
       BeginIO(ad);
       WaitIO(ad);
   }
   
   ad->ioa_Request.io_Command=CMD_WRITE;
   ad->ioa_Request.io_Flags=ADIOF_PERVOL|IOF_QUICK;
   ad->ioa_Data=Sound->Data;
   ad->ioa_Cycles=Sound->Cycles;
   ad->ioa_Length=Sound->Length;
   ad->ioa_Period=Sound->Period;
   ad->ioa_Volume=Sound->Volume;
   BeginIO(ad);
   if (!(AudioExtra[0])) {
        *Audio[5] = *ad;
	ad = Audio[5];
        AudioExtra[0] = TRUE;
   }
   else {
	if (!(AudioExtra[1])) {
            *Audio[6] = *ad;
            ad = Audio[6];
            AudioExtra[1] = TRUE;
        }
        else return(FALSE);
   }
   ad->ioa_Request.io_Command=ADCMD_PERVOL;
   ad->ioa_Request.io_Flags=IOF_QUICK;
   return(ad);
}
   
BOOL LoadSound(name,ss)
   char *name;
   SOUNDSTRUCT *ss;
{
   long size;
   FILE *file;
   int i;
   WORD *pt;
 
   if (!(file = fopen(name,"r"))) {
       printf("Could not open %s sound file.\n",name);
       _abort();
   }
   size = FLength(file);
   ss->Length = size;
   fseek(file,0L,0);
   if (!(ss->Data =(UBYTE *)AllocMem(sizeof(UBYTE)*size,
               MEMF_CHIP | MEMF_CLEAR))) {
           printf("Unable to Allocate memory for sound data\n");
           fclose(file);
           _abort();
   }
       if (!(fread(ss->Data,size,1,file))) {
           printf("Unable to read file into buffer\n");
           printf("Got to %d\n",ftell(file));
           fclose(file);
           _abort();
       }

   fclose(file);
   return(TRUE);
}

FreeSoundData(ss)
   SOUNDSTRUCT *ss;
{
   if (ss->Data) FreeMem(ss->Data,ss->Length);
}



LoadAllSounds()
{
   if (!(LoadSound("Data:Entrance",&Entrance_Sound[0]))) _abort;
   Entrance_Sound[1].Data = Entrance_Sound[0].Data;
   Entrance_Sound[1].Length = Entrance_Sound[0].Length;

}

RemoveAllSounds()
{

   if (Entrance_Sound[0].Data) FreeSoundData(&Entrance_Sound[0]);
}

long FLength(file)
   FILE *file;
{
   long i;
   
   fseek(file,0L,2);
   i = ftell(file);
   return(i);
}

/*
main()
{
   long i;
   
   SoundSetup();
   LoadAllSounds();
   PlaySound(&Entrance_Sound[0]);
   for(i=0;i<1000;i++);
   PlaySound(&Entrance_Sound[1]);
   for(i=0;i<100000;i++);
   RemoveAllSounds();
   FreeSound();
   exit(1);
}
*/