1 /* Tower Toppler - Nebulus
2  * Copyright (C) 2000-2012  Andreas Röver
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.  See the
12  * GNU General Public License for more details.
13 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18 
19 #include "decl.h"
20 #include "soundsys.h"
21 #include "archi.h"
22 
23 #include <stdio.h>
24 #include <string.h>
25 
ttsounds(void)26 ttsounds::ttsounds(void)
27 {
28 #ifdef HAVE_LIBSDL_MIXER
29   useSound = false;
30   n_sounds = 0;
31   sounds = NULL;
32 
33   debugprintf(9, "ttsounds::ttsounds\n");
34 
35   title = 0;
36 #endif
37 }
38 
~ttsounds(void)39 ttsounds::~ttsounds(void)
40 {
41 #ifdef HAVE_LIBSDL_MIXER
42   closesound();
43 
44   for (int t = 0; t < n_sounds; t++)
45     if (sounds[t].sound)
46       Mix_FreeChunk(sounds[t].sound);
47 
48   delete [] sounds;
49 
50   debugprintf(9, "ttsounds::~ttsounds\n");
51 #endif
52 }
53 
addsound(const char * fname,int id,int vol,int loops)54 void ttsounds::addsound(const char *fname, int id, int vol, int loops)
55 {
56 #ifdef HAVE_LIBSDL_MIXER
57   struct ttsnddat *tmp;
58   bool need_add = true;
59   int add_pos = n_sounds;
60 
61   if (sounds && n_sounds)
62     for (int t = 0; t < n_sounds; t++)
63       if (!sounds[t].in_use) {
64         need_add = false;
65         add_pos = t;
66         break;
67       }
68 
69   if (need_add) {
70     tmp = new struct ttsnddat [n_sounds + 1];
71 
72     if (!tmp) return;
73 
74     if (n_sounds) {
75       memcpy(tmp, sounds, sizeof(struct ttsnddat) * n_sounds);
76       delete [] sounds;
77     }
78     sounds = tmp;
79   }
80 
81   file f(dataarchive, fname);
82 
83   sounds[add_pos].sound = Mix_LoadWAV_RW(f.rwOps(), 1);
84 
85   if (sounds[add_pos].sound) {
86     sounds[add_pos].in_use = true;
87     sounds[add_pos].play = false;
88     sounds[add_pos].id_num = id;
89     sounds[add_pos].channel = -1;
90     sounds[add_pos].volume = vol;
91     sounds[add_pos].loops = loops;
92     debugprintf(8,"ttsounds::addsound(\"%s\", %i, %i) = %i\n", fname, vol, loops, add_pos);
93   } else
94     debugprintf(0,"ttsounds::addsound(): No such file as '%s'\n", fname);
95 
96   n_sounds++;
97 
98   return;
99 #endif
100 }
101 
play(void)102 void ttsounds::play(void)
103 {
104 #ifdef HAVE_LIBSDL_MIXER
105   if (!useSound) return;
106 
107   for (int t = 0; t < n_sounds; t++)
108     if (sounds[t].in_use && sounds[t].play) {
109 
110       sounds[t].channel = Mix_PlayChannel(-1, sounds[t].sound, sounds[t].loops);
111       Mix_Volume(sounds[t].channel, sounds[t].volume);
112 
113       sounds[t].play = false;
114     }
115   debugprintf(9,"ttsounds::play()\n");
116 #endif
117 }
118 
stop(void)119 void ttsounds::stop(void)
120 {
121 #ifdef HAVE_LIBSDL_MIXER
122   for (int t = 0; t < n_sounds; t++) stopsound(t);
123 #endif
124 }
125 
stopsound(int snd)126 void ttsounds::stopsound(int snd)
127 {
128 #ifdef HAVE_LIBSDL_MIXER
129   if (useSound) {
130     if ((snd >= 0) && (snd < n_sounds)) {
131       if (sounds[snd].channel != -1) {
132 
133         Mix_HaltChannel(sounds[snd].channel);
134         sounds[snd].channel = -1;
135       }
136       sounds[snd].play = false;
137     }
138   }
139   debugprintf(9,"ttsounds::stopsound(%i)\n", snd);
140 #endif
141 }
142 
startsound(int snd)143 void ttsounds::startsound(int snd)
144 {
145 #ifdef HAVE_LIBSDL_MIXER
146   if (!useSound) return;
147 
148   if ((snd >= 0) && (snd < n_sounds)) sounds[snd].play = true;
149 
150   debugprintf(9,"ttsounds::startsound(%i)\n", snd);
151 #endif
152 }
153 
setsoundvol(int snd,int vol)154 void ttsounds::setsoundvol(int snd, int vol)
155 {
156 #ifdef HAVE_LIBSDL_MIXER
157   if (useSound) {
158     if ((snd >= 0) && (snd < n_sounds)) {
159       if (sounds[snd].channel != -1) {
160 
161         Mix_Volume(sounds[snd].channel, vol);
162 
163       }
164       sounds[snd].volume = vol;
165     }
166 
167     debugprintf(9,"ttsounds::setsoundvol(%i, %i)\n", snd, vol);
168   }
169 #endif
170 }
171 
instance(void)172 ttsounds * ttsounds::instance(void) {
173   if (!inst)
174     inst = new ttsounds();
175 
176   return inst;
177 }
178 
179 class ttsounds *ttsounds::inst = 0;
180 
opensound(void)181 void ttsounds::opensound(void) {
182 #ifdef HAVE_LIBSDL_MIXER
183   if(SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) {
184     debugprintf(0, "Couldn't init the sound system, muting.\n");
185     return;
186   }
187 
188   if (Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 1024) < 0) {
189     debugprintf(0, "Could not open audio, muting.\n");
190     SDL_QuitSubSystem(SDL_INIT_AUDIO);
191     return;
192   }
193 
194   useSound = true;
195 #endif
196 
197 }
198 
closesound(void)199 void ttsounds::closesound(void) {
200 #ifdef HAVE_LIBSDL_MIXER
201   if (!useSound) return;
202 
203   while (Mix_Playing(-1)) dcl_wait();
204 
205   Mix_CloseAudio();
206   SDL_QuitSubSystem(SDL_INIT_AUDIO);
207 
208   useSound = false;
209 #endif
210 }
211 
212 
playmusic(const char * fname)213 void ttsounds::playmusic(const char * fname) {
214 #ifdef HAVE_LIBSDL_MIXER
215   if (!useSound) return;
216 
217   char f[500];
218   if (get_data_file_path(fname, f, 500)) {
219     title = Mix_LoadMUS(f);
220     Mix_PlayMusic(title, -1);
221     musicVolume = MIX_MAX_VOLUME;
222   }
223 #endif
224 }
stopmusic(void)225 void ttsounds::stopmusic(void) {
226 #ifdef HAVE_LIBSDL_MIXER
227   if (!useSound) return;
228 
229   if (title) {
230     Mix_FadeOutMusic(1000);
231 
232     while (Mix_FadingMusic() != MIX_NO_FADING) dcl_wait();
233   }
234 #endif
235 }
236 
fadeToVol(int vol)237 void ttsounds::fadeToVol(int vol) {
238 #ifdef HAVE_LIBSDL_MIXER
239   if (!title) return;
240 
241   while (musicVolume != vol) {
242 
243     if (musicVolume > vol) {
244       musicVolume -= 4;
245       if (musicVolume < vol)
246         musicVolume = vol;
247     } else {
248       musicVolume += 4;
249       if (musicVolume > vol)
250         musicVolume = vol;
251     }
252 
253     Mix_VolumeMusic(musicVolume);
254     dcl_wait();
255   }
256 #endif
257 }
258 
259