/* * This is an alternate backend for the music system. * It uses SDL_mixer to provide a more reliable playback, * and allow processing of multiple audio formats. * * -- MD2211 (2006-04-24) */ #include #include #include #include #include "args.h" #include "hmp2mid.h" #include "digi_mixer_music.h" #include "jukebox.h" #include "cfile.h" #include "u_mem.h" #define MIX_MUSIC_DEBUG 0 #define MUSIC_FADE_TIME 500 //milliseconds #define MUSIC_EXTENSION_ARG "-music_ext" Mix_Music *current_music = NULL; void music_done() { Mix_HaltMusic(); Mix_FreeMusic(current_music); current_music = NULL; jukebox_stop_hook(); } void convert_hmp(char *filename, char *mid_filename) { if (!PHYSFS_exists(mid_filename)) { const char *err; PHYSFS_file *hmp_in; PHYSFS_file *mid_out = PHYSFSX_openWriteBuffered(mid_filename); if (!mid_out) { fprintf(stderr, "Error could not open: %s for writing: %s\n", mid_filename, PHYSFS_getLastError()); return; } if (MIX_MUSIC_DEBUG) printf("convert_hmp: converting %s to %s\n", filename, mid_filename); hmp_in = PHYSFSX_openReadBuffered(filename); if (!hmp_in) { fprintf(stderr, "Error could not open: %s\n", filename); PHYSFS_close(mid_out); return; } err = hmp2mid(hmp_in, mid_out); PHYSFS_close(mid_out); PHYSFS_close(hmp_in); if (err) { fprintf(stderr, "%s\n", err); PHYSFS_delete(mid_filename); return; } } else { if (MIX_MUSIC_DEBUG) printf("convert_hmp: %s already exists\n", mid_filename); } } /* * Plays a music given its name (regular game songs) */ void mix_play_music(char *filename, int loop) { int i, got_end=0; char rel_filename[32]; // just the filename of the actual music file used char music_title[16]; char *basedir = "Music"; loop *= -1; // Quick hack to filter out the .hmp extension for (i=0; !got_end; i++) { switch (filename[i]) { case '.': case '\0': music_title[i] = '\0'; got_end = 1; break; default: music_title[i] = filename[i]; } } if (!PHYSFS_isDirectory(basedir)) PHYSFS_mkdir(basedir); // tidy up those files // What is the extension of external files? If none, default to internal MIDI if (GameArg.SndExternalMusic) { sprintf(rel_filename, "%s/%s.%3s", basedir, music_title, GameArg.SndExternalMusic); // add extension } else { sprintf(rel_filename, "%s/%s.mid", basedir, music_title); convert_hmp(filename, rel_filename); } mix_play_file(rel_filename, loop); } /* * Plays a music file from an absolute path (used by jukebox) */ void mix_play_file(char *filename, int loop) { char real_filename[PATH_MAX]; PHYSFSX_getRealPath(filename, real_filename); // build absolute path if ((current_music = Mix_LoadMUS(real_filename))) { if (Mix_PlayingMusic()) { // Fade-in effect sounds cleaner if we're already playing something Mix_FadeInMusic(current_music, loop, MUSIC_FADE_TIME); } else { Mix_PlayMusic(current_music, loop); } Mix_HookMusicFinished(music_done); } else { fprintf(stderr, "Music %s could not be loaded\n", real_filename); Mix_HaltMusic(); } } void mix_set_music_volume(int vol) { //printf("mix_set_music_volume %d\n", vol); Mix_VolumeMusic(vol); } void mix_stop_music() { Mix_HaltMusic(); }