From a9684aecd9e8f292ac90a404b3f854df03dfd119 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 3 May 2006 18:54:08 +0000 Subject: Allow .mid files in PWADs (via including a MID inside a music lump). This actually seems to work in Vanilla, as long as the MID is less than ~96k. This isn't perfect. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 473 --- src/i_sound.c | 104 ++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 32 deletions(-) (limited to 'src/i_sound.c') diff --git a/src/i_sound.c b/src/i_sound.c index b0dfca71..0ef92b22 100644 --- a/src/i_sound.c +++ b/src/i_sound.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: i_sound.c 429 2006-03-23 17:43:15Z fraggle $ +// $Id: i_sound.c 473 2006-05-03 18:54:08Z fraggle $ // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005 Simon Howard @@ -128,7 +128,7 @@ //----------------------------------------------------------------------------- static const char -rcsid[] = "$Id: i_sound.c 429 2006-03-23 17:43:15Z fraggle $"; +rcsid[] = "$Id: i_sound.c 473 2006-05-03 18:54:08Z fraggle $"; #include #include @@ -154,6 +154,8 @@ rcsid[] = "$Id: i_sound.c 429 2006-03-23 17:43:15Z fraggle $"; #define NUM_CHANNELS 16 +#define MAXMIDLENGTH (96 * 1024) + static boolean sound_initialised = false; static boolean music_initialised = false; @@ -669,34 +671,32 @@ void I_UnRegisterSong(void *handle) Mix_FreeMusic(music); } -void *I_RegisterSong(void *data, int len) +// Determine whether memory block is a .mid file + +static boolean IsMid(byte *mem, int len) +{ + return len > 4 && !memcmp(mem, "MThd", 4); +} + +// Determine whether memory block is a .mus file + +static boolean IsMus(byte *mem, int len) +{ + return len > 3 && !memcmp(mem, "MUS", 3); +} + +static boolean ConvertMus(byte *musdata, int len, char *filename) { - char filename[64]; - Mix_Music *music; MIDI *mididata; UBYTE *mid; int midlen; - - if (!music_initialised) - return NULL; - - // MUS files begin with "MUS" - // Reject anything which doesnt have this signature - - if (len < 3 || memcmp(data, "MUS", 3) != 0) - return NULL; - -#ifdef _WIN32 - sprintf(filename, "doom.mid"); -#else - sprintf(filename, "/tmp/doom-%i.mid", getpid()); -#endif + boolean result; // Convert from mus to midi // Bits here came from PrBoom mididata = Z_Malloc(sizeof(MIDI), PU_STATIC, 0); - mmus2mid(data, mididata, 89, 0); + mmus2mid(musdata, mididata, 89, 0); if (MIDIToMidi(mididata, &mid, &midlen)) { @@ -704,7 +704,7 @@ void *I_RegisterSong(void *data, int len) fprintf(stderr, "Error converting MUS lump.\n"); - music = NULL; + result = false; } else { @@ -716,22 +716,62 @@ void *I_RegisterSong(void *data, int len) free(mid); free_mididata(mididata); - music = Mix_LoadMUS(filename); - - if (music == NULL) - { - // Failed to load - fprintf(stderr, "Error loading midi\n"); - } + result = true; + } - // remove file now + Z_Free(mididata); + + return result; +} - remove(filename); +void *I_RegisterSong(void *data, int len) +{ + char filename[64]; + Mix_Music *music; + + if (!music_initialised) + return NULL; + + // MUS files begin with "MUS" + // Reject anything which doesnt have this signature + +#ifdef _WIN32 + sprintf(filename, "doom.mid"); +#else + sprintf(filename, "/tmp/doom-%i.mid", getpid()); +#endif + + if (IsMus(data, len)) + { + ConvertMus(data, len, filename); + } + else if (IsMid(data, len) && len < MAXMIDLENGTH) + { + M_WriteFile(filename, data, len); } + else + { + // Unrecognised: unable to load - Z_Free(mididata); + return NULL; + } + + // Load the MIDI + + music = Mix_LoadMUS(filename); + if (music == NULL) + { + // Failed to load + + fprintf(stderr, "Error loading midi\n"); + } + + // remove file now + + remove(filename); + return music; } -- cgit v1.2.3