This patch resulted after a feature request [ 1597004 ] at our tracker: http://sourceforge.net/tracker/index.php?func=detail&aid=1597004&group_id=124987&atid=701009 Initial support for allowing ogg, mp3, and mod (mod, it, s3m) external music files to be played instead of the original midi files. The music files are searched first under /data1/music and then under ~/.hexen2/data1/music. In the first pass, the original midi filename is searched with a proper extension. If nothing is found, then trackXX is searched similarly (XX : cd-track number for the running map). If it is not found either, then the original midi file is played. Note: replace data1 with portals for the mission pack. If you are running a mod, then replace it with the mod's name. A more technical explanation: the music files are searched under the 'music' directories of the whole of the game's internal search path. Do remember that this depends on SDL_mixer and whatever option it was compiled with: It needs mikmod for mod files, ogg/vorbis libraries for ogg files, and smpeg, or preferably libmad, for mp3 files. If, say, it wasn't linked against smpeg or libmad, then mp3 files won't be played. In the game, choose midi as the background music format and you'll be ready to go. --- midi_sdl.c~ 2007-09-21 10:26:37.000000000 +0300 +++ midi_sdl.c 2007-09-21 10:32:54.000000000 +0300 @@ -120,6 +120,7 @@ qboolean MIDI_Init(void) int audio_channels = 2; int audio_buffers = 4096; + char musicdir[MAX_OSPATH]; void *selfsyms; const SDL_version *smixer_version; const SDL_version *(*Mix_Linked_Version_fp)(void) = NULL; @@ -187,6 +188,9 @@ bad_version: if (midi_endmusicfnc) Mix_HookMusicFinished(midi_endmusicfnc); + qerr_snprintf(musicdir, sizeof(musicdir), "%s/music", fs_userdir); + Sys_mkdir (musicdir); + Con_Printf("MIDI music initialized.\n"); Cmd_AddCommand ("midi_play", MIDI_Play_f); @@ -206,11 +210,30 @@ bad_version: #define TEMP_MUSICNAME "tmpmusic" +#define MIDI_DIRNAME "midi" +#define MUSIC_DIRNAME "music" +#define MUSIC_DIRNAME2 "mod" /* UQE Hexen II uses this name */ + +static const struct +{ + Mix_MusicType type; /* as enum'ed in SDL_mixer.h */ + char *ext; /* the file extension */ +} MusicFile[] = +{ + { MUS_OGG, "ogg" }, + { MUS_MP3, "mp3" }, + { MUS_MOD, "mod" }, + { MUS_MOD, "it" }, + { MUS_MOD, "s3m" }, + { MUS_MID, "mid" }, /* midi must be the last before NULL */ + { MUS_NONE, NULL } /* the last entry must be NULL */ +}; void MIDI_Play (const char *Name) { FILE *midiFile; char midiName[MAX_OSPATH], tempName[MAX_QPATH]; + int i, search_cdrip; if (!bMidiInited) //don't try to play if there is no midi return; @@ -223,11 +246,50 @@ void MIDI_Play (const char *Name) return; } - q_snprintf (tempName, sizeof(tempName), "%s.%s", Name, "mid"); - FS_OpenFile (va("%s/%s", "midi", tempName), &midiFile, false); + search_cdrip = 0; +retry: + i = 0; + if (search_cdrip) + { + Con_Printf ("trying a cd-rip for track %d\n", cl.cdtrack); + } + while (MusicFile[i].ext != NULL) + { + if (MusicFile[i].type == MUS_MID) + { + if (!search_cdrip) + { + search_cdrip = 1; + goto retry; + } + else + { + search_cdrip = 0; + Con_Printf ("trying a midi file\n"); + } + } + if (search_cdrip) + { + if (MusicFile[i].type != MUS_MP3 && MusicFile[i].type != MUS_OGG) + { + ++i; + continue; + } + q_snprintf (tempName, sizeof(tempName), "track%02d.%s", cl.cdtrack, MusicFile[i].ext); + } + else + { + q_snprintf (tempName, sizeof(tempName), "%s.%s", Name, MusicFile[i].ext); + } + FS_OpenFile (va("%s/%s", MusicFile[i].type == MUS_MID ? MIDI_DIRNAME : MUSIC_DIRNAME, tempName), &midiFile, false); + if (midiFile) + break; + ++i; + } + if (!midiFile) { - Con_Printf("music file %s not found\n", tempName); + Con_Printf("no music file for %s was found\n", Name); return; } else @@ -237,7 +299,7 @@ void MIDI_Play (const char *Name) int ret; Con_Printf("Extracting %s from pakfile\n", tempName); - q_snprintf (midiName, sizeof(midiName), "%s/%s.%s", host_parms->userdir, TEMP_MUSICNAME, "mid"); + q_snprintf (midiName, sizeof(midiName), "%s/%s.%s", host_parms->userdir, TEMP_MUSICNAME, MusicFile[i].ext); ret = FS_CopyFromFile (midiFile, midiName, fs_filesize); fclose (midiFile); if (ret != 0) @@ -249,7 +311,8 @@ void MIDI_Play (const char *Name) else /* use the file directly */ { fclose (midiFile); - q_snprintf (midiName, sizeof(midiName), "%s/%s/%s", fs_filepath, "midi", tempName); + q_snprintf (midiName, sizeof(midiName), "%s/%s/%s", + fs_filepath, MusicFile[i].type == MUS_MID ? MIDI_DIRNAME : MUSIC_DIRNAME, tempName); } }