]> git.mxchange.org Git - quix0rs-blobwars.git/blob - src/CAudio.cpp
Added .gitignore to ignore certain files + fixed access rights on Makefile* as
[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::playSoundRelative(int snd, int channel, float x)
182 {
183         if ((!engine->useAudio) || (soundVolume == 0))
184                 return;
185         
186         if (!output)
187         {
188                 return;
189         }
190
191         int angle = atanf(x / 480) * 180 / M_PI;
192         int attenuation = fabsf(x) / 40;
193
194         if (angle < 0)
195                 angle += 360;
196
197         if (attenuation > 255)
198                 attenuation = 255;
199
200         Mix_Volume(channel, soundVolume);
201         Mix_PlayChannel(channel, sound[snd], 0);
202         Mix_SetPosition(channel, angle, attenuation);
203 }
204
205 void Audio::playSound(int snd, int channel, float x)
206 {
207         x -= (engine->playerPosX + 320);
208         playSoundRelative(snd, channel, x);
209 }
210
211 void Audio::playSound(int snd, int channel)
212 {
213         playSoundRelative(snd, channel, 0);
214 }
215
216 void Audio::playMusic()
217 {
218         if (!engine->useAudio)
219                 return;
220         
221         if (!output)
222         {
223                 return;
224         }
225
226         Mix_PlayMusic(music, -1);
227
228         Mix_VolumeMusic(musicVolume);
229 }
230
231 void Audio::playMusicOnce()
232 {
233         if (!engine->useAudio)
234                 return;
235         
236         if (!output)
237         {
238                 return;
239         }
240
241         Mix_PlayMusic(music, 0);
242
243         Mix_VolumeMusic(musicVolume);
244 }
245
246 bool Audio::loadGameOverMusic()
247 {
248         char tempPath[PATH_MAX];
249         
250         snprintf(tempPath, sizeof tempPath, "%smusic.mod", engine->userHomeDirectory);
251         
252         if (!engine->useAudio)
253         {
254                 return true;
255         }
256
257         remove(tempPath);
258         SDL_Delay(250); // wait a bit, just to be sure!
259
260         if (music != NULL)
261         {
262                 Mix_HaltMusic();
263                 SDL_Delay(5);
264                 Mix_FreeMusic(music);
265                 music = NULL;
266         }
267
268         #if USEPAK
269                 engine->unpack("music/gameover", PAK_MUSIC);
270                 music = Mix_LoadMUS(tempPath);
271         #else
272                 music = Mix_LoadMUS("music/gameover");
273         #endif
274
275         if (!music)
276         {
277                 return false;
278         }
279
280         return true;
281 }
282
283 bool Audio::reloadLevelMusic()
284 {
285         // remove the Game Over music first...
286
287         if (music != NULL)
288         {
289                 Mix_HaltMusic();
290                 SDL_Delay(5);
291                 Mix_FreeMusic(music);
292                 music = NULL;
293         }
294
295         return loadMusic(levelMusicName);
296 }
297
298 void Audio::playAmbiance()
299 {
300         if ((!engine->useAudio) || (soundVolume == 0))
301         {
302                 return;
303         }
304         
305         if (!output)
306         {
307                 return;
308         }
309
310         Mix_PlayChannel(CH_AMBIANCE, sound[SND_AMBIANCE], -1);
311 }
312
313 void Audio::stopAmbiance()
314 {
315         if ((!engine->useAudio) || (soundVolume == 0))
316                 return;
317
318         Mix_HaltChannel(CH_AMBIANCE);
319 }
320
321 int Audio::playMenuSound(int sound)
322 {
323         if ((!engine->useAudio) || (soundVolume == 0))
324                 return sound;
325
326         if ((sound == 0) || (sound == 3))
327                 return sound;
328
329         if (sound == 1)
330                 playSound(SND_HIGHLIGHT, CH_ANY);
331
332         if (sound == 2)
333                 playSound(SND_SELECT, CH_ANY);
334                 
335         return sound;
336 }
337
338 void Audio::pause()
339 {
340         if (!engine->useAudio)
341                 return;
342
343         for (int i = 0 ; i < 8 ; i++)
344                 Mix_Pause(i);
345
346         Mix_PauseMusic();
347 }
348
349 void Audio::resume()
350 {
351         if (!engine->useAudio)
352                 return;
353         
354         if (!output)
355         {
356                 return;
357         }
358
359         for (int i = 0 ; i < 8 ; i++)
360                 Mix_Resume(i);
361
362         Mix_ResumeMusic();
363 }
364
365 void Audio::stopMusic()
366 {
367         if (!engine->useAudio)
368                 return;
369
370         Mix_HaltMusic();
371 }
372
373 void Audio::fadeMusic()
374 {
375         if (!engine->useAudio)
376                 return;
377
378         Mix_FadeOutMusic(3500);
379 }
380
381 void Audio::free()
382 {
383         for (int i = 0 ; i < MAX_SOUNDS - 3 ; i++)
384         {
385                 if (sound[i] != NULL)
386                 {
387                         Mix_FreeChunk(sound[i]);
388                         sound[i] = NULL;
389                 }
390         }
391
392         if (music != NULL)
393         {
394                 Mix_HaltMusic();
395                 SDL_Delay(5);
396                 Mix_FreeMusic(music);
397         }
398
399         music = NULL;
400
401         if (quickSound != NULL)
402                 Mix_FreeChunk(quickSound);
403
404         quickSound = NULL;
405 }
406
407 void Audio::destroy()
408 {
409         free();
410
411         for (int i = MAX_SOUNDS - 3 ; i < MAX_SOUNDS ; i++)
412         {
413                 if (sound[i] != NULL)
414                 {
415                         Mix_FreeChunk(sound[i]);
416                         sound[i] = NULL;
417                 }
418         }
419 }