|
From: <sag...@us...> - 2011-10-07 18:01:23
|
Revision: 1095
http://modplug.svn.sourceforge.net/modplug/?rev=1095&view=rev
Author: saga-games
Date: 2011-10-07 18:01:17 +0000 (Fri, 07 Oct 2011)
Log Message:
-----------
[Fix] A great number of mind-boggling combinations of Note Off, Instrument Number, Note Delay, etc... has been fixed, plus some things which broke in revision 1082. I might be going insane now.
Revision Links:
--------------
http://modplug.svn.sourceforge.net/modplug/?rev=1082&view=rev
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/modcommand.cpp
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-10-07 01:33:41 UTC (rev 1094)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-10-07 18:01:17 UTC (rev 1095)
@@ -1402,8 +1402,7 @@
if(GetNumInstruments() < 1 && instr < MAX_SAMPLES)
{
pChn->pModSample = &Samples[instr];
- }
- else
+ } else
{
if(instr < MAX_INSTRUMENTS)
pChn->pModInstrument = Instruments[instr];
@@ -1436,16 +1435,14 @@
if (instr) pChn->nNewIns = instr;
bool retrigEnv = (!note) && (instr);
+ // Apparently, any note number in a pattern causes instruments to recall their original volume settings - no matter if there's a Note Off next to it or whatever.
+ // Test cases: keyoff+instr.xm, delay.xm
+ bool reloadInstrSettings = (IsCompatibleMode(TRK_FASTTRACKER2) && instr != 0);
+ bool keepInstr = (GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT));
+
// Now it's time for some FT2 crap...
if (GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))
{
- if(IsCompatibleMode(TRK_FASTTRACKER2) && instr != 0)
- {
- // Apparently, any note number in a pattern causes instruments to retrigger - no matter if there's a Note Off next to it or whatever.
- // Test cases: keyoff+instr.xm, delay.xm
- retrigEnv = true;
- }
-
// XM: FT2 ignores a note next to a K00 effect, and a fade-out seems to be done when no volume envelope is present (not exactly the Kxx behaviour)
if(cmd == CMD_KEYOFF && param == 0 && IsCompatibleMode(TRK_FASTTRACKER2))
{
@@ -1465,14 +1462,53 @@
// XM Compatibility: Some special hacks for rogue note delays... (EDx with x > 0)
// Apparently anything that is next to a note delay behaves totally unpredictable in FT2. Swedish tracker logic. :)
- // If there's a note delay but no note, retrig the last note.
if(note == NOTE_NONE)
{
+ // If there's a note delay but no real note, retrig the last note.
+ // Test case: delay2.xm
note = pChn->nNote - pChn->nTranspose;
+ retrigEnv = true;
+ } else if(note >= NOTE_MIN_SPECIAL)
+ {
+ // Gah! Even Note Off + Note Delay will cause envelopes to *retrigger*! How stupid is that?
+ retrigEnv = true;
+ // ... Well, and that is actually all it does if there's an envelope. No fade out, no nothing. *sigh*
+ // Test case: OffDelay.xm
+ note = NOTE_NONE;
+ keepInstr = false;
+ } else
+ {
+ retrigEnv = true;
+ keepInstr = true;
}
}
}
+ if(retrigEnv || reloadInstrSettings)
+ {
+ const MODSAMPLE *oldSample = nullptr;
+ // Reset default volume when retriggering envelopes
+
+ if (GetNumInstruments())
+ {
+ oldSample = pChn->pModSample;
+ } else if (instr <= GetNumSamples())
+ {
+ // Case: Only samples are used; no instruments.
+ oldSample = &Samples[instr];
+ }
+
+ if(oldSample != nullptr)
+ {
+ pChn->nVolume = oldSample->nVolume;
+ if(reloadInstrSettings)
+ {
+ // Also reload panning
+ pChn->nPan = oldSample->nPan;
+ }
+ }
+ }
+
if (retrigEnv) //Case: instrument with no note data.
{
//IT compatibility: Instrument with no note.
@@ -1490,23 +1526,16 @@
}
}
- if (m_nInstruments)
+ if (GetNumInstruments() && (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2)))
{
- if (pChn->pModSample) pChn->nVolume = pChn->pModSample->nVolume;
- if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
- {
- pChn->dwFlags |= CHN_FASTVOLRAMP;
- ResetChannelEnvelopes(pChn);
- pChn->nAutoVibDepth = 0;
- pChn->nAutoVibPos = 0;
- pChn->dwFlags &= ~CHN_NOTEFADE;
- pChn->nFadeOutVol = 65536;
- }
- } else //Case: Only samples are used; no instruments.
- {
- if (instr < MAX_SAMPLES) pChn->nVolume = Samples[instr].nVolume;
+ pChn->dwFlags |= CHN_FASTVOLRAMP;
+ ResetChannelEnvelopes(pChn);
+ pChn->nAutoVibDepth = 0;
+ pChn->nAutoVibPos = 0;
+ pChn->dwFlags &= ~CHN_NOTEFADE;
+ pChn->nFadeOutVol = 65536;
}
- if (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) instr = 0;
+ if (!keepInstr) instr = 0;
}
// Invalid Instrument ?
if (instr >= MAX_INSTRUMENTS) instr = 0;
@@ -1514,15 +1543,15 @@
// Note Cut/Off/Fade => ignore instrument
if (note >= NOTE_MIN_SPECIAL) instr = 0;
- if ((note) && (note <= NOTE_MAX))
+ if (note != NOTE_NONE && NOTE_IS_VALID(note))
{
pChn->nNewNote = pChn->nLastNote = note;
- }
- // New Note Action ?
- if (note != NOTE_NONE && NOTE_IS_VALID(note) && !bPorta)
- {
- CheckNNA(nChn, instr, note, FALSE);
+ // New Note Action ?
+ if (!bPorta)
+ {
+ CheckNNA(nChn, instr, note, FALSE);
+ }
}
if(note)
@@ -1773,14 +1802,17 @@
// -> CODE#0010
// -> DESC="add extended parameter mechanism to pattern effects"
m = NULL;
- if (m_nRow < Patterns[m_nPattern].GetNumRows()-1) {
+ if (m_nRow < Patterns[m_nPattern].GetNumRows()-1)
+ {
m = Patterns[m_nPattern] + (m_nRow+1) * m_nChannels + nChn;
}
- if (m && m->command == CMD_XPARAM) {
- if (m_nType & MOD_TYPE_XM) {
+ if (m && m->command == CMD_XPARAM)
+ {
+ if (GetType() & MOD_TYPE_XM)
+ {
param -= 0x20; //with XM, 0x20 is the lowest tempo. Anything below changes ticks per row.
}
- param = (param<<8) + m->param;
+ param = (param << 8) + m->param;
}
// -! NEW_FEATURE#0010
if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT))
@@ -1802,14 +1834,14 @@
case CMD_ARPEGGIO:
// IT compatibility 01. Don't ignore Arpeggio if no note is playing (also valid for ST3)
if ((m_nTickCount) || (((!pChn->nPeriod) || !pChn->nNote) && !IsCompatibleMode(TRK_IMPULSETRACKER | TRK_SCREAMTRACKER))) break;
- if ((!param) && (!(m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)))) break;
+ if ((!param) && (!(GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)))) break;
pChn->nCommand = CMD_ARPEGGIO;
if (param) pChn->nArpeggio = param;
break;
// Retrig
case CMD_RETRIG:
- if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+ if (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))
{
if (!(param & 0xF0)) param |= pChn->nRetrigParam & 0xF0;
if (!(param & 0x0F)) param |= pChn->nRetrigParam & 0x0F;
@@ -3708,7 +3740,7 @@
MODCHANNEL *pChn = &Chn[nChn];
const bool bKeyOn = (pChn->dwFlags & CHN_KEYOFF) ? false : true;
pChn->dwFlags |= CHN_KEYOFF;
- //if ((!pChn->pModInstrument) || (!(pChn->dwFlags & CHN_VOLENV)))
+ //if ((!pChn->pModInstrument) || (!(pChn->VolEnv.flags & CHN_VOLENV)))
if ((pChn->pModInstrument) && (!(pChn->VolEnv.flags & ENV_ENABLED)))
{
pChn->dwFlags |= CHN_NOTEFADE;
@@ -3739,9 +3771,10 @@
pChn->nLength = pSmp->nLength;
}
}
+
if (pChn->pModInstrument)
{
- MODINSTRUMENT *pIns = pChn->pModInstrument;
+ const MODINSTRUMENT *pIns = pChn->pModInstrument;
if (((pIns->VolEnv.dwFlags & ENV_LOOP) || (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) && (pIns->nFadeOut))
{
pChn->dwFlags |= CHN_NOTEFADE;
Modified: trunk/OpenMPT/soundlib/modcommand.cpp
===================================================================
--- trunk/OpenMPT/soundlib/modcommand.cpp 2011-10-07 01:33:41 UTC (rev 1094)
+++ trunk/OpenMPT/soundlib/modcommand.cpp 2011-10-07 18:01:17 UTC (rev 1095)
@@ -597,10 +597,18 @@
m->command = m->param = 0;
}
- // Instrument numbers next to Key-Off reset instrument settings
if(m->note >= NOTE_MIN_SPECIAL)
{
+ // Instrument numbers next to Note Off reset instrument settings
m->instr = 0;
+
+ if(m->command == CMD_MODCMDEX && (m->param & 0xF0) == 0xD0)
+ {
+ // Note Off + Note Delay does nothing when using envelopes.
+ m->note = NOTE_NONE;
+ m->command = CMD_KEYOFF;
+ m->param &= 0x0F;
+ }
}
if(!m->command) switch(m->volcmd)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|