From: <sag...@us...> - 2011-10-05 16:48:21
|
Revision: 1084 http://modplug.svn.sourceforge.net/modplug/?rev=1084&view=rev Author: saga-games Date: 2011-10-05 16:48:14 +0000 (Wed, 05 Oct 2011) Log Message: ----------- [Mod] Some compatibility mode settings are now also applied in "normal" mode. Pattern / Sample / Instrument settings in tunes made with older versions of MPT are now fixed while such files are loaded so that the old behaviour is still used for them. Settings that are now always handled as they were previously handled in compatible mode only are: Instrument PPS depth, SC0 / SD0 handling in IT / MPTM files, Autovibrato Sweep = 0 (IT / MPTM), Out-of-range Global Volume. For the latter, compatibility with older versions of MPT is actually improved, because compatible playback is always enabled for S3M files, but the fix is also applied for S3M files made with MPT 1.16. Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2011-10-04 14:34:04 UTC (rev 1083) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2011-10-05 16:48:14 UTC (rev 1084) @@ -1386,24 +1386,24 @@ bool CModDoc::IsChannelMuted(CHANNELINDEX nChn) const //--------------------------------------------------- { - if (nChn >= m_SndFile.m_nChannels) return true; - return (m_SndFile.ChnSettings[nChn].dwFlags & CHN_MUTE) ? true : false; + if (nChn >= m_SndFile.GetNumChannels()) return true; + return (m_SndFile.ChnSettings[nChn].dwFlags & CHN_MUTE) != 0; } bool CModDoc::IsSampleMuted(SAMPLEINDEX nSample) const //---------------------------------------------------- { - if ((!nSample) || (nSample > m_SndFile.m_nSamples)) return false; - return (m_SndFile.GetSample(nSample).uFlags & CHN_MUTE) ? true : false; + if ((!nSample) || (nSample > m_SndFile.GetNumSamples())) return false; + return (m_SndFile.GetSample(nSample).uFlags & CHN_MUTE) != 0; } bool CModDoc::IsInstrumentMuted(INSTRUMENTINDEX nInstr) const //----------------------------------------------------------- { - if ((!nInstr) || (nInstr > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nInstr])) return false; - return (m_SndFile.Instruments[nInstr]->dwFlags & INS_MUTE) ? true : false; + if ((!nInstr) || (nInstr > m_SndFile.GetNumInstruments()) || (!m_SndFile.Instruments[nInstr])) return false; + return (m_SndFile.Instruments[nInstr]->dwFlags & INS_MUTE) != 0; } @@ -1425,20 +1425,19 @@ } -BOOL CModDoc::IsChildSample(UINT nIns, UINT nSmp) const -//----------------------------------------------------- +bool CModDoc::IsChildSample(INSTRUMENTINDEX nIns, SAMPLEINDEX nSmp) const +//----------------------------------------------------------------------- { - MODINSTRUMENT *pIns; - if ((nIns < 1) || (nIns > m_SndFile.m_nInstruments)) return FALSE; - pIns = m_SndFile.Instruments[nIns]; - if (pIns) + if((nIns < 1) || (nIns > m_SndFile.GetNumInstruments())) return false; + MODINSTRUMENT *pIns = m_SndFile.Instruments[nIns]; + if(pIns != nullptr) { - for (UINT i=0; i<NOTE_MAX; i++) + for(UINT i = 0; i < NOTE_MAX; i++) { - if (pIns->Keyboard[i] == nSmp) return TRUE; + if(pIns->Keyboard[i] == nSmp) return true; } } - return FALSE; + return false; } @@ -2970,7 +2969,7 @@ case 0xC0: // note cut case 0xD0: // note delay //IT compatibility 22. SD0 == SD1, SC0 == SC1 - if(((param & 0x0F) == 1) || ((param & 0x0F) == 0 && m_SndFile.IsCompatibleMode(TRK_IMPULSETRACKER))) + if(((param & 0x0F) == 1) || ((param & 0x0F) == 0 && (m_SndFile.GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)))) strcpy(s, "1 tick"); else strcat(s, " ticks"); Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2011-10-04 14:34:04 UTC (rev 1083) +++ trunk/OpenMPT/mptrack/Moddoc.h 2011-10-05 16:48:14 UTC (rev 1084) @@ -331,7 +331,7 @@ CHANNELINDEX GetNumChannels() const { return m_SndFile.m_nChannels; } UINT GetPatternSize(PATTERNINDEX nPat) const; BOOL AdjustEndOfSample(UINT nSample); - BOOL IsChildSample(UINT nIns, UINT nSmp) const; + bool IsChildSample(INSTRUMENTINDEX nIns, SAMPLEINDEX nSmp) const; UINT FindSampleParent(UINT nSmp) const; UINT FindInstrumentChild(UINT nIns) const; bool MoveOrder(ORDERINDEX nSourceNdx, ORDERINDEX nDestNdx, bool bUpdate = true, bool bCopy = false, SEQUENCEINDEX nSourceSeq = SEQUENCEINDEX_INVALID, SEQUENCEINDEX nDestSeq = SEQUENCEINDEX_INVALID); Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2011-10-04 14:34:04 UTC (rev 1083) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2011-10-05 16:48:14 UTC (rev 1084) @@ -1009,10 +1009,6 @@ pSmp->nVibRate = pis->vis; pSmp->nVibDepth = pis->vid & 0x7F; pSmp->nVibSweep = pis->vir; //(pis->vir + 3) / 4; - if(pSmp->nVibSweep == 0 && (pSmp->nVibDepth || pSmp->nVibRate) && m_dwLastSavedWithVersion && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 03, 02)) - { - pSmp->nVibSweep = 255; // Let's correct this little stupid mistake in history. - } if(pis->samplepointer) lastSampleOffset = pis->samplepointer; // MPTX hack @@ -1468,7 +1464,7 @@ memset(header.chnpan, 0xA0, 64); memset(header.chnvol, 64, 64); - for (size_t ich = 0; ich < min(m_nChannels, 64); ich++) // Header only has room for settings for 64 chans... + for (CHANNELINDEX ich = 0; ich < min(m_nChannels, 64); ich++) // Header only has room for settings for 64 chans... { header.chnpan[ich] = ChnSettings[ich].nPan >> 2; if (ChnSettings[ich].dwFlags & CHN_SURROUND) header.chnpan[ich] = 100; Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-10-04 14:34:04 UTC (rev 1083) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2011-10-05 16:48:14 UTC (rev 1084) @@ -353,15 +353,9 @@ // } if (!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) param <<= 1; - if(IsCompatibleMode(TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER)) + // IT compatibility 16. FT2, ST3 and IT ignore out-of-range values + if (param <= 128) { - //IT compatibility 16. FT2, ST3 and IT ignore out-of-range values - if (param <= 128) - nGlbVol = param << 1; - } - else - { - if (param > 128) param = 128; nGlbVol = param << 1; } break; @@ -1393,7 +1387,7 @@ if(nStartTick == 0) { //IT compatibility 22. SD0 == SD1 - if(IsCompatibleMode(TRK_IMPULSETRACKER)) + if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) nStartTick = 1; //ST3 ignores notes with SD0 completely else if(GetType() == MOD_TYPE_S3M) @@ -3665,7 +3659,7 @@ if(nTick == 0) { //IT compatibility 22. SC0 == SC1 - if(IsCompatibleMode(TRK_IMPULSETRACKER)) + if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) nTick = 1; // ST3 doesn't cut notes with SC0 else if(GetType() == MOD_TYPE_S3M) Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2011-10-04 14:34:04 UTC (rev 1083) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2011-10-05 16:48:14 UTC (rev 1084) @@ -2882,25 +2882,6 @@ } -void FixMIDIConfigString(char *line) -//---------------------------------- -{ - for(size_t i = 0; i < MACRO_LENGTH; i++) - { - if(line[i] >= 'a' && line[i] <= 'f') // both A-F and a-f were treated as hex constants - { - line[i] = line[i] - 'a' + 'A'; - } else if(line[i] == 'K' || line[i] == 'k') // channel was K or k - { - line[i] = 'c'; - } else if(line[i] == 'X' || line[i] == 'x' || line[i] == 'Y' || line[i] == 'y') // those were pointless - { - line[i] = 'z'; - } - } -} - - // For old files made with MPT that don't have m_dwSongFlags set yet, set the flags appropriately. void CSoundFile::UpgradeModFlags() //-------------------------------- @@ -2931,23 +2912,106 @@ } +struct UpgradePatternData +//======================= +{ + UpgradePatternData(CSoundFile *pSndFile) + { + this->pSndFile = pSndFile; + } + + void operator()(MODCOMMAND& m) + { + if(pSndFile->m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 03, 02) || + (!pSndFile->IsCompatibleMode(TRK_ALLTRACKERS) && pSndFile->m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 20, 00, 00))) + { + if(m.command == CMD_GLOBALVOLUME) + { + // Out-of-range global volume commands should be ignored. + // OpenMPT 1.17.03.02 fixed this in compatible mode, OpenMPT 1.20 fixes it in normal mode as well. + // So for tracks made with older versions than OpenMPT 1.17.03.02 or tracks made with 1.17.03.02 <= version < 1.20, we limit invalid global volume commands. + LimitMax(m.param, (pSndFile->GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) ? BYTE(128): BYTE(64)); + } else if(m.command == CMD_S3MCMDEX && (pSndFile->GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) + { + // SC0 and SD0 should be interpreted as SC1 and SD1 in IT files. + // OpenMPT 1.17.03.02 fixed this in compatible mode, OpenMPT 1.20 fixes it in normal mode as well. + if(m.param == 0xC0) + { + m.command = CMD_NONE; + m.volcmd = VOLCMD_VOLUME; + m.vol = 0; + } else if(m.param == 0xD0) + { + m.command = CMD_NONE; + } + } + } + + } + + CSoundFile *pSndFile; +}; + + void CSoundFile::UpgradeSong() //---------------------------- { if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 20, 00, 00)) { - // Previously, volume swing values ranged from 0 to 64. They should reach from 0 to 100 instead. for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) if(Instruments[i] != nullptr) { + // Previously, volume swing values ranged from 0 to 64. They should reach from 0 to 100 instead. Instruments[i]->nVolSwing = min(Instruments[i]->nVolSwing * 100 / 64, 100); + + if(!IsCompatibleMode(TRK_IMPULSETRACKER) || m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 18, 00, 00)) + { + // Previously, Pitch/Pan Separation was only half depth. + // This was corrected in compatible mode in OpenMPT 1.18, and in OpenMPT 1.20 it is corrected in normal mode as well. + Instruments[i]->nPPS = (Instruments[i]->nPPS + (Instruments[i]->nPPS >= 0 ? 1 : -1)) / 2; + } } + if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 03, 02) || !IsCompatibleMode(TRK_IMPULSETRACKER))) + { + // In the IT format, a sweep value of 0 shouldn't apply vibrato at all. Previously, a value of 0 was treated as "no sweep". + // In OpenMPT 1.17.03.02, this was corrected in compatible mode, in OpenMPT 1.20 it is corrected in normal mode as well, + // so we have to fix the setting while loading. + for(SAMPLEINDEX i = 1; i <= GetNumSamples(); i++) + { + if(Samples[i].nVibSweep == 0 && (Samples[i].nVibDepth | Samples[i].nVibRate)) + { + Samples[i].nVibSweep = 255; + } + } + } + // Fix old nasty broken (non-standard) MIDI configs in files. FixMIDIConfigStrings(m_MidiCfg); } + + Patterns.ForEachModCommand(UpgradePatternData(this)); } +void FixMIDIConfigString(char *line) +//---------------------------------- +{ + for(size_t i = 0; i < MACRO_LENGTH; i++) + { + if(line[i] >= 'a' && line[i] <= 'f') // both A-F and a-f were treated as hex constants + { + line[i] = line[i] - 'a' + 'A'; + } else if(line[i] == 'K' || line[i] == 'k') // channel was K or k + { + line[i] = 'c'; + } else if(line[i] == 'X' || line[i] == 'x' || line[i] == 'Y' || line[i] == 'y') // those were pointless + { + line[i] = 'z'; + } + } +} + + // Fix old-format (not conforming to IT's MIDI macro definitions) MIDI config strings. void CSoundFile::FixMIDIConfigStrings(MODMIDICFG &midiCfg) //-------------------------------------------------------- Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2011-10-04 14:34:04 UTC (rev 1083) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2011-10-05 16:48:14 UTC (rev 1084) @@ -1180,7 +1180,7 @@ int envpitchdest = (((int)pIns->PitchEnv.Values[pt]) - 32) * 8; envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1); } - envpitch = CLAMP(envpitch, -256, 256); + Limit(envpitch, -256, 256); //if (pIns->PitchEnv.dwFlags & ENV_FILTER) if (pChn->PitchEnv.flags & ENV_FILTER) @@ -1363,9 +1363,8 @@ { // PPS value is 1/512, i.e. PPS=1 will adjust by 8/512 = 1/64 for each 8 semitones // with PPS = 32 / PPC = C-5, E-6 will pan hard right (and D#6 will not) - // IT compatibility: IT has a wider pan range here - int pandelta = (int)pChn->nRealPan + (int)((int)(pChn->nNote - pIns->nPPC - 1) * (int)pIns->nPPS) / (int)(IsCompatibleMode(TRK_IMPULSETRACKER) ? 4 : 8); - pChn->nRealPan = CLAMP(pandelta, 0, 256); + int pandelta = (int)pChn->nRealPan + (int)((int)(pChn->nNote - pIns->nPPC - 1) * (int)pIns->nPPS) / 4; + pChn->nRealPan = Clamp(pandelta, 0, 256); } } @@ -1688,13 +1687,13 @@ } else { // MPT's autovibrato code - if (pSmp->nVibSweep == 0) + if (pSmp->nVibSweep == 0 && !(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) { pChn->nAutoVibDepth = pSmp->nVibDepth << 8; } else { // Calculate current autovibrato depth using vibsweep - if (m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) + if (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) { // Note: changed bitshift from 3 to 1 as the variable is not divided by 4 in the IT loader anymore // - so we divide sweep by 4 here. @@ -1906,26 +1905,9 @@ m_nSamplesPerTick = m_nBufferCount; //rewbs.flu -// robinf: this block causes envelopes to behave incorrectly when -// playback is triggered from instrument panel. -// I can't see why it would be useful. Dissabling for now. -// -// if (m_dwSongFlags & SONG_PAUSED) { -// m_nBufferCount = gdwMixingFreq / 64; // 1/64 seconds -// } - - // Master Volume + Pre-Amplification / Attenuation setup DWORD nMasterVol; { - /*int nchn32 = 0; - MODCHANNEL *pChn = Chn; - for (CHANNELINDEX nChn=0; nChn<m_nChannels; nChn++,pChn++) - { - //if(!(pChn->dwFlags & CHN_MUTE)) //removed by rewbs: fix http://www.modplug.com/forum/viewtopic.php?t=3358 - nchn32++; - } - nchn32 = CLAMP(nchn32, 1, 31);*/ int nchn32 = CLAMP(m_nChannels, 1, 31); DWORD mastervol; @@ -1960,6 +1942,7 @@ nMasterVol = mastervol; } } + //////////////////////////////////////////////////////////////////////////////////// // Update channels data m_nMixChannels = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |