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