foxygit / doom Log in
commit bd0a63d92b625ce22fe7e1859c785ce46cf56777
Author:     nukeykt <alexeytf2@icloud.com>
AuthorDate: Tue May 3 22:42:30 2016 +0900
Commit:     nukeykt <alexeytf2@icloud.com>
CommitDate: Tue May 3 22:42:30 2016 +0900

    music: DMX's "GUS instrument mappings bug" emulation
---
 src/gusconf.c | 38 +++++++++++++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/gusconf.c b/src/gusconf.c
index 5785da6c..c3d0c54e 100644
--- a/src/gusconf.c
+++ b/src/gusconf.c
@@ -35,7 +35,9 @@
 typedef struct
 {
     char *patch_names[MAX_INSTRUMENTS];
+    int used[MAX_INSTRUMENTS];
     int mapping[MAX_INSTRUMENTS];
+    unsigned int count;
 } gus_config_t;

 char *gus_patch_path = "";
@@ -109,6 +111,7 @@ static int SplitLine(char *line, char **fields, unsigned int max_fields)
 static void ParseLine(gus_config_t *config, char *line)
 {
     char *fields[6];
+    unsigned int i;
     unsigned int num_fields;
     unsigned int instr_id, mapped_id;

@@ -120,11 +123,33 @@ static void ParseLine(gus_config_t *config, char *line)
     }

     instr_id = atoi(fields[0]);
+
+    // Skip non GM percussions.
+    if ((instr_id >= 128 && instr_id < 128 + 35) || instr_id > 128 + 81)
+    {
+        return;
+    }
+
     mapped_id = atoi(fields[MappingIndex()]);

-    free(config->patch_names[instr_id]);
-    config->patch_names[instr_id] = M_StringDuplicate(fields[5]);
-    config->mapping[instr_id] = mapped_id;
+    for (i = 0; i < config->count; i++)
+    {
+        if (config->used[i] == mapped_id)
+        {
+            break;
+        }
+    }
+
+    if (i == config->count)
+    {
+        // DMX uses wrong patch name (we should use name of 'mapped_id'
+        // instrument, but DMX uses name of 'instr_id' instead).
+        free(config->patch_names[i]);
+        config->patch_names[i] = M_StringDuplicate(fields[5]);
+        config->used[i] = mapped_id;
+        config->count++;
+    }
+    config->mapping[instr_id] = i;
 }

 static void ParseDMXConfig(char *dmxconf, gus_config_t *config)
@@ -137,8 +162,11 @@ static void ParseDMXConfig(char *dmxconf, gus_config_t *config)
     for (i = 0; i < MAX_INSTRUMENTS; ++i)
     {
         config->mapping[i] = -1;
+        config->used[i] = -1;
     }

+    config->count = 0;
+
     p = dmxconf;

     for (;;)
@@ -225,8 +253,8 @@ static boolean WriteTimidityConfig(char *path, gus_config_t *config)
     }

     fprintf(fstream, "\ndrumset 0\n\n");
-
-    for (i = 128 + 25; i < MAX_INSTRUMENTS; ++i)
+
+    for (i = 128 + 35; i <= 128 + 81; ++i)
     {
         if (config->mapping[i] >= 0 && config->mapping[i] < MAX_INSTRUMENTS
          && config->patch_names[config->mapping[i]] != NULL)