]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/CAudio.cpp
Add doc/samples which more accurately tracks samples origin
[quix0rs-blobwars.git] / src / CAudio.cpp
1 /*
2 Copyright (C) 2004-2010 Parallel Realities
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20
21 #include "headers.h"
22
23 Audio::Audio()
24 {
25         output = 2;
26         useSound = true;
27         useMusic = true;
28
29         for (int i = 0 ; i < MAX_SOUNDS ; i++)
30         {
31                 sound[i] = NULL;
32         }
33
34         music = NULL;
35         quickSound = NULL;
36         
37         levelMusicName[0] = 0;
38         songtitle[0] = 0;
39         songalbum[0] = 0;
40         songartist[0] = 0;
41         songlicense = -1;
42 }
43
44 void Audio::setSoundVolume(int soundVolume)
45 {
46         this->soundVolume = soundVolume;
47         if (engine->useAudio)
48                 Mix_Volume(-1, soundVolume);
49 }
50
51 void Audio::setMusicVolume(int musicVolume)
52 {
53         this->musicVolume = musicVolume;
54         if (engine->useAudio)
55         {
56                 Mix_VolumeMusic(musicVolume);
57         }
58 }
59
60 void Audio::registerEngine(Engine *engine)
61 {
62         this->engine = engine;
63 }
64
65 bool Audio::loadSound(int i, const char *filename)
66 {
67         if (!engine->useAudio)
68         {
69                 return true;
70         }
71                 
72         if (i >= MAX_SOUNDS)
73         {
74                 printf("ERROR: SOUND INDEX IS HIGHER THAN MAXIMUM ALLOWED %d >= %d\n", i, MAX_SOUNDS);
75                 exit(1);
76         }
77
78         if (sound[i] != NULL)
79         {
80                 Mix_FreeChunk(sound[i]);
81                 sound[i] = NULL;
82         }
83
84         #if USEPAK
85                 engine->unpack(filename, PAK_SOUND);
86                 sound[i] = Mix_LoadWAV_RW(engine->sdlrw, 1);
87         #else
88                 sound[i] = Mix_LoadWAV(filename);
89         #endif
90
91         if (!sound[i])
92         {
93                 debug(("WARNING - Failed to load %s\n", filename));
94                 return false;
95         }
96         
97         return true;
98 }
99
100 bool Audio::loadMusic(const char *filename)
101 {
102         char tempPath[PATH_MAX];
103         
104         snprintf(tempPath, sizeof tempPath, "%smusic.mod", engine->userHomeDirectory);
105         
106         if (!engine->useAudio)
107         {
108                 return true;
109         }
110
111         remove(tempPath);
112         
113         if (music != NULL)
114         {
115                 Mix_HaltMusic();
116                 SDL_Delay(5);
117                 Mix_FreeMusic(music);
118                 music = NULL;
119         }
120
121         #if USEPAK
122                 engine->unpack(filename, PAK_MUSIC);
123                 music = Mix_LoadMUS(tempPath);
124         #else
125                 music = Mix_LoadMUS(filename);
126         #endif
127
128         songtitle[0] = 0;
129         songalbum[0] = 0;
130         songartist[0] = 0;
131         songlicense = -1;
132
133         if (!music)
134         {
135                 debug(("WARNING - Failed to load %s\n", filename));
136                 return false;
137         }
138
139         #if USEPAK
140                 snprintf(tempPath, sizeof tempPath, "%smusic.tags", engine->userHomeDirectory);
141                 remove(tempPath);
142                 char tagfilename[PATH_MAX];
143                 snprintf(tagfilename, sizeof tagfilename, "%s.tags", filename);
144                 engine->unpack(tagfilename, PAK_TAGS);
145         #else
146                 snprintf(tempPath, sizeof tempPath, "%s.tags", filename);
147         #endif
148         FILE *fp = fopen(tempPath, "r");
149         char line[1024];
150         
151         while(fp && fgets(line, sizeof line, fp))
152         {
153                 int l = strlen(line);
154                 if(line[l - 1] == '\n')
155                         line[l - 1] = 0;
156
157                 if(!strncasecmp(line, "title=", 6))
158                          strlcpy(songtitle, line + 6, sizeof songtitle);
159                 else if(!strncasecmp(line, "album=", 6))
160                          strlcpy(songalbum, line + 6, sizeof songalbum);
161                 else if(!strncasecmp(line, "artist=", 7))
162                          strlcpy(songartist, line + 7, sizeof songartist);
163                 else if(!strncasecmp(line, "license=", 8))
164                 {
165                         if(!strncasecmp(line + 8, "CC-BY ", 6))
166                                 songlicense = 0;
167                         else if(!strncasecmp(line + 8, "CC-BY-SA ", 9))
168                                 songlicense = 1;
169                 }
170         }
171
172         if(fp)
173                 fclose(fp);
174         
175         strlcpy(levelMusicName, filename, sizeof levelMusicName);
176
177         return true;
178 }
179
180 void Audio::playSound(int snd, int channel)
181 {
182         if ((!engine->useAudio) || (soundVolume == 0))
183                 return;
184         
185         if (!output)
186         {
187                 return;
188         }
189
190         Mix_Volume(channel, soundVolume);
191
192         Mix_PlayChannel(channel, sound[snd], 0);
193 }
194
195 void Audio::playMusic()
196 {
197         if (!engine->useAudio)
198                 return;
199         
200         if (!output)
201         {
202                 return;
203         }
204
205         Mix_PlayMusic(music, -1);
206
207         Mix_VolumeMusic(musicVolume);
208 }
209
210 void Audio::playMusicOnce()
211 {
212         if (!engine->useAudio)
213                 return;
214         
215         if (!output)
216         {
217                 return;
218         }
219
220         Mix_PlayMusic(music, 0);
221
222         Mix_VolumeMusic(musicVolume);
223 }
224
225 bool Audio::loadGameOverMusic()
226 {
227         char tempPath[PATH_MAX];
228         
229         snprintf(tempPath, sizeof tempPath, "%smusic.mod", engine->userHomeDirectory);
230         
231         if (!engine->useAudio)
232         {
233                 return true;
234         }
235
236         remove(tempPath);
237         SDL_Delay(250); // wait a bit, just to be sure!
238
239         if (music != NULL)
240         {
241                 Mix_HaltMusic();
242                 SDL_Delay(5);
243                 Mix_FreeMusic(music);
244                 music = NULL;
245         }
246
247         #if USEPAK
248                 engine->unpack("music/gameover", PAK_MUSIC);
249                 music = Mix_LoadMUS(tempPath);
250         #else
251                 music = Mix_LoadMUS("music/gameover");
252         #endif
253
254         if (!music)
255         {
256                 return false;
257         }
258
259         return true;
260 }
261
262 bool Audio::reloadLevelMusic()
263 {
264         // remove the Game Over music first...
265
266         if (music != NULL)
267         {
268                 Mix_HaltMusic();
269                 SDL_Delay(5);
270                 Mix_FreeMusic(music);
271                 music = NULL;
272         }
273
274         return loadMusic(levelMusicName);
275 }
276
277 void Audio::playAmbiance()
278 {
279         if ((!engine->useAudio) || (soundVolume == 0))
280         {
281                 return;
282         }
283         
284         if (!output)
285         {
286                 return;
287         }
288
289         Mix_PlayChannel(CH_AMBIANCE, sound[SND_AMBIANCE], -1);
290 }
291
292 void Audio::stopAmbiance()
293 {
294         if ((!engine->useAudio) || (soundVolume == 0))
295                 return;
296
297         Mix_HaltChannel(CH_AMBIANCE);
298 }
299
300 int Audio::playMenuSound(int sound)
301 {
302         if ((!engine->useAudio) || (soundVolume == 0))
303                 return sound;
304
305         if ((sound == 0) || (sound == 3))
306                 return sound;
307
308         if (sound == 1)
309                 playSound(SND_HIGHLIGHT, CH_ANY);
310
311         if (sound == 2)
312                 playSound(SND_SELECT, CH_ANY);
313                 
314         return sound;
315 }
316
317 void Audio::pause()
318 {
319         if (!engine->useAudio)
320                 return;
321
322         for (int i = 0 ; i < 8 ; i++)
323                 Mix_Pause(i);
324
325         Mix_PauseMusic();
326 }
327
328 void Audio::resume()
329 {
330         if (!engine->useAudio)
331                 return;
332         
333         if (!output)
334         {
335                 return;
336         }
337
338         for (int i = 0 ; i < 8 ; i++)
339                 Mix_Resume(i);
340
341         Mix_ResumeMusic();
342 }
343
344 void Audio::stopMusic()
345 {
346         if (!engine->useAudio)
347                 return;
348
349         Mix_HaltMusic();
350 }
351
352 void Audio::fadeMusic()
353 {
354         if (!engine->useAudio)
355                 return;
356
357         Mix_FadeOutMusic(3500);
358 }
359
360 void Audio::free()
361 {
362         for (int i = 0 ; i < MAX_SOUNDS - 3 ; i++)
363         {
364                 if (sound[i] != NULL)
365                 {
366                         Mix_FreeChunk(sound[i]);
367                         sound[i] = NULL;
368                 }
369         }
370
371         if (music != NULL)
372         {
373                 Mix_HaltMusic();
374                 SDL_Delay(5);
375                 Mix_FreeMusic(music);
376         }
377
378         music = NULL;
379
380         if (quickSound != NULL)
381                 Mix_FreeChunk(quickSound);
382
383         quickSound = NULL;
384 }
385
386 void Audio::destroy()
387 {
388         free();
389
390         for (int i = MAX_SOUNDS - 3 ; i < MAX_SOUNDS ; i++)
391         {
392                 if (sound[i] != NULL)
393                 {
394                         Mix_FreeChunk(sound[i]);
395                         sound[i] = NULL;
396                 }
397         }
398 }