|
From: <sag...@us...> - 2010-03-21 22:07:32
|
Revision: 543
http://modplug.svn.sourceforge.net/modplug/?rev=543&view=rev
Author: saga-games
Date: 2010-03-21 22:07:22 +0000 (Sun, 21 Mar 2010)
Log Message:
-----------
[Imp] ULT Loader: Experimental fixing of the 3xx and F00 effects.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_ult.cpp
Modified: trunk/OpenMPT/soundlib/Load_ult.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_ult.cpp 2010-03-21 21:29:43 UTC (rev 542)
+++ trunk/OpenMPT/soundlib/Load_ult.cpp 2010-03-21 22:07:22 UTC (rev 543)
@@ -42,11 +42,7 @@
9xx - set sample offset to xx * 1024
with 9yy: set sample offset to xxyy * 4
E0x - set vibrato strength (2 is normal)
-F00 - reset speed/tempo to 6/125
-Apparently 3xx will CONTINUE to slide until it reaches its destination, or
-until a 300 effect is encountered. I'm not attempting to handle this (yet).
-
The logarithmic volume scale used in older format versions here, or pretty
much anywhere for that matter. I don't even think Ultra Tracker tries to
convert them. */
@@ -85,11 +81,6 @@
if (!p)
*pe = CMD_NONE;
break;
- case 0x03:
- // 300 apparently stops sliding, which is totally weird
- if (!p)
- p = 1; // close enough?
- break;
case 0x05:
// play backwards
if((p & 0x0F) == 0x02)
@@ -242,6 +233,76 @@
return repeat;
}
+// Functor for postfixing ULT patterns (this is easier than just remembering everything WHILE we're reading the pattern events)
+struct PostFixUltCommands
+//=======================
+{
+ PostFixUltCommands(CHANNELINDEX numChannels)
+ {
+ this->numChannels = numChannels;
+ curChannel = 0;
+ writeT125 = false;
+ isPortaActive.resize(numChannels, false);
+ }
+
+ void operator()(MODCOMMAND& m)
+ {
+ // Attempt to fix portamentos.
+ // UltraTracker will slide until the destination note is reached or 300 is encountered.
+
+ // Stop porta?
+ if(m.command == CMD_TONEPORTAMENTO && m.param == 0)
+ {
+ isPortaActive[curChannel] = false;
+ m.command = CMD_NONE;
+ }
+ if(m.volcmd == VOLCMD_TONEPORTAMENTO && m.vol == 0)
+ {
+ isPortaActive[curChannel] = false;
+ m.volcmd = VOLCMD_NONE;
+ }
+
+ // Apply porta?
+ if(m.note == NOTE_NONE && isPortaActive[curChannel])
+ {
+ if(m.command == CMD_NONE && m.vol != VOLCMD_TONEPORTAMENTO)
+ {
+ m.command = CMD_TONEPORTAMENTO;
+ m.param = 0;
+ } else if(m.volcmd == VOLCMD_NONE && m.command != CMD_TONEPORTAMENTO)
+ {
+ m.volcmd = VOLCMD_TONEPORTAMENTO;
+ m.vol = 0;
+ }
+ } else // new note -> stop porta (or initialize again)
+ {
+ isPortaActive[curChannel] = (m.command == CMD_TONEPORTAMENTO || m.volcmd == VOLCMD_TONEPORTAMENTO);
+ }
+
+ // attempt to fix F00 (reset to tempo 125, speed 6)
+ if(writeT125 && m.command == CMD_NONE)
+ {
+ m.command = CMD_TEMPO;
+ m.param = 125;
+ }
+ if(m.command == CMD_SPEED && m.param == 0)
+ {
+ m.param = 6;
+ writeT125 = true;
+ }
+ if(m.command == CMD_TEMPO) // don't try to fix this anymore if the tempo has already changed.
+ {
+ writeT125 = false;
+ }
+ curChannel = (curChannel + 1) % numChannels;
+ }
+
+ vector<bool> isPortaActive;
+ bool writeT125;
+ CHANNELINDEX numChannels, curChannel;
+};
+
+
bool CSoundFile::ReadUlt(const BYTE *lpStream, DWORD dwMemLength)
//---------------------------------------------------------------
{
@@ -409,6 +470,9 @@
}
}
+ // Post-fix some effects.
+ Patterns.ForEachModCommand(PostFixUltCommands(m_nChannels));
+
for(SAMPLEINDEX nSmp = 0; nSmp < m_nSamples; nSmp++)
{
dwMemPos += ReadSample(&Samples[nSmp + 1], (Samples[nSmp + 1].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S, (LPCSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|