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