/*

InvaderCraft von J.Hertel
(C) CW-Publikationen

  "sound.c"


    Wenn keine Soundfiles verfuegbar sind, kann dieser Programmteil
                  vollstaendig weggelassen werden !


Kompilieren mit Aztec C Version 3.20a.

Im Include-Directory muss sich das Header-File "invadercraft1.h" befinden!

Aufruf:  cc sound -a
         as sound

Linken:  siehe invadercraft.c

*/

#include <libraries/dos.h>
#include <devices/audio.h>
#include <exec/memory.h>

/* Vor Compiler-Aufruf unbedingt "invadercraft1.h" in include/ -
Directory kopieren! */

#include <invadercraft1.h>

extern struct FileInfoBlock *fib;
extern struct Lock *lock,*Lock();
extern struct FileHandle *fh,*Open();
extern long Read(),Examine();
extern UBYTE *AllocMem();

struct MsgPort *port[5],*CreatePort();
struct IOAudio *ioa[5],CreateExtIO();
long OpenDevice(),deverror=1;

UBYTE alloc[]={0xf};

/* Fuer jeden Sound sind hier der Name, die Rate, die Anzahl an
Wiederholungen und die Lautstaerke einzutragen (in dieser Reihenfolge).

Name: Unter diesem Namen ist der Sound auf Diskette zu finden.
      Wird eine 0 (ohne Anfuehrungszeichen) eingetragen, so gilt der
      Sound als nicht verfuegbar, die uebrigen Eintraege koennen entfallen.

Rate: Frequenzbestimmend, in der Regel etwa 90...1000 (alle bekannten
      Digitizer messen die Frequenz in dieser Einheit)

Wiederholungen: >= 0, 0 entspricht dauernder Wiederholung

Lautstaerke:  0...64, 64 entspricht maximaler Lautstaerke

Laengenangabe ist nicht erforderlich.
Die folgende Eintraege sind fuer die Sound-Daten auf der Leserservice-
Diskette zurechtgeschnitten und dienen als Beispiel fuer eigene Kreationen.
*/

struct format sdata[ANZSOUNDS]={      /* Nr. Bedeutung          */
{"ic.data:sound/0",400,1,50},         /* 0   Schuss abgefeuert  */
{"ic.data:sound/1",400,1,64},         /* 1   Panzer abgeschossen */
{0},                                  /* 2   Panzer bewegen */
{"ic.data:sound/3",400,1,64},         /* 3   Panzer ueberollt */
{"ic.data:sound/4",350,1,50},         /* 4   Missile abgefeuert */
{"ic.data:sound/5",450,1,64},         /* 5   Invader abgeschossen */
{"ic.data:sound/6",300,1,64},         /* 6   Invader bewegt sich */
{"ic.data:sound/7",400,1,64},         /* 7   Bunker getroffen */
{"ic.data:sound/8",400,1,64},         /* 8   Missile getroffen */
{"ic.data:sound/9",400,1,64},         /* 9   Mutterschiff abgeschossen */
{"ic.data:sound/10",1300,1,45},       /* 10  Mutterschiff bewegt sich */
{"ic.data:sound/11",480,1,64},        /* 11  "Get Ready" */
{"ic.data:sound/12",490,1,64},        /* 12  "Game Over" */
{"ic.data:sound/13",500,1,64},        /* 13  zus. Sound zu "Get Ready" */
{"ic.data:sound/14",200,1,35},        /* 14  zus. Sound zu "Game Over" */

/* Die folgenden Eintraege an Wiederholungen und Lautstaerke sind
ausnahmsweise mit 0 zu fuellen (Keinen One-Shot-Sound verwenden) */

{"ic.data:sound/menusound",300,0,0},  /* 15  Sound waehrend der Menus */
{"ic.data:sound/titelsound",240,0,0}, /* 16  Titelsound waehrend des Ladens */
};

soundladen(i)
int i;

/* Erkennen der Laenge der Sounds, Speicher reservieren und File laden
i gibt die Nummer des Files an */

{
   if(sdata[i].name==0)
      return();
   if((fib=(struct FileInfoBlock *)AllocMem((long)sizeof(struct
    FileInfoBlock),MEMF_PUBLIC))==0)
      closeall(1);
   if((lock=Lock(sdata[i].name,ACCESS_READ))==0) {
      printf("Sound-Datei %s existiert nicht!\n",sdata[i].name);
      closeall(0);
   }
   if(Examine(lock,fib)==0) {
      printf("Examine() bei Sound-Datei %s erfolglos!\n",sdata[i].name);
      closeall(0);
   }
   sdata[i].len=fib->fib_Size;
   UnLock(lock); lock=0;
   FreeMem(fib,(long)sizeof(struct FileInfoBlock)); fib=0;

   if((sdata[i].buffer=(UBYTE *)AllocMem(sdata[i].len,MEMF_CHIP))==0) {
      printf("Kein Speicher verfuegbar fuer Sound-Datei %s !\n",
       sdata[i].name);
      closeall(0);
   }
   if((fh=Open(sdata[i].name,MODE_OLDFILE))==0) {
      printf("Open() bei Sound-Datei %s erfolglos!\n",sdata[i].name);
      closeall(0);
   }
   if(Read(fh,sdata[i].buffer,sdata[i].len)!=sdata[i].len) {
      printf("Lesefehler in Sound-Datei %s !\n",sdata[i].name);
      closeall(0);
   }
   Close(fh); fh=0;
}

titelsladen()

/* Titelsound laden und sanft einblenden */

{
   int j;

   soundladen(16);
   sound(16,0,3);
   sound(16,0,4);
   for(j=0;j<33;j++) {
      sync();
      soundvol(16,j*2,3);
      sync();
      soundvol(16,j*2,4);
   }
}

frees()

/* Audio-Device, Ports und IORequests schliessen */

{
   int i;
   if(!deverror) {
      CloseDevice(ioa[0]);
   }
   for(i=0;i<5;i++)
      if(ioa[i])
         DeleteExtIO(ioa[i]);

   for(i=0;i<5;i++)
      if(port[i])
         DeletePort(port[i]);
}

salloc()

/* Audio-Device eroeffnen, Ports und IORequest initialisieren */

{
   int i;
   for(i=0;i<5;i++) {
      if((port[i]=CreatePort(0L,0L))==0) {
         closeall(1);
      }
   }
   for(i=0;i<5;i++) {
      if((ioa[i]=CreateExtIO(port[i],(long)sizeof(struct IOAudio)))==0){
         closeall(1);
      }
      ioa[i]->ioa_Request.io_Message.mn_Node.ln_Pri=20;
   }
   ioa[0]->ioa_Length=sizeof(alloc);
   ioa[0]->ioa_Data=alloc;
   if(deverror=OpenDevice(AUDIONAME,0L,ioa[0],0L)) {
      printf("OpenDevice() (AudioDevice) erfolglos\n");
      closeall(0);
   }
   for(i=1;i<5;i++) {
      *ioa[i]=*ioa[0];
      ioa[i]->ioa_Request.io_Message.mn_ReplyPort=port[i];
      ioa[i]->ioa_Request.io_Unit=(struct Unit *)(1L<<(i-1));
   }
}
