changeset 1244:072851dcec5c

Improve module optimization.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 07 Mar 2015 15:29:37 +0200
parents 377c8a603d21
children 2a0488078b78
files tools/xm2jss.c
diffstat 1 files changed, 62 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/tools/xm2jss.c	Sat Mar 07 15:23:13 2015 +0200
+++ b/tools/xm2jss.c	Sat Mar 07 15:29:37 2015 +0200
@@ -698,13 +698,51 @@
 }
 
 
+/* Scan given pattern for used instruments and channels.
+ * Also checks if the pattern is emty.
+ */
+void scanPattern(JSSModule *module, JSSPattern *pattern, int npattern, BOOL *usedExtInstruments, BOOL *usedChannels, BOOL *empty)
+{
+    int row, channel;
+    JSSNote *n = pattern->data;
+    *empty = FALSE;
+
+    // Check all notes in this pattern to see what instruments are used
+    for (row = 0; row < pattern->nrows; row++)
+    for (channel = 0; channel < pattern->nchannels; channel++, n++)
+    {
+        if (n->instrument != jsetNotSet)
+        {
+            if (n->instrument >= 0 && n->instrument < module->nextInstruments)
+                usedExtInstruments[n->instrument] = TRUE;
+            else
+            {
+                dmMsg(2, "Pattern 0x%x, row=0x%x, chn=%d has invalid instrument 0x%x\n",
+                npattern + 1, row, channel, n->instrument + 1);
+            }
+        }
+
+        if (n->note != jsetNotSet ||
+            n->instrument != jsetNotSet ||
+            n->volume != jsetNotSet ||
+            n->effect != jsetNotSet ||
+            n->param != jsetNotSet)
+        {
+            usedChannels[channel] = TRUE;
+            *empty = FALSE;
+        }
+    }
+}
+
+
 /* Optimize a given module
  */
 JSSModule *optimizeModule(JSSModule *m)
 {
     BOOL usedPatterns[jsetMaxPatterns + 1],
          usedInstruments[jsetMaxInstruments + 1],
-         usedExtInstruments[jsetMaxInstruments + 1];
+         usedExtInstruments[jsetMaxInstruments + 1],
+         usedChannels[jsetMaxChannels];
     int  mapExtInstruments[jsetMaxInstruments + 1],
          mapInstruments[jsetMaxInstruments + 1],
          mapPatterns[jsetMaxPatterns + 1];
@@ -726,8 +764,12 @@
     r->intVersion       = m->intVersion;
     r->nchannels        = m->nchannels;
     r->norders          = m->norders;
+
     for (i = 0; i < jsetNChannels; i++)
+    {
         r->defPanning[i] = m->defPanning[i];
+        usedChannels[i]  = FALSE;
+    }
 
     // Initialize values
     for (i = 0; i <= jsetMaxInstruments; i++)
@@ -748,51 +790,47 @@
     // Find out all actually used patterns and ext.instruments
     // by going through all patterns specified in the order list
     //
+    dmMsg(1, "Scanning patterns for used instruments and channels...\n");
     for (i = 0; i < m->norders; i++)
     {
-        int pattern = m->orderList[i];
-        if (pattern >= 0 && pattern < m->npatterns)
+        int npat = m->orderList[i];
+        if (npat >= 0 && npat < m->npatterns)
         {
-            JSSPattern *p = m->patterns[pattern];
-            if (p != NULL)
+            JSSPattern *pattern = m->patterns[npat];
+            if (pattern != NULL)
             {
-                int row, channel;
-                JSSNote *n = p->data;
+                BOOL empty;
 
                 // Mark this pattern as used
-                usedPatterns[pattern] = TRUE;
+                usedPatterns[npat] = TRUE;
 
-                // Check all notes in this pattern to see what instruments are used
-                for (row = 0; row < p->nrows; row++)
-                for (channel = 0; channel < p->nchannels; channel++, n++)
-                if (n->instrument != jsetNotSet)
+                // Scan for used instruments and channels
+                scanPattern(m, pattern, npat, usedExtInstruments, usedChannels, &empty);
+
+                // Empty patterns with 64 rows are "removed"
+                if (empty && pattern->nrows == 64)
                 {
-                    if (n->instrument >= 0 && n->instrument < m->nextInstruments)
-                        usedExtInstruments[n->instrument] = TRUE;
-                    else
-                    {
-                        dmMsg(2, "Pattern 0x%x, row=0x%x, chn=%d has invalid instrument 0x%x\n",
-                        pattern, row, channel, n->instrument + 1);
-                    }
+                    m->orderList[i] = jsetNotSet;
+                    usedPatterns[npat] = FALSE;
                 }
             }
             else
             {
                 dmErrorMsg("Pattern 0x%x is used on order 0x%x, but has no data!\n",
-                    pattern, i);
+                    npat, i);
 
                 // Fix it.
-                m->orderList[i] = jsetMaxPatterns;
+                m->orderList[i] = jsetNotSet;
             }
         }
         else
-        if (pattern != jsetMaxPatterns)
+        if (npat != jsetNotSet)
         {
             dmErrorMsg("Order 0x%x has invalid pattern number 0x%x, changing to empty!\n",
-                i, pattern);
+                i, npat);
 
             // Fix it.
-            m->orderList[i] = jsetMaxPatterns;
+            m->orderList[i] = jsetNotSet;
         }
     }