First bits of the new exception system.
[dbw.git] / src / CAudio.cpp
blobc5738c4993d7c651209c550bfab0e9878b6bcea8
1 /*
2 Copyright © 2004 Parallel Realities
3 Copyright © 2007-2008 Kővágó Zoltán <DirtY.iCE.hu@gmail.com>
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.
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.
14 See the GNU General Public License for more details.
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.
22 #include <stdexcept>
24 #include "CAudio.h"
25 #include "physfs/physfs.hpp"
27 Audio::Audio()
29 output = 2;
30 useSound = true;
31 useMusic = true;
33 for (int i = 0 ; i < MAX_SOUNDS ; i++)
35 sound[i] = NULL;
38 music = NULL;
39 quickSound = NULL;
41 strcpy(levelMusicName, "");
44 void Audio::setSoundVolume(int soundVolume)
46 this->soundVolume = soundVolume;
47 if (engine->useAudio)
48 Mix_Volume(-1, soundVolume);
51 void Audio::setMusicVolume(int musicVolume)
53 this->musicVolume = musicVolume;
54 if (engine->useAudio)
56 Mix_VolumeMusic(musicVolume);
60 void Audio::registerEngine(Engine *engine)
62 this->engine = engine;
65 /**
66 * Loads a sound file
67 * @param i: the id to load the sound to
68 * @param filename: the file to load (relative to datadir)
71 bool Audio::loadSound(int i, const char *filename)
73 if (!engine->useAudio)
75 return true;
78 if (i >= MAX_SOUNDS)
80 error << "Sound index is higher than maximum allowed (requested " << i << ", maximum is " << MAX_SOUNDS << ")" << std::endl
81 << "Ignoring, but this is an internal error, so report it!" << std::endl;
82 return false;
85 if (sound[i] != NULL)
87 Mix_FreeChunk(sound[i]);
88 sound[i] = NULL;
91 try
93 SDL_RWops * buffer = PhysFS::instance->RWopsFile(filename);
94 sound[i] = Mix_LoadWAV_RW(buffer, 1);
96 if (!sound[i])
98 Exception::SdlMixerError e(AT);
99 e.AddInfo("Mix_GetError()", Mix_GetError());
100 e.AddInfo("File tried to load", filename);
101 throw e;
104 catch (const Exception::Base& e)
106 error << e.GetDesc() << std::endl;
107 return false;
109 catch (const std::exception& e)
111 error << "Failed to load '" << filename << "'" << std::endl << "The error was: " << e.what() << std::endl;
112 return false;
114 catch (...)
116 error << "Failed to load '" << filename << "'" << std::endl << "Unknown error while loading." << std::endl;
117 return false;
120 return true;
123 bool Audio::loadMusic(const char *filename)
125 if (!engine->useAudio)
127 return true;
130 if (music != NULL)
132 Mix_HaltMusic();
133 SDL_Delay(5);
134 Mix_FreeMusic(music);
135 music = NULL;
136 SDL_FreeRW(music_rwops);
142 music_rwops = PhysFS::instance->RWopsFile(filename);
143 music = Mix_LoadMUS_RW(music_rwops);
145 if (!music)
147 Exception::SdlMixerError e(AT);
148 e.AddInfo("Mix_GetError()", Mix_GetError());
149 e.AddInfo("File tried to load", filename);
150 throw e;
153 catch (const Exception::Base& e)
155 error << e.GetDesc() << std::endl;
156 return false;
158 catch (const std::exception& e)
160 error << "Failed to load '" << filename << "'" << std::endl << "The error was: " << e.what() << std::endl;
161 return false;
163 catch (...)
165 error << "Failed to load '" << filename << "'" << std::endl << "Unknown error while loading." << std::endl;
166 return false;
169 strcpy(levelMusicName, filename);
171 return true;
174 void Audio::playSound(int snd, int channel)
176 if ((!engine->useAudio) || (soundVolume == 0))
177 return;
179 if (!output)
181 return;
184 Mix_Volume(channel, soundVolume);
186 Mix_PlayChannel(channel, sound[snd], 0);
189 void Audio::playMusic()
191 if (!engine->useAudio)
192 return;
194 if (!output)
196 return;
199 Mix_PlayMusic(music, -1);
201 Mix_VolumeMusic(musicVolume);
204 void Audio::playMusicOnce()
206 if (!engine->useAudio)
207 return;
209 if (!output)
211 return;
214 Mix_PlayMusic(music, 0);
216 Mix_VolumeMusic(musicVolume);
219 bool Audio::loadGameOverMusic()
221 #if DEMO
222 return true;
223 #endif
225 return loadMusic("music/friendDied.mod");
228 bool Audio::reloadLevelMusic()
230 // remove the Game Over music first...
232 if (music != NULL)
234 Mix_HaltMusic();
235 SDL_Delay(5);
236 Mix_FreeMusic(music);
237 music = NULL;
240 return loadMusic(levelMusicName);
243 void Audio::playAmbiance()
245 if ((!engine->useAudio) || (soundVolume == 0))
246 return;
248 if (!output)
250 return;
253 Mix_PlayChannel(CH_AMBIANCE, sound[SND_AMBIANCE], -1);
256 void Audio::stopAmbiance()
258 if ((!engine->useAudio) || (soundVolume == 0))
259 return;
261 Mix_HaltChannel(CH_AMBIANCE);
264 int Audio::playMenuSound(int sound)
266 if ((!engine->useAudio) || (soundVolume == 0))
267 return sound;
269 if ((sound == 0) || (sound == 3))
270 return sound;
272 if (sound == 1)
273 playSound(SND_HIGHLIGHT, CH_ANY);
275 if (sound == 2)
276 playSound(SND_SELECT, CH_ANY);
278 return sound;
281 void Audio::pause()
283 if (!engine->useAudio)
284 return;
286 for (int i = 0 ; i < 8 ; i++)
287 Mix_Pause(i);
289 Mix_PauseMusic();
292 void Audio::resume()
294 if (!engine->useAudio)
295 return;
297 if (!output)
299 return;
302 for (int i = 0 ; i < 8 ; i++)
303 Mix_Resume(i);
305 Mix_ResumeMusic();
308 void Audio::stopMusic()
310 if (!engine->useAudio)
311 return;
313 Mix_HaltMusic();
316 void Audio::fadeMusic()
318 if (!engine->useAudio)
319 return;
321 Mix_FadeOutMusic(3500);
324 void Audio::free()
326 for (int i = 0 ; i < MAX_SOUNDS - 3 ; i++)
328 if (sound[i] != NULL)
330 Mix_FreeChunk(sound[i]);
331 sound[i] = NULL;
335 if (music != NULL)
337 Mix_HaltMusic();
338 SDL_Delay(5);
339 Mix_FreeMusic(music);
342 music = NULL;
344 if (quickSound != NULL)
345 Mix_FreeChunk(quickSound);
347 quickSound = NULL;
350 void Audio::destroy()
352 free();
354 for (int i = MAX_SOUNDS - 3 ; i < MAX_SOUNDS ; i++)
356 if (sound[i] != NULL)
358 Mix_FreeChunk(sound[i]);
359 sound[i] = NULL;