shithub: choc

Download patch

ref: a9684aecd9e8f292ac90a404b3f854df03dfd119
parent: 934c9c337b6dc5dd8e78f616e818df67b4fef811
author: Simon Howard <fraggle@gmail.com>
date: Wed May 3 14:54:08 EDT 2006

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

--- 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 <stdio.h>
 #include <stdlib.h>
@@ -154,6 +154,8 @@
 
 #define NUM_CHANNELS		16
 
+#define MAXMIDLENGTH        (96 * 1024)
+
 static boolean sound_initialised = false;
 static boolean music_initialised = false;
 
@@ -669,34 +671,32 @@
     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)
 {
-    char filename[64];
-    Mix_Music *music;
+    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)
+{
     MIDI *mididata;
     UBYTE *mid;
     int midlen;
+    boolean result;
 
-    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
-
     // 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 @@
 
         fprintf(stderr, "Error converting MUS lump.\n");
 
-        music = NULL;
+        result = false;
     }
     else
     {
@@ -716,22 +716,62 @@
        
         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);
 
-        remove(filename);
+    return result;
+}
+
+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;
 }