|
From: <sag...@us...> - 2015-03-06 22:16:29
|
Revision: 4830
http://sourceforge.net/p/modplug/code/4830
Author: saga-games
Date: 2015-03-06 22:16:16 +0000 (Fri, 06 Mar 2015)
Log Message:
-----------
[Fix] More PLM fixes (+ features not supported in the alpha version of DT2 available on Modland), tx dojoe
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_plm.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/soundlib/Load_plm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_plm.cpp 2015-03-05 00:08:20 UTC (rev 4829)
+++ trunk/OpenMPT/soundlib/Load_plm.cpp 2015-03-06 22:16:16 UTC (rev 4830)
@@ -50,6 +50,7 @@
enum SampleFlags
{
smp16Bit = 1,
+ smpPingPong = 2,
};
char magic[4]; // "PLS\x1A"
@@ -140,8 +141,10 @@
InitializeChannels();
SetModFlag(MSF_COMPATIBLE_PLAY, true);
m_nType = MOD_TYPE_PLM;
+ m_SongFlags = SONG_ITOLDEFFECTS;
madeWithTracker = "Disorder Tracker 2";
- mpt::String::Read<mpt::String::maybeNullTerminated>(songName, fileHeader.songName);
+ // Some PLMs use ASCIIZ, some space-padding strings...weird. Oh, and the file browser stops at 0 bytes in the name, the main GUI doesn't.
+ mpt::String::Read<mpt::String::spacePadded>(songName, fileHeader.songName);
m_nChannels = fileHeader.numChannels + 1; // Additional channel for writing pattern breaks
m_nSamplePreAmp = fileHeader.amplify;
m_nDefaultTempo = fileHeader.tempo;
@@ -194,7 +197,11 @@
// Apparently there is a bug in DT2 which adds an extra byte before the sample data.
sampleHeader.headerSize++;
}
- if(sample.nLoopEnd > sample.nLoopStart) sample.uFlags.set(CHN_LOOP);
+ if(sample.nLoopEnd > sample.nLoopStart)
+ {
+ sample.uFlags.set(CHN_LOOP);
+ if(sampleHeader.flags & PLMSampleHeader::smpPingPong) sample.uFlags.set(CHN_PINGPONGLOOP);
+ }
sample.SanitizeLoops();
if(loadFlags & loadSampleData)
@@ -242,7 +249,8 @@
CMD_S3MCMDEX, // Pattern Delay
CMD_FINEVIBRATO,
CMD_VIBRATOVOL,
- CMD_TONEPORTAVOL
+ CMD_TONEPORTAVOL,
+ CMD_OFFSET, // Percentage offset
};
for(uint16 i = 0; i < fileHeader.numOrders; i++)
@@ -256,7 +264,7 @@
ORDERINDEX curOrd = ord.x / rowsPerPat;
ROWINDEX curRow = ord.x % rowsPerPat;
- const CHANNELINDEX numChannels = std::min<CHANNELINDEX>(patHeader.numChannels, fileHeader.numChannels - ord.y);
+ const CHANNELINDEX numChannels = std::min<uint8>(patHeader.numChannels, fileHeader.numChannels - ord.y);
const uint32 patternEnd = ord.x + patHeader.numRows;
maxPos = std::max(maxPos, patternEnd);
@@ -333,7 +341,7 @@
m->param = 0xC0 | std::min<ModCommand::PARAM>(m->param, 0x0F);
break;
case 0x12: // Pattern Delay
- m->param = 0x60 | std::min<ModCommand::PARAM>(m->param, 0x0F);
+ m->param = 0xE0 | std::min<ModCommand::PARAM>(m->param, 0x0F);
break;
case 0x04: // Volume Slide
case 0x14: // Vibrato + Volume Slide
@@ -344,6 +352,11 @@
m->param |= 0x0F;
}
break;
+ case 0x16: // Percentage offset
+ if(m->instr > 0 && m->instr <= m_nSamples)
+ {
+ m->param = mpt::saturate_cast<ModCommand::PARAM>(((m->param * Samples[m->instr].nLength) / 255) >> 8);
+ }
}
}
}
@@ -363,6 +376,19 @@
Patterns[endPat].Resize(endPatSize);
}
}
+ // If there are still any non-existent patterns in our order list, insert some blank patterns.
+ PATTERNINDEX blankPat = PATTERNINDEX_INVALID;
+ for(ORDERINDEX i = 0; i < Order.size(); i++)
+ {
+ if(Order[i] == Order.GetInvalidPatIndex())
+ {
+ if(blankPat == PATTERNINDEX_INVALID)
+ {
+ blankPat = Patterns.Insert(rowsPerPat);
+ }
+ Order[i] = blankPat;
+ }
+ }
return true;
}
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2015-03-05 00:08:20 UTC (rev 4829)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2015-03-06 22:16:16 UTC (rev 4830)
@@ -3051,6 +3051,10 @@
else
PortamentoMPT(pChn, param);
return;
+ } else if(GetType() == MOD_TYPE_PLM)
+ {
+ // A normal portamento up or down makes a follow-up tone portamento go the same direction.
+ pChn->nPortamentoDest = 1;
}
if (doFineSlides && param >= 0xE0)
@@ -3104,6 +3108,10 @@
else
PortamentoMPT(pChn, -static_cast<int>(param));
return;
+ } else if(GetType() == MOD_TYPE_PLM)
+ {
+ // A normal portamento up or down makes a follow-up tone portamento go the same direction.
+ pChn->nPortamentoDest = 65535;
}
if(doFineSlides && param >= 0xE0)
@@ -3414,8 +3422,16 @@
return;
} //End candidate MPT behavior.
+ bool doPorta = !pChn->isFirstTick || GetType() == MOD_TYPE_DBM;
+ if(GetType() == MOD_TYPE_PLM && param >= 0xF0)
+ {
+ param -= 0xF0;
+ doPorta = pChn->isFirstTick;
+ }
+
if(param) pChn->nPortamentoSlide = param * 4;
- if(pChn->nPeriod && pChn->nPortamentoDest && (!pChn->isFirstTick || GetType() == MOD_TYPE_DBM))
+
+ if(pChn->nPeriod && pChn->nPortamentoDest && doPorta)
{
if (pChn->nPeriod < pChn->nPortamentoDest)
{
@@ -4542,8 +4558,7 @@
pChn->nPos = pChn->nLength; // Old FX: Clip to end of sample
else
pChn->nPos = 0; // Reset to beginning of sample
- }
- else
+ } else
{
pChn->nPos = pChn->nLoopStart;
if(m_SongFlags[SONG_ITOLDEFFECTS] && pChn->nLength > 4)
@@ -4719,7 +4734,7 @@
void CSoundFile::DoFreqSlide(ModChannel *pChn, LONG nFreqSlide) const
//-------------------------------------------------------------------
{
- if (!pChn->nPeriod) return;
+ if(!pChn->nPeriod) return;
if(m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM)
{
// IT Linear slides
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|