- added standard copyright header to every file
[supertux.git] / src / sound.cpp
1 //  $Id$
2 //
3 //  SuperTux -  A Jump'n Run
4 //  Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
5 //  Copyright (C) 2004 Duong-Khang NGUYEN <neoneurone@users.sf.net>
6 //
7 //  This program is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU General Public License
9 //  as published by the Free Software Foundation; either version 2
10 //  of the License, or (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 #include "defines.h"
22 #include "globals.h"
23 #include "sound.h"
24 #include "setup.h"
25
26 /*global variable*/
27 bool use_sound;           /* handle sound on/off menu and command-line option */
28 bool use_music;           /* handle music on/off menu and command-line option */
29 bool audio_device;        /* != 0: available and initialized */
30 int current_music;
31
32 char * soundfilenames[NUM_SOUNDS] = {
33                                        "/sounds/jump.wav",
34                                        "/sounds/bigjump.wav",
35                                        "/sounds/skid.wav",
36                                        "/sounds/distro.wav",
37                                        "/sounds/herring.wav",
38                                        "/sounds/brick.wav",
39                                        "/sounds/hurt.wav",
40                                        "/sounds/squish.wav",
41                                        "/sounds/fall.wav",
42                                        "/sounds/ricochet.wav",
43                                        "/sounds/bump-upgrade.wav",
44                                        "/sounds/upgrade.wav",
45                                        "/sounds/excellent.wav",
46                                        "/sounds/coffee.wav",
47                                        "/sounds/shoot.wav",
48                                        "/sounds/lifeup.wav",
49                                        "/sounds/stomp.wav",
50                                        "/sounds/kick.wav"
51                                     };
52
53
54 #include <SDL_mixer.h>
55
56 Mix_Chunk * sounds[NUM_SOUNDS];
57 Mix_Music * level_song, * level_song_fast, * herring_song;
58
59 /* --- OPEN THE AUDIO DEVICE --- */
60
61 int open_audio (int frequency, Uint16 format, int channels, int chunksize)
62 {
63   /* if success we reserved some channels and register panning effects */
64   if (Mix_OpenAudio( frequency, format, channels, chunksize ) == 0)
65     {
66       if (Mix_ReserveChannels( SOUND_RESERVED_CHANNELS )
67                             != SOUND_RESERVED_CHANNELS )
68         {
69           DEBUG_MSG( "Warning: open_audio could'nt reserve channels" );
70         }
71
72       /* prepare the spanning effects, no error checking */
73       Mix_SetPanning( SOUND_LEFT_SPEAKER, 230, 24 );
74       Mix_SetPanning( SOUND_RIGHT_SPEAKER, 24, 230 );
75       return 0;
76     }
77   else
78     {
79       return -1;
80     }
81 }
82
83
84 /* --- CLOSE THE AUDIO DEVICE --- */
85
86 void close_audio( void )
87 {
88   if (audio_device) {
89     Mix_UnregisterAllEffects( SOUND_LEFT_SPEAKER );
90     Mix_UnregisterAllEffects( SOUND_RIGHT_SPEAKER );
91     Mix_CloseAudio();
92   }
93 }
94
95
96 /* --- LOAD A SOUND --- */
97
98 Mix_Chunk * load_sound(const std::string& file)
99 {
100   Mix_Chunk * snd;
101
102   snd = Mix_LoadWAV(file.c_str());
103
104   /* printf message and abort if there is an initialized audio device */
105   if ((snd == NULL) && audio_device)
106     st_abort("Can't load", file);
107
108   return(snd);
109 }
110
111
112 /* --- LOAD A SONG --- */
113
114 Mix_Music * load_song(const std::string& file)
115 {
116   Mix_Music * sng;
117
118   sng = Mix_LoadMUS(file.c_str());
119
120   /* printf message and abort if there is an initialized audio device */
121   if ((sng == NULL) && audio_device)
122     st_abort("Can't load", file);
123   return (sng);
124 }
125
126
127 /* --- PLAY A SOUND ON LEFT OR RIGHT OR CENTER SPEAKER --- */
128
129 void play_sound(Mix_Chunk * snd, enum Sound_Speaker whichSpeaker)
130 {
131   /* this won't call the function if the user has disabled sound
132    * either via menu or via command-line option
133    */
134   if (use_sound && audio_device)
135     {
136       Mix_PlayChannel( whichSpeaker, snd, 0);
137
138       /* prepare for panning effects for next call */
139       /* warning: currently, I do not check for errors here */
140       switch (whichSpeaker) {
141         case SOUND_LEFT_SPEAKER:
142           Mix_SetPanning( SOUND_LEFT_SPEAKER, 230, 24 );
143           break;
144         case SOUND_RIGHT_SPEAKER:
145           Mix_SetPanning( SOUND_RIGHT_SPEAKER, 24, 230 );
146           break;
147         default:  // keep the compiler happy
148           break;
149       }
150     }
151 }
152
153
154 void free_chunk(Mix_Chunk *chunk)
155 {
156   if (chunk != NULL)
157     {
158       DEBUG_MSG( __PRETTY_FUNCTION__ );
159       Mix_FreeChunk( chunk );
160       chunk = NULL;
161     }
162 }
163
164
165 int playing_music(void)
166 {
167   if (use_music)
168     {
169       return Mix_PlayingMusic();
170     }
171   else
172     {
173       /* we are in --disable-music we can't be playing music */
174       return 0;
175     }
176 }
177
178
179 int halt_music(void)
180 {
181   if (use_music && audio_device)
182     {
183       return Mix_HaltMusic();
184     }
185   else
186     {
187       return 0;
188     }
189 }
190
191
192 int play_music(Mix_Music *music, int loops)
193 {
194   if (use_music && audio_device)
195     {
196       DEBUG_MSG(__PRETTY_FUNCTION__);
197       return Mix_PlayMusic(music, loops);
198     }
199   else
200     {
201       /* return error since you're trying to play music in --disable-sound mode */
202       return -1;
203     }
204 }
205
206
207 void free_music(Mix_Music *music)
208 {
209   if ( music != NULL )
210     {
211       DEBUG_MSG(__PRETTY_FUNCTION__);
212       Mix_FreeMusic( music );
213       music = NULL;
214     }
215 }
216  int get_current_music()
217   {
218  return current_music;
219  }
220  
221  void set_current_music(int music)
222  {
223  current_music = music;
224  }
225  
226  void play_current_music()
227  {
228  if(playing_music())
229    halt_music();
230  
231  switch(current_music)
232    {
233    case LEVEL_MUSIC:
234      play_music(level_song, -1);  // -1 to play forever
235      break;
236    case HERRING_MUSIC:
237      play_music(herring_song, -1);
238      break;
239    case HURRYUP_MUSIC:
240      play_music(level_song_fast, -1);
241      break;
242    case NO_MUSIC:      // keep the compiler happy for the moment :-)
243      {}
244  /*default:*/
245  }
246  /* use halt_music whenever you want to stop it */
247 }
248