1 #ifndef NOSOUND
2 #include <AL/al.h>
3 #include <AL/alc.h>
4 #include <AL/alut.h>
5 #endif
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11 
12 
13 #include "globals.h"
14 
15 
16 #ifndef NOSOUND
17 typedef struct {
18   ALsizei size;
19   ALsizei bits;
20   ALsizei freq;
21   ALsizei format;
22   void *wave;
23 } wavSound;
24 
25 
26 void setvolume();
27 void stopsoundinloop(int soundnum);
28 void playwave(int soundnum, ALfloat *Position);
29 int playwaveinloop(int soundnum);
30 void LoadWavs();
31 ALboolean SourceIsPlaying(ALuint sid);
32 
33 
34 ALuint sounddesc[MAX_SOUNDS];
35 ALuint soundbuf[MAX_SOUNDS];
36 wavSound Wavs[NUM_SOUNDS];
37 ALuint loopsounddesc[MAX_LOOPING_SOUNDS];
38 ALuint loopsoundbuf[MAX_LOOPING_SOUNDS];
39 #endif
40 
41 int volume;
42 int newvolume;
43 int WarpSoundNum;
44 int ThrustSoundNum;
45 int ShieldSoundNum;
46 float volumevals[MAX_VOLUME];
47 
48 
initsound(int * argc,char * argv[])49 void initsound(int *argc, char *argv[])
50 {
51 #ifndef NOSOUND
52   int i, j;
53 
54   alutInit(argc, argv);
55 
56   for (i=0; i<MAX_SOUNDS; i++) {
57     sounddesc[i]=0;
58     soundbuf[i]=0;
59   }
60 
61   for (i=0; i<MAX_LOOPING_SOUNDS; i++) {
62     loopsounddesc[i]=0;
63     loopsoundbuf[i]=0;
64   }
65 
66   for (i=0; i<=MAX_VOLUME; i++) {
67     volumevals[i]=1.0;
68     for (j=MAX_VOLUME; j>i; j--) {
69       volumevals[i]/=1.6;
70     }
71   }
72 
73   newvolume=volume;
74   setvolume();
75 
76   ThrustSoundNum=-1;
77   ShieldSoundNum=-1;
78   WarpSoundNum=-1;
79 
80   LoadWavs();
81 #endif
82 }
83 
84 
setvolume()85 void setvolume()
86 {
87   if (volume > MAX_VOLUME) {
88     volume=MAX_VOLUME;
89   }
90 
91   if (volume < 0) {
92     volume=0;
93   }
94 
95 #ifndef NOSOUND
96   alListenerf(AL_GAIN, volumevals[volume]);
97 #endif
98 }
99 
100 
101 // Function to play a sound file
playsound(int soundnum,struct Point * Position=& ZeroPosition)102 void playsound(int soundnum, struct Point *Position=&ZeroPosition)
103 {
104 #ifndef NOSOUND
105   ALfloat SoundPosition[3];
106   float Distance;
107 
108   SoundPosition[0]=Position->x;
109   SoundPosition[1]=Position->y;
110   SoundPosition[2]=Position->z;
111   if (soundnum==NukeExplodeSound) {
112     SoundPosition[0]/=2.5;
113     SoundPosition[1]/=2.5;
114     SoundPosition[2]/=2.5;
115   } else if (soundnum==NukeAlertSound) {
116     if (SoundPosition[0]*SoundPosition[0]+
117         SoundPosition[1]*SoundPosition[1]+
118         SoundPosition[2]*SoundPosition[2] > 25.0) {
119       return;
120     }
121     SoundPosition[0]=0.0;
122     SoundPosition[1]=0.0;
123     SoundPosition[2]=0.0;
124   }
125 
126   playwave(soundnum, SoundPosition);
127 #endif
128 }
129 
130 
131 // Function to play a sound file continuously
playsoundinloop(int soundnum)132 int playsoundinloop(int soundnum)
133 {
134 #ifndef NOSOUND
135   return(playwaveinloop(soundnum));
136 #endif
137 
138   return(-1);
139 }
140 
141 
stopsoundinloop(int soundnum)142 void stopsoundinloop(int soundnum)
143 {
144 #ifndef NOSOUND
145   alSourceStop(loopsounddesc[soundnum]);
146 #endif
147 }
148 
149 
150 #ifndef NOSOUND
playwave(int soundnum,ALfloat * Position)151 void playwave(int soundnum, ALfloat *Position)
152 {
153   ALsizei size;
154   ALsizei bits;
155   ALsizei freq;
156   ALsizei format;
157   ALboolean err;
158   void *wave;
159   int i;
160 
161   if (!volume) {
162     return;
163   }
164 
165   // Find an open sound buffer to add sound to, and clean up existing buffers
166   for (i=0; i<MAX_SOUNDS; i++) {
167     if (SourceIsPlaying(sounddesc[i]) == AL_TRUE) {
168       if (i==MAX_SOUNDS) {
169         return;
170       }
171     } else {
172       if (sounddesc) {
173         alDeleteBuffers(1, &soundbuf[i]);
174         alDeleteSources(1, &sounddesc[i]);
175         soundbuf[i]=0;
176         sounddesc[i]=0;
177       }
178       alGenBuffers(1, &soundbuf[i]);
179       break;
180     }
181   }
182 
183   alBufferData(soundbuf[i], Wavs[soundnum].format,
184                Wavs[soundnum].wave, Wavs[soundnum].size,
185                Wavs[soundnum].freq);
186 
187   alGenSources(1, &sounddesc[i]);
188   alSourcefv(sounddesc[i], AL_POSITION, Position);
189   alSourcei(sounddesc[i], AL_BUFFER, soundbuf[i]);
190   alSourcei(sounddesc[i], AL_LOOPING, AL_FALSE);
191 
192   alSourcePlay(sounddesc[i]);
193 }
194 
195 
playwaveinloop(int soundnum)196 int playwaveinloop(int soundnum)
197 {
198   ALsizei size;
199   ALsizei bits;
200   ALsizei freq;
201   ALsizei format;
202   ALboolean err;
203   void *wave;
204   int i;
205 
206   if (!volume) {
207     return(-1);
208   }
209 
210   // Find an open sound buffer to add sound to, and clean up existing buffers
211   for (i=0; i<MAX_LOOPING_SOUNDS; i++) {
212     if (SourceIsPlaying(loopsounddesc[i]) == AL_TRUE) {
213       if (i==MAX_LOOPING_SOUNDS) {
214         return(-1);
215       }
216     } else {
217       if (loopsounddesc) {
218         alDeleteBuffers(1, &loopsoundbuf[i]);
219         alDeleteSources(1, &loopsounddesc[i]);
220         loopsoundbuf[i]=0;
221         loopsounddesc[i]=0;
222       }
223       alGenBuffers(1, &loopsoundbuf[i]);
224       break;
225     }
226   }
227 
228   alBufferData(loopsoundbuf[i], Wavs[soundnum].format,
229                Wavs[soundnum].wave, Wavs[soundnum].size,
230                Wavs[soundnum].freq);
231 
232   alGenSources(1, &loopsounddesc[i]);
233   alSourcei(loopsounddesc[i], AL_BUFFER, loopsoundbuf[i]);
234   alSourcei(loopsounddesc[i], AL_LOOPING, AL_TRUE);
235 
236   alSourcePlay(loopsounddesc[i]);
237 
238   return(i);
239 }
240 
241 
242 // Function to check if a sound is playing in the buffer sid
SourceIsPlaying(ALuint sid)243 ALboolean SourceIsPlaying(ALuint sid)
244 {
245   ALint state;
246 
247   if (alIsSource(sid) == AL_FALSE) {
248     return(AL_FALSE);
249   }
250 
251   state = AL_INITIAL;
252   alGetSourceiv(sid, AL_SOURCE_STATE, &state);
253 
254   switch(state) {
255   case AL_PLAYING:
256   case AL_PAUSED:
257     return(AL_TRUE);
258   default:
259     break;
260   }
261 
262   return(AL_FALSE);
263 }
264 #endif
265 
266 
CleanupSounds()267 void CleanupSounds()
268 {
269 #ifndef NOSOUND
270   if (ShieldSoundNum!=-1) {
271     stopsoundinloop(ShieldSoundNum);
272     ShieldSoundNum=-1;
273   }
274   if (ThrustSoundNum!=-1) {
275     stopsoundinloop(ThrustSoundNum);
276     ThrustSoundNum=-1;
277   }
278   if (WarpSoundNum!=-1) {
279     stopsoundinloop(WarpSoundNum);
280     WarpSoundNum=-1;
281   }
282 #endif
283 }
284 
285 
286 #ifndef NOSOUND
LoadWavs()287 void LoadWavs()
288 {
289   int i;
290   char filename[1000];
291   ALboolean loop;
292 
293   for (i=0; i<NUM_SOUNDS; i++) {
294 #ifdef WINDOWS
295     sprintf(filename, "sounds/%d.wav", i);
296 #else
297     sprintf(filename, "%s/atr3d/sounds/%d.wav", DATADIR, i);
298 #endif
299 
300     alutLoadWAVFile((ALbyte*)filename, &Wavs[i].format, &Wavs[i].wave,
301                 &Wavs[i].size, &Wavs[i].freq, &loop);
302   }
303 }
304 #endif
305