1 // BlinkenSisters - Hunt for the Lost Pixels
2 // Bringing back the fun of the 80s
3 //
4 // (C) 2005-07 Rene Schickbauer, Wolfgang Dautermann
5 //
6 // See License.txt for licensing information
7 //
8
9
10 #include <stdlib.h>
11 #include "globals.h"
12 #include "sound.h"
13 #include "errorhandler.h"
14
15
16 int audio_rate = 44100;
17 Uint16 audio_format = AUDIO_S16; /* 16-bit stereo */
18 int audio_channels = 2;
19 Uint32 audio_buffers = AUDIOBUFFERSIZE;
20 extern bool soundOK ;
21 bool soundInitOK = false;
22 char bgMusicFile[1000];
23
24 #ifndef DISABLE_SOUND
25 Mix_Music *levelMusic = NULL;
26 Mix_Chunk *sound_fx[FX_MAX_PREDEF + MAX_FX_SAMPLES];
27 Mix_Chunk *sound_fx_video = 0;
28 Uint32 sndfxcnt = 0;
29 #endif
30 bool playOnceFinished = false;
31 bool onlyPlayOnce = true;
32 Uint32 soundSimTick = 0; // Simulated sound length if we have no sound
33
initSound()34 void initSound()
35 {
36 if (soundOK==false) { return ; } // Sound support not compiled or disabled by command line switch -s
37 #ifndef DISABLE_SOUND
38 /* This is where we open up our audio device. Mix_OpenAudio takes
39 as its parameters the audio format we'd /like/ to have. */
40 if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) {
41 printf("Unable to open audio!\n");
42 soundInitOK = false;
43 return;
44 } else {
45 soundInitOK = true;
46 Mix_HookMusicFinished(soundMusicFinished);
47 }
48
49 /* If we actually care about what we got, we can ask here. In this
50 program we don't... yet */
51 Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
52 sound_fx[FX_COLLECT_PIXEL] = Mix_LoadWAV(configGetPath("fx_collect_pixel.ogg"));
53 sound_fx[FX_KILL_MONSTER] = Mix_LoadWAV(configGetPath("fx_kill_monster.ogg"));
54 sound_fx[FX_KILL_PLAYER] = Mix_LoadWAV(configGetPath("fx_killed.ogg"));
55 sound_fx[FX_LEVEL_FINISHED] = Mix_LoadWAV(configGetPath("fx_level_finished.ogg"));
56 sound_fx[FX_MENU] = Mix_LoadWAV(configGetPath("fx_menu.ogg"));
57 sound_fx[FX_RESPAWNPOINT] = Mix_LoadWAV(configGetPath("fx_respawnpoint.ogg"));
58 #endif // DISABLE_SOUND
59 }
60
deInitSound()61 void deInitSound()
62 {
63 printf("De-init sound\n");
64 if(!soundOK || !soundInitOK) {
65 return;
66 }
67 #ifndef DISABLE_SOUND
68 soundStopMusic();
69 levelMusic = NULL;
70
71 Mix_FreeChunk(sound_fx[FX_COLLECT_PIXEL]);
72 Mix_FreeChunk(sound_fx[FX_KILL_MONSTER]);
73 Mix_FreeChunk(sound_fx[FX_KILL_PLAYER]);
74 Mix_FreeChunk(sound_fx[FX_LEVEL_FINISHED]);
75 Mix_FreeChunk(sound_fx[FX_MENU]);
76
77 deInitSoundFXLua();
78
79 Mix_CloseAudio();
80 soundInitOK = false;
81 #endif // DISABLE_SOUND
82 }
83
84
soundPlayFX(Uint32 fx)85 void soundPlayFX(Uint32 fx) {
86 if(!soundOK || !soundInitOK) {
87 return;
88 }
89 #ifndef DISABLE_SOUND
90 Mix_PlayChannel(-1, sound_fx[fx], 0);
91 #endif // DISABLE_SOUND
92 }
93
94
soundStartMusic(const char * fname,bool playOnce)95 void soundStartMusic(const char* fname, bool playOnce)
96 {
97 // There are some things that ALWAYS needs to be done, no matter if sound actually works
98 soundStopMusic(); // Has his own checks and simulated to-do list
99 playOnceFinished = false;
100 onlyPlayOnce = playOnce;
101
102 if(!soundOK || !soundInitOK) {
103 soundSimTick = SDL_GetTicks() + 45000; // Simulated sound plays 45 seconds
104 return;
105 }
106 #ifndef DISABLE_SOUND
107
108
109 sprintf(bgMusicFile, "%s", fname); // Remember original Filename
110
111 char fullfname[MAX_FNAME_LENGTH];
112 sprintf(fullfname, "%s", configGetPath(fname));
113 levelMusic = Mix_LoadMUS(fullfname);
114 if(!levelMusic) {
115 DIE(ERROR_SOUND_READ, fullfname);
116 }
117 /*
118 if(!playOnce) {
119 Mix_PlayMusic(levelMusic, -1);
120 } else {
121 Mix_PlayMusic(levelMusic, 1);
122 }
123 We do NOT use automated repeat - we do it ourself to try and fix a bug
124 */
125 Mix_PlayMusic(levelMusic, 1);
126
127
128 Mix_VolumeMusic(MIX_MAX_VOLUME / 2);
129 #endif // DISABLE_SOUND
130 }
131
soundStopMusic()132 void soundStopMusic()
133 {
134 // There are some things that ALWAYS needs to be done, no matter if sound actually works
135 playOnceFinished = false;
136 onlyPlayOnce = false;
137
138 if(!soundOK || !soundInitOK) {
139 soundSimTick = 0;
140 return;
141 }
142 #ifndef DISABLE_SOUND
143 Mix_HaltMusic();
144 if(levelMusic) {
145 Mix_FreeMusic(levelMusic);
146 levelMusic = 0;
147 }
148
149 #endif // DISABLE_SOUND
150 }
151
addSoundFXLua(char * fname)152 Uint32 addSoundFXLua(char* fname) {
153 if(!soundOK || !soundInitOK) {
154 return 0;
155 }
156 #ifndef DISABLE_SOUND
157 char fullfname[MAX_FNAME_LENGTH];
158 sprintf(fullfname, "%s", configGetPath(fname));
159
160 if(sndfxcnt >= MAX_FX_SAMPLES) {
161 DIE(ERROR_BOUNDARY, "too many FX samples");
162 }
163 sound_fx[sndfxcnt + FX_MAX_PREDEF] = Mix_LoadWAV(fullfname);
164 if(!sound_fx[sndfxcnt + FX_MAX_PREDEF]) {
165 DIE(ERROR_SOUND_READ, fname);
166 }
167 sndfxcnt++;
168 return (sndfxcnt-1);
169 #else // DISABLE_SOUND
170 return 0 ;
171 #endif // DISABLE_SOUND
172 }
173
soundPlayFXLua(Uint32 fx)174 void soundPlayFXLua(Uint32 fx) {
175 if(!soundOK || !soundInitOK) {
176 return;
177 }
178 #ifndef DISABLE_SOUND
179 if(fx >= sndfxcnt) {
180 DIE(ERROR_INDEX_INVALID, "Unknown sample");
181 }
182 soundPlayFX(fx + FX_MAX_PREDEF);
183 #endif // DISABLE_SOUND
184 }
185
initSoundFXLua()186 void initSoundFXLua() {
187 if(!soundOK || !soundInitOK) {
188 return;
189 }
190 #ifndef DISABLE_SOUND
191 sndfxcnt = 0;
192 #endif // DISABLE_SOUND
193 }
194
deInitSoundFXLua()195 void deInitSoundFXLua() {
196 if(!soundOK || !soundInitOK) {
197 return;
198 }
199 #ifndef DISABLE_SOUND
200 for(Uint32 i = 0; i < sndfxcnt; i++) {
201 Mix_FreeChunk(sound_fx[i + FX_MAX_PREDEF]);
202 }
203 sndfxcnt = 0;
204 #endif // DISABLE_SOUND
205 }
206
soundStartVideoFX(SDL_RWops * src)207 void soundStartVideoFX(SDL_RWops* src) {
208 if(!soundOK || !soundInitOK) {
209 return;
210 }
211 #ifndef DISABLE_SOUND
212 sound_fx_video=Mix_LoadWAV_RW(src, 0);
213 if(!sound_fx_video) {
214 printf("Couldn't start video sound\n");
215 return;
216 }
217 Mix_PlayChannel(-1, sound_fx_video, 0);
218 #endif // DISABLE_SOUND
219 }
220
soundStopVideoFX()221 void soundStopVideoFX() {
222 if(!soundOK || !soundInitOK) {
223 return;
224 }
225 #ifndef DISABLE_SOUND
226 if(!sound_fx_video) {
227 return;
228 }
229 Mix_FreeChunk(sound_fx_video);
230 sound_fx_video = 0;
231 #endif // DISABLE_SOUND
232 }
233
soundMusicFinished()234 void soundMusicFinished() {
235 if(onlyPlayOnce) {
236 soundStopMusic();
237 playOnceFinished = true;
238 } else {
239 // soundStartMusic auto-unloads current file, so we don't have to call
240 // it explicitely
241 soundStartMusic(bgMusicFile, false);
242 }
243 }
244
soundPlayOnceFinished()245 bool soundPlayOnceFinished() {
246 if(!soundOK || !soundInitOK) {
247 // Simulate playonce
248 if(soundSimTick != 0 && SDL_GetTicks() > soundSimTick) {
249 if(onlyPlayOnce) {
250 playOnceFinished = true;
251 }
252 }
253 }
254 return playOnceFinished;
255 }
256
257