1 /*
2 *
3 * Copyright (c) 1994, 2002, 2003 Johannes Prix
4 * Copyright (c) 1994, 2002, 2003 Reinhard Prix
5 *
6 *
7 * This file is part of Freedroid
8 *
9 * Freedroid is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * Freedroid is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Freedroid; see the file COPYING. If not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 *
24 */
25
26 /*----------------------------------------------------------------------
27 *
28 * Desc: all functions dealing with sound are contained in this file.
29 *
30 *----------------------------------------------------------------------*/
31
32 #ifndef _sound_c
33 #define _sound_c
34 #endif
35
36 #include "system.h"
37
38 #include "defs.h"
39 #include "struct.h"
40 #include "global.h"
41 #include "proto.h"
42
43 // The following is the definition of the sound file names used in freedroid
44 // DO NOT CHANGE THE ORDER OF APPEARENCE IN THIS LIST unless you
45 // also adjust the order of appearance in defs.h!
46
47 char *SoundSampleFilenames[ALL_SOUNDS] = {
48 "ERRORSOUND_NILL.NOWAV",
49 "Blast_Sound_0.wav",
50 "Collision_Sound_0.wav",
51 "GotIntoBlast_Sound_0.wav",
52 "MoveElevator_Sound_0.wav",
53 "Refresh_Sound_0.wav",
54 "LeaveElevator_Sound_0.wav",
55 "EnterElevator_Sound_0.wav",
56 "ThouArtDefeated_Sound_0.wav",
57 "Got_Hit_Sound_0.wav",
58 "TakeoverSetCapsule_Sound_0.wav",
59 "Menu_Item_Selected_Sound_0.wav",
60 "Move_Menu_Position_Sound_0.wav",
61 "Takeover_Game_Won_Sound_0.wav",
62 "Takeover_Game_Deadlock_Sound_0.wav",
63 "Takeover_Game_Lost_Sound_0.wav",
64 "Fire_Bullet_Pulse_Sound_0.wav",
65 "Fire_Bullet_Single_Pulse_Sound_0.wav",
66 "Fire_Bullet_Military_Sound_0.wav",
67 "Fire_Bullet_Flash_Sound_0.wav",
68 "Fire_Bullet_Exterminator_Sound_0.wav",
69 "Fire_Bullet_Laser_Rifle_Sound.wav",
70 "Cry_Sound_0.wav",
71 "Takeover_Sound_0.wav",
72 "Countdown_Sound.wav",
73 "EndCountdown_Sound.wav",
74 "InfluExplosion.wav",
75 "WhiteNoise.wav",
76 "Alert.wav"
77 };
78
79 #ifdef HAVE_LIBSDL_MIXER
80 Mix_Chunk *Loaded_WAV_Files[ALL_SOUNDS];
81 #endif
82
83 char *MusicFiles [NUM_COLORS] = { // we have a background song per color now
84 "AnarchyMenu1.mod", // RED
85 "starpaws.mod", // YELLOW
86 "The_Last_V8.mod", // GREEN
87 "dreamfish-green_beret.mod", // GRAY
88 "dreamfish-sanxion.mod", // BLUE
89 "kollaps-tron.mod", // GREENBLUE
90 "dreamfish-uridium2_loader.mod" // DARK
91 };
92
93 #ifdef HAVE_LIBSDL_MIXER
94 Mix_Music *MusicSongs[NUM_COLORS];
95 Mix_Music *Tmp_MOD_File;
96 #endif
97
98 void
Init_Audio(void)99 Init_Audio(void)
100 {
101 #ifndef HAVE_LIBSDL_MIXER
102 return;
103 #else
104 char *fpath;
105 int i;
106 int audio_rate = 22050;
107 Uint16 audio_format = AUDIO_S16;
108 int audio_channels = 2;
109 // int audio_buffers = 4096;
110 int audio_buffers = 2048;
111
112 DebugPrintf(1, "\nInitializing SDL Audio Systems....\n");
113
114 if ( !sound_on ) return;
115
116
117 // Now SDL_AUDIO is initialized here:
118
119 if ( SDL_InitSubSystem ( SDL_INIT_AUDIO ) == -1 )
120 {
121 DebugPrintf (0, "WARNING: SDL Sound subsystem could not be initialized.\n\
122 Continuing with sound disabled\n");
123 sound_on = FALSE;
124 return;
125 }
126 else
127 DebugPrintf(1, "SDL Audio initialisation successful.\n");
128
129 // Now that we have initialized the audio SubSystem, we must open
130 // an audio channel. This will be done here (see code from Mixer-Tutorial):
131
132 if ( Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) )
133 {
134 DebugPrintf (0, "WARNING: SDL audio channel could not be opened. \n");
135 DebugPrintf (0, "SDL Mixer Error: %s\nContinuing with sound disabled\n", Mix_GetError());
136 sound_on = FALSE;
137 return;
138 }
139 else
140 DebugPrintf (1, "\nSuccessfully opened SDL audio channel." );
141
142 if (Mix_AllocateChannels(20) != 20)
143 DebugPrintf (0, "\nWARNING: could not get all 20 mixer-channels I asked for...\n");
144
145 // Now that the audio channel is opend, its time to load all the
146 // WAV files into memory, something we NEVER did while using the yiff,
147 // because the yiff did all the loading, analyzing and playing...
148
149 Loaded_WAV_Files[0]=NULL;
150 for (i = 1; i < ALL_SOUNDS; i++)
151 {
152 fpath = find_file (SoundSampleFilenames[ i ], SOUND_DIR, NO_THEME, WARNONLY);
153 if (fpath) Loaded_WAV_Files[ i ] = Mix_LoadWAV(fpath);
154 if ( Loaded_WAV_Files[i] == NULL )
155 {
156 DebugPrintf (0, "Error: could not load Sound-sample: %s", SoundSampleFilenames[ i ]);
157 DebugPrintf (0, "SDL Mixer Error: %s\n Continuing with sound disabled\n", Mix_GetError());
158 sound_on = FALSE;
159 return;
160 } // if ( !Loaded_WAV...
161 else
162 DebugPrintf (1, "\nSuccessfully loaded file %s.", SoundSampleFilenames[i]);
163 } // for (i=1; ...
164
165 for (i = 0; i < NUM_COLORS; i++)
166 {
167 fpath = find_file ( MusicFiles [ i ], SOUND_DIR, NO_THEME, WARNONLY);
168 if (fpath) MusicSongs [ i ] = Mix_LoadMUS( fpath );
169 if ( MusicSongs[ i ] == NULL )
170 {
171 DebugPrintf ( 0, "\nError loading sound-file: %s\n", MusicFiles[ i ]);
172 DebugPrintf (0, "SDL Mixer Error: %s\n Continuing with sound disabled\n", Mix_GetError());
173 sound_on = FALSE;
174 return;
175 } // if ( !Loaded_WAV...
176 else
177 DebugPrintf ( 1 , "\nSuccessfully loaded file %s.", MusicFiles[ i ]);
178 } // for
179
180
181 //--------------------
182 // Now that the music files have been loaded successfully, it's time to set
183 // the music and sound volumes accoridingly, i.e. as specifies by the users
184 // configuration.
185 //
186 Set_Sound_FX_Volume( GameConfig.Current_Sound_FX_Volume );
187
188 // DebugPrintf (1, "done.");
189 // fflush(stdout);
190 #endif // HAVE_SDL_MIXER
191 } // void InitAudio(void)
192
193 void
Set_BG_Music_Volume(float NewVolume)194 Set_BG_Music_Volume(float NewVolume)
195 {
196
197 #ifndef HAVE_LIBSDL_MIXER
198 return;
199 #else
200 if ( !sound_on ) return;
201
202 Mix_VolumeMusic( (int) rintf( NewVolume * MIX_MAX_VOLUME ) );
203
204 #endif // HAVE_LIBSDL_MIXER
205 } // void Set_BG_Music_Volume(float NewVolume)
206
207 void
Set_Sound_FX_Volume(float NewVolume)208 Set_Sound_FX_Volume(float NewVolume)
209 {
210 int i;
211 #ifndef HAVE_LIBSDL_MIXER
212 return;
213 #else
214 if ( !sound_on ) return;
215
216 // Set the volume IN the loaded files, if SDL is used...
217 // This is done here for the Files 1,2,3 and 4, since these
218 // are background music files.
219 for ( i=5 ; i<ALL_SOUNDS ; i++ )
220 {
221 Mix_VolumeChunk( Loaded_WAV_Files[i], (int) rintf(NewVolume* MIX_MAX_VOLUME) );
222 }
223
224 #endif // HAVE_LIBSDL_MIXER
225
226 } // void Set_BG_Music_Volume(float NewVolume)
227
228
229 void
CountdownSound(void)230 CountdownSound (void)
231 {
232 Play_Sound (COUNTDOWN_SOUND);
233 }
234
235 void
EndCountdownSound(void)236 EndCountdownSound (void)
237 {
238 Play_Sound (ENDCOUNTDOWN_SOUND);
239 }
240
241 /*@Function============================================================
242 @Desc: Starts a Tune.
243
244 @Ret:
245 @Int:
246 * $Function----------------------------------------------------------*/
247 void
StartSound(int Tune)248 StartSound (int Tune)
249 {
250
251 } /* void StartSound(int Tune) */
252
253 /*@Function============================================================
254 @Desc:
255
256 @Ret:
257 @Int:
258 * $Function----------------------------------------------------------*/
259 void
CrySound(void)260 CrySound (void)
261 {
262 Play_Sound ( CRY_SOUND );
263 }
264
265 /*@Function============================================================
266 @Desc:
267
268 @Ret:
269 @Int:
270 * $Function----------------------------------------------------------*/
271 void
TransferSound(void)272 TransferSound (void)
273 {
274 Play_Sound ( TRANSFER_SOUND );
275 }
276
277 /*@Function============================================================
278 @Desc:
279
280 This function is intended to provide a convenient way of switching
281 between different backround sounds in freedroid.
282 If no background sound was yet running, the function should start playing
283 the given background music.
284 If some background sound was already playing, the function should shut down
285 the old background music and start playing the new one.
286
287 Technical details:
288
289
290
291 @Ret:
292 @Int:
293 * $Function----------------------------------------------------------*/
294 void
Switch_Background_Music_To(char * filename_raw)295 Switch_Background_Music_To ( char* filename_raw )
296 {
297 char* fpath;
298 static int prev_color = -1;
299 static bool paused = FALSE;
300
301 #ifndef HAVE_LIBSDL_MIXER
302 return;
303 #else
304
305 if ( !sound_on ) return;
306
307 if ( filename_raw == NULL )
308 {
309 Mix_PauseMusic(); // pause currently played background music
310 paused = TRUE;
311 return;
312 }
313
314 // rp: lets cheat when using Mingw32
315 #if (!defined __WIN32__ && !defined HAVE_LIBVORBIS)
316 if (strstr (filename_raw, ".ogg"))
317 {
318 DebugPrintf (1, "\n\nWARNING: no ogg vorbis libs were found when configuring,\n\
319 can't play %s!\n", filename_raw);
320 return;
321 }
322
323 #endif
324
325 // New feature: choose background music by level-color:
326 // if filename_raw==BYCOLOR then chose bg_music[color]
327 // NOTE: if new level-color is the same as before, just resume paused music!
328 if (!strcmp( filename_raw, BYCOLOR))
329 {
330 if (paused && (prev_color == CurLevel->color) ) // current level-song was just paused
331 {
332 Mix_ResumeMusic ();
333 paused = FALSE;
334 }
335 else
336 {
337 Mix_PlayMusic (MusicSongs[CurLevel->color], -1);
338 paused = FALSE;
339 prev_color = CurLevel->color;
340 }
341 }
342 else // not using BYCOLOR mechanism: just play specified song
343 {
344 if (Tmp_MOD_File) Mix_FreeMusic(Tmp_MOD_File);
345 fpath = find_file (filename_raw, SOUND_DIR, NO_THEME, WARNONLY);
346 if (fpath) Tmp_MOD_File = Mix_LoadMUS (fpath);
347 if ( Tmp_MOD_File == NULL )
348 {
349 DebugPrintf (0, "\nError loading sound-file: %s\n", filename_raw);
350 DebugPrintf (0, "SDL Mixer Error: %s\n Continuing with sound disabled\n", Mix_GetError());
351 sound_on = FALSE;
352 return;
353 } // if ( !Loaded_WAV...
354 Mix_PlayMusic (Tmp_MOD_File, -1);
355 }
356
357 Mix_VolumeMusic ( (int) rintf( GameConfig.Current_BG_Music_Volume * MIX_MAX_VOLUME ) );
358
359 #endif // HAVE_LIBSDL_MIXER
360
361 }; // void Switch_Background_Music_To(int Tune)
362
363
364 /*@Function============================================================
365 @Desc:
366
367 @Ret:
368 @Int:
369 * $Function----------------------------------------------------------*/
370 void
Play_Sound(int Tune)371 Play_Sound (int Tune)
372 {
373 #ifndef HAVE_LIBSDL_MIXER
374 return;
375 #else
376 int Newest_Sound_Channel=0;
377
378 if ( !sound_on ) return;
379
380 Newest_Sound_Channel = Mix_PlayChannel(-1, Loaded_WAV_Files[Tune] , 0);
381 if ( Newest_Sound_Channel == -1 )
382 {
383 DebugPrintf (0, "WARNING: Could not play sound-sample: %s Error: %s\n\
384 This usually just means that too many samples where played at the same time\n",
385 SoundSampleFilenames[ Tune ] , Mix_GetError() );
386 } // if ( ... = -1
387 else
388 DebugPrintf( 2 , "\nSuccessfully playing file %s.", SoundSampleFilenames[ Tune ]);
389
390 #endif // HAVE_LIBSDL_MIXER
391
392 } // void Play_Sound(int Tune)
393
394 /*@Function============================================================
395 @Desc:
396
397 @Ret:
398 @Int:
399 * $Function----------------------------------------------------------*/
400 void
GotHitSound(void)401 GotHitSound (void)
402 {
403 if (!sound_on) return;
404
405 Play_Sound (GOT_HIT_SOUND);
406 } // void GotHitSound(void)
407
408
409 /*@Function============================================================
410 @Desc:
411
412 @Ret:
413 @Int:
414 * $Function----------------------------------------------------------*/
415 void
GotIntoBlastSound(void)416 GotIntoBlastSound (void)
417 {
418 if (!sound_on) return;
419
420 Play_Sound (GOT_INTO_BLAST_SOUND);
421 return;
422 } // void GotIntoBlastSound(void)
423
424 /*@Function============================================================
425 @Desc:
426
427 @Ret:
428 @Int:
429 * $Function----------------------------------------------------------*/
430 void
RefreshSound(void)431 RefreshSound (void)
432 {
433 if (!sound_on) return;
434
435 Play_Sound (REFRESH_SOUND);
436 return;
437 } // void RefreshSound(void)
438
439
440 /*@Function============================================================
441 @Desc:
442
443 @Ret:
444 @Int:
445 * $Function----------------------------------------------------------*/
446 void
MoveLiftSound(void)447 MoveLiftSound (void)
448 {
449 if (!sound_on) return;
450
451 Play_Sound (MOVE_ELEVATOR_SOUND);
452 } // void MoveLiftSound(void)
453
454 /*@Function============================================================
455 @Desc:
456
457 @Ret:
458 @Int:
459 * $Function----------------------------------------------------------*/
460 void
MenuItemSelectedSound(void)461 MenuItemSelectedSound (void)
462 {
463 if (!sound_on) return;
464
465 Play_Sound (MENU_ITEM_SELECTED_SOUND);
466 } // void MoveLiftSound(void)
467
468 /*@Function============================================================
469 @Desc:
470
471 @Ret:
472 @Int:
473 * $Function----------------------------------------------------------*/
474 void
MoveMenuPositionSound(void)475 MoveMenuPositionSound (void)
476 {
477 if (!sound_on) return;
478
479 Play_Sound (MOVE_MENU_POSITION_SOUND);
480 } // void MoveLiftSound(void)
481
482
483 /*@Function============================================================
484 @Desc:
485
486 @Ret:
487 @Int:
488 * $Function----------------------------------------------------------*/
489 void
ThouArtDefeatedSound(void)490 ThouArtDefeatedSound (void)
491 {
492 if (!sound_on) return;
493 Play_Sound (THOU_ART_DEFEATED_SOUND);
494 } // void MoveLiftSound(void)
495
496
497 /*@Function============================================================
498 @Desc:
499
500 @Ret:
501 @Int:
502 * $Function----------------------------------------------------------*/
503 void
EnterLiftSound(void)504 EnterLiftSound (void)
505 {
506 if (!sound_on) return;
507
508 Play_Sound (ENTER_ELEVATOR_SOUND);
509 return;
510 } // void EnterLiftSound(void)
511
512
513 /*@Function============================================================
514 @Desc:
515
516 @Ret:
517 @Int:
518 * $Function----------------------------------------------------------*/
519 void
LeaveLiftSound(void)520 LeaveLiftSound (void)
521 {
522 if (!sound_on) return;
523
524 Play_Sound (LEAVE_ELEVATOR_SOUND);
525
526 return;
527 } // void LeaveLiftSound(void)
528
529
530 /*@Function============================================================
531 @Desc:
532
533 @Ret:
534 @Int:
535 * $Function----------------------------------------------------------*/
536 void
Fire_Bullet_Sound(int BulletType)537 Fire_Bullet_Sound (int BulletType)
538 {
539 if (!sound_on) return;
540
541 switch (BulletType)
542 {
543 case PULSE:
544 Play_Sound ( FIRE_BULLET_PULSE_SOUND );
545 break;
546
547 case SINGLE_PULSE:
548 Play_Sound ( FIRE_BULLET_SINGLE_PULSE_SOUND );
549 break;
550
551 case MILITARY:
552 Play_Sound ( FIRE_BULLET_MILITARY_SOUND );
553 break;
554
555 case FLASH:
556 Play_Sound ( FIRE_BULLET_FLASH_SOUND );
557 break;
558
559 case EXTERMINATOR:
560 Play_Sound ( FIRE_BULLET_EXTERMINATOR_SOUND );
561 break;
562
563 case LASER_RIFLE:
564 Play_Sound ( FIRE_BULLET_LASER_RIFLE_SOUND );
565 break;
566
567 }
568 } // void FireBulletSound(void)
569
570
571 /*@Function============================================================
572 @Desc:
573
574 @Ret:
575 @Int:
576 * $Function----------------------------------------------------------*/
577 void
Takeover_Set_Capsule_Sound(void)578 Takeover_Set_Capsule_Sound (void)
579 {
580 if (!sound_on) return;
581
582 Play_Sound (TAKEOVER_SET_CAPSULE_SOUND);
583 } // void FireBulletSound(void)
584
585 /*@Function============================================================
586 @Desc:
587
588 @Ret:
589 @Int:
590 * $Function----------------------------------------------------------*/
591 void
Takeover_Game_Won_Sound(void)592 Takeover_Game_Won_Sound (void)
593 {
594 if (!sound_on) return;
595
596 Play_Sound ( TAKEOVER_GAME_WON_SOUND );
597 } // void FireBulletSound(void)
598
599 /*@Function============================================================
600 @Desc:
601
602 @Ret:
603 @Int:
604 * $Function----------------------------------------------------------*/
605 void
Takeover_Game_Deadlock_Sound(void)606 Takeover_Game_Deadlock_Sound (void)
607 {
608 if (!sound_on) return;
609
610 Play_Sound ( TAKEOVER_GAME_DEADLOCK_SOUND );
611 } // void FireBulletSound(void)
612
613 /*@Function============================================================
614 @Desc:
615
616 @Ret:
617 @Int:
618 * $Function----------------------------------------------------------*/
619 void
Takeover_Game_Lost_Sound(void)620 Takeover_Game_Lost_Sound (void)
621 {
622 if (!sound_on) return;
623
624 Play_Sound ( TAKEOVER_GAME_LOST_SOUND );
625 } // void FireBulletSound(void)
626
627
628 /*@Function============================================================
629 @Desc:
630
631 @Ret:
632 @Int:
633 * $Function----------------------------------------------------------*/
634 void
BounceSound(void)635 BounceSound (void)
636 {
637 if (!sound_on) return;
638
639 // Play_Sound (COMBAT_BACKGROUND_MUSIC_SOUND );
640 Play_Sound ( COLLISIONSOUND );
641
642 } // void BounceSound(void)
643
644 /*@Function============================================================
645 @Desc:
646
647 @Ret:
648 @Int:
649 * $Function----------------------------------------------------------*/
650 void
DruidBlastSound(void)651 DruidBlastSound (void)
652 {
653 if (!sound_on) return;
654
655 Play_Sound (BLASTSOUND);
656
657 } // void BounceSound(void)
658
659
660 #undef _sound_c
661