# HG changeset patch # User Matti Hamalainen # Date 1425734977 -7200 # Node ID 072851dcec5c97a88c4d6fe3fd4e5ea168a7f191 # Parent 377c8a603d21717f657fb3fa1e5f0badd8ee92ba Improve module optimization. diff -r 377c8a603d21 -r 072851dcec5c tools/xm2jss.c --- 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; } }