00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <string.h>
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include "SDL.h"
00020 #include "audio.h"
00021
00022
00023
00024 bool audio::audio_initialized = false;
00025
00026 int audio::background_volume;
00027 int audio::effects_volume;
00028 #ifdef OGG_MUSIC
00029
00030 #endif
00031 Mix_Music *audio::music[NUM_MUSIC];
00032 string audio::music_file[NUM_MUSIC];
00033 Mix_Chunk *audio::sounds[NUM_WAVES];
00034 int audio::current_background;
00035 int audio::last_background;
00036 bool audio::background_paused;
00037 int audio::audio_rate;
00038 Uint16 audio::buffer_size;
00039 Uint16 audio::audio_format;
00040 int audio::audio_channels;
00041
00042
00043 py_object audio::schedule;
00044 bool audio::schedule_active = 0;
00045 PyObject *audio::schedule_args = NULL;
00046
00047
00048 void audio::init (config *myconfig) {
00049 int i;
00050
00051
00052 switch( myconfig->audio_sample_rate ) {
00053 case 0: {
00054 audio_rate = 11025;
00055 break; }
00056 case 1: {
00057 audio_rate = 22050;
00058 break; }
00059 default: {
00060 audio_rate = 44100;
00061 break; }
00062 }
00063
00064
00065 audio_format = myconfig->audio_resolution == 0 ? AUDIO_S8 : AUDIO_S16;
00066
00067
00068 audio_channels = myconfig->audio_channels == 0 ? 1 : 2;
00069
00070
00071 background_volume = myconfig->audio_volume;
00072
00073 buffer_size = 4096;
00074 effects_volume = 128;
00075 current_background = -1;
00076 last_background = -1;
00077 background_paused = false;
00078 audio_initialized = false;
00079 schedule_active = false;
00080
00081
00082 for (i = 0; i < NUM_WAVES; i++) sounds[i] = NULL;
00083 for (i = 0; i < NUM_MUSIC; i++) {
00084 music[i] = NULL;
00085 music_file[i] = "";
00086 }
00087
00088
00089 i = Mix_OpenAudio(audio_rate, audio_format, audio_channels, buffer_size);
00090
00091
00092
00093 if ( i < 0 ) {
00094 fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
00095 fprintf(stderr, "Audio will not be used.\n");
00096
00097
00098 } else {
00099 audio_initialized = true;
00100 Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
00101 set_background_volume (background_volume);
00102 }
00103 }
00104
00105 void audio::cleanup(void)
00106 {
00107 int i;
00108
00109 current_background = -1;
00110
00111
00112 for (i = 0; i < NUM_WAVES; i++)
00113 {
00114 unload_wave(i);
00115 sounds[i] = NULL;
00116 }
00117
00118 for (i = 0; i < NUM_MUSIC; i++)
00119 {
00120 unload_background(i);
00121 music[i] = NULL;
00122 music_file[i] = "";
00123 }
00124
00125
00126 schedule.clear ();
00127
00128
00129 if (audio_initialized == true)
00130 {
00131 Mix_CloseAudio();
00132 audio_initialized = false;
00133 }
00134 }
00135
00136 int audio::load_background(int slot, char *filename) {
00137
00138 if (!audio_initialized) return (0);
00139
00140
00141 if ((slot >= NUM_MUSIC) || (slot < 0)) {
00142 fprintf(stderr, "Error: Tried to put music in invalid slot.\n");
00143 return(0);
00144 }
00145
00146
00147 FILE *f = fopen (filename, "r");
00148 if (!f) {
00149 fprintf(stderr, "Error: No such file: %s.\n", filename);
00150 return 0;
00151 }
00152 fclose (f);
00153
00154
00155 if (music[slot] != NULL)
00156 unload_background (slot);
00157
00158
00159 music[slot] = Mix_LoadMUS(filename);
00160 music_file[slot] = filename;
00161
00162 #ifdef OGG_MUSIC
00163
00164
00165
00166
00167
00168 #endif
00169 return(1);
00170 }
00171
00172 void audio::unload_background (int slot)
00173 {
00174 if (music[slot] == NULL) return;
00175
00176
00177
00178 if (current_background == slot)
00179 {
00180 last_background = current_background;
00181 current_background = -1;
00182
00183
00184 Mix_HaltMusic();
00185 Mix_ResumeMusic ();
00186 }
00187
00188 Mix_FreeMusic (music[slot]);
00189 music[slot] = NULL;
00190 music_file[slot] = "";
00191
00192 #ifdef OGG_MUSIC
00193
00194 #endif
00195 }
00196
00197 void audio::pause_music(void) {
00198 Mix_PauseMusic();
00199 }
00200
00201 void audio::unpause_music(void) {
00202 Mix_ResumeMusic();
00203 }
00204
00205
00206
00207 void audio::set_background_volume(int volume) {
00208
00209
00210 if (volume < 0) {
00211 background_volume = 0;
00212 } else if (volume > 100) {
00213 background_volume = 100;
00214 } else
00215 background_volume = volume;
00216
00217
00218 Mix_VolumeMusic(int(background_volume * 1.28));
00219 }
00220
00221
00222
00223 int audio::load_wave(int slot, char *filename) {
00224
00225 if (!audio_initialized) return(1);
00226
00227
00228 if ((slot >= NUM_WAVES) || (slot < 0)) {
00229 fprintf(stderr, "Error: Tried to put wave in invalid slot.\n");
00230 return(1);
00231 } else {
00232
00233 FILE *f = fopen (filename, "r");
00234 if (!f)
00235 {
00236 sounds[slot] = NULL;
00237 return 1;
00238 }
00239
00240 fclose (f);
00241
00242 sounds[slot] = Mix_LoadWAV(filename);
00243 }
00244 return(0);
00245 }
00246
00247 void audio::unload_wave(int wave) {
00248 if (sounds[wave] != NULL) {
00249 Mix_FreeChunk(sounds[wave]);
00250 sounds[wave] = NULL;
00251 }
00252 }
00253
00254 void audio::play_wave(int channel, int slot) {
00255 if ((slot > -1) && (slot < NUM_CHANNELS))
00256 if (sounds[slot] != NULL) Mix_PlayChannel(channel, sounds[slot], 0);
00257 }
00258
00259 void audio::play_background(int slot) {
00260 if (music[slot] != NULL) {
00261 current_background = slot;
00262 Mix_PlayMusic(music[current_background], 0);
00263 }
00264 }
00265
00266 void audio::fade_out_background(int time) {
00267 if (Mix_PlayingMusic ())
00268 {
00269 Mix_FadeOutMusic(time);
00270 last_background = current_background;
00271 current_background = -1;
00272 }
00273 #ifdef OGG_MUSIC
00274
00275 #endif
00276 }
00277
00278 void audio::fade_in_background(int slot, int time) {
00279 if (music[slot] != NULL) {
00280 current_background = slot;
00281 Mix_FadeInMusic(music[slot], 0, time);
00282 }
00283 }
00284
00285
00286 void audio::change_background(int slot, int time) {
00287 fade_out_background(time);
00288 fade_in_background(slot, time);
00289 }
00290
00291 #ifdef OGG_MUSIC
00292
00293
00294
00295
00296 #endif
00297
00298
00299 void audio::set_schedule (string file, PyObject * args)
00300 {
00301
00302 schedule.clear ();
00303 Py_XDECREF (schedule_args);
00304 schedule_args = NULL;
00305
00306
00307 if (file != "")
00308 {
00309 schedule_args = args;
00310 Py_XINCREF (schedule_args);
00311 schedule.create_instance ("schedules.audio." + file, file, args);
00312 }
00313 }
00314
00315
00316 void audio::run_schedule ()
00317 {
00318 PyObject *song = Py_BuildValue ("(i)", last_background);
00319 if (schedule_active) schedule.call_method ("music_finished", song);
00320 Py_DECREF (song);
00321 }
00322
00323
00324 s_int8 audio::put_state (ogzstream& file)
00325 {
00326
00327 current_background >> file;
00328
00329
00330 if (current_background != -1) music_file[current_background] >> file;
00331
00332
00333 schedule.class_name () >> file;
00334 if (schedule_args)
00335 {
00336 true >> file;
00337 python::put_tuple (schedule_args, file);
00338 }
00339 else false >> file;
00340 is_schedule_activated () >> file;
00341
00342 return 1;
00343 }
00344
00345
00346 s_int8 audio::get_state (igzstream& file)
00347 {
00348 string song, script;
00349 bool have_args;
00350
00351
00352 last_background << file;
00353
00354
00355 if (last_background != -1)
00356 {
00357 song << file;
00358
00359
00360 if (load_background (last_background, (char *) song.c_str ()))
00361 play_background (last_background);
00362 }
00363
00364
00365 PyObject * args = NULL;
00366 script << file;
00367
00368 have_args << file;
00369 if (have_args) args = python::get_tuple (file);
00370 set_schedule (script, args);
00371 Py_XDECREF (args);
00372
00373 schedule_active << file;
00374
00375 return 1;
00376 }