You can subscribe to this list here.
| 2006 |
Jan
|
Feb
|
Mar
(1) |
Apr
(1) |
May
|
Jun
(1) |
Jul
|
Aug
(10) |
Sep
|
Oct
|
Nov
|
Dec
(3) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(1) |
Feb
(2) |
Mar
(3) |
Apr
(2) |
May
(10) |
Jun
(2) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(3) |
Dec
|
| 2008 |
Jan
(6) |
Feb
(4) |
Mar
(5) |
Apr
(2) |
May
(1) |
Jun
(1) |
Jul
(4) |
Aug
(6) |
Sep
(2) |
Oct
(9) |
Nov
(1) |
Dec
(4) |
| 2009 |
Jan
(9) |
Feb
(2) |
Mar
(2) |
Apr
(2) |
May
(6) |
Jun
(18) |
Jul
(33) |
Aug
(39) |
Sep
(33) |
Oct
(24) |
Nov
(23) |
Dec
(22) |
| 2010 |
Jan
(29) |
Feb
(32) |
Mar
(51) |
Apr
(17) |
May
(31) |
Jun
(21) |
Jul
(32) |
Aug
(28) |
Sep
(35) |
Oct
(27) |
Nov
(11) |
Dec
(13) |
| 2011 |
Jan
(14) |
Feb
(13) |
Mar
(27) |
Apr
(27) |
May
(28) |
Jun
(20) |
Jul
(43) |
Aug
(52) |
Sep
(66) |
Oct
(61) |
Nov
(11) |
Dec
(8) |
| 2012 |
Jan
(20) |
Feb
(30) |
Mar
(38) |
Apr
(21) |
May
(33) |
Jun
(21) |
Jul
(25) |
Aug
(9) |
Sep
(24) |
Oct
(42) |
Nov
(27) |
Dec
(41) |
| 2013 |
Jan
(20) |
Feb
(35) |
Mar
(156) |
Apr
(298) |
May
(258) |
Jun
(201) |
Jul
(105) |
Aug
(60) |
Sep
(193) |
Oct
(245) |
Nov
(280) |
Dec
(194) |
| 2014 |
Jan
(63) |
Feb
(202) |
Mar
(200) |
Apr
(23) |
May
(53) |
Jun
(105) |
Jul
(18) |
Aug
(26) |
Sep
(110) |
Oct
(187) |
Nov
(97) |
Dec
(74) |
| 2015 |
Jan
(45) |
Feb
(55) |
Mar
(116) |
Apr
(116) |
May
(193) |
Jun
(164) |
Jul
(50) |
Aug
(111) |
Sep
(98) |
Oct
(71) |
Nov
(103) |
Dec
(63) |
| 2016 |
Jan
(33) |
Feb
(101) |
Mar
(182) |
Apr
(139) |
May
(140) |
Jun
(103) |
Jul
(165) |
Aug
(286) |
Sep
(208) |
Oct
(127) |
Nov
(97) |
Dec
(54) |
| 2017 |
Jan
(64) |
Feb
(335) |
Mar
(202) |
Apr
(212) |
May
(139) |
Jun
(127) |
Jul
(294) |
Aug
(154) |
Sep
(170) |
Oct
(152) |
Nov
(156) |
Dec
(62) |
| 2018 |
Jan
(168) |
Feb
(237) |
Mar
(196) |
Apr
(174) |
May
(174) |
Jun
(161) |
Jul
(127) |
Aug
(88) |
Sep
(149) |
Oct
(66) |
Nov
(52) |
Dec
(135) |
| 2019 |
Jan
(146) |
Feb
(126) |
Mar
(104) |
Apr
(58) |
May
(60) |
Jun
(28) |
Jul
(197) |
Aug
(129) |
Sep
(141) |
Oct
(148) |
Nov
(63) |
Dec
(100) |
| 2020 |
Jan
(74) |
Feb
(37) |
Mar
(59) |
Apr
(154) |
May
(194) |
Jun
(133) |
Jul
(313) |
Aug
(197) |
Sep
(49) |
Oct
(162) |
Nov
(143) |
Dec
(57) |
| 2021 |
Jan
(120) |
Feb
(107) |
Mar
(314) |
Apr
(157) |
May
(524) |
Jun
(169) |
Jul
(72) |
Aug
(133) |
Sep
(135) |
Oct
(146) |
Nov
(198) |
Dec
(325) |
| 2022 |
Jan
(409) |
Feb
(249) |
Mar
(138) |
Apr
(95) |
May
(102) |
Jun
(221) |
Jul
(66) |
Aug
(120) |
Sep
(192) |
Oct
(131) |
Nov
(53) |
Dec
(171) |
| 2023 |
Jan
(357) |
Feb
(82) |
Mar
(168) |
Apr
(218) |
May
(196) |
Jun
(86) |
Jul
(115) |
Aug
(49) |
Sep
(190) |
Oct
(102) |
Nov
(45) |
Dec
(76) |
| 2024 |
Jan
(86) |
Feb
(50) |
Mar
(324) |
Apr
(209) |
May
(197) |
Jun
(232) |
Jul
(194) |
Aug
(247) |
Sep
(219) |
Oct
(266) |
Nov
(328) |
Dec
(304) |
| 2025 |
Jan
(191) |
Feb
(115) |
Mar
(137) |
Apr
(32) |
May
(126) |
Jun
(403) |
Jul
(213) |
Aug
(203) |
Sep
(148) |
Oct
(109) |
Nov
(191) |
Dec
(209) |
| 2026 |
Jan
(127) |
Feb
(123) |
Mar
(160) |
Apr
(141) |
May
(49) |
Jun
(55) |
Jul
(91) |
Aug
(191) |
Sep
|
Oct
(68) |
Nov
|
Dec
|
|
From: <sag...@us...> - 2009-09-10 21:01:07
|
Revision: 360
http://modplug.svn.sourceforge.net/modplug/?rev=360&view=rev
Author: saga-games
Date: 2009-09-10 21:00:57 +0000 (Thu, 10 Sep 2009)
Log Message:
-----------
[Fix] Instrument Tab: Proper limits for IT/XM fadeout values
[Fix] XM / IT Saver: Limit fadeout values properly
[Imp] IT Compatibility Export: Removed stereo sample support
[Imp] Updated DE_jojo.mkb keymap (added Save As command)
[Imp] Updated IT Mod Specifications
[Imp] Comments tab: Usage of existing sample size + bit depth functions to calculate information
[Imp] XM Loader: Advanced "made with MPT" detection
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_ins.cpp
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/view_com.cpp
trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/mod_specifications.h
Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-09-10 13:31:37 UTC (rev 359)
+++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-09-10 21:00:57 UTC (rev 360)
@@ -801,7 +801,7 @@
m_ComboDCA.AddString("Note Off");
m_ComboDCA.AddString("Note Fade");
// FadeOut Volume
- m_SpinFadeOut.SetRange(0, 32000);
+ m_SpinFadeOut.SetRange(0, 8192);
// Global Volume
m_SpinGlobalVol.SetRange(0, 64);
// Panning
@@ -1072,7 +1072,13 @@
m_SpinMidiPR.EnableWindow(bITandXM);
m_SpinMidiBK.EnableWindow(bITandXM); //rewbs.MidiBank
//end rewbs.instroVSTi
+
m_SpinFadeOut.EnableWindow(bITandXM);
+ if(m_pSndFile->m_nType & MOD_TYPE_XM)
+ m_SpinFadeOut.SetRange(0, 4095);
+ else
+ m_SpinFadeOut.SetRange(0, 8192);
+
m_NoteMap.EnableWindow(bITandXM);
m_CbnResampling.EnableWindow(bITandXM);
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-10 13:31:37 UTC (rev 359)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-10 21:00:57 UTC (rev 360)
@@ -768,7 +768,7 @@
//-------------------------------------------------------
{
// shorten instrument envelope if necessary (for mod conversion)
- const int iEnvMax = m_SndFile.GetModSpecifications().envelopePointsMax;
+ const UINT iEnvMax = m_SndFile.GetModSpecifications().envelopePointsMax;
bool bResult = false;
#define TRIMENV(i) if(i > iEnvMax) {i = iEnvMax; bResult = true;}
Modified: trunk/OpenMPT/mptrack/view_com.cpp
===================================================================
--- trunk/OpenMPT/mptrack/view_com.cpp 2009-09-10 13:31:37 UTC (rev 359)
+++ trunk/OpenMPT/mptrack/view_com.cpp 2009-09-10 21:00:57 UTC (rev 360)
@@ -252,15 +252,13 @@
case SMPLIST_SIZE:
if (pSmp->nLength)
{
- UINT nShift = (pSmp->uFlags & CHN_16BIT) ? 9 : 10;
- if (pSmp->uFlags & CHN_STEREO) nShift--;
- wsprintf(s, "%d KB", pSmp->nLength >> nShift);
+ wsprintf(s, "%d KB", pSmp->GetSampleSizeInBytes() >> 10);
}
break;
case SMPLIST_TYPE:
if (pSmp->nLength)
{
- strcpy(s, (pSmp->uFlags & CHN_16BIT) ? "16 Bit" : "8 Bit");
+ wsprintf(s, "%d Bit", pSmp->GetElementarySampleSize() << 3);
}
break;
case SMPLIST_INSTR:
Modified: trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb
===================================================================
--- trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-09-10 13:31:37 UTC (rev 359)
+++ trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-09-10 21:00:57 UTC (rev 360)
@@ -8,6 +8,7 @@
0:1346:2:79:1 //File/Open: Ctrl+O (KeyDown)
0:1348:2:87:5 //File/Close: Ctrl+W (KeyDown|KeyHold)
0:1349:2:83:1 //File/Save: Ctrl+S (KeyDown)
+0:1350:3:83:1 //File/Save As: Shift+Ctrl+S (KeyDown)
0:1693:0:166:1 //Previous Document: (KeyDown)
0:1694:0:167:1 //Next Document: (KeyDown)
0:1030:0:116:1 //Play song/Pause song: F5 (KeyDown)
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-10 13:31:37 UTC (rev 359)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-10 21:00:57 UTC (rev 360)
@@ -301,7 +301,7 @@
}
if (pis->mbank<=128)
pIns->wMidiBank = pis->mbank;
- pIns->nFadeOut = pis->fadeout << 5; // should be 6?
+ pIns->nFadeOut = pis->fadeout << 5;
pIns->nGlobalVol = pis->gbv >> 1;
if (pIns->nGlobalVol > 64) pIns->nGlobalVol = 64;
for (UINT j = 0; j < 120; j++)
@@ -2003,7 +2003,7 @@
//if (pIns->nDCT<DCT_PLUGIN) iti.dct = pIns->nDCT; else iti.dct =0;
iti.dct = pIns->nDCT; //rewbs.instroVSTi: will other apps barf if they get an unknown DCT?
iti.dca = pIns->nDNA;
- iti.fadeout = pIns->nFadeOut >> 5; // should be 6?
+ iti.fadeout = min(pIns->nFadeOut >> 5 , 256);
iti.pps = pIns->nPPS;
iti.ppc = pIns->nPPC;
iti.gbv = (BYTE)(pIns->nGlobalVol << 1);
@@ -2648,7 +2648,7 @@
iti.nna = pIns->nNNA;
if (pIns->nDCT<DCT_PLUGIN) iti.dct = pIns->nDCT; else iti.dct =0;
iti.dca = pIns->nDNA;
- iti.fadeout = pIns->nFadeOut >> 5;
+ iti.fadeout = min(pIns->nFadeOut >> 5 , 256);
iti.pps = pIns->nPPS;
iti.ppc = pIns->nPPC;
iti.gbv = (BYTE)(pIns->nGlobalVol << 1);
@@ -2991,30 +2991,10 @@
if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80;
if ((psmp->pSample) && (psmp->nLength)) itss.cvt = 0x01;
UINT flags = RS_PCM8S;
- /*
-#ifndef NO_PACKING
- if (nPacking)
+ if (psmp->uFlags & CHN_16BIT)
{
- if ((!(psmp->uFlags & (CHN_16BIT|CHN_STEREO)))
- && (CanPackSample(psmp->pSample, psmp->nLength, nPacking)))
- {
- flags = RS_ADPCM4;
- itss.cvt = 0xFF;
- }
- } else
-#endif // NO_PACKING
- */
- {
- if (psmp->uFlags & CHN_STEREO)
- {
- flags = RS_STPCM8S;
- itss.flags |= 0x04;
- }
- if (psmp->uFlags & CHN_16BIT)
- {
- itss.flags |= 0x02;
- flags = (psmp->uFlags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S;
- }
+ itss.flags |= 0x02;
+ flags = RS_PCM16S;
}
itss.samplepointer = dwPos;
fseek(f, smppos[nsmp-1], SEEK_SET);
Modified: trunk/OpenMPT/soundlib/Load_xm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-10 13:31:37 UTC (rev 359)
+++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-10 21:00:57 UTC (rev 360)
@@ -119,22 +119,6 @@
if ((!channels) || (channels > MAX_BASECHANNELS)) return false;
// -! BEHAVIOUR_CHANGE#0006
- if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
- if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v 2.00 ", 20))
- {
- bMadeWithModPlug = true;
- m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, 00);
- }
-
- if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8))
- {
- //bMadeWithModPlug = true; // Don't set it - it's also used by compatibility export
- CHAR sVersion[13];
- memcpy(sVersion, lpStream + 0x26 + 8, 12);
- sVersion[12] = 0;
- m_dwLastSavedWithVersion = MptVersion::ToNum(sVersion);
- }
-
m_nType = MOD_TYPE_XM;
m_nMinPeriod = 27;
m_nMaxPeriod = 54784;
@@ -334,7 +318,10 @@
Instruments[iIns]->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE;
memcpy(Instruments[iIns]->name, pih->name, 22);
-
+ // look for null-terminated instr name - that's most likely a tune made with modplug
+ for(int i = 0; i < 22; i++)
+ if(pih->name[i] == 0) bProbablyMadeWithModPlug = true;
+
if ((nsamples = pih->samples) > 0)
{
/* we have samples, so let's read the rest of this instrument
@@ -560,6 +547,9 @@
pSmp->nVibRate = xmsh.vibrate;
memcpy(pSmp->filename, xmss.name, 22);
pSmp->filename[21] = 0;
+ // look for null-terminated sample name - that's most likely a tune made with modplug
+ for(int i = 0; i < 22; i++)
+ if(xmss.name[i] == 0) bProbablyMadeWithModPlug = true;
}
#if 0
if ((xmsh.reserved2 > nsamples) && (xmsh.reserved2 <= 16))
@@ -648,6 +638,25 @@
bMadeWithModPlug = true;
}
+ // Check various things to find out whether this has been made with MPT.
+ // Null chars in names -> most likely made with MPT, which disguises as FT2
+ if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
+ if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v 2.00 ", 20))
+ {
+ // Early MPT 1.0 alpha/beta versions
+ bMadeWithModPlug = true;
+ m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, 00);
+ }
+
+ if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8))
+ {
+ //bMadeWithModPlug = true; // Don't set it - it's also used by compatibility export
+ CHAR sVersion[13];
+ memcpy(sVersion, lpStream + 0x26 + 8, 12);
+ sVersion[12] = 0;
+ m_dwLastSavedWithVersion = MptVersion::ToNum(sVersion);
+ }
+
if(bMadeWithModPlug)
{
SetModFlag(MSF_COMPATIBLE_PLAY, false);
@@ -862,7 +871,7 @@
{
memcpy(xmih.name, pIns->name, 22);
xmih.type = pIns->nMidiProgram;
- xmsh.volfade = pIns->nFadeOut;
+ xmsh.volfade = min(pIns->nFadeOut, 0xFFF); // FFF is maximum in FT2
xmsh.vnum = (BYTE)pIns->VolEnv.nNodes;
xmsh.pnum = (BYTE)pIns->PanEnv.nNodes;
if (xmsh.vnum > 12) xmsh.vnum = 12;
Modified: trunk/OpenMPT/soundlib/mod_specifications.h
===================================================================
--- trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-10 13:31:37 UTC (rev 359)
+++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-10 21:00:57 UTC (rev 360)
@@ -33,10 +33,10 @@
INSTRUMENTINDEX instrumentsMax;
BYTE defaultMixLevels;
BYTE MIDIMappingDirectivesMax;
- UINT speedMin;
- UINT speedMax;
- bool hasComments;
- int envelopePointsMax;
+ UINT speedMin; // Minimum ticks per frame
+ UINT speedMax; // Maximum ticks per frame
+ bool hasComments; // True if format has a comments field
+ UINT envelopePointsMax; // Maximum number of points of each envelope
};
@@ -103,7 +103,7 @@
1, //Min Speed
31, //Max Speed
false, //No song comments
- 0, //Envelope point count
+ 0, //No instrument envelopes
};
// MOD with MPT extensions.
@@ -132,7 +132,7 @@
1, //Min Speed
31, //Max Speed
false, //No song comments
- 0, //Envelope point count
+ 0, //No instrument envelopes
};
const CModSpecifications xm =
@@ -216,7 +216,7 @@
1, //Min Speed
255, //Max Speed
false, //No song comments
- 0, //Envelope point count
+ 0, //No instrument envelopes
};
// S3M with MPT extensions
@@ -245,7 +245,7 @@
1, //Min Speed
255, //Max Speed
false, //No song comments
- 0, //Envelope point count
+ 0, //No instrument envelopes
};
const CModSpecifications it =
@@ -266,8 +266,8 @@
1, //Min pattern rows
256, //Max pattern rows
25, //Max mod name length
- 256, //SamplesMax
- 200, //instrumentMax
+ 99, //SamplesMax
+ 99, //instrumentMax
mixLevels_original, //defaultMixLevels
0, //Max MIDI mapping directives
1, //Min Speed
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-09-10 13:31:46
|
Revision: 359
http://modplug.svn.sourceforge.net/modplug/?rev=359&view=rev
Author: saga-games
Date: 2009-09-10 13:31:37 +0000 (Thu, 10 Sep 2009)
Log Message:
-----------
[Fix] Instrument editor: Can now also copy long MPTM envelopes
[Ref] Make use of the new envelope struct in envelope c&p and scale env points code
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-09 23:14:18 UTC (rev 358)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-10 13:31:37 UTC (rev 359)
@@ -2388,71 +2388,51 @@
{
CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
HANDLE hCpy;
- CHAR s[1024];
+ CHAR s[4096];
MODINSTRUMENT *pIns;
DWORD dwMemSize;
- UINT susBegin, susEnd, loopBegin, loopEnd, bSus, bLoop, bCarry, nPoints, releaseNode;
- WORD *pPoints;
- BYTE *pValues;
+ UINT bSus, bLoop, bCarry;
if ((nIns < 1) || (nIns > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nIns]) || (!pMainFrm)) return FALSE;
BeginWaitCursor();
pIns = m_SndFile.Instruments[nIns];
+
+ INSTRUMENTENVELOPE *pEnv = nullptr;
+
switch(nEnv)
{
case ENV_PANNING:
- pPoints = pIns->PanEnv.Ticks;
- pValues = pIns->PanEnv.Values;
- nPoints = pIns->PanEnv.nNodes;
- bLoop = (pIns->dwFlags & ENV_PANLOOP) ? TRUE : FALSE;
- bSus = (pIns->dwFlags & ENV_PANSUSTAIN) ? TRUE : FALSE;
- bCarry = (pIns->dwFlags & ENV_PANCARRY) ? TRUE : FALSE;
- susBegin = pIns->PanEnv.nSustainStart;
- susEnd = pIns->PanEnv.nSustainEnd;
- loopBegin = pIns->PanEnv.nLoopStart;
- loopEnd = pIns->PanEnv.nLoopEnd;
- releaseNode = pIns->PanEnv.nReleaseNode;
+ pEnv = &pIns->PanEnv;
+ bLoop = (pIns->dwFlags & ENV_PANLOOP) ? 1 : 0;
+ bSus = (pIns->dwFlags & ENV_PANSUSTAIN) ? 1 : 0;
+ bCarry = (pIns->dwFlags & ENV_PANCARRY) ? 1 : 0;
break;
case ENV_PITCH:
- pPoints = pIns->PitchEnv.Ticks;
- pValues = pIns->PitchEnv.Values;
- nPoints = pIns->PitchEnv.nNodes;
- bLoop = (pIns->dwFlags & ENV_PITCHLOOP) ? TRUE : FALSE;
- bSus = (pIns->dwFlags & ENV_PITCHSUSTAIN) ? TRUE : FALSE;
- bCarry = (pIns->dwFlags & ENV_PITCHCARRY) ? TRUE : FALSE;
- susBegin = pIns->PitchEnv.nSustainStart;
- susEnd = pIns->PitchEnv.nSustainEnd;
- loopBegin = pIns->PitchEnv.nLoopStart;
- loopEnd = pIns->PitchEnv.nLoopEnd;
- releaseNode = pIns->PitchEnv.nReleaseNode;
+ pEnv = &pIns->PitchEnv;
+ bLoop = (pIns->dwFlags & ENV_PITCHLOOP) ? 1 : 0;
+ bSus = (pIns->dwFlags & ENV_PITCHSUSTAIN) ? 1 : 0;
+ bCarry = (pIns->dwFlags & ENV_PITCHCARRY) ? 1 : 0;
break;
default:
- pPoints = pIns->VolEnv.Ticks;
- pValues = pIns->VolEnv.Values;
- nPoints = pIns->VolEnv.nNodes;
- bLoop = (pIns->dwFlags & ENV_VOLLOOP) ? TRUE : FALSE;
- bSus = (pIns->dwFlags & ENV_VOLSUSTAIN) ? TRUE : FALSE;
- bCarry = (pIns->dwFlags & ENV_VOLCARRY) ? TRUE : FALSE;
- susBegin = pIns->VolEnv.nSustainStart;
- susEnd = pIns->VolEnv.nSustainEnd;
- loopBegin = pIns->VolEnv.nLoopStart;
- loopEnd = pIns->VolEnv.nLoopEnd;
- releaseNode = pIns->VolEnv.nReleaseNode;
+ pEnv = &pIns->VolEnv;
+ bLoop = (pIns->dwFlags & ENV_VOLLOOP) ? 1 : 0;
+ bSus = (pIns->dwFlags & ENV_VOLSUSTAIN) ? 1 : 0;
+ bCarry = (pIns->dwFlags & ENV_VOLCARRY) ? 1 : 0;
break;
}
strcpy(s, pszEnvHdr);
- wsprintf(s+strlen(s), pszEnvFmt, nPoints, susBegin, susEnd, loopBegin, loopEnd, bSus, bLoop, bCarry);
- for (UINT i=0; i<nPoints; i++)
+ wsprintf(s + strlen(s), pszEnvFmt, pEnv->nNodes, pEnv->nSustainStart, pEnv->nSustainEnd, pEnv->nLoopStart, pEnv->nLoopEnd, bSus, bLoop, bCarry);
+ for (UINT i = 0; i < pEnv->nNodes; i++)
{
if (strlen(s) >= sizeof(s)-32) break;
- wsprintf(s+strlen(s), "%d,%d\x0D\x0A", pPoints[i], pValues[i]);
+ wsprintf(s+strlen(s), "%d,%d\x0D\x0A", pEnv->Ticks[i], pEnv->Values[i]);
}
//Writing release node
if(strlen(s) < sizeof(s) - 32)
- wsprintf(s+strlen(s), "%u\x0D\x0A", releaseNode);
+ wsprintf(s+strlen(s), "%u\x0D\x0A", pEnv->nReleaseNode);
dwMemSize = strlen(s)+1;
if ((pMainFrm->OpenClipboard()) && ((hCpy = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, dwMemSize))!=NULL))
@@ -2486,6 +2466,8 @@
if ((hCpy) && ((p = (LPSTR)GlobalLock(hCpy)) != NULL))
{
MODINSTRUMENT *pIns = m_SndFile.Instruments[nIns];
+ INSTRUMENTENVELOPE *pEnv = nullptr;
+
UINT susBegin=0, susEnd=0, loopBegin=0, loopEnd=0, bSus=0, bLoop=0, bCarry=0, nPoints=0, releaseNode = ENV_RELEASE_NODE_UNSET;
DWORD dwMemSize = GlobalSize(hCpy), dwPos = strlen(pszEnvHdr);
if ((dwMemSize > dwPos) && (!_strnicmp(p, pszEnvHdr, dwPos-2)))
@@ -2508,60 +2490,45 @@
}
while ((dwPos < dwMemSize) && ((p[dwPos] >= '0') && (p[dwPos] <= '9'))) dwPos++;
}
- if (nPoints > 31) nPoints = 31;
+ nPoints = min(nPoints, m_SndFile.GetModSpecifications().envelopePointsMax);
if (susEnd >= nPoints) susEnd = 0;
if (susBegin > susEnd) susBegin = susEnd;
if (loopEnd >= nPoints) loopEnd = 0;
if (loopBegin > loopEnd) loopBegin = loopEnd;
- WORD *pPoints;
- BYTE *pValues;
+
switch(nEnv)
{
case ENV_PANNING:
- pPoints = pIns->PanEnv.Ticks;
- pValues = pIns->PanEnv.Values;
- pIns->PanEnv.nNodes = nPoints;
+ pEnv = &pIns->PanEnv;
pIns->dwFlags &= ~(ENV_PANLOOP|ENV_PANSUSTAIN|ENV_PANCARRY);
if (bLoop) pIns->dwFlags |= ENV_PANLOOP;
if (bSus) pIns->dwFlags |= ENV_PANSUSTAIN;
if (bCarry) pIns->dwFlags |= ENV_PANCARRY;
- pIns->PanEnv.nSustainStart = susBegin;
- pIns->PanEnv.nSustainEnd = susEnd;
- pIns->PanEnv.nLoopStart = loopBegin;
- pIns->PanEnv.nLoopEnd = loopEnd;
- pIns->PanEnv.nReleaseNode = releaseNode;
break;
case ENV_PITCH:
- pPoints = pIns->PitchEnv.Ticks;
- pValues = pIns->PitchEnv.Values;
- pIns->PitchEnv.nNodes = nPoints;
+ pEnv = &pIns->PitchEnv;
pIns->dwFlags &= ~(ENV_PITCHLOOP|ENV_PITCHSUSTAIN|ENV_PITCHCARRY);
if (bLoop) pIns->dwFlags |= ENV_PITCHLOOP;
if (bSus) pIns->dwFlags |= ENV_PITCHSUSTAIN;
if (bCarry) pIns->dwFlags |= ENV_PITCHCARRY;
- pIns->PitchEnv.nSustainStart = susBegin;
- pIns->PitchEnv.nSustainEnd = susEnd;
- pIns->PitchEnv.nLoopStart = loopBegin;
- pIns->PitchEnv.nLoopEnd = loopEnd;
- pIns->PitchEnv.nReleaseNode = releaseNode;
break;
default:
- pPoints = pIns->VolEnv.Ticks;
- pValues = pIns->VolEnv.Values;
- pIns->VolEnv.nNodes = nPoints;
+ pEnv = &pIns->VolEnv;
pIns->dwFlags &= ~(ENV_VOLLOOP|ENV_VOLSUSTAIN|ENV_VOLCARRY);
if (bLoop) pIns->dwFlags |= ENV_VOLLOOP;
if (bSus) pIns->dwFlags |= ENV_VOLSUSTAIN;
if (bCarry) pIns->dwFlags |= ENV_VOLCARRY;
- pIns->VolEnv.nSustainStart = susBegin;
- pIns->VolEnv.nSustainEnd = susEnd;
- pIns->VolEnv.nLoopStart = loopBegin;
- pIns->VolEnv.nLoopEnd = loopEnd;
- pIns->VolEnv.nReleaseNode = releaseNode;
break;
}
+ pEnv->nNodes = nPoints;
+ pEnv->nSustainStart = susBegin;
+ pEnv->nSustainEnd = susEnd;
+ pEnv->nLoopStart = loopBegin;
+ pEnv->nLoopEnd = loopEnd;
+ pEnv->nReleaseNode = releaseNode;
+
int oldn = 0;
for (UINT i=0; i<nPoints; i++)
{
@@ -2573,8 +2540,8 @@
if (dwPos >= dwMemSize) break;
int n2 = atoi(p+dwPos);
if ((n1 < oldn) || (n1 > 0x3FFF)) n1 = oldn+1;
- pPoints[i] = (WORD)n1;
- pValues[i] = (BYTE)n2;
+ pEnv->Ticks[i] = (WORD)n1;
+ pEnv->Values[i] = (BYTE)n2;
oldn = n1;
while ((dwPos < dwMemSize) && (p[dwPos] != 0x0D)) dwPos++;
if (dwPos >= dwMemSize) break;
@@ -2585,20 +2552,7 @@
{
BYTE r = static_cast<BYTE>(atoi(p + dwPos));
if(r == 0 || r >= nPoints) r = ENV_RELEASE_NODE_UNSET;
- switch(nEnv)
- {
- case ENV_PANNING:
- pIns->PanEnv.nReleaseNode = r;
- break;
-
- case ENV_PITCH:
- pIns->PitchEnv.nReleaseNode = r;
- break;
-
- default:
- pIns->VolEnv.nReleaseNode = r;
- break;
- }
+ pEnv->nReleaseNode = r;
}
}
GlobalUnlock(hCpy);
Modified: trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp
===================================================================
--- trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp 2009-09-09 23:14:18 UTC (rev 358)
+++ trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp 2009-09-10 13:31:37 UTC (rev 359)
@@ -45,36 +45,20 @@
float factor = ConvertStrTo<float>(buffer);
if(factor > 0)
{
- WORD (*array)[MAX_ENVPOINTS] = NULL;
- UINT* arraySize = NULL;
+ INSTRUMENTENVELOPE *pEnv = nullptr;
switch(m_Env)
{
- case ENV_VOLUME:
- array = &m_pInstrument->VolEnv.Ticks;
- arraySize = &m_pInstrument->VolEnv.nNodes;
- break;
-
- case ENV_PANNING:
- array = &m_pInstrument->PanEnv.Ticks;
- arraySize = &m_pInstrument->PanEnv.nNodes;
- break;
-
- case ENV_PITCH:
- array = &m_pInstrument->PitchEnv.Ticks;
- arraySize = &m_pInstrument->PitchEnv.nNodes;
- break;
+ case ENV_PANNING: pEnv = &m_pInstrument->PanEnv; break;
+ case ENV_PITCH: pEnv = &m_pInstrument->PitchEnv; break;
+ default: pEnv = &m_pInstrument->VolEnv; break;
}
-
- if(array && arraySize)
+ for(UINT i = 0; i< pEnv->nNodes; i++)
{
- for(UINT i = 0; i<*arraySize; i++)
- {
- (*array)[i] = static_cast<WORD>(factor * (*array)[i]);
+ pEnv->Ticks[i] = static_cast<WORD>(factor * pEnv->Ticks[i]);
- //Checking that the order of points is preserved.
- if(i > 0 && (*array)[i] <= (*array)[i-1])
- (*array)[i] = (*array)[i-1]+1;
- }
+ //Checking that the order of points is preserved.
+ if(i > 0 && pEnv->Ticks[i] <= pEnv->Ticks[i - 1])
+ pEnv->Ticks[i] = pEnv->Ticks[i - 1] + 1;
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-09-09 23:14:33
|
Revision: 358
http://modplug.svn.sourceforge.net/modplug/?rev=358&view=rev
Author: saga-games
Date: 2009-09-09 23:14:18 +0000 (Wed, 09 Sep 2009)
Log Message:
-----------
[Imp] Mod Conversion: Trim instrument envelopes if they're too long for the new format.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Moddoc.h
trunk/OpenMPT/mptrack/Modedit.cpp
Modified: trunk/OpenMPT/mptrack/Moddoc.h
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.h 2009-09-09 22:43:27 UTC (rev 357)
+++ trunk/OpenMPT/mptrack/Moddoc.h 2009-09-09 23:14:18 UTC (rev 358)
@@ -296,6 +296,10 @@
virtual void SetModifiedFlag(BOOL bModified=TRUE);
//}}AFX_VIRTUAL
+ // for mod conversion
+ bool UpdateEnvelopes(INSTRUMENTENVELOPE *mptEnv);
+
+
// Implementation
public:
virtual ~CModDoc();
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-09 22:43:27 UTC (rev 357)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-09 23:14:18 UTC (rev 358)
@@ -654,7 +654,7 @@
// Convert MOD/XM to S3M/IT/MPT
if (oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT)
{
- for (UINT i=1; i<=m_SndFile.m_nSamples; i++)
+ for (SAMPLEINDEX i=1; i<=m_SndFile.m_nSamples; i++)
{
m_SndFile.Samples[i].nC5Speed = CSoundFile::TransposeToFrequency(m_SndFile.Samples[i].RelativeTone, m_SndFile.Samples[i].nFineTune);
m_SndFile.Samples[i].RelativeTone = 0;
@@ -666,13 +666,13 @@
// Convert S3M/IT/MPT to XM
if (oldTypeIsS3M_IT_MPT && newTypeIsXM)
{
- for (UINT i=1; i<=m_SndFile.m_nSamples; i++)
+ for (SAMPLEINDEX i=1; i<=m_SndFile.m_nSamples; i++)
{
CSoundFile::FrequencyToTranspose(&m_SndFile.Samples[i]);
if (!(m_SndFile.Samples[i].uFlags & CHN_PANNING)) m_SndFile.Samples[i].nPan = 128;
}
bool bBrokenNoteMap = false, bBrokenSustainLoop = false;
- for (UINT j = 1; j <= m_SndFile.m_nInstruments; j++)
+ for (INSTRUMENTINDEX j = 1; j <= m_SndFile.m_nInstruments; j++)
{
MODINSTRUMENT *pIns = m_SndFile.Instruments[j];
if (pIns)
@@ -747,6 +747,16 @@
m_SndFile.m_nDefaultTempo = CLAMP(m_SndFile.m_nDefaultTempo, specs.tempoMin, specs.tempoMax);
m_SndFile.m_nDefaultSpeed = CLAMP(m_SndFile.m_nDefaultSpeed, specs.speedMin, specs.speedMax);
+ bool bTrimmedEnvelopes = false;
+ for(INSTRUMENTINDEX i = 1; i <= m_SndFile.m_nInstruments; i++)
+ {
+ bTrimmedEnvelopes |= UpdateEnvelopes(&m_SndFile.Instruments[i]->VolEnv);
+ bTrimmedEnvelopes |= UpdateEnvelopes(&m_SndFile.Instruments[i]->PanEnv);
+ bTrimmedEnvelopes |= UpdateEnvelopes(&m_SndFile.Instruments[i]->PitchEnv);
+ }
+ if(bTrimmedEnvelopes == true)
+ AddToLog("WARNING: Instrument envelopes have been shortened.\n");
+
SetModified();
ClearUndo();
UpdateAllViews(NULL, HINT_MODTYPE | HINT_MODGENERAL);
@@ -754,11 +764,32 @@
return TRUE;
}
+bool CModDoc::UpdateEnvelopes(INSTRUMENTENVELOPE *mptEnv)
+//-------------------------------------------------------
+{
+ // shorten instrument envelope if necessary (for mod conversion)
+ const int iEnvMax = m_SndFile.GetModSpecifications().envelopePointsMax;
+ bool bResult = false;
+ #define TRIMENV(i) if(i > iEnvMax) {i = iEnvMax; bResult = true;}
+ TRIMENV(mptEnv->nNodes);
+ TRIMENV(mptEnv->nLoopStart);
+ TRIMENV(mptEnv->nLoopEnd);
+ TRIMENV(mptEnv->nSustainStart);
+ TRIMENV(mptEnv->nSustainEnd);
+ TRIMENV(mptEnv->nReleaseNode);
+ #undef TRIMENV
+ return bResult;
+}
+
+
+
+
+
// Change the number of channels
BOOL CModDoc::ChangeNumChannels(UINT nNewChannels, const bool showCancelInRemoveDlg)
//------------------------------------------------
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-09-09 22:43:42
|
Revision: 357
http://modplug.svn.sourceforge.net/modplug/?rev=357&view=rev
Author: saga-games
Date: 2009-09-09 22:43:27 +0000 (Wed, 09 Sep 2009)
Log Message:
-----------
[New] MPTM: Allow up to 240 envelope points (did not set it to 255 to have a safety margin). Write additional loop points to extended instrument properties.
[Ref] Rewrote a bit of the IT loader to avoid C&P code, removed constants where they should not be used
Modified Paths:
--------------
trunk/OpenMPT/mptrack/View_ins.cpp
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/Snd_defs.h
trunk/OpenMPT/soundlib/mod_specifications.h
Modified: trunk/OpenMPT/mptrack/View_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-07 20:24:18 UTC (rev 356)
+++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-09 22:43:27 UTC (rev 357)
@@ -1256,9 +1256,6 @@
int nValue = ScreenToValue(m_ptMenu.y);
if(nTick < 0) return false;
- UINT maxpoints = (pSndFile->m_nType == MOD_TYPE_XM) ? 12 : 25;
- //To check: Should there be MAX_ENVPOINTS?
-
nValue = CLAMP(nValue, 0, 64);
INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
@@ -1280,7 +1277,7 @@
return false;
}
- if (envelope->nNodes < maxpoints)
+ if (envelope->nNodes < pSndFile->GetModSpecifications().envelopePointsMax)
{
if (!envelope->nNodes)
{
@@ -1973,8 +1970,6 @@
CModDoc *pModDoc = GetDocument();
if ((pModDoc) && (node>0) && (node <= EnvGetLastPoint()))
{
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
-
INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
if(envelope == nullptr) return;
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-07 20:24:18 UTC (rev 356)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-09 22:43:27 UTC (rev 357)
@@ -216,11 +216,31 @@
return (value > 9) ? 9 : value;
}
+// Convert IT/MPTM envelope data into MPT's internal envelope format - To be used by ITInstrToMPT()
+void ITEnvToMPT(const ITENVELOPE *itEnv, INSTRUMENTENVELOPE *mptEnv, const BYTE envOffset, const int iEnvMax)
+//-----------------------------------------------------------------------------------------------------------
+{
+ mptEnv->nNodes = min(itEnv->num, iEnvMax);
+ mptEnv->nLoopStart = itEnv->lpb;
+ mptEnv->nLoopEnd = itEnv->lpe;
+ mptEnv->nSustainStart = itEnv->slb;
+ mptEnv->nSustainEnd = itEnv->sle;
+ // Attention: Full MPTM envelope is stored in extended instrument properties
+ for (UINT ev = 0; ev < 25; ev++)
+ {
+ mptEnv->Values[ev] = itEnv->data[ev * 3] + envOffset;
+ mptEnv->Ticks[ev] = (itEnv->data[ev * 3 + 2] << 8) | (itEnv->data[ev * 3 + 1]);
+ }
+}
+
//BOOL CSoundFile::ITInstrToMPT(const void *p, MODINSTRUMENT *pIns, UINT trkvers)
long CSoundFile::ITInstrToMPT(const void *p, MODINSTRUMENT *pIns, UINT trkvers) //rewbs.modularInstData
//--------------------------------------------------------------------------------
{
+ // Envelope point count. Limited to 25 in IT format.
+ const int iEnvMax = (m_nType & MOD_TYPE_MPT) ? MAX_ENVPOINTS : 25;
+
long returnVal=0;
pIns->pTuning = m_defaultInstrument.pTuning;
pIns->nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL;
@@ -257,6 +277,7 @@
}
pIns->VolEnv.Values[ev] = pis->nodes[ev*2+1];
}
+
pIns->nNNA = pis->nna;
pIns->nDCT = pis->dnc;
pIns->nPan = 0x80;
@@ -283,7 +304,7 @@
pIns->nFadeOut = pis->fadeout << 5; // should be 6?
pIns->nGlobalVol = pis->gbv >> 1;
if (pIns->nGlobalVol > 64) pIns->nGlobalVol = 64;
- for (UINT j=0; j<NOTE_MAX; j++)
+ for (UINT j = 0; j < 120; j++)
{
UINT note = pis->keyboard[j*2];
UINT ins = pis->keyboard[j*2+1];
@@ -295,7 +316,7 @@
if (*((int *)pis->dummy) == 'MPTX')
{
const ITINSTRUMENTEX *pisex = (const ITINSTRUMENTEX *)pis;
- for (UINT k=0; k<NOTE_MAX; k++)
+ for (UINT k = 0; k < 120; k++)
{
pIns->Keyboard[k] |= ((UINT)pisex->keyboardhi[k] << 8);
}
@@ -352,45 +373,21 @@
if (pis->volenv.flags & 2) pIns->dwFlags |= ENV_VOLLOOP;
if (pis->volenv.flags & 4) pIns->dwFlags |= ENV_VOLSUSTAIN;
if (pis->volenv.flags & 8) pIns->dwFlags |= ENV_VOLCARRY;
- pIns->VolEnv.nNodes = pis->volenv.num;
- if (pIns->VolEnv.nNodes > 25) pIns->VolEnv.nNodes = 25;
- pIns->VolEnv.nLoopStart = pis->volenv.lpb;
- pIns->VolEnv.nLoopEnd = pis->volenv.lpe;
- pIns->VolEnv.nSustainStart = pis->volenv.slb;
- pIns->VolEnv.nSustainEnd = pis->volenv.sle;
+ ITEnvToMPT(&pis->volenv, &pIns->VolEnv, 0, iEnvMax);
// Panning Envelope
if (pis->panenv.flags & 1) pIns->dwFlags |= ENV_PANNING;
if (pis->panenv.flags & 2) pIns->dwFlags |= ENV_PANLOOP;
if (pis->panenv.flags & 4) pIns->dwFlags |= ENV_PANSUSTAIN;
if (pis->panenv.flags & 8) pIns->dwFlags |= ENV_PANCARRY;
- pIns->PanEnv.nNodes = pis->panenv.num;
- if (pIns->PanEnv.nNodes > 25) pIns->PanEnv.nNodes = 25;
- pIns->PanEnv.nLoopStart = pis->panenv.lpb;
- pIns->PanEnv.nLoopEnd = pis->panenv.lpe;
- pIns->PanEnv.nSustainStart = pis->panenv.slb;
- pIns->PanEnv.nSustainEnd = pis->panenv.sle;
+ ITEnvToMPT(&pis->panenv, &pIns->PanEnv, 32, iEnvMax);
// Pitch Envelope
if (pis->pitchenv.flags & 1) pIns->dwFlags |= ENV_PITCH;
if (pis->pitchenv.flags & 2) pIns->dwFlags |= ENV_PITCHLOOP;
if (pis->pitchenv.flags & 4) pIns->dwFlags |= ENV_PITCHSUSTAIN;
if (pis->pitchenv.flags & 8) pIns->dwFlags |= ENV_PITCHCARRY;
if (pis->pitchenv.flags & 0x80) pIns->dwFlags |= ENV_FILTER;
- pIns->PitchEnv.nNodes = pis->pitchenv.num;
- if (pIns->PitchEnv.nNodes > 25) pIns->PitchEnv.nNodes = 25;
- pIns->PitchEnv.nLoopStart = pis->pitchenv.lpb;
- pIns->PitchEnv.nLoopEnd = pis->pitchenv.lpe;
- pIns->PitchEnv.nSustainStart = pis->pitchenv.slb;
- pIns->PitchEnv.nSustainEnd = pis->pitchenv.sle;
- // Envelopes Data
- for (UINT ev=0; ev<25; ev++)
- {
- pIns->VolEnv.Values[ev] = pis->volenv.data[ev*3];
- pIns->VolEnv.Ticks[ev] = (pis->volenv.data[ev*3+2] << 8) | (pis->volenv.data[ev*3+1]);
- pIns->PanEnv.Values[ev] = pis->panenv.data[ev*3] + 32;
- pIns->PanEnv.Ticks[ev] = (pis->panenv.data[ev*3+2] << 8) | (pis->panenv.data[ev*3+1]);
- pIns->PitchEnv.Values[ev] = pis->pitchenv.data[ev*3] + 32;
- pIns->PitchEnv.Ticks[ev] = (pis->pitchenv.data[ev*3+2] << 8) | (pis->pitchenv.data[ev*3+1]);
- }
+ ITEnvToMPT(&pis->pitchenv, &pIns->PitchEnv, 32, iEnvMax);
+
pIns->nNNA = pis->nna;
pIns->nDCT = pis->dct;
pIns->nDNA = pis->dca;
@@ -407,9 +404,10 @@
if (pIns->nPan > 256) pIns->nPan = 128;
if (pis->dfp < 0x80) pIns->dwFlags |= ENV_SETPANNING;
}
- if ((pIns->VolEnv.nLoopStart >= 25) || (pIns->VolEnv.nLoopEnd >= 25)) pIns->dwFlags &= ~ENV_VOLLOOP;
- if ((pIns->VolEnv.nSustainStart >= 25) || (pIns->VolEnv.nSustainEnd >= 25)) pIns->dwFlags &= ~ENV_VOLSUSTAIN;
+ if ((pIns->VolEnv.nLoopStart >= iEnvMax) || (pIns->VolEnv.nLoopEnd >= iEnvMax)) pIns->dwFlags &= ~ENV_VOLLOOP;
+ if ((pIns->VolEnv.nSustainStart >= iEnvMax) || (pIns->VolEnv.nSustainEnd >= iEnvMax)) pIns->dwFlags &= ~ENV_VOLSUSTAIN;
+
return returnVal; //return offset
}
@@ -3504,7 +3502,20 @@
WriteInstrumentPropertyForAllInstruments('PTTL', sizeof(m_defaultInstrument.wPitchToTempoLock), f, instruments, nInstruments);
WriteInstrumentPropertyForAllInstruments('PVEH', sizeof(m_defaultInstrument.nPluginVelocityHandling), f, instruments, nInstruments);
WriteInstrumentPropertyForAllInstruments('PVOH', sizeof(m_defaultInstrument.nPluginVolumeHandling), f, instruments, nInstruments);
-
+
+ if(m_nType & MOD_TYPE_MPT)
+ {
+ // write full envelope information for MPTM files (more env points)
+ WriteInstrumentPropertyForAllInstruments('VP[.', sizeof(m_defaultInstrument.VolEnv.Ticks ), f, instruments, nInstruments);
+ WriteInstrumentPropertyForAllInstruments('VE[.', sizeof(m_defaultInstrument.VolEnv.Values), f, instruments, nInstruments);
+
+ WriteInstrumentPropertyForAllInstruments('PP[.', sizeof(m_defaultInstrument.PanEnv.Ticks), f, instruments, nInstruments);
+ WriteInstrumentPropertyForAllInstruments('PE[.', sizeof(m_defaultInstrument.PanEnv.Values), f, instruments, nInstruments);
+
+ WriteInstrumentPropertyForAllInstruments('PiP[', sizeof(m_defaultInstrument.PitchEnv.Ticks), f, instruments, nInstruments);
+ WriteInstrumentPropertyForAllInstruments('PiE[', sizeof(m_defaultInstrument.PitchEnv.Values), f, instruments, nInstruments);
+ }
+
return;
}
Modified: trunk/OpenMPT/soundlib/Load_xm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-07 20:24:18 UTC (rev 356)
+++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-09-09 22:43:27 UTC (rev 357)
@@ -51,7 +51,7 @@
DWORD shsize; // size of XMSAMPLESTRUCT
BYTE snum[96];
WORD venv[24];
- WORD pIns[24];
+ WORD penv[24];
BYTE vnum, pnum;
BYTE vsustain, vloops, vloope, psustain, ploops, ploope;
BYTE vtype, ptype;
@@ -354,7 +354,7 @@
for (int i = 0; i < 24; ++i) {
xmsh.venv[i] = LittleEndianW(xmsh.venv[i]);
- xmsh.pIns[i] = LittleEndianW(xmsh.pIns[i]);
+ xmsh.penv[i] = LittleEndianW(xmsh.penv[i]);
}
xmsh.volfade = LittleEndianW(xmsh.volfade);
xmsh.res = LittleEndianW(xmsh.res);
@@ -473,8 +473,8 @@
{
pIns->VolEnv.Ticks[ienv] = (WORD)xmsh.venv[ienv*2];
pIns->VolEnv.Values[ienv] = (BYTE)xmsh.venv[ienv*2+1];
- pIns->PanEnv.Ticks[ienv] = (WORD)xmsh.pIns[ienv*2];
- pIns->PanEnv.Values[ienv] = (BYTE)xmsh.pIns[ienv*2+1];
+ pIns->PanEnv.Ticks[ienv] = (WORD)xmsh.penv[ienv*2];
+ pIns->PanEnv.Values[ienv] = (BYTE)xmsh.penv[ienv*2+1];
if (ienv)
{
if (pIns->VolEnv.Ticks[ienv] < pIns->VolEnv.Ticks[ienv-1])
@@ -871,8 +871,8 @@
{
xmsh.venv[ienv*2] = pIns->VolEnv.Ticks[ienv];
xmsh.venv[ienv*2+1] = pIns->VolEnv.Values[ienv];
- xmsh.pIns[ienv*2] = pIns->PanEnv.Ticks[ienv];
- xmsh.pIns[ienv*2+1] = pIns->PanEnv.Values[ienv];
+ xmsh.penv[ienv*2] = pIns->PanEnv.Ticks[ienv];
+ xmsh.penv[ienv*2+1] = pIns->PanEnv.Values[ienv];
}
if (pIns->dwFlags & ENV_VOLUME) xmsh.vtype |= 1;
if (pIns->dwFlags & ENV_VOLSUSTAIN) xmsh.vtype |= 2;
Modified: trunk/OpenMPT/soundlib/Snd_defs.h
===================================================================
--- trunk/OpenMPT/soundlib/Snd_defs.h 2009-09-07 20:24:18 UTC (rev 356)
+++ trunk/OpenMPT/soundlib/Snd_defs.h 2009-09-09 22:43:27 UTC (rev 357)
@@ -71,7 +71,7 @@
#define MAX_BASECHANNELS 127 // Max pattern channels.
//#endif
// -! BEHAVIOUR_CHANGE#0006
-#define MAX_ENVPOINTS 32
+#define MAX_ENVPOINTS 240
#define MIN_PERIOD 0x0020
#define MAX_PERIOD 0xFFFF
#define MAX_PATTERNNAME 32
Modified: trunk/OpenMPT/soundlib/mod_specifications.h
===================================================================
--- trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-07 20:24:18 UTC (rev 356)
+++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-09 22:43:27 UTC (rev 357)
@@ -36,6 +36,7 @@
UINT speedMin;
UINT speedMax;
bool hasComments;
+ int envelopePointsMax;
};
@@ -71,6 +72,7 @@
1, //Min Speed
255, //Max Speed
true, //Has song comments
+ 240, //Envelope point count
};
@@ -101,6 +103,7 @@
1, //Min Speed
31, //Max Speed
false, //No song comments
+ 0, //Envelope point count
};
// MOD with MPT extensions.
@@ -129,6 +132,7 @@
1, //Min Speed
31, //Max Speed
false, //No song comments
+ 0, //Envelope point count
};
const CModSpecifications xm =
@@ -156,6 +160,7 @@
1, //Min Speed
31, //Max Speed
false, //No song comments
+ 12, //Envelope point count
};
// XM with MPT extensions
@@ -184,6 +189,7 @@
1, //Min Speed
31, //Max Speed
true, //Has song comments
+ 12, //Envelope point count
};
const CModSpecifications s3m =
@@ -210,6 +216,7 @@
1, //Min Speed
255, //Max Speed
false, //No song comments
+ 0, //Envelope point count
};
// S3M with MPT extensions
@@ -238,6 +245,7 @@
1, //Min Speed
255, //Max Speed
false, //No song comments
+ 0, //Envelope point count
};
const CModSpecifications it =
@@ -265,6 +273,7 @@
1, //Min Speed
255, //Max Speed
true, //Has song comments
+ 25, //Envelope point count
};
const CModSpecifications itEx =
@@ -292,6 +301,7 @@
1, //Min Speed
255, //Max Speed
true, //Has song comments
+ 25, //Envelope point count
};
} //namespace ModSpecs
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-09-07 20:24:27
|
Revision: 356
http://modplug.svn.sourceforge.net/modplug/?rev=356&view=rev
Author: saga-games
Date: 2009-09-07 20:24:18 +0000 (Mon, 07 Sep 2009)
Log Message:
-----------
[New] Pattern editor: When shift-clicking somewhere, a selection will be drawn from the previous cursor position to the new position.
[Fix] Mod Saving: The compatibility export was only working properly for 8-bit mono samples. Everything else is going to be downsampled later, so the sample "fixing" has to be done before.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/soundlib/Load_mod.cpp
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-06 19:53:01 UTC (rev 355)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-07 20:24:18 UTC (rev 356)
@@ -1032,32 +1032,40 @@
DragToSel(m_dwEndSel, TRUE);
} else */
{
- m_dwStartSel = GetPositionFromPoint(point);
- if (((m_dwStartSel & 0xFFFF) >> 3) < pModDoc->GetNumChannels())
+ if(CMainFrame::GetInputHandler()->ShiftPressed())
{
- m_dwStatus |= PATSTATUS_MOUSEDRAGSEL;
+ // Shift pressed -> set 2nd selection point
+ DragToSel(GetPositionFromPoint(point), TRUE);
+ } else
+ {
+ // Set first selection point
+ m_dwStartSel = GetPositionFromPoint(point);
+ if (((m_dwStartSel & 0xFFFF) >> 3) < pModDoc->GetNumChannels())
+ {
+ m_dwStatus |= PATSTATUS_MOUSEDRAGSEL;
- if (m_dwStatus & PATSTATUS_CTRLDRAGSEL)
- {
- SetCurSel(m_dwStartSel, m_dwStartSel);
+ if (m_dwStatus & PATSTATUS_CTRLDRAGSEL)
+ {
+ SetCurSel(m_dwStartSel, m_dwStartSel);
+ }
+ if ((CMainFrame::m_dwPatternSetup & PATTERN_DRAGNDROPEDIT)
+ && ((m_dwBeginSel != m_dwEndSel) || (m_dwStatus & PATSTATUS_CTRLDRAGSEL))
+ && ((m_dwStartSel >> 16) >= (m_dwBeginSel >> 16))
+ && ((m_dwStartSel >> 16) <= (m_dwEndSel >> 16))
+ && ((m_dwStartSel & 0xFFFF) >= (m_dwBeginSel & 0xFFFF))
+ && ((m_dwStartSel & 0xFFFF) <= (m_dwEndSel & 0xFFFF)))
+ {
+ m_dwStatus |= PATSTATUS_DRAGNDROPEDIT;
+ } else
+ if (CMainFrame::m_dwPatternSetup & PATTERN_CENTERROW)
+ {
+ SetCurSel(m_dwStartSel, m_dwStartSel);
+ } else
+ {
+ // Fix: Horizontal scrollbar pos screwed when selecting with mouse
+ SetCursorPosition( m_dwStartSel >> 16, m_dwStartSel & 0xFFFF );
+ }
}
- if ((CMainFrame::m_dwPatternSetup & PATTERN_DRAGNDROPEDIT)
- && ((m_dwBeginSel != m_dwEndSel) || (m_dwStatus & PATSTATUS_CTRLDRAGSEL))
- && ((m_dwStartSel >> 16) >= (m_dwBeginSel >> 16))
- && ((m_dwStartSel >> 16) <= (m_dwEndSel >> 16))
- && ((m_dwStartSel & 0xFFFF) >= (m_dwBeginSel & 0xFFFF))
- && ((m_dwStartSel & 0xFFFF) <= (m_dwEndSel & 0xFFFF)))
- {
- m_dwStatus |= PATSTATUS_DRAGNDROPEDIT;
- } else
- if (CMainFrame::m_dwPatternSetup & PATTERN_CENTERROW)
- {
- SetCurSel(m_dwStartSel, m_dwStartSel);
- } else
- {
- // Fix: Horizontal scrollbar pos screwed when selecting with mouse
- SetCursorPosition( m_dwStartSel >> 16, m_dwStartSel & 0xFFFF );
- }
}
}
}
Modified: trunk/OpenMPT/soundlib/Load_mod.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-09-06 19:53:01 UTC (rev 355)
+++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-09-07 20:24:18 UTC (rev 356)
@@ -546,8 +546,8 @@
MODSAMPLE *pSmp = &Samples[insmap[ismpd]];
if(bCompatibilityExport == true) // first two bytes have to be 0 due to PT's one-shot loop ("no loop")
{
- if(pSmp->nLength > 0) pSmp->pSample[0] = 0;
- if(pSmp->nLength > 1) pSmp->pSample[1] = 0;
+ int iOverwriteLen = 2 * pSmp->GetElementarySampleSize() * ((pSmp->uFlags & CHN_STEREO) ? 2 : 1);
+ memset(pSmp->pSample, 0, min(iOverwriteLen, pSmp->GetSampleSizeInBytes()));
}
UINT flags = RS_PCM8S;
#ifndef NO_PACKING
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-09-06 19:53:11
|
Revision: 355
http://modplug.svn.sourceforge.net/modplug/?rev=355&view=rev
Author: saga-games
Date: 2009-09-06 19:53:01 +0000 (Sun, 06 Sep 2009)
Log Message:
-----------
[Fix] Pattern editor: Find/Replace works now, also with high instrument numbers. Also, empty instrument numbers won't be affected by "ins+1" anymore
[Imp] Pattern editor: Find/Replace has "Search in whole song" and "Replace all" enabled by default.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/View_ins.cpp
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/View_pat.h
trunk/OpenMPT/mptrack/dlg_misc.cpp
Modified: trunk/OpenMPT/mptrack/View_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-06 16:09:09 UTC (rev 354)
+++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-06 19:53:01 UTC (rev 355)
@@ -1974,7 +1974,6 @@
if ((pModDoc) && (node>0) && (node <= EnvGetLastPoint()))
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
if(envelope == nullptr) return;
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-06 16:09:09 UTC (rev 354)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-06 19:53:01 UTC (rev 355)
@@ -25,8 +25,8 @@
MODCOMMAND CViewPattern::m_cmdOld = {0,0,0,0,0,0};
MODCOMMAND CViewPattern::m_cmdFind = {0,0,0,0,0,0};
MODCOMMAND CViewPattern::m_cmdReplace = {0,0,0,0,0,0};
-DWORD CViewPattern::m_dwFindFlags = 0;
-DWORD CViewPattern::m_dwReplaceFlags = 0;
+DWORD CViewPattern::m_dwFindFlags = PATSEARCH_FULLSEARCH;
+DWORD CViewPattern::m_dwReplaceFlags = PATSEARCH_REPLACEALL;
UINT CViewPattern::m_nFindMinChn = 0;
UINT CViewPattern::m_nFindMaxChn = 0;
signed char cInstrRelChange = 0;
@@ -1901,11 +1901,11 @@
if ((m_dwReplaceFlags & PATSEARCH_INSTR))
{
// Instr--
- if (m_cInstrRelChange == -1)
- if (m->instr > 1) m->instr--;
+ if (m_cInstrRelChange == -1 && m->instr > 1)
+ m->instr--;
// Instr++
- else if (m_cInstrRelChange == 1)
- if (m->instr < MAX_INSTRUMENTS - 1) m->instr++;
+ else if (m_cInstrRelChange == 1 && m->instr > 0 && m->instr < (MAX_INSTRUMENTS - 1))
+ m->instr++;
else m->instr = m_cmdReplace.instr;
}
if ((m_dwReplaceFlags & PATSEARCH_VOLCMD))
Modified: trunk/OpenMPT/mptrack/View_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.h 2009-09-06 16:09:09 UTC (rev 354)
+++ trunk/OpenMPT/mptrack/View_pat.h 2009-09-06 19:53:01 UTC (rev 355)
@@ -76,7 +76,7 @@
static MODCOMMAND m_cmdFind, m_cmdReplace, m_cmdOld;
static DWORD m_dwFindFlags, m_dwReplaceFlags;
static UINT m_nFindMinChn, m_nFindMaxChn;
- signed char m_cInstrRelChange; // relative instrument change (quick'n'dirty fix)
+ signed char m_cInstrRelChange; // relative instrument change (quick'n'dirty fix, this should be implemented in a less cryptic way)
protected:
CFastBitmap m_Dib;
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-09-06 16:09:09 UTC (rev 354)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-09-06 19:53:01 UTC (rev 355)
@@ -847,6 +847,8 @@
// Instrument
if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO2)) != NULL)
{
+ m_nInstr = 0;
+ cInstrRelChange = 0;
switch(combo->GetItemData(combo->GetCurSel()))
{
case replaceInstrumentMinusOne:
@@ -857,7 +859,6 @@
break;
default:
m_nInstr = combo->GetItemData(combo->GetCurSel());
- cInstrRelChange = 0;
break;
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-09-06 16:09:20
|
Revision: 354
http://modplug.svn.sourceforge.net/modplug/?rev=354&view=rev
Author: saga-games
Date: 2009-09-06 16:09:09 +0000 (Sun, 06 Sep 2009)
Log Message:
-----------
[Fix] Rearrange Samples: Sample names were copied to the mod title (again...)
[Fix] Treeview: Playing sounds from a soundfont was broken
Modified Paths:
--------------
trunk/OpenMPT/mptrack/MainFrm.cpp
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/mptrack/Moddoc.h
trunk/OpenMPT/mptrack/Modedit.cpp
Modified: trunk/OpenMPT/mptrack/MainFrm.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-09-06 12:45:07 UTC (rev 353)
+++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-09-06 16:09:09 UTC (rev 354)
@@ -2008,6 +2008,7 @@
m_WaveFile.m_nChannels = 4;
m_WaveFile.m_nInstruments = 1;
m_WaveFile.m_nSamples = 1;
+ m_WaveFile.Order.resize(3);
m_WaveFile.Order[0] = 0;
m_WaveFile.Order[1] = 1;
m_WaveFile.Order[2] = m_WaveFile.Order.GetInvalidPatIndex();
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-06 12:45:07 UTC (rev 353)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-06 16:09:09 UTC (rev 354)
@@ -62,7 +62,7 @@
ON_COMMAND(ID_INSTRUMENTS_REMOVEALL,OnRemoveAllInstruments)
// -> CODE#0020
// -> DESC="rearrange sample list"
- ON_COMMAND(ID_REARRANGE_SAMPLES, RearrangeSampleList)
+ ON_COMMAND(ID_REARRANGE_SAMPLES, RearrangeSamples)
// -! NEW_FEATURE#0020
ON_COMMAND(ID_ESTIMATESONGLENGTH, OnEstimateSongLength)
ON_COMMAND(ID_APPROX_BPM, OnApproximateBPM)
@@ -1641,7 +1641,7 @@
::MessageBox(NULL,"Warning: the exported file will not contain any of MPT's file-format hacks.", "Compatibility export warning.",MB_ICONINFORMATION | MB_OK);
break;
default:
- ::MessageBox(NULL,"Compatibility export is currently only available for MOD and IT modules.", "Can't do compatibility export.",MB_ICONINFORMATION | MB_OK);
+ ::MessageBox(NULL,"Compatibility export is currently only available for MOD, XM and IT modules.", "Can't do compatibility export.",MB_ICONINFORMATION | MB_OK);
return;
}
Modified: trunk/OpenMPT/mptrack/Moddoc.h
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.h 2009-09-06 12:45:07 UTC (rev 353)
+++ trunk/OpenMPT/mptrack/Moddoc.h 2009-09-06 16:09:09 UTC (rev 354)
@@ -194,7 +194,7 @@
BOOL RemoveUnusedPlugs();
UINT RemovePlugs(const bool (&keepMask)[MAX_MIXPLUGINS]);
BOOL RemoveUnusedPatterns(BOOL bRemove=TRUE);
- void RearrangeSampleList();
+ void RearrangeSamples();
BOOL CompoCleanup();
PATTERNINDEX InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64);
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-06 12:45:07 UTC (rev 353)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-06 16:09:09 UTC (rev 354)
@@ -1067,8 +1067,8 @@
-void CModDoc::RearrangeSampleList()
-//---------------------------------
+void CModDoc::RearrangeSamples()
+//------------------------------
{
if(m_SndFile.m_nSamples < 2)
return;
@@ -1103,7 +1103,7 @@
// This gotta be moved
m_SndFile.MoveSample(i, nSampleMap[i]);
m_SndFile.Samples[i].pSample = nullptr;
- strcpy(m_SndFile.m_szNames[nSampleMap[i]], m_SndFile.m_szNames[i]);
+ if(nSampleMap[i] > 0) strcpy(m_SndFile.m_szNames[nSampleMap[i]], m_SndFile.m_szNames[i]);
memset(m_SndFile.m_szNames[i], 0, sizeof(m_SndFile.m_szNames[i]));
// Also update instrument mapping (if module is in instrument mode)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-09-06 12:45:22
|
Revision: 353
http://modplug.svn.sourceforge.net/modplug/?rev=353&view=rev
Author: saga-games
Date: 2009-09-06 12:45:07 +0000 (Sun, 06 Sep 2009)
Log Message:
-----------
[Fix] Playback: Fixed a severe bug that caused a crash when trying to play a module that has an empty order list. (introduced in rev. 338)
[Fix] IT Loader: The fix for old instrument header versions was wrong.
[Fix] Note Properties: When double-clicking on a note in the pattern editor, the noteMin offset was not taken into consideration, which lead to wrong information for some formats.
[Fix] Note Properties: Works partly with PC notes now.
[Imp] Instrument editor: When inserting new envelope points using Shift+Click, the point can now be instantly dragged.
[Imp] Setup: Added note to "always center active row" hint that this is required to be enabled for greyed out patterns
[Imp] XI Saver: Fill out the "created with" field properly (OpenMPT instead of FastTracker 2)
[Ref] Find/Replace: Partly rewrote Ins+/-1 code, does not work yet (didn't work before, either)
[Ref] Renamed Echo Paste to Overflow Paste
Modified Paths:
--------------
trunk/OpenMPT/mptrack/CommandSet.cpp
trunk/OpenMPT/mptrack/CommandSet.h
trunk/OpenMPT/mptrack/Ctrl_ins.cpp
trunk/OpenMPT/mptrack/Ctrl_pat.cpp
trunk/OpenMPT/mptrack/Ctrl_pat.h
trunk/OpenMPT/mptrack/Ctrl_smp.cpp
trunk/OpenMPT/mptrack/Mainfrm.h
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/Moptions.cpp
trunk/OpenMPT/mptrack/View_ins.cpp
trunk/OpenMPT/mptrack/View_ins.h
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/View_pat.h
trunk/OpenMPT/mptrack/dlg_misc.cpp
trunk/OpenMPT/mptrack/dlg_misc.h
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/res/patterns.bmp
trunk/OpenMPT/mptrack/resource.h
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Sampleio.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/mptrack/CommandSet.cpp
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/CommandSet.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -2315,10 +2315,10 @@
commands[kcChannelReset].isDummy = false;
commands[kcChannelReset].Message = "Reset channel";
- commands[kcSwitchEchoPaste].UID = 1787;
- commands[kcSwitchEchoPaste].Message = "Switch echo paste";
- commands[kcSwitchEchoPaste].isHidden = false;
- commands[kcSwitchEchoPaste].isDummy = false;
+ commands[kcSwitchOverflowPaste].UID = 1787;
+ commands[kcSwitchOverflowPaste].Message = "Toggle overflow paste";
+ commands[kcSwitchOverflowPaste].isHidden = false;
+ commands[kcSwitchOverflowPaste].isDummy = false;
commands[kcNotePC].UID = 1788;
commands[kcNotePC].isHidden = false;
Modified: trunk/OpenMPT/mptrack/CommandSet.h
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.h 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/CommandSet.h 2009-09-06 12:45:07 UTC (rev 353)
@@ -84,7 +84,7 @@
kcEditPaste,
kcEditMixPaste,
kcEditMixPasteITStyle,
- kcSwitchEchoPaste,
+ kcSwitchOverflowPaste,
kcEditSelectAll,
kcEditFind,
kcEditFindNext,
Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -314,7 +314,10 @@
}
wsprintf(s, "Map all notes to sample %d", pIns->Keyboard[m_nNote]);
AppendMenu(hMenu, MF_STRING, ID_NOTEMAP_COPY_SMP, s);
- wsprintf(s, "Map all notes to %s", pSndFile->GetNoteName(pIns->NoteMap[m_nNote], m_nInstrument).c_str());
+ if(pIns->NoteMap[m_nNote] < NOTE_MIN_SPECIAL)
+ wsprintf(s, "Map all notes to %s", pSndFile->GetNoteName(pIns->NoteMap[m_nNote], m_nInstrument).c_str());
+ else
+ wsprintf(s, "Map all notes to %s", szSpecialNoteNames[pIns->NoteMap[m_nNote] - NOTE_MIN_SPECIAL]);
AppendMenu(hMenu, MF_STRING, ID_NOTEMAP_COPY_NOTE, s);
AppendMenu(hMenu, MF_STRING, ID_NOTEMAP_RESET, "Reset note mapping");
AppendMenu(hMenu, MF_STRING, ID_INSTRUMENT_DUPLICATE, "Duplicate Instrument\tShift+New");
Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -52,7 +52,7 @@
ON_COMMAND(ID_PATTERNDETAIL_LO, OnDetailLo)
ON_COMMAND(ID_PATTERNDETAIL_MED, OnDetailMed)
ON_COMMAND(ID_PATTERNDETAIL_HI, OnDetailHi)
- ON_COMMAND(ID_ECHOPASTE, OnToggleEchoPaste)
+ ON_COMMAND(ID_OVERFLOWPASTE, OnToggleOverflowPaste)
ON_CBN_SELCHANGE(IDC_COMBO_INSTRUMENT, OnInstrumentChanged)
// -> CODE#0012
// -> DESC="midi keyboard split"
@@ -158,7 +158,7 @@
m_ToolBar.AddButton(ID_PATTERNDETAIL_MED, 31, TBSTYLE_CHECK, TBSTATE_ENABLED);
m_ToolBar.AddButton(ID_PATTERNDETAIL_HI, 32, TBSTYLE_CHECK, TBSTATE_ENABLED|TBSTATE_CHECKED);
m_ToolBar.AddButton(ID_SEPARATOR, 0, TBSTYLE_SEP);
- m_ToolBar.AddButton(ID_ECHOPASTE, 38, TBSTYLE_CHECK, ((CMainFrame::m_dwPatternSetup & PATTERN_ECHOPASTE) ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED);
+ m_ToolBar.AddButton(ID_OVERFLOWPASTE, 38, TBSTYLE_CHECK, ((CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE) ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED);
// Special edit controls -> tab switch to view
m_EditSpacing.SetParent(this);
@@ -297,7 +297,7 @@
// -> CODE#0007
// -> DESC="uncheck follow song checkbox by default"
CheckDlgButton(IDC_PATTERN_FOLLOWSONG, (CMainFrame::m_dwPatternSetup & PATTERN_FOLLOWSONGOFF) ? MF_UNCHECKED : MF_CHECKED);
- m_ToolBar.SetState(ID_ECHOPASTE, ((CMainFrame::m_dwPatternSetup & PATTERN_ECHOPASTE) ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED);
+ m_ToolBar.SetState(ID_OVERFLOWPASTE, ((CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE) ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED);
// -! BEHAVIOUR_CHANGE#0007
}
if (dwHintMask & (HINT_MODTYPE|HINT_INSNAMES|HINT_SMPNAMES|HINT_PATNAMES))
@@ -1216,10 +1216,10 @@
SwitchToView();
}
-void CCtrlPatterns::OnToggleEchoPaste()
+void CCtrlPatterns::OnToggleOverflowPaste()
//-------------------------------------
{
- CMainFrame::m_dwPatternSetup ^= PATTERN_ECHOPASTE;
+ CMainFrame::m_dwPatternSetup ^= PATTERN_OVERFLOWPASTE;
UpdateView(HINT_MPTOPTIONS, NULL);
SwitchToView();
}
Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-09-06 12:45:07 UTC (rev 353)
@@ -227,7 +227,7 @@
afx_msg void OnUpdateRecord(CCmdUI *pCmdUI);
afx_msg void TogglePluginEditor(); //rewbs.instroVST
afx_msg void ToggleSplitPluginEditor(); //rewbs.instroVST
- afx_msg void OnToggleEchoPaste();
+ afx_msg void OnToggleOverflowPaste();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -618,7 +618,7 @@
DWORD d;
// Length / Type
- wsprintf(s, "%d-bit %s, len: %d", (pSmp->uFlags & CHN_16BIT) ? 16 : 8, (pSmp->uFlags & CHN_STEREO) ? "stereo" : "mono", pSmp->nLength);
+ wsprintf(s, "%d-bit %s, len: %d", pSmp->GetElementarySampleSize() * 8, (pSmp->uFlags & CHN_STEREO) ? "stereo" : "mono", pSmp->nLength);
SetDlgItemText(IDC_TEXT5, s);
// Name
memcpy(s, m_pSndFile->m_szNames[m_nSample], 32);
Modified: trunk/OpenMPT/mptrack/Mainfrm.h
===================================================================
--- trunk/OpenMPT/mptrack/Mainfrm.h 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-09-06 12:45:07 UTC (rev 353)
@@ -207,7 +207,7 @@
#define PATTERN_SYNCMUTE 0x1000000
#define PATTERN_AUTODELAY 0x2000000
#define PATTERN_NOTEFADE 0x4000000
-#define PATTERN_ECHOPASTE 0x8000000
+#define PATTERN_OVERFLOWPASTE 0x8000000
#define PATTERN_POSITIONAWARETIMER 0x10000000
#define PATTERN_RESETCHANNELS 0x20000000
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -2315,7 +2315,7 @@
nrow++;
//jojo.echopaste
- if(CMainFrame::m_dwPatternSetup & PATTERN_ECHOPASTE)
+ if(CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE)
{
while(nrow >= m_SndFile.PatternSize[nPattern])
{
Modified: trunk/OpenMPT/mptrack/Moptions.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moptions.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/Moptions.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -605,7 +605,7 @@
OPTGEN_SYNCMUTE,
OPTGEN_AUTODELAY,
OPTGEN_PATNOTEFADE,
- OPTGEN_ECHOPASTE,
+ OPTGEN_OVERFLOWPASTE,
OPTGEN_POSITIONAWARETIMER,
OPTGEN_RESETCHANNELS,
OPTGEN_MAXOPTIONS
@@ -625,7 +625,7 @@
{"Ignored muted channels", "Notes will not be played on muted channels (unmuting will only start on a new note)."},
{"Quick cursor paste Auto-Repeat", "Leaving the space bar pressed will auto-repeat the action"},
{"No loud samples", "Disable loud playback of samples in the sample/instrument editor"},
- {"Show Prev/Next patterns", "Displays grayed-out version of the previous/next patterns in the pattern editor"},
+ {"Show Prev/Next patterns", "Displays grayed-out version of the previous/next patterns in the pattern editor. Does not work if \"always center active row\" is disabled."},
{"Continuous scroll", "Jumps to the next pattern when moving past the end of a pattern"},
{"Record note off", "Record note off when a key is released on the PC keyboard (Only works in instrument mode)."},
{"Follow song off by default", "Ensure follow song is off when opening or starting a new song."}, //rewbs.noFollow
@@ -644,7 +644,7 @@
{"Maintain sample sync on mute", "Samples continue to be processed when channels are muted (like in IT2 and FT2)"},
{"Automatic delay commands", "Automatically insert appropriate note-delay commands when recording notes during live playback."},
{"Note fade on key up", "Enable to fade/stop notes on key up in pattern tab." },
- {"Echo paste mode", "Wrap pasted pattern data into next pattern. This is useful for creating echo channels."},
+ {"Overflow paste mode", "Wrap pasted pattern data into next pattern. This is useful for creating echo channels."},
{"Position aware timer", "If enabled, timer will show the playback position time if possible instead of running timer."},
{"Reset channels on loop", "If enabled, channels will be reset to their initial state when song looping is enabled.\nNote: This does not affect manual song loops (i.e. triggered by pattern commands)"},
};
@@ -709,7 +709,7 @@
case OPTGEN_AUTODELAY: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_AUTODELAY); break;
case OPTGEN_PATNOTEFADE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_NOTEFADE); break;
- case OPTGEN_ECHOPASTE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_ECHOPASTE); break;
+ case OPTGEN_OVERFLOWPASTE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_OVERFLOWPASTE); break;
case OPTGEN_POSITIONAWARETIMER: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_POSITIONAWARETIMER); break;
case OPTGEN_RESETCHANNELS: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_RESETCHANNELS); break;
}
@@ -774,13 +774,13 @@
// case OPTGEN_ALTERNTIVEBPMSPEED: mask = PATTERN_ALTERNTIVEBPMSPEED; break;
// rewbs: this options is now available under song settings. It is therefore saved with the song.
// -! NEW_FEATURE#0022
- case OPTGEN_PATTERNCTXMENUSTYLE: mask = PATTERN_OLDCTXMENUSTYLE; break;
- case OPTGEN_SYNCMUTE: mask = PATTERN_SYNCMUTE; break;
- case OPTGEN_AUTODELAY: mask = PATTERN_AUTODELAY; break;
- case OPTGEN_PATNOTEFADE: mask = PATTERN_NOTEFADE; break;
- case OPTGEN_ECHOPASTE: mask = PATTERN_ECHOPASTE; break;
- case OPTGEN_POSITIONAWARETIMER: mask = PATTERN_POSITIONAWARETIMER; break;
- case OPTGEN_RESETCHANNELS: mask = PATTERN_RESETCHANNELS; break;
+ case OPTGEN_PATTERNCTXMENUSTYLE: mask = PATTERN_OLDCTXMENUSTYLE; break;
+ case OPTGEN_SYNCMUTE: mask = PATTERN_SYNCMUTE; break;
+ case OPTGEN_AUTODELAY: mask = PATTERN_AUTODELAY; break;
+ case OPTGEN_PATNOTEFADE: mask = PATTERN_NOTEFADE; break;
+ case OPTGEN_OVERFLOWPASTE: mask = PATTERN_OVERFLOWPASTE; break;
+ case OPTGEN_POSITIONAWARETIMER: mask = PATTERN_POSITIONAWARETIMER; break;
+ case OPTGEN_RESETCHANNELS: mask = PATTERN_RESETCHANNELS; break;
}
if (bCheck) CMainFrame::m_dwPatternSetup |= mask; else CMainFrame::m_dwPatternSetup &= ~mask;
Modified: trunk/OpenMPT/mptrack/View_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -1204,7 +1204,117 @@
return envelope->Ticks[EnvGetReleaseNode()];
}
+bool CViewInstrument::EnvRemovePoint()
+//--------------------------------------
+{
+ CModDoc *pModDoc = GetDocument();
+ if ((pModDoc) && (m_nDragItem) && (m_nDragItem-1 <= EnvGetLastPoint()))
+ {
+ CSoundFile *pSndFile = pModDoc->GetSoundFile();
+ MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
+ if (pIns)
+ {
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr || envelope->nNodes == 0) return false;
+ UINT nPoint = m_nDragItem - 1;
+
+ envelope->nNodes--;
+ for (UINT i=nPoint; i<envelope->nNodes; i++)
+ {
+ envelope->Ticks[i] = envelope->Ticks[i + 1];
+ envelope->Values[i] = envelope->Values[i + 1];
+ }
+ if (nPoint >= envelope->nNodes) nPoint = envelope->nNodes-1;
+ if (envelope->nLoopStart > nPoint) envelope->nLoopStart--;
+ if (envelope->nLoopEnd > nPoint) envelope->nLoopEnd--;
+ if (envelope->nSustainStart > nPoint) envelope->nSustainStart--;
+ if (envelope->nSustainEnd > nPoint) envelope->nSustainEnd--;
+ if (envelope->nReleaseNode>nPoint && envelope->nReleaseNode!=ENV_RELEASE_NODE_UNSET) envelope->nReleaseNode--;
+ envelope->Ticks[0] = 0;
+
+ pModDoc->SetModified();
+ pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL);
+ return true;
+ }
+ }
+ return false;
+}
+
+// Insert point. Returns 0 if error occured, else point ID + 1.
+UINT CViewInstrument::EnvInsertPoint()
+//------------------------------------
+{
+ CModDoc *pModDoc = GetDocument();
+ if (pModDoc)
+ {
+ CSoundFile *pSndFile = pModDoc->GetSoundFile();
+ MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
+ if (pIns)
+ {
+ int nTick = ScreenToTick(m_ptMenu.x);
+ int nValue = ScreenToValue(m_ptMenu.y);
+ if(nTick < 0) return false;
+
+ UINT maxpoints = (pSndFile->m_nType == MOD_TYPE_XM) ? 12 : 25;
+ //To check: Should there be MAX_ENVPOINTS?
+
+ nValue = CLAMP(nValue, 0, 64);
+
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return false;
+ BYTE cDefaultValue;
+
+ switch(m_nEnv)
+ {
+ case ENV_VOLUME:
+ cDefaultValue = 64;
+ break;
+ case ENV_PANNING:
+ cDefaultValue = 32;
+ break;
+ case ENV_PITCH:
+ cDefaultValue = (pIns->dwFlags & ENV_FILTER) ? 64 : 32;
+ break;
+ default:
+ return false;
+ }
+
+ if (envelope->nNodes < maxpoints)
+ {
+ if (!envelope->nNodes)
+ {
+ envelope->Ticks[0] = 0;
+ envelope->Values[0] = cDefaultValue;
+ envelope->nNodes = 1;
+ }
+ UINT i = 0;
+ for (i = 0; i < envelope->nNodes; i++) if (nTick <= envelope->Ticks[i]) break;
+ for (UINT j = envelope->nNodes; j > i; j--)
+ {
+ envelope->Ticks[j] = envelope->Ticks[j - 1];
+ envelope->Values[j] = envelope->Values[j - 1];
+ }
+ envelope->Ticks[i] = (WORD)nTick;
+ envelope->Values[i] = (BYTE)nValue;
+ envelope->nNodes++;
+ if (envelope->nLoopStart >= i) envelope->nLoopStart++;
+ if (envelope->nLoopEnd >= i) envelope->nLoopEnd++;
+ if (envelope->nSustainStart >= i) envelope->nSustainStart++;
+ if (envelope->nSustainEnd >= i) envelope->nSustainEnd++;
+ if (envelope->nReleaseNode >= i && envelope->nReleaseNode != ENV_RELEASE_NODE_UNSET) envelope->nReleaseNode++;
+
+ pModDoc->SetModified();
+ pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL);
+ return i + 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+
void CViewInstrument::DrawPositionMarks(HDC hdc)
//----------------------------------------------
{
@@ -1705,7 +1815,13 @@
if(CMainFrame::GetMainFrame()->GetInputHandler()->ShiftPressed())
{
m_ptMenu = pt;
- OnEnvInsertPoint();
+ m_nDragItem = EnvInsertPoint(); // returns point ID + 1 if successful, else 0.
+ if(m_nDragItem > 0)
+ {
+ // Drag point if successful
+ SetCapture();
+ m_dwStatus |= INSSTATUS_DRAGGING;
+ }
}
}
}
@@ -1939,106 +2055,13 @@
void CViewInstrument::OnEnvRemovePoint()
//--------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if ((pModDoc) && (m_nDragItem) && (m_nDragItem-1 <= EnvGetLastPoint()))
- {
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
- if(envelope == nullptr || envelope->nNodes == 0) return;
-
- UINT nPoint = m_nDragItem - 1;
-
- envelope->nNodes--;
- for (UINT i=nPoint; i<envelope->nNodes; i++)
- {
- envelope->Ticks[i] = envelope->Ticks[i + 1];
- envelope->Values[i] = envelope->Values[i + 1];
- }
- if (nPoint >= envelope->nNodes) nPoint = envelope->nNodes-1;
- if (envelope->nLoopStart > nPoint) envelope->nLoopStart--;
- if (envelope->nLoopEnd > nPoint) envelope->nLoopEnd--;
- if (envelope->nSustainStart > nPoint) envelope->nSustainStart--;
- if (envelope->nSustainEnd > nPoint) envelope->nSustainEnd--;
- if (envelope->nReleaseNode>nPoint && envelope->nReleaseNode!=ENV_RELEASE_NODE_UNSET) envelope->nReleaseNode--;
- envelope->Ticks[0] = 0;
-
- pModDoc->SetModified();
- pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL);
- }
- }
+ EnvRemovePoint();
}
-
void CViewInstrument::OnEnvInsertPoint()
//--------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if (pModDoc)
- {
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- int nTick = ScreenToTick(m_ptMenu.x);
- int nValue = ScreenToValue(m_ptMenu.y);
- if(nTick < 0) return;
-
- UINT maxpoints = (pSndFile->m_nType == MOD_TYPE_XM) ? 12 : 25;
- //To check: Should there be MAX_ENVPOINTS?
-
- nValue = CLAMP(nValue, 0, 64);
-
- INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
- if(envelope == nullptr) return;
- BYTE cDefaultValue;
-
- switch(m_nEnv)
- {
- case ENV_VOLUME:
- cDefaultValue = 64;
- break;
- case ENV_PANNING:
- cDefaultValue = 32;
- break;
- case ENV_PITCH:
- cDefaultValue = (pIns->dwFlags & ENV_FILTER) ? 64 : 32;
- break;
- default:
- return;
- }
-
- if (envelope->nNodes < maxpoints)
- {
- if (!envelope->nNodes)
- {
- envelope->Ticks[0] = 0;
- envelope->Values[0] = cDefaultValue;
- envelope->nNodes = 1;
- }
- UINT i = 0;
- for (i = 0; i < envelope->nNodes; i++) if (nTick <= envelope->Ticks[i]) break;
- for (UINT j = envelope->nNodes; j > i; j--)
- {
- envelope->Ticks[j] = envelope->Ticks[j - 1];
- envelope->Values[j] = envelope->Values[j - 1];
- }
- envelope->Ticks[i] = (WORD)nTick;
- envelope->Values[i] = (BYTE)nValue;
- envelope->nNodes++;
- if (envelope->nLoopStart >= i) envelope->nLoopStart++;
- if (envelope->nLoopEnd >= i) envelope->nLoopEnd++;
- if (envelope->nSustainStart >= i) envelope->nSustainStart++;
- if (envelope->nSustainEnd >= i) envelope->nSustainEnd++;
- if (envelope->nReleaseNode >= i && envelope->nReleaseNode != ENV_RELEASE_NODE_UNSET) envelope->nReleaseNode++;
-
- pModDoc->SetModified();
- pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL);
- }
- }
- }
+ EnvInsertPoint();
}
Modified: trunk/OpenMPT/mptrack/View_ins.h
===================================================================
--- trunk/OpenMPT/mptrack/View_ins.h 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/View_ins.h 2009-09-06 12:45:07 UTC (rev 353)
@@ -69,6 +69,8 @@
bool EnvSetPanEnv(bool bEnable);
bool EnvSetPitchEnv(bool bEnable);
bool EnvSetFilterEnv(bool bEnable);
+ UINT EnvInsertPoint();
+ bool EnvRemovePoint();
int TickToScreen(int nTick) const;
int PointToScreen(int nPoint) const;
int ScreenToTick(int x) const;
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -29,6 +29,7 @@
DWORD CViewPattern::m_dwReplaceFlags = 0;
UINT CViewPattern::m_nFindMinChn = 0;
UINT CViewPattern::m_nFindMaxChn = 0;
+signed char cInstrRelChange = 0;
IMPLEMENT_SERIAL(CViewPattern, CModScrollView, 0)
@@ -1688,6 +1689,7 @@
pageReplace.m_nCommand = m_cmdReplace.command;
pageReplace.m_nParam = m_cmdReplace.param;
pageReplace.m_dwFlags = m_dwReplaceFlags;
+ pageReplace.cInstrRelChange = m_cInstrRelChange;
dlg.AddPage(&pageFind);
dlg.AddPage(&pageReplace);
if (dlg.DoModal() == IDOK)
@@ -1708,6 +1710,7 @@
m_cmdReplace.command = pageReplace.m_nCommand;
m_cmdReplace.param = pageReplace.m_nParam;
m_dwReplaceFlags = pageReplace.m_dwFlags;
+ m_cInstrRelChange = pageReplace.cInstrRelChange;
m_bContinueSearch = FALSE;
OnEditFindNext();
}
@@ -1866,7 +1869,7 @@
if (!(m_dwReplaceFlags & PATSEARCH_REPLACE)) goto EndSearch;
if (!(m_dwReplaceFlags & PATSEARCH_REPLACEALL))
{
- UINT ans = MessageBox("Replace this occurrence ?", "Replace", MB_YESNOCANCEL);
+ UINT ans = MessageBox("Replace this occurrence?", "Replace", MB_YESNOCANCEL);
if (ans == IDYES) bReplace = TRUE; else
if (ans == IDNO) bReplace = FALSE; else goto EndSearch;
}
@@ -1875,22 +1878,22 @@
if ((m_dwReplaceFlags & PATSEARCH_NOTE))
{
// -1 octave
- if (m_cmdReplace.note == CFindReplaceTab::replaceMinusOctave)
+ if (m_cmdReplace.note == CFindReplaceTab::replaceNoteMinusOctave)
{
if (m->note > 12) m->note -= 12;
} else
// +1 octave
- if (m_cmdReplace.note == CFindReplaceTab::replacePlusOctave)
+ if (m_cmdReplace.note == CFindReplaceTab::replaceNotePlusOctave)
{
if (m->note <= NOTE_MAX - 12) m->note += 12;
} else
// Note--
- if (m_cmdReplace.note == CFindReplaceTab::replaceMinusOne)
+ if (m_cmdReplace.note == CFindReplaceTab::replaceNoteMinusOne)
{
if (m->note > 1) m->note--;
} else
// Note++
- if (m_cmdReplace.note == CFindReplaceTab::replacePlusOne)
+ if (m_cmdReplace.note == CFindReplaceTab::replaceNotePlusOne)
{
if (m->note < NOTE_MAX) m->note++;
} else m->note = m_cmdReplace.note;
@@ -1898,15 +1901,12 @@
if ((m_dwReplaceFlags & PATSEARCH_INSTR))
{
// Instr--
- if (m_cmdReplace.instr == CFindReplaceTab::replaceMinusOne)
- {
+ if (m_cInstrRelChange == -1)
if (m->instr > 1) m->instr--;
- } else
// Instr++
- if (m_cmdReplace.instr == CFindReplaceTab::replacePlusOne)
- {
- if (m->instr < MAX_INSTRUMENTS-1) m->instr++;
- } else m->instr = m_cmdReplace.instr;
+ else if (m_cInstrRelChange == 1)
+ if (m->instr < MAX_INSTRUMENTS - 1) m->instr++;
+ else m->instr = m_cmdReplace.instr;
}
if ((m_dwReplaceFlags & PATSEARCH_VOLCMD))
{
@@ -3609,7 +3609,7 @@
case kcChangeLoopStatus: SendCtrlMessage(CTRLMSG_PAT_LOOP, -1); return wParam;
case kcNewPattern: SendCtrlMessage(CTRLMSG_PAT_NEWPATTERN); return wParam;
case kcSwitchToOrderList: OnSwitchToOrderList();
- case kcSwitchEchoPaste: CMainFrame::m_dwPatternSetup ^= PATTERN_ECHOPASTE; return wParam;
+ case kcSwitchOverflowPaste: CMainFrame::m_dwPatternSetup ^= PATTERN_OVERFLOWPASTE; return wParam;
}
//Ranges:
Modified: trunk/OpenMPT/mptrack/View_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.h 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/View_pat.h 2009-09-06 12:45:07 UTC (rev 353)
@@ -76,6 +76,7 @@
static MODCOMMAND m_cmdFind, m_cmdReplace, m_cmdOld;
static DWORD m_dwFindFlags, m_dwReplaceFlags;
static UINT m_nFindMinChn, m_nFindMaxChn;
+ signed char m_cInstrRelChange; // relative instrument change (quick'n'dirty fix)
protected:
CFastBitmap m_Dib;
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -667,10 +667,10 @@
combo->SetItemData(combo->AddString("..."), 0);
if (m_bReplace)
{
- combo->SetItemData(combo->AddString("note-1"), replaceMinusOne);
- combo->SetItemData(combo->AddString("note+1"), replacePlusOne);
- combo->SetItemData(combo->AddString("-1 oct"), replaceMinusOctave);
- combo->SetItemData(combo->AddString("+1 oct"), replacePlusOctave);
+ combo->SetItemData(combo->AddString("note-1"), replaceNoteMinusOne);
+ combo->SetItemData(combo->AddString("note+1"), replaceNotePlusOne);
+ combo->SetItemData(combo->AddString("-1 oct"), replaceNoteMinusOctave);
+ combo->SetItemData(combo->AddString("+1 oct"), replaceNotePlusOctave);
} else
{
combo->SetItemData(combo->AddString("any"), findAny);
@@ -690,8 +690,8 @@
combo->SetItemData(combo->AddString(".."), 0);
if (m_bReplace)
{
- combo->SetItemData(combo->AddString("ins-1"), replaceMinusOne);
- combo->SetItemData(combo->AddString("ins+1"), replacePlusOne);
+ combo->SetItemData(combo->AddString("ins-1"), replaceInstrumentMinusOne);
+ combo->SetItemData(combo->AddString("ins+1"), replaceInstrumentPlusOne);
}
for (UINT n=1; n<MAX_INSTRUMENTS; n++)
{
@@ -705,10 +705,13 @@
combo->SetItemData(combo->AddString(s), n);
}
UINT ncount = combo->GetCount();
- for (UINT i=0; i<ncount; i++) if (m_nInstr == combo->GetItemData(i))
+ for (UINT i=0; i<ncount; i++)
{
- combo->SetCurSel(i);
- break;
+ if (m_nInstr == combo->GetItemData(i) || (cInstrRelChange == -1 && combo->GetItemData(i) == replaceInstrumentMinusOne) || (cInstrRelChange == 1 && combo->GetItemData(i) == replaceInstrumentPlusOne))
+ {
+ combo->SetCurSel(i);
+ break;
+ }
}
}
// Volume Command
@@ -844,7 +847,19 @@
// Instrument
if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO2)) != NULL)
{
- m_nInstr = combo->GetItemData(combo->GetCurSel());
+ switch(combo->GetItemData(combo->GetCurSel()))
+ {
+ case replaceInstrumentMinusOne:
+ cInstrRelChange = -1;
+ break;
+ case replaceInstrumentPlusOne:
+ cInstrRelChange = 1;
+ break;
+ default:
+ m_nInstr = combo->GetItemData(combo->GetCurSel());
+ cInstrRelChange = 0;
+ break;
+ }
}
// Volume Command
if (((combo = (CComboBox *)GetDlgItem(IDC_COMBO3)) != NULL) && (m_pModDoc))
@@ -1230,7 +1245,10 @@
AppendNotesToControlEx(*combo, pSndFile, m_nInstr);
if (m_nNote <= NOTE_MAX)
- combo->SetCurSel(m_nNote);
+ {
+ const MODCOMMAND::NOTE noteStart = (pSndFile != nullptr) ? pSndFile->GetModSpecifications().noteMin : 1;
+ combo->SetCurSel(m_nNote - (noteStart - 1));
+ }
else
{
for(int i = combo->GetCount() - 1; i >= 0; --i)
@@ -1248,21 +1266,31 @@
if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO2)) != NULL)
{
combo->ResetContent();
- combo->SetItemData(combo->AddString("No Instrument"), 0);
- UINT max = pSndFile->m_nInstruments;
- if (!max) max = pSndFile->m_nSamples;
- for (UINT i=1; i<=max; i++)
+
+ if(m_nNote == NOTE_PC || m_nNote == NOTE_PCS)
{
- wsprintf(s, "%02d:", i);
- int k = strlen(s);
- if (pSndFile->m_nInstruments)
+ // control plugin param note
+ combo->SetItemData(combo->AddString("No Effect"), 0);
+ AddPluginNamesToCombobox(*combo, pSndFile->m_MixPlugins, false);
+ } else
+ {
+ // instrument / sample
+ combo->SetItemData(combo->AddString("No Instrument"), 0);
+ UINT max = max(pSndFile->m_nInstruments, pSndFile->m_nSamples); // instrument / sample mode
+ for (UINT i = 1; i <= max; i++)
{
- if (pSndFile->Instruments[i])
- memcpy(s+k, pSndFile->Instruments[i]->name, 32);
- } else
- memcpy(s+k, pSndFile->m_szNames[i], 32);
- s[k+32] = 0;
- combo->SetItemData(combo->AddString(s), i);
+ wsprintf(s, "%02d: ", i);
+ int k = strlen(s);
+ // instrument / sample
+ if (pSndFile->m_nInstruments)
+ {
+ if (pSndFile->Instruments[i])
+ memcpy(s+k, pSndFile->Instruments[i]->name, 32);
+ } else
+ memcpy(s+k, pSndFile->m_szNames[i], 32);
+ s[k+32] = 0;
+ combo->SetItemData(combo->AddString(s), i);
+ }
}
combo->SetCurSel(m_nInstr);
}
@@ -1272,6 +1300,8 @@
void CPageEditNote::OnNoteChanged()
//---------------------------------
{
+ bool bWasParamControl = (m_nNote == NOTE_PC || m_nNote == NOTE_PCS) ? true : false;
+
CComboBox *combo;
if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO1)) != NULL)
{
@@ -1294,6 +1324,10 @@
}
}
}
+ bool bIsNowParamControl = (m_nNote == NOTE_PC || m_nNote == NOTE_PCS) ? true : false;
+ if(bWasParamControl != bIsNowParamControl)
+ UpdateDialog();
+
if (m_pParent) m_pParent->UpdateNote(m_nNote, m_nInstr);
}
@@ -1324,7 +1358,7 @@
if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO1)) != NULL)
{
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
- if (pSndFile->m_nType == MOD_TYPE_MOD)
+ if (pSndFile->m_nType == MOD_TYPE_MOD || m_bIsParamControl)
{
combo->EnableWindow(FALSE);
return;
@@ -1427,18 +1461,27 @@
pSndFile = m_pModDoc->GetSoundFile();
if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO1)) != NULL)
{
- UINT numfx = m_pModDoc->GetNumEffects();
- UINT fxndx = m_pModDoc->GetIndexFromEffect(m_nCommand, m_nParam);
combo->ResetContent();
- combo->SetItemData(combo->AddString(" None"), (DWORD)-1);
- if (!m_nCommand) combo->SetCurSel(0);
- for (UINT i=0; i<numfx; i++)
+ if(m_bIsParamControl)
{
- if (m_pModDoc->GetEffectInfo(i, s, TRUE))
+ // plugin param control note
+ AddPluginParameternamesToCombobox(*combo, pSndFile->m_MixPlugins[m_nPlugin]);
+ combo->SetCurSel(m_nPluginParam);
+ } else
+ {
+ // process as effect
+ UINT numfx = m_pModDoc->GetNumEffects();
+ UINT fxndx = m_pModDoc->GetIndexFromEffect(m_nCommand, m_nParam);
+ combo->SetItemData(combo->AddString(" None"), (DWORD)-1);
+ if (!m_nCommand) combo->SetCurSel(0);
+ for (UINT i=0; i<numfx; i++)
{
- int k = combo->AddString(s);
- combo->SetItemData(k, i);
- if (i == fxndx) combo->SetCurSel(k);
+ if (m_pModDoc->GetEffectInfo(i, s, TRUE))
+ {
+ int k = combo->AddString(s);
+ combo->SetItemData(k, i);
+ if (i == fxndx) combo->SetCurSel(k);
+ }
}
}
}
Modified: trunk/OpenMPT/mptrack/dlg_misc.h
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.h 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/dlg_misc.h 2009-09-06 12:45:07 UTC (rev 353)
@@ -133,6 +133,7 @@
public:
UINT m_nNote, m_nInstr, m_nVolCmd, m_nVol, m_nCommand, m_nParam, m_nMinChannel, m_nMaxChannel;
+ signed char cInstrRelChange;
DWORD m_dwFlags;
enum findItem
@@ -143,10 +144,13 @@
enum replaceItem
{
- replaceMinusOctave = NOTE_MIN_SPECIAL - 1,
- replacePlusOctave = NOTE_MIN_SPECIAL - 2,
- replaceMinusOne = NOTE_MIN_SPECIAL - 3,
- replacePlusOne = NOTE_MIN_SPECIAL - 4
+ replaceNotePlusOne = NOTE_MAX + 1,
+ replaceNoteMinusOne = NOTE_MAX + 2,
+ replaceNotePlusOctave = NOTE_MAX + 3,
+ replaceNoteMinusOctave = NOTE_MAX + 4,
+
+ replaceInstrumentPlusOne = MAX_INSTRUMENTS + 1,
+ replaceInstrumentMinusOne = MAX_INSTRUMENTS + 2,
};
// Make sure there's unused notes between NOTE_MAX and NOTE_MIN_SPECIAL.
@@ -235,10 +239,11 @@
{
protected:
UINT m_nVolCmd, m_nVolume;
+ bool m_bIsParamControl;
public:
CPageEditVolume(CModDoc *pModDoc, CEditCommand *parent):CPageEditCommand(pModDoc, parent, IDD_PAGEEDITVOLUME) {}
- void Init(MODCOMMAND &m) { m_nVolCmd = m.volcmd; m_nVolume = m.vol; }
+ void Init(MODCOMMAND &m) { m_nVolCmd = m.volcmd; m_nVolume = m.vol; m_bIsParamControl = (m.note == NOTE_PC || m.note == NOTE_PCS) ? true : false;}
void UpdateDialog();
void UpdateRanges();
@@ -256,7 +261,9 @@
//============================================
{
protected:
- UINT m_nCommand, m_nParam;
+ UINT m_nCommand, m_nParam, m_nPlugin;
+ UINT m_nPluginParam;
+ bool m_bIsParamControl;
// -> CODE#0010
// -> DESC="add extended parameter mechanism to pattern effects"
UINT m_nXParam, m_nMultiplier;
@@ -268,7 +275,7 @@
CPageEditEffect(CModDoc *pModDoc, CEditCommand *parent):CPageEditCommand(pModDoc, parent, IDD_PAGEEDITEFFECT) {}
// -> CODE#0010
// -> DESC="add extended parameter mechanism to pattern effects"
- void Init(MODCOMMAND &m) { m_nCommand = m.command; m_nParam = m.param; m_pModcommand = &m;}
+ void Init(MODCOMMAND &m) { m_nCommand = m.command; m_nParam = m.param; m_pModcommand = &m; m_bIsParamControl = (m.note == NOTE_PC || m.note == NOTE_PCS) ? true : false; m_nPlugin = m.instr; m_nPluginParam = MODCOMMAND::GetValueVolCol(m.volcmd, m.vol);}
void XInit(UINT xparam = 0, UINT multiplier = 1) { m_nXParam = xparam; m_nMultiplier = multiplier; }
// -! NEW_FEATURE#0010
void UpdateDialog();
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2009-09-06 12:45:07 UTC (rev 353)
@@ -2120,7 +2120,7 @@
BEGIN
ID_EDIT_GOTO_MENU "Go to row / channel / pattern / order"
ID_CLEANUP_COMPO "Reset attributes to defaults (useful for creating sample packs)\nCompo Cleanup"
- ID_ECHOPASTE "Toggle echo paste\nToggle echo paste"
+ ID_OVERFLOWPASTE "Toggle overflow paste\nToggle overflow paste"
END
STRINGTABLE
Modified: trunk/OpenMPT/mptrack/res/patterns.bmp
===================================================================
(Binary files differ)
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/mptrack/resource.h 2009-09-06 12:45:07 UTC (rev 353)
@@ -1113,7 +1113,7 @@
#define ID_CLEANUP_COMPO 59221
#define ID_SAMPLE_DRAW 59224
#define ID_SAMPLE_ADDSILENCE 59225
-#define ID_ECHOPASTE 59226
+#define ID_OVERFLOWPASTE 59226
#define ID_NOTEMAP_COPY_NOTE 59227
#define ID_CLEANUP_REARRANGESAMPLES 59228
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -230,7 +230,7 @@
const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p;
memcpy(pIns->name, pis->name, 26);
memcpy(pIns->filename, pis->filename, 12);
- pIns->nFadeOut = pis->fadeout << 7;
+ pIns->nFadeOut = pis->fadeout << 6;
pIns->nGlobalVol = 64;
for (UINT j=0; j<NOTE_MAX; j++)
{
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -776,7 +776,10 @@
for(uint32 nCell = 0; nCell < m_nChannels * Patterns[endPattern].GetNumRows(); nCell++)
{
if(row_data->command == CMD_PATTERNBREAK || row_data->command == CMD_POSITIONJUMP)
+ {
lastRow = nCell / m_nChannels;
+ break;
+ }
row_data++;
}
TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, true);
Modified: trunk/OpenMPT/soundlib/Sampleio.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -1324,7 +1324,7 @@
memcpy(xfh.extxi, "Extended Instrument: ", 21);
memcpy(xfh.name, pIns->name, 22);
xfh.name[22] = 0x1A;
- memcpy(xfh.trkname, "FastTracker v2.00 ", 20);
+ memcpy(xfh.trkname, "Created by OpenMPT ", 20);
xfh.shsize = 0x102;
fwrite(&xfh, 1, sizeof(xfh), f);
// XI Instrument Header
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-09-01 22:08:43 UTC (rev 352)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-09-06 12:45:07 UTC (rev 353)
@@ -642,16 +642,18 @@
if ((m_nPattern < Patterns.Size()) && (!Patterns[m_nPattern])) m_nPattern = Order.GetIgnoreIndex();
while (m_nPattern >= Patterns.Size())
{
- // End of song ?
+ // End of song?
if ((m_nPattern == Order.GetInvalidPatIndex()) || (m_nCurrentPattern >= Order.size()))
{
if (!m_nRepeatCount) return FALSE;
ORDERINDEX nRestartPosOverride = m_nRestartPos;
- if(!m_nRestartPos && m_nCurrentPattern <= Order.size())
+ if(!m_nRestartPos && m_nCurrentPattern <= Order.size() && m_nCurrentPattern > 0)
{
- // if we're in a subtune and there's no restart position, go to the first order of the subtune
+ /* Subtune detection. Subtunes are separated by "---" order items, so if we're in a
+ subtune and there's no restart position, we go to the first order of the subtune
+ (i.e. the first order after the previous "---" item) */
for(ORDERINDEX iOrd = m_nCurrentPattern - 1; iOrd > 0; iOrd--)
{
if(Order[iOrd] == Order.GetInvalidPatIndex())
@@ -709,7 +711,6 @@
//Handle Repeat position
if (m_nRepeatCount > 0) m_nRepeatCount--;
m_nCurrentPattern = nRestartPosOverride;
- //m_nRow = 0;
m_dwSongFlags &= ~SONG_BREAKTOROW;
//If restart pos points to +++, move along
while (Order[m_nCurrentPattern] == Order.GetIgnoreIndex()) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-09-01 22:08:51
|
Revision: 352
http://modplug.svn.sourceforge.net/modplug/?rev=352&view=rev
Author: saga-games
Date: 2009-09-01 22:08:43 +0000 (Tue, 01 Sep 2009)
Log Message:
-----------
[Imp] S3M saver: Orderlist is now as small as possible (multiple of 2 instead of multiple of 16); Using ST3's default UltraClick value
[Imp] PSM loader: "Cosmetic" changes (use default values of first subtune for default speed/tempo/panning/etc., don't touch patterns if only one subtune is present.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/mptrack/Mptrack.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_s3m.cpp
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-01 18:50:33 UTC (rev 351)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-09-01 22:08:43 UTC (rev 352)
@@ -2077,7 +2077,7 @@
#define MOD_TYPE_XMIT (MOD_TYPE_XM|MOD_TYPE_IT)
#define MOD_TYPE_XMITMPT (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)
#define MOD_TYPE_ITMPT (MOD_TYPE_IT|MOD_TYPE_MPT)
-#define MAX_FXINFO 66 //rewbs.smoothVST, increased from 64... I wonder what this will break?
+#define MAX_FXINFO 68 //rewbs.smoothVST, increased from 64... I wonder what this will break?
const MPTEFFECTINFO gFXInfo[MAX_FXINFO] =
@@ -2153,8 +2153,10 @@
{CMD_S3MCMDEX, 0xF0,0x70, 0, MOD_TYPE_ITMPT, "Instr. control"},
// -> CODE#0010
// -> DESC="add extended parameter mechanism to pattern effects"
- {CMD_XPARAM, 0x00,0x00, 0, MOD_TYPE_XMITMPT, "X param"}
+ {CMD_XPARAM, 0x00,0x00, 0, MOD_TYPE_XMITMPT, "X param"},
// -! NEW_FEATURE#0010
+ {CMD_NOTESLIDEUP, 0x00,0x00, 0, 0, "Note Slide Up"}, // .IMF effect
+ {CMD_NOTESLIDEDOWN, 0x00,0x00, 0, 0, "Note Slide Down"}, // .IMF effect
};
Modified: trunk/OpenMPT/mptrack/Mptrack.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-09-01 18:50:33 UTC (rev 351)
+++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-09-01 22:08:43 UTC (rev 352)
@@ -1689,6 +1689,7 @@
"coda for sample drawing code|"
"http://coda.s3m.us/|"
"Storlek for all the IT compatibility hints and testcases|"
+ "as well as the IMF loader|"
"http://schismtracker.org/|"
"Pel K. Txnder for the scrolling credits control :)|"
"http://tinyurl.com/4yze8|"
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-01 18:50:33 UTC (rev 351)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-09-01 22:08:43 UTC (rev 352)
@@ -283,13 +283,13 @@
case 0x07: // Default Speed
if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
- m_nDefaultSpeed = subsong.defaultSpeed = lpStream[dwSettingsOffset + 1];
+ subsong.defaultSpeed = lpStream[dwSettingsOffset + 1];
dwSettingsOffset += 2;
break;
case 0x08: // Default Tempo
if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
- m_nDefaultTempo = subsong.defaultTempo = lpStream[dwSettingsOffset + 1];
+ subsong.defaultTempo = lpStream[dwSettingsOffset + 1];
dwSettingsOffset += 2;
break;
@@ -313,20 +313,17 @@
switch(lpStream[dwSettingsOffset + 3])
{
case 0: // use panning
- ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = lpStream[dwSettingsOffset + 2] ^ 128;
- ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelPanning[nChn] = lpStream[dwSettingsOffset + 2] ^ 128;
subsong.channelSurround[nChn] = false;
break;
case 2: // surround
- ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
- ChnSettings[nChn].dwFlags |= CHN_SURROUND;
+ subsong.channelPanning[nChn] = 128;
subsong.channelSurround[nChn] = true;
break;
case 4: // center
- ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
- ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelPanning[nChn] = 128;
subsong.channelSurround[nChn] = false;
break;
@@ -341,10 +338,10 @@
dwSettingsOffset += 4;
break;
- case 0x0E: // Channel volume table (0...255)
+ case 0x0E: // Channel volume table (0...255) - apparently always 255
if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break;
if(lpStream[dwSettingsOffset + 1] < MAX_BASECHANNELS)
- ChnSettings[lpStream[dwSettingsOffset + 1]].nVolume = subsong.channelVolume[lpStream[dwSettingsOffset + 1]] = (lpStream[dwSettingsOffset + 2] >> 2) + 1;
+ subsong.channelVolume[lpStream[dwSettingsOffset + 1]] = (lpStream[dwSettingsOffset + 2] >> 2) + 1;
dwSettingsOffset += 3;
break;
@@ -375,20 +372,17 @@
switch(lpStream[dwChunkPos + i])
{
case 0: // use panning
- ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = lpStream[dwChunkPos + i + 1] ^ 128;
- ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelPanning[nChn] = lpStream[dwChunkPos + i + 1] ^ 128;
subsong.channelSurround[nChn] = false;
break;
case 2: // surround
- ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
- ChnSettings[nChn].dwFlags |= CHN_SURROUND;
+ subsong.channelPanning[nChn] = 128;
subsong.channelSurround[nChn] = true;
break;
case 4: // center
- ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
- ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelPanning[nChn] = 128;
subsong.channelSurround[nChn] = false;
break;
}
@@ -478,9 +472,23 @@
dwMemPos += chunkSize;
}
- if(m_nChannels == 0)
+ if(m_nChannels == 0 || subsongs.size() == 0)
return false;
+ // Make the default variables of the first subsong global
+ m_nDefaultSpeed = subsongs[0].defaultSpeed;
+ m_nDefaultTempo = subsongs[0].defaultTempo;
+ m_nRestartPos = subsongs[0].restartPos;
+ for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++)
+ {
+ ChnSettings[nChn].nVolume = subsongs[0].channelVolume[nChn];
+ ChnSettings[nChn].nPan = subsongs[0].channelPanning[nChn];
+ if(subsongs[0].channelSurround[nChn])
+ ChnSettings[nChn].dwFlags |= CHN_SURROUND;
+ else
+ ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ }
+
// Now that we know the number of channels, we can go through all the patterns.
// This is a bit stupid since we will even read duplicate patterns twice, but hey, we do this just once... so who cares?
PATTERNINDEX nPat = 0;
@@ -582,7 +590,7 @@
case 0x04: // volslide down
command = CMD_VOLUMESLIDE;
if (bNewFormat) param &= 0x0F;
- else param = (param >> 1) & 0x0F;
+ else if(param < 2) param |= 0xF0; else param = (param >> 1) & 0x0F;
break;
// Portamento
@@ -728,48 +736,51 @@
nPat++;
}
- // write subsong "configuration" to patterns
- for(uint32 i = 0; i < subsongs.size(); i++)
+ if(subsongs.size() > 1)
{
- PATTERNINDEX startPattern = Order[subsongs[i].startOrder], endPattern = Order[subsongs[i].endOrder];
- if(startPattern == PATTERNINDEX_INVALID || endPattern == PATTERNINDEX_INVALID) continue; // what, invalid subtune?
+ // write subsong "configuration" to patterns (only if there are multiple subsongs)
+ for(uint32 i = 0; i < subsongs.size(); i++)
+ {
+ PATTERNINDEX startPattern = Order[subsongs[i].startOrder], endPattern = Order[subsongs[i].endOrder];
+ if(startPattern == PATTERNINDEX_INVALID || endPattern == PATTERNINDEX_INVALID) continue; // what, invalid subtune?
- // set the subsong name to all pattern names
- for(PATTERNINDEX nPat = startPattern; nPat <= endPattern; nPat++)
- {
- SetPatternName(nPat, subsongs[i].songName);
- }
-
- // subsongs with different panning setup -> write to pattern (MUSIC_C.PSM)
- if(bSubsongPanningDiffers)
- {
- for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++)
+ // set the subsong name to all pattern names
+ for(PATTERNINDEX nPat = startPattern; nPat <= endPattern; nPat++)
{
- if(subsongs[i].channelSurround[nChn] == true)
- TryWriteEffect(startPattern, 0, CMD_S3MCMDEX, 0x91, false, nChn, false, true);
- else
- TryWriteEffect(startPattern, 0, CMD_PANNING8, subsongs[i].channelPanning[nChn], false, nChn, false, true);
+ SetPatternName(nPat, subsongs[i].songName);
}
- }
- // write default tempo/speed to pattern
- TryWriteEffect(startPattern, 0, CMD_SPEED, subsongs[i].defaultSpeed, false, CHANNELINDEX_INVALID, false, true);
- TryWriteEffect(startPattern, 0, CMD_TEMPO, subsongs[i].defaultTempo, false, CHANNELINDEX_INVALID, false, true);
- // don't write channel volume for now, as it's always set to 100% anyway
+ // subsongs with different panning setup -> write to pattern (MUSIC_C.PSM)
+ if(bSubsongPanningDiffers)
+ {
+ for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++)
+ {
+ if(subsongs[i].channelSurround[nChn] == true)
+ TryWriteEffect(startPattern, 0, CMD_S3MCMDEX, 0x91, false, nChn, false, true);
+ else
+ TryWriteEffect(startPattern, 0, CMD_PANNING8, subsongs[i].channelPanning[nChn], false, nChn, false, true);
+ }
+ }
+ // write default tempo/speed to pattern
+ TryWriteEffect(startPattern, 0, CMD_SPEED, subsongs[i].defaultSpeed, false, CHANNELINDEX_INVALID, false, true);
+ TryWriteEffect(startPattern, 0, CMD_TEMPO, subsongs[i].defaultTempo, false, CHANNELINDEX_INVALID, false, true);
- // there's a restart pos, so let's try to insert a Bxx command in the last pattern
- if(subsongs[i].restartPos != ORDERINDEX_INVALID)
- {
- ROWINDEX lastRow = Patterns[endPattern].GetNumRows() - 1;
- MODCOMMAND *row_data;
- row_data = Patterns[endPattern];
- for(uint32 nCell = 0; nCell < m_nChannels * Patterns[endPattern].GetNumRows(); nCell++)
+ // don't write channel volume for now, as it's always set to 100% anyway
+
+ // there's a restart pos, so let's try to insert a Bxx command in the last pattern
+ if(subsongs[i].restartPos != ORDERINDEX_INVALID)
{
- if(row_data->command == CMD_PATTERNBREAK || row_data->command == CMD_POSITIONJUMP)
- lastRow = nCell / m_nChannels;
- row_data++;
+ ROWINDEX lastRow = Patterns[endPattern].GetNumRows() - 1;
+ MODCOMMAND *row_data;
+ row_data = Patterns[endPattern];
+ for(uint32 nCell = 0; nCell < m_nChannels * Patterns[endPattern].GetNumRows(); nCell++)
+ {
+ if(row_data->command == CMD_PATTERNBREAK || row_data->command == CMD_POSITIONJUMP)
+ lastRow = nCell / m_nChannels;
+ row_data++;
+ }
+ TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, true);
}
- TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, true);
}
}
Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-09-01 18:50:33 UTC (rev 351)
+++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-09-01 22:08:43 UTC (rev 352)
@@ -527,7 +527,6 @@
nbo = 2;
else if (nbo & 1) // number of orders must be even
nbo++;
- nbo = (nbo + 15) & 0xF0; // TODO why does it not work otherwise? nbo should be multiple of 2, not 16!
if(nbo > 0xF0) nbo = 0xF0; // sequence too long
header[0x20] = nbo & 0xFF;
header[0x21] = nbo >> 8;
@@ -560,7 +559,7 @@
header[0x31] = CLAMP(m_nDefaultSpeed, 1, 255);
header[0x32] = CLAMP(m_nDefaultTempo, 32, 255);
header[0x33] = CLAMP(m_nSamplePreAmp, 0x10, 0x7F) | 0x80; // Bit 8 = Stereo
- header[0x34] = 0x10; // 16 Channels for UltraClick removal
+ header[0x34] = 0x08; // 8 Channels for UltraClick removal (default)
header[0x35] = 0xFC; // Write pan positions
for (i=0; i<32; i++)
{
@@ -571,7 +570,7 @@
} else header[0x40+i] = 0xFF;
}
fwrite(header, 0x60, 1, f);
- Order.WriteAsByte(f, nbo);
+ nbo = Order.WriteAsByte(f, nbo);
memset(patptr, 0, sizeof(patptr));
memset(insptr, 0, sizeof(insptr));
UINT ofs0 = 0x60 + nbo;
@@ -595,6 +594,7 @@
{
fwrite(S3MFiller, 0x10 - ((nbi*2+nbp*2) & 0x0F), 1, f);
}
+ fseek(f, ofs1, SEEK_SET);
ofs1 = ftell(f);
fwrite(insex, nbi, 0x50, f);
// Packing patterns
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-09-01 18:50:54
|
Revision: 351
http://modplug.svn.sourceforge.net/modplug/?rev=351&view=rev
Author: relabsoluness
Date: 2009-09-01 18:50:33 +0000 (Tue, 01 Sep 2009)
Log Message:
-----------
[Ref] Moved constants from Sndfile.h to a new file, renamed OrderToPatternTable files, added some utility functions, minor code cleanup.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/misc_util.h
trunk/OpenMPT/mptrack/mptrack.vcproj
trunk/OpenMPT/mptrack/mptrack_08.vcproj
trunk/OpenMPT/mptrack/typedefs.h
trunk/OpenMPT/soundlib/Sndfile.h
trunk/OpenMPT/soundlib/mod_specifications.h
trunk/OpenMPT/soundlib/pattern.h
trunk/OpenMPT/soundlib/patternContainer.h
Added Paths:
-----------
trunk/OpenMPT/soundlib/ModSequence.cpp
trunk/OpenMPT/soundlib/ModSequence.h
trunk/OpenMPT/soundlib/Snd_defs.h
Removed Paths:
-------------
trunk/OpenMPT/soundlib/OrderToPatternTable.cpp
trunk/OpenMPT/soundlib/OrderToPatternTable.h
Modified: trunk/OpenMPT/mptrack/misc_util.h
===================================================================
--- trunk/OpenMPT/mptrack/misc_util.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/mptrack/misc_util.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -81,4 +81,33 @@
LPCCH LoadResource(LPCTSTR lpName, LPCTSTR lpType, LPCCH& pData, size_t& nSize, HGLOBAL& hglob);
+namespace utilImpl
+{
+ template <bool bMemcpy>
+ struct ArrayCopyImpl {};
+
+ template <>
+ struct ArrayCopyImpl<true>
+ {
+ template <class T>
+ static void Do(T* pDst, const T* pSrc, const size_t n) {memcpy(pDst, pSrc, sizeof(T) * n);}
+ };
+
+ template <>
+ struct ArrayCopyImpl<false>
+ {
+ template <class T>
+ static void Do(T* pDst, const T* pSrc, const size_t n) {std::copy(pSrc, pSrc + n, pDst);}
+ };
+} // namespace utilImpl
+
+
+// Copies n elements from array pSrc to array pDst.
+// If the source and destination arrays overlap, behaviour is undefined.
+template <class T>
+void ArrayCopy(T* pDst, const T* pSrc, const size_t n)
+{
+ utilImpl::ArrayCopyImpl<std::tr1::has_trivial_assign<T>::value>::Do(pDst, pSrc, n);
+}
+
#endif
Modified: trunk/OpenMPT/mptrack/mptrack.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-09-01 18:50:33 UTC (rev 351)
@@ -367,6 +367,9 @@
RelativePath=".\Modedit.cpp">
</File>
<File
+ RelativePath="..\soundlib\ModSequence.cpp">
+ </File>
+ <File
RelativePath="..\soundlib\modsmp_ctrl.cpp">
</File>
<File
@@ -397,9 +400,6 @@
RelativePath=".\OpenGLEditor.cpp">
</File>
<File
- RelativePath="..\soundlib\OrderToPatternTable.cpp">
- </File>
- <File
RelativePath="..\soundlib\pattern.cpp">
</File>
<File
@@ -795,6 +795,9 @@
RelativePath=".\moddoc.h">
</File>
<File
+ RelativePath="..\soundlib\ModSequence.h">
+ </File>
+ <File
RelativePath="..\soundlib\modsmp_ctrl.h">
</File>
<File
@@ -819,12 +822,6 @@
RelativePath=".\OpenGLEditor.h">
</File>
<File
- RelativePath=".\order.h">
- </File>
- <File
- RelativePath="..\soundlib\OrderToPatternTable.h">
- </File>
- <File
RelativePath="..\soundlib\pattern.h">
</File>
<File
@@ -852,6 +849,9 @@
RelativePath=".\serialization_utils.h">
</File>
<File
+ RelativePath="..\soundlib\Snd_defs.h">
+ </File>
+ <File
RelativePath="..\Soundlib\snddev.h">
</File>
<File
Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-09-01 18:50:33 UTC (rev 351)
@@ -493,6 +493,10 @@
>
</File>
<File
+ RelativePath="..\soundlib\ModSequence.cpp"
+ >
+ </File>
+ <File
RelativePath="..\soundlib\modsmp_ctrl.cpp"
>
</File>
@@ -533,10 +537,6 @@
>
</File>
<File
- RelativePath="..\soundlib\OrderToPatternTable.cpp"
- >
- </File>
- <File
RelativePath="..\soundlib\pattern.cpp"
>
</File>
@@ -1051,6 +1051,10 @@
>
</File>
<File
+ RelativePath="..\soundlib\ModSequence.h"
+ >
+ </File>
+ <File
RelativePath="..\soundlib\modsmp_ctrl.h"
>
</File>
@@ -1083,14 +1087,6 @@
>
</File>
<File
- RelativePath=".\order.h"
- >
- </File>
- <File
- RelativePath="..\soundlib\OrderToPatternTable.h"
- >
- </File>
- <File
RelativePath="..\soundlib\pattern.h"
>
</File>
@@ -1127,6 +1123,10 @@
>
</File>
<File
+ RelativePath="..\soundlib\Snd_defs.h"
+ >
+ </File>
+ <File
RelativePath="..\Soundlib\snddev.h"
>
</File>
Modified: trunk/OpenMPT/mptrack/typedefs.h
===================================================================
--- trunk/OpenMPT/mptrack/typedefs.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/mptrack/typedefs.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -31,26 +31,26 @@
typedef float float32;
-typedef uint32 ROWINDEX;
- const ROWINDEX ROWINDEX_MAX = uint32_max;
-typedef uint16 CHANNELINDEX;
- const CHANNELINDEX CHANNELINDEX_MAX = uint16_max;
- const CHANNELINDEX CHANNELINDEX_INVALID = CHANNELINDEX_MAX;
-typedef uint16 ORDERINDEX;
- const ORDERINDEX ORDERINDEX_MAX = uint16_max;
- const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX;
-typedef uint16 PATTERNINDEX;
- const PATTERNINDEX PATTERNINDEX_MAX = uint16_max;
- const PATTERNINDEX PATTERNINDEX_INVALID = PATTERNINDEX_MAX;
-typedef uint8 PLUGINDEX;
-typedef uint16 TEMPO;
-typedef uint16 SAMPLEINDEX;
- const SAMPLEINDEX SAMPLEINDEX_MAX = uint16_max;
- const SAMPLEINDEX SAMPLEINDEX_INVALID = SAMPLEINDEX_MAX;
-typedef uint16 INSTRUMENTINDEX;
- const SAMPLEINDEX INSTRUMENTINDEX_MAX = uint16_max;
- const SAMPLEINDEX INSTRUMENTINDEX_INVALID = INSTRUMENTINDEX_MAX;
-typedef uint32 MODTYPE;
+#if !_HAS_TR1
+ namespace std
+ {
+ namespace tr1
+ {
+ template <class T> struct has_trivial_assign {static const bool value = false;};
+ #define SPECIALIZE_TRIVIAL_ASSIGN(type) template <> struct has_trivial_assign<type> {static const bool value = true;}
+ SPECIALIZE_TRIVIAL_ASSIGN(int8);
+ SPECIALIZE_TRIVIAL_ASSIGN(uint8);
+ SPECIALIZE_TRIVIAL_ASSIGN(int16);
+ SPECIALIZE_TRIVIAL_ASSIGN(uint16);
+ SPECIALIZE_TRIVIAL_ASSIGN(int32);
+ SPECIALIZE_TRIVIAL_ASSIGN(uint32);
+ SPECIALIZE_TRIVIAL_ASSIGN(int64);
+ SPECIALIZE_TRIVIAL_ASSIGN(uint64);
+ #undef SPECIALIZE_TRIVIAL_ASSIGN
+ };
+ };
+#endif
+
#endif
Copied: trunk/OpenMPT/soundlib/ModSequence.cpp (from rev 349, trunk/OpenMPT/soundlib/OrderToPatternTable.cpp)
===================================================================
--- trunk/OpenMPT/soundlib/ModSequence.cpp (rev 0)
+++ trunk/OpenMPT/soundlib/ModSequence.cpp 2009-09-01 18:50:33 UTC (rev 351)
@@ -0,0 +1,221 @@
+#include "stdafx.h"
+#include "sndfile.h"
+#include "ModSequence.h"
+#include "../mptrack/serialization_utils.h"
+
+#define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u."))))
+
+DWORD COrderToPatternTable::Deserialize(const BYTE* const src, const DWORD memLength)
+//-------------------------------------------------------------------------
+{
+ if(memLength < 2 + 4) return 0;
+ uint16 version = 0;
+ uint32 s = 0;
+ DWORD memPos = 0;
+ memcpy(&version, src, sizeof(version));
+ memPos += sizeof(version);
+ if(version != 0) return memPos;
+ memcpy(&s, src+memPos, sizeof(s));
+ memPos += sizeof(s);
+ if(s > 65000) return true;
+ if(memLength < memPos+s*4) return memPos;
+
+ const uint32 nOriginalSize = s;
+ if(s > ModSpecs::mptm.ordersMax)
+ s = ModSpecs::mptm.ordersMax;
+
+ resize(max(s, MAX_ORDERS));
+ for(size_t i = 0; i<s; i++, memPos +=4 )
+ {
+ uint32 temp;
+ memcpy(&temp, src+memPos, 4);
+ (*this)[i] = static_cast<PATTERNINDEX>(temp);
+ }
+ memPos += 4*(nOriginalSize - s);
+ return memPos;
+}
+
+
+size_t COrderToPatternTable::WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize)
+//-----------------------------------------------------------------------------
+{
+ if(numOfBytes > destSize) return true;
+ if(size() < numOfBytes) resize(numOfBytes, 0xFF);
+ UINT i = 0;
+ for(i = 0; i<numOfBytes; i++)
+ {
+ dest[i] = static_cast<BYTE>((*this)[i]);
+ }
+ return i; //Returns the number of bytes written.
+}
+
+
+size_t COrderToPatternTable::WriteAsByte(FILE* f, const UINT count)
+//---------------------------------------------------------------
+{
+ if(size() < count) resize(count, GetInvalidPatIndex());
+
+ size_t i = 0;
+
+ for(i = 0; i<count; i++)
+ {
+ const PATTERNINDEX pat = (*this)[i];
+ BYTE temp = static_cast<BYTE>((*this)[i]);
+
+ if(pat > 0xFD)
+ {
+ if(pat == GetInvalidPatIndex()) temp = 0xFF;
+ else temp = 0xFE;
+ }
+ fwrite(&temp, 1, 1, f);
+ }
+ return i; //Returns the number of bytes written.
+}
+
+bool COrderToPatternTable::ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength)
+//-------------------------------------------------------------------------
+{
+ if(howMany < 0 || howMany > memLength) return true;
+ if(m_rSndFile.GetType() != MOD_TYPE_MPT && howMany > MAX_ORDERS) return true;
+
+ if(size() < static_cast<size_t>(howMany))
+ resize(howMany, GetInvalidPatIndex());
+
+ for(int i = 0; i<howMany; i++, pFrom++)
+ (*this)[i] = *pFrom;
+ return false;
+}
+
+
+bool COrderToPatternTable::NeedsExtraDatafield() const
+//----------------------------------------------
+{
+ if(m_rSndFile.GetType() == MOD_TYPE_MPT && m_rSndFile.Patterns.Size() > 0xFD)
+ return true;
+ else
+ return false;
+}
+
+
+void COrderToPatternTable::OnModTypeChanged(const MODTYPE oldtype)
+//----------------------------------------------------------------
+{
+ const CModSpecifications specs = m_rSndFile.GetModSpecifications();
+
+ //Resize orderlist if needed. Because old orderlist had MAX_ORDERS(256) elements, not making it
+ //smaller than that even if the modtype doesn't support that many orders.
+ if(specs.ordersMax < GetCount())
+ {
+ resize(max(MAX_ORDERS, specs.ordersMax));
+ for(ORDERINDEX i = GetCount(); i>specs.ordersMax; --i) (*this)[i-1] = GetInvalidPatIndex();
+ }
+ if (GetCount() < MAX_ORDERS)
+ resize(MAX_ORDERS, GetInvalidPatIndex());
+
+ //Replace items used to denote end of song/skip order.
+ replace(begin(), end(), GetInvalidPatIndex(oldtype), GetInvalidPatIndex());
+ replace(begin(), end(), GetIgnoreIndex(oldtype), GetIgnoreIndex());
+}
+
+
+ORDERINDEX COrderToPatternTable::GetLengthTailTrimmed() const
+//-----------------------------------------------------------
+{
+ ORDERINDEX nEnd = GetCount();
+ if(nEnd == 0) return 0;
+ nEnd--;
+ const PATTERNINDEX iInvalid = GetInvalidPatIndex();
+ while(nEnd > 0 && (*this)[nEnd] == iInvalid)
+ nEnd--;
+ return ((*this)[nEnd] == iInvalid) ? 0 : nEnd+1;
+}
+
+
+ORDERINDEX COrderToPatternTable::GetLengthFirstEmpty() const
+//----------------------------------------------------------
+{
+ const ORDERINDEX nLength = GetCount();
+ ORDERINDEX nMax = 0;
+ while ((nMax < nLength) && ((*this)[nMax] != (*this).GetInvalidPatIndex())) nMax++;
+ return nMax;
+}
+
+
+ORDERINDEX COrderToPatternTable::GetNextOrderIgnoringSkips(const ORDERINDEX start) const
+//-------------------------------------------------------------------------------------
+{
+ const ORDERINDEX count = GetCount();
+ if(count == 0) return 0;
+ ORDERINDEX next = min(count-1, start+1);
+ while(next+1 < count && (*this)[next] == GetIgnoreIndex()) next++;
+ return next;
+}
+
+ORDERINDEX COrderToPatternTable::GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const
+//-------------------------------------------------------------------------------------
+{
+ const ORDERINDEX count = GetCount();
+ if(start == 0 || count == 0) return 0;
+ ORDERINDEX prev = min(start-1, count-1);
+ while(prev > 0 && (*this)[prev] == GetIgnoreIndex()) prev--;
+ return prev;
+}
+
+
+void COrderToPatternTable::Init()
+//-------------------------------
+{
+ resize(MAX_ORDERS, GetInvalidPatIndex());
+ for(ORDERINDEX i = 0; i < GetCount(); i++)
+ {
+ (*this)[i] = GetInvalidPatIndex();
+ }
+}
+
+
+
+PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65535 : 0xFF;}
+PATTERNINDEX COrderToPatternTable::GetIgnoreIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65534 : 0xFE;}
+
+PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex() const {return GetInvalidPatIndex(m_rSndFile.GetType());}
+PATTERNINDEX COrderToPatternTable::GetIgnoreIndex() const {return GetIgnoreIndex(m_rSndFile.GetType());}
+
+
+void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t)
+//--------------------------------------------------------------------------------
+{
+ uint16 size;
+ srlztn::Binaryread<uint16>(iStrm, size);
+ if(size > ModSpecs::mptm.ordersMax)
+ {
+ // Hack: Show message here if trying to load longer sequence than what is supported.
+ CString str; str.Format(str_SequenceTruncationNote, size, ModSpecs::mptm.ordersMax);
+ AfxMessageBox(str, MB_ICONWARNING);
+ size = ModSpecs::mptm.ordersMax;
+ }
+ seq.resize(max(size, MAX_ORDERS), seq.GetInvalidPatIndex());
+ if(size == 0)
+ { seq.Init(); return; }
+
+ for(size_t i = 0; i < size; i++)
+ {
+ uint16 temp;
+ srlztn::Binaryread<uint16>(iStrm, temp);
+ seq[i] = temp;
+ }
+}
+
+
+void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq)
+//-------------------------------------------------------------------------
+{
+ uint16 size = seq.GetCount();
+ srlztn::Binarywrite<uint16>(oStrm, size);
+ const COrderToPatternTable::const_iterator endIter = seq.end();
+ for(COrderToPatternTable::const_iterator citer = seq.begin(); citer != endIter; citer++)
+ {
+ const uint16 temp = static_cast<uint16>(*citer);
+ srlztn::Binarywrite<uint16>(oStrm, temp);
+ }
+}
+
Copied: trunk/OpenMPT/soundlib/ModSequence.h (from rev 349, trunk/OpenMPT/soundlib/OrderToPatternTable.h)
===================================================================
--- trunk/OpenMPT/soundlib/ModSequence.h (rev 0)
+++ trunk/OpenMPT/soundlib/ModSequence.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -0,0 +1,68 @@
+#ifndef ORDERTOPATTERNTABLE_H
+#define ORDERTOPATTERNTABLE_H
+
+#include <vector>
+using std::vector;
+
+class CSoundFile;
+
+
+#pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data.
+
+
+//==============================================
+class COrderToPatternTable : public vector<PATTERNINDEX>
+//==============================================
+{
+public:
+ COrderToPatternTable(const CSoundFile& sndFile) : m_rSndFile(sndFile) {}
+
+ // Initialize default sized sequence.
+ void Init();
+
+ bool ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength);
+
+ size_t WriteAsByte(FILE* f, const UINT count);
+
+ size_t WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize);
+
+ ORDERINDEX GetCount() const {return size();}
+
+ //Deprecated function used for MPTm's created in 1.17.02.46 - 1.17.02.48.
+ DWORD Deserialize(const BYTE* const src, const DWORD memLength);
+
+ //Returns true if the IT orderlist datafield is not sufficient to store orderlist information.
+ bool NeedsExtraDatafield() const;
+
+ void OnModTypeChanged(const MODTYPE oldtype);
+
+ // Returns length of sequence without counting trailing '---' items.
+ ORDERINDEX GetLengthTailTrimmed() const;
+
+ // Returns length of sequence stopping counting on first '---' (or at the end of sequence).
+ ORDERINDEX GetLengthFirstEmpty() const;
+
+ PATTERNINDEX GetInvalidPatIndex() const; //To correspond 0xFF
+ static PATTERNINDEX GetInvalidPatIndex(const MODTYPE type);
+
+ PATTERNINDEX GetIgnoreIndex() const; //To correspond 0xFE
+ static PATTERNINDEX GetIgnoreIndex(const MODTYPE type);
+
+ //Returns the previous/next order ignoring skip indeces(+++).
+ //If no previous/next order exists, return first/last order, and zero
+ //when orderlist is empty.
+ ORDERINDEX GetNextOrderIgnoringSkips(const ORDERINDEX start) const;
+ ORDERINDEX GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const;
+
+private:
+ const CSoundFile& m_rSndFile;
+};
+
+#pragma warning(default:4244) //conversion from 'type1' to 'type2', possible loss of data.
+
+
+void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t nSize = 0);
+void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq);
+
+#endif
+
Deleted: trunk/OpenMPT/soundlib/OrderToPatternTable.cpp
===================================================================
--- trunk/OpenMPT/soundlib/OrderToPatternTable.cpp 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/OrderToPatternTable.cpp 2009-09-01 18:50:33 UTC (rev 351)
@@ -1,221 +0,0 @@
-#include "stdafx.h"
-#include "sndfile.h"
-#include "ordertopatterntable.h"
-#include "../mptrack/serialization_utils.h"
-
-#define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u."))))
-
-DWORD COrderToPatternTable::Deserialize(const BYTE* const src, const DWORD memLength)
-//-------------------------------------------------------------------------
-{
- if(memLength < 2 + 4) return 0;
- uint16 version = 0;
- uint32 s = 0;
- DWORD memPos = 0;
- memcpy(&version, src, sizeof(version));
- memPos += sizeof(version);
- if(version != 0) return memPos;
- memcpy(&s, src+memPos, sizeof(s));
- memPos += sizeof(s);
- if(s > 65000) return true;
- if(memLength < memPos+s*4) return memPos;
-
- const uint32 nOriginalSize = s;
- if(s > ModSpecs::mptm.ordersMax)
- s = ModSpecs::mptm.ordersMax;
-
- resize(max(s, MAX_ORDERS));
- for(size_t i = 0; i<s; i++, memPos +=4 )
- {
- uint32 temp;
- memcpy(&temp, src+memPos, 4);
- (*this)[i] = static_cast<PATTERNINDEX>(temp);
- }
- memPos += 4*(nOriginalSize - s);
- return memPos;
-}
-
-
-size_t COrderToPatternTable::WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize)
-//-----------------------------------------------------------------------------
-{
- if(numOfBytes > destSize) return true;
- if(size() < numOfBytes) resize(numOfBytes, 0xFF);
- UINT i = 0;
- for(i = 0; i<numOfBytes; i++)
- {
- dest[i] = static_cast<BYTE>((*this)[i]);
- }
- return i; //Returns the number of bytes written.
-}
-
-
-size_t COrderToPatternTable::WriteAsByte(FILE* f, const UINT count)
-//---------------------------------------------------------------
-{
- if(size() < count) resize(count, GetInvalidPatIndex());
-
- size_t i = 0;
-
- for(i = 0; i<count; i++)
- {
- const PATTERNINDEX pat = (*this)[i];
- BYTE temp = static_cast<BYTE>((*this)[i]);
-
- if(pat > 0xFD)
- {
- if(pat == GetInvalidPatIndex()) temp = 0xFF;
- else temp = 0xFE;
- }
- fwrite(&temp, 1, 1, f);
- }
- return i; //Returns the number of bytes written.
-}
-
-bool COrderToPatternTable::ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength)
-//-------------------------------------------------------------------------
-{
- if(howMany < 0 || howMany > memLength) return true;
- if(m_rSndFile.GetType() != MOD_TYPE_MPT && howMany > MAX_ORDERS) return true;
-
- if(size() < static_cast<size_t>(howMany))
- resize(howMany, GetInvalidPatIndex());
-
- for(int i = 0; i<howMany; i++, pFrom++)
- (*this)[i] = *pFrom;
- return false;
-}
-
-
-bool COrderToPatternTable::NeedsExtraDatafield() const
-//----------------------------------------------
-{
- if(m_rSndFile.GetType() == MOD_TYPE_MPT && m_rSndFile.Patterns.Size() > 0xFD)
- return true;
- else
- return false;
-}
-
-
-void COrderToPatternTable::OnModTypeChanged(const MODTYPE oldtype)
-//----------------------------------------------------------------
-{
- const CModSpecifications specs = m_rSndFile.GetModSpecifications();
-
- //Resize orderlist if needed. Because old orderlist had MAX_ORDERS(256) elements, not making it
- //smaller than that even if the modtype doesn't support that many orders.
- if(specs.ordersMax < GetCount())
- {
- resize(max(MAX_ORDERS, specs.ordersMax));
- for(ORDERINDEX i = GetCount(); i>specs.ordersMax; --i) (*this)[i-1] = GetInvalidPatIndex();
- }
- if (GetCount() < MAX_ORDERS)
- resize(MAX_ORDERS, GetInvalidPatIndex());
-
- //Replace items used to denote end of song/skip order.
- replace(begin(), end(), GetInvalidPatIndex(oldtype), GetInvalidPatIndex());
- replace(begin(), end(), GetIgnoreIndex(oldtype), GetIgnoreIndex());
-}
-
-
-ORDERINDEX COrderToPatternTable::GetLengthTailTrimmed() const
-//-----------------------------------------------------------
-{
- ORDERINDEX nEnd = GetCount();
- if(nEnd == 0) return 0;
- nEnd--;
- const PATTERNINDEX iInvalid = GetInvalidPatIndex();
- while(nEnd > 0 && (*this)[nEnd] == iInvalid)
- nEnd--;
- return ((*this)[nEnd] == iInvalid) ? 0 : nEnd+1;
-}
-
-
-ORDERINDEX COrderToPatternTable::GetLengthFirstEmpty() const
-//----------------------------------------------------------
-{
- const ORDERINDEX nLength = GetCount();
- ORDERINDEX nMax = 0;
- while ((nMax < nLength) && ((*this)[nMax] != (*this).GetInvalidPatIndex())) nMax++;
- return nMax;
-}
-
-
-ORDERINDEX COrderToPatternTable::GetNextOrderIgnoringSkips(const ORDERINDEX start) const
-//-------------------------------------------------------------------------------------
-{
- const ORDERINDEX count = GetCount();
- if(count == 0) return 0;
- ORDERINDEX next = min(count-1, start+1);
- while(next+1 < count && (*this)[next] == GetIgnoreIndex()) next++;
- return next;
-}
-
-ORDERINDEX COrderToPatternTable::GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const
-//-------------------------------------------------------------------------------------
-{
- const ORDERINDEX count = GetCount();
- if(start == 0 || count == 0) return 0;
- ORDERINDEX prev = min(start-1, count-1);
- while(prev > 0 && (*this)[prev] == GetIgnoreIndex()) prev--;
- return prev;
-}
-
-
-void COrderToPatternTable::Init()
-//-------------------------------
-{
- resize(MAX_ORDERS, GetInvalidPatIndex());
- for(ORDERINDEX i = 0; i < GetCount(); i++)
- {
- (*this)[i] = GetInvalidPatIndex();
- }
-}
-
-
-
-PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65535 : 0xFF;}
-PATTERNINDEX COrderToPatternTable::GetIgnoreIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65534 : 0xFE;}
-
-PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex() const {return GetInvalidPatIndex(m_rSndFile.GetType());}
-PATTERNINDEX COrderToPatternTable::GetIgnoreIndex() const {return GetIgnoreIndex(m_rSndFile.GetType());}
-
-
-void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t)
-//--------------------------------------------------------------------------------
-{
- uint16 size;
- srlztn::Binaryread<uint16>(iStrm, size);
- if(size > ModSpecs::mptm.ordersMax)
- {
- // Hack: Show message here if trying to load longer sequence than what is supported.
- CString str; str.Format(str_SequenceTruncationNote, size, ModSpecs::mptm.ordersMax);
- AfxMessageBox(str, MB_ICONWARNING);
- size = ModSpecs::mptm.ordersMax;
- }
- seq.resize(max(size, MAX_ORDERS), seq.GetInvalidPatIndex());
- if(size == 0)
- { seq.Init(); return; }
-
- for(size_t i = 0; i < size; i++)
- {
- uint16 temp;
- srlztn::Binaryread<uint16>(iStrm, temp);
- seq[i] = temp;
- }
-}
-
-
-void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq)
-//-------------------------------------------------------------------------
-{
- uint16 size = seq.GetCount();
- srlztn::Binarywrite<uint16>(oStrm, size);
- const COrderToPatternTable::const_iterator endIter = seq.end();
- for(COrderToPatternTable::const_iterator citer = seq.begin(); citer != endIter; citer++)
- {
- const uint16 temp = static_cast<uint16>(*citer);
- srlztn::Binarywrite<uint16>(oStrm, temp);
- }
-}
-
Deleted: trunk/OpenMPT/soundlib/OrderToPatternTable.h
===================================================================
--- trunk/OpenMPT/soundlib/OrderToPatternTable.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/OrderToPatternTable.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -1,68 +0,0 @@
-#ifndef ORDERTOPATTERNTABLE_H
-#define ORDERTOPATTERNTABLE_H
-
-#include <vector>
-using std::vector;
-
-class CSoundFile;
-
-
-#pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data.
-
-
-//==============================================
-class COrderToPatternTable : public vector<PATTERNINDEX>
-//==============================================
-{
-public:
- COrderToPatternTable(const CSoundFile& sndFile) : m_rSndFile(sndFile) {}
-
- // Initialize default sized sequence.
- void Init();
-
- bool ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength);
-
- size_t WriteAsByte(FILE* f, const UINT count);
-
- size_t WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize);
-
- ORDERINDEX GetCount() const {return size();}
-
- //Deprecated function used for MPTm's created in 1.17.02.46 - 1.17.02.48.
- DWORD Deserialize(const BYTE* const src, const DWORD memLength);
-
- //Returns true if the IT orderlist datafield is not sufficient to store orderlist information.
- bool NeedsExtraDatafield() const;
-
- void OnModTypeChanged(const MODTYPE oldtype);
-
- // Returns length of sequence without counting trailing '---' items.
- ORDERINDEX GetLengthTailTrimmed() const;
-
- // Returns length of sequence stopping counting on first '---' (or at the end of sequence).
- ORDERINDEX GetLengthFirstEmpty() const;
-
- PATTERNINDEX GetInvalidPatIndex() const; //To correspond 0xFF
- static PATTERNINDEX GetInvalidPatIndex(const MODTYPE type);
-
- PATTERNINDEX GetIgnoreIndex() const; //To correspond 0xFE
- static PATTERNINDEX GetIgnoreIndex(const MODTYPE type);
-
- //Returns the previous/next order ignoring skip indeces(+++).
- //If no previous/next order exists, return first/last order, and zero
- //when orderlist is empty.
- ORDERINDEX GetNextOrderIgnoringSkips(const ORDERINDEX start) const;
- ORDERINDEX GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const;
-
-private:
- const CSoundFile& m_rSndFile;
-};
-
-#pragma warning(default:4244) //conversion from 'type1' to 'type2', possible loss of data.
-
-
-void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t nSize = 0);
-void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq);
-
-#endif
-
Added: trunk/OpenMPT/soundlib/Snd_defs.h
===================================================================
--- trunk/OpenMPT/soundlib/Snd_defs.h (rev 0)
+++ trunk/OpenMPT/soundlib/Snd_defs.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -0,0 +1,367 @@
+/*
+ * OpenMPT
+ *
+ * Snd_defs.h
+ *
+ * Authors: Olivier Lapicque <oli...@jp...>
+ * OpenMPT devs
+*/
+
+#ifndef SND_DEF_H
+#define SND_DEF_H
+
+#ifndef LPCBYTE
+typedef const BYTE * LPCBYTE;
+#endif
+
+typedef uint32 ROWINDEX;
+ const ROWINDEX ROWINDEX_MAX = uint32_max;
+typedef uint16 CHANNELINDEX;
+ const CHANNELINDEX CHANNELINDEX_MAX = uint16_max;
+ const CHANNELINDEX CHANNELINDEX_INVALID = CHANNELINDEX_MAX;
+typedef uint16 ORDERINDEX;
+ const ORDERINDEX ORDERINDEX_MAX = uint16_max;
+ const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX;
+typedef uint16 PATTERNINDEX;
+ const PATTERNINDEX PATTERNINDEX_MAX = uint16_max;
+ const PATTERNINDEX PATTERNINDEX_INVALID = PATTERNINDEX_MAX;
+typedef uint8 PLUGINDEX;
+typedef uint16 TEMPO;
+typedef uint16 SAMPLEINDEX;
+ const SAMPLEINDEX SAMPLEINDEX_MAX = uint16_max;
+ const SAMPLEINDEX SAMPLEINDEX_INVALID = SAMPLEINDEX_MAX;
+typedef uint16 INSTRUMENTINDEX;
+ const SAMPLEINDEX INSTRUMENTINDEX_MAX = uint16_max;
+ const SAMPLEINDEX INSTRUMENTINDEX_INVALID = INSTRUMENTINDEX_MAX;
+typedef uint8 SEQUENCEINDEX;
+ const SEQUENCEINDEX SEQUENCEINDEX_MAX = uint8_max;
+ const SEQUENCEINDEX SEQUENCEINDEX_INVALID = SEQUENCEINDEX_MAX;
+typedef uint32 MODTYPE;
+
+#define MAX_PATTERN_ROWS 1024 // -> CODE#0008 -> DESC="#define to set pattern size" -! BEHAVIOUR_CHANGE#0008
+
+
+#define MOD_AMIGAC2 0x1AB
+// -> CODE#0006
+// -> DESC="misc quantity changes"
+#define MAX_SAMPLE_LENGTH 0x10000000 // 0x04000000 (64MB -> now 256MB).
+ // Note: Sample size in bytes can be more than 256 MB.
+// -! BEHAVIOUR_CHANGE#0006
+#define MAX_SAMPLE_RATE 100000
+#define MAX_ORDERS 256
+const SEQUENCEINDEX MAX_SEQUENCES = 10;
+#define MAX_PATTERNS 240
+#define MAX_SAMPLES 4000
+
+#define MAX_INSTRUMENTS 256 //200 // -> CODE#0006 -> DESC="misc quantity changes" // -! BEHAVIOUR_CHANGE#0006
+//#ifdef FASTSOUNDLIB
+//#define MAX_CHANNELS 80
+//#else
+// -> CODE#0006
+// -> DESC="misc quantity changes"
+#define MAX_CHANNELS 256 //200 // Note: This is the maximum number of sound channels,
+ // see MAX_BASECHANNELS for max pattern channels.
+// -! BEHAVIOUR_CHANGE#0006
+//#endif
+// -> CODE#0006
+// -> DESC="misc quantity changes"
+//#ifdef FASTSOUNDLIB
+//#define MAX_BASECHANNELS 64
+//#else
+#define MAX_BASECHANNELS 127 // Max pattern channels.
+//#endif
+// -! BEHAVIOUR_CHANGE#0006
+#define MAX_ENVPOINTS 32
+#define MIN_PERIOD 0x0020
+#define MAX_PERIOD 0xFFFF
+#define MAX_PATTERNNAME 32
+#define MAX_CHANNELNAME 20
+#define MAX_INFONAME 80
+#define MAX_EQ_BANDS 6
+
+#define MAX_MIXPLUGINS 100 //50 // -> CODE#0006 -> DESC="misc quantity changes" -! BEHAVIOUR_CHANGE#0006
+#define MAX_PLUGPRESETS 1000 //rewbs.plugPresets
+
+#define MOD_TYPE_NONE 0x00
+#define MOD_TYPE_MOD 0x01
+#define MOD_TYPE_S3M 0x02
+#define MOD_TYPE_XM 0x04
+#define MOD_TYPE_MED 0x08
+#define MOD_TYPE_MTM 0x10
+#define MOD_TYPE_IT 0x20
+#define MOD_TYPE_669 0x40
+#define MOD_TYPE_ULT 0x80
+#define MOD_TYPE_STM 0x100
+#define MOD_TYPE_FAR 0x200
+#define MOD_TYPE_WAV 0x400
+#define MOD_TYPE_AMF 0x800
+#define MOD_TYPE_AMS 0x1000
+#define MOD_TYPE_DSM 0x2000
+#define MOD_TYPE_MDL 0x4000
+#define MOD_TYPE_OKT 0x8000
+#define MOD_TYPE_MID 0x10000
+#define MOD_TYPE_DMF 0x20000
+#define MOD_TYPE_PTM 0x40000
+#define MOD_TYPE_DBM 0x80000
+#define MOD_TYPE_MT2 0x100000
+#define MOD_TYPE_AMF0 0x200000
+#define MOD_TYPE_PSM 0x400000
+#define MOD_TYPE_J2B 0x800000
+#define MOD_TYPE_MPT 0x1000000
+#define MOD_TYPE_UMX 0x80000000 // Fake type
+#define MAX_MODTYPE 24
+
+// For compatibility mode
+#define TRK_IMPULSETRACKER MOD_TYPE_IT | MOD_TYPE_MPT
+#define TRK_FASTTRACKER2 MOD_TYPE_XM
+#define TRK_SCREAMTRACKER MOD_TYPE_S3M
+#define TRK_PROTRACKER MOD_TYPE_MOD
+#define TRK_ALLTRACKERS TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER | TRK_PROTRACKER
+
+
+
+// Channel flags:
+// Bits 0-7: Sample Flags
+#define CHN_16BIT 0x01
+#define CHN_LOOP 0x02
+#define CHN_PINGPONGLOOP 0x04
+#define CHN_SUSTAINLOOP 0x08
+#define CHN_PINGPONGSUSTAIN 0x10
+#define CHN_PANNING 0x20
+#define CHN_STEREO 0x40
+#define CHN_PINGPONGFLAG 0x80 //When flag is on, bidiloop is processed backwards?
+// Bits 8-31: Channel Flags
+#define CHN_MUTE 0x100
+#define CHN_KEYOFF 0x200
+#define CHN_NOTEFADE 0x400
+#define CHN_SURROUND 0x800
+#define CHN_NOIDO 0x1000
+#define CHN_HQSRC 0x2000
+#define CHN_FILTER 0x4000
+#define CHN_VOLUMERAMP 0x8000
+#define CHN_VIBRATO 0x10000
+#define CHN_TREMOLO 0x20000
+#define CHN_PANBRELLO 0x40000
+#define CHN_PORTAMENTO 0x80000
+#define CHN_GLISSANDO 0x100000
+#define CHN_VOLENV 0x200000
+#define CHN_PANENV 0x400000
+#define CHN_PITCHENV 0x800000
+#define CHN_FASTVOLRAMP 0x1000000
+#define CHN_EXTRALOUD 0x2000000
+#define CHN_REVERB 0x4000000
+#define CHN_NOREVERB 0x8000000
+#define CHN_SOLO 0x10000000 // -> CODE#0012 -> DESC="midi keyboard split" -! NEW_FEATURE#0012
+#define CHN_NOFX 0x20000000 // -> CODE#0015 -> DESC="channels management dlg" -! NEW_FEATURE#0015
+#define CHN_SYNCMUTE 0x40000000
+
+#define ENV_VOLUME 0x0001
+#define ENV_VOLSUSTAIN 0x0002
+#define ENV_VOLLOOP 0x0004
+#define ENV_PANNING 0x0008
+#define ENV_PANSUSTAIN 0x0010
+#define ENV_PANLOOP 0x0020
+#define ENV_PITCH 0x0040
+#define ENV_PITCHSUSTAIN 0x0080
+#define ENV_PITCHLOOP 0x0100
+#define ENV_SETPANNING 0x0200
+#define ENV_FILTER 0x0400
+#define ENV_VOLCARRY 0x0800
+#define ENV_PANCARRY 0x1000
+#define ENV_PITCHCARRY 0x2000
+#define ENV_MUTE 0x4000
+
+
+// Filter Modes
+#define FLTMODE_UNCHANGED 0xFF
+#define FLTMODE_LOWPASS 0
+#define FLTMODE_HIGHPASS 1
+#define FLTMODE_BANDPASS 2
+
+
+#define RSF_16BIT 0x04
+#define RSF_STEREO 0x08
+
+#define RS_PCM8S 0 // 8-bit signed
+#define RS_PCM8U 1 // 8-bit unsigned
+#define RS_PCM8D 2 // 8-bit delta values
+#define RS_ADPCM4 3 // 4-bit ADPCM-packed
+#define RS_PCM16D 4 // 16-bit delta values
+#define RS_PCM16S 5 // 16-bit signed
+#define RS_PCM16U 6 // 16-bit unsigned
+#define RS_PCM16M 7 // 16-bit motorola order
+#define RS_STPCM8S (RS_PCM8S|RSF_STEREO) // stereo 8-bit signed
+#define RS_STPCM8U (RS_PCM8U|RSF_STEREO) // stereo 8-bit unsigned
+#define RS_STPCM8D (RS_PCM8D|RSF_STEREO) // stereo 8-bit delta values
+#define RS_STPCM16S (RS_PCM16S|RSF_STEREO) // stereo 16-bit signed
+#define RS_STPCM16U (RS_PCM16U|RSF_STEREO) // stereo 16-bit unsigned
+#define RS_STPCM16D (RS_PCM16D|RSF_STEREO) // stereo 16-bit delta values
+#define RS_STPCM16M (RS_PCM16M|RSF_STEREO) // stereo 16-bit signed big endian
+// IT 2.14 compressed samples
+#define RS_IT2148 0x10
+#define RS_IT21416 0x14
+#define RS_IT2158 0x12
+#define RS_IT21516 0x16
+// AMS Packed Samples
+#define RS_AMS8 0x11
+#define RS_AMS16 0x15
+// DMF Huffman compression
+#define RS_DMF8 0x13
+#define RS_DMF16 0x17
+// MDL Huffman compression
+#define RS_MDL8 0x20
+#define RS_MDL16 0x24
+#define RS_PTM8DTO16 0x25
+// Stereo Interleaved Samples
+#define RS_STIPCM8S (RS_PCM8S|0x40|RSF_STEREO) // stereo 8-bit signed
+#define RS_STIPCM8U (RS_PCM8U|0x40|RSF_STEREO) // stereo 8-bit unsigned
+#define RS_STIPCM16S (RS_PCM16S|0x40|RSF_STEREO) // stereo 16-bit signed
+#define RS_STIPCM16U (RS_PCM16U|0x40|RSF_STEREO) // stereo 16-bit unsigned
+#define RS_STIPCM16M (RS_PCM16M|0x40|RSF_STEREO) // stereo 16-bit signed big endian
+// 24-bit signed
+#define RS_PCM24S (RS_PCM16S|0x80) // mono 24-bit signed
+#define RS_STIPCM24S (RS_PCM16S|0x80|RSF_STEREO) // stereo 24-bit signed
+// 32-bit
+#define RS_PCM32S (RS_PCM16S|0xC0) // mono 32-bit signed
+#define RS_STIPCM32S (RS_PCM16S|0xC0|RSF_STEREO) // stereo 32-bit signed
+
+
+
+// NNA types (New Note Action)
+#define NNA_NOTECUT 0
+#define NNA_CONTINUE 1
+#define NNA_NOTEOFF 2
+#define NNA_NOTEFADE 3
+
+// DCT types (Duplicate Check Types)
+#define DCT_NONE 0
+#define DCT_NOTE 1
+#define DCT_SAMPLE 2
+#define DCT_INSTRUMENT 3
+#define DCT_PLUGIN 4 //rewbs.VSTiNNA
+
+// DNA types (Duplicate Note Action)
+#define DNA_NOTECUT 0
+#define DNA_NOTEOFF 1
+#define DNA_NOTEFADE 2
+
+// Mixer Hardware-Dependent features
+#define SYSMIX_ENABLEMMX 0x01
+#define SYSMIX_SLOWCPU 0x02
+#define SYSMIX_FASTCPU 0x04
+#define SYSMIX_MMXEX 0x08
+#define SYSMIX_3DNOW 0x10
+#define SYSMIX_SSE 0x20
+
+// Module flags
+#define SONG_EMBEDMIDICFG 0x0001
+#define SONG_FASTVOLSLIDES 0x0002
+#define SONG_ITOLDEFFECTS 0x0004
+#define SONG_ITCOMPATMODE 0x0008
+#define SONG_LINEARSLIDES 0x0010
+#define SONG_PATTERNLOOP 0x0020
+#define SONG_STEP 0x0040
+#define SONG_PAUSED 0x0080
+#define SONG_FADINGSONG 0x0100
+#define SONG_ENDREACHED 0x0200
+#define SONG_GLOBALFADE 0x0400
+#define SONG_CPUVERYHIGH 0x0800
+#define SONG_FIRSTTICK 0x1000
+#define SONG_MPTFILTERMODE 0x2000
+#define SONG_SURROUNDPAN 0x4000
+#define SONG_EXFILTERRANGE 0x8000
+#define SONG_AMIGALIMITS 0x10000
+// -> CODE#0023
+// -> DESC="IT project files (.itp)"
+#define SONG_ITPROJECT 0x20000
+#define SONG_ITPEMBEDIH 0x40000
+// -! NEW_FEATURE#0023
+#define SONG_BREAKTOROW 0x80000
+#define SONG_POSJUMP 0x100000
+
+// Global Options (Renderer)
+#define SNDMIX_REVERSESTEREO 0x0001
+#define SNDMIX_NOISEREDUCTION 0x0002
+#define SNDMIX_AGC 0x0004
+#define SNDMIX_NORESAMPLING 0x0008
+// SNDMIX_NOLINEARSRCMODE is the default
+//#define SNDMIX_HQRESAMPLER 0x0010 //rewbs.resamplerConf: renamed SNDMIX_HQRESAMPLER to SNDMIX_SPLINESRCMODE
+#define SNDMIX_SPLINESRCMODE 0x0010
+#define SNDMIX_MEGABASS 0x0020
+#define SNDMIX_SURROUND 0x0040
+#define SNDMIX_REVERB 0x0080
+#define SNDMIX_EQ 0x0100
+#define SNDMIX_SOFTPANNING 0x0200
+//#define SNDMIX_ULTRAHQSRCMODE 0x0400 //rewbs.resamplerConf: renamed SNDMIX_ULTRAHQSRCMODE to SNDMIX_POLYPHASESRCMODE
+#define SNDMIX_POLYPHASESRCMODE 0x0400
+#define SNDMIX_FIRFILTERSRCMODE 0x0800 //rewbs: added SNDMIX_FIRFILTERSRCMODE
+
+//rewbs.resamplerConf: for stuff that applies to cubic spline, polyphase and FIR
+#define SNDMIX_HQRESAMPLER (SNDMIX_SPLINESRCMODE|SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE)
+
+////rewbs.resamplerConf: for stuff that applies to polyphase and FIR
+#define SNDMIX_ULTRAHQSRCMODE (SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE)
+
+// Misc Flags (can safely be turned on or off)
+#define SNDMIX_DIRECTTODISK 0x10000
+#define SNDMIX_ENABLEMMX 0x20000
+#define SNDMIX_NOBACKWARDJUMPS 0x40000
+#define SNDMIX_MAXDEFAULTPAN 0x80000 // Used by the MOD loader
+#define SNDMIX_MUTECHNMODE 0x100000 // Notes are not played on muted channels
+#define SNDMIX_EMULATE_MIX_BUGS 0x200000 // rewbs.emulateMixBugs
+
+#define MAX_GLOBAL_VOLUME 256
+
+// Resampling modes
+enum {
+ SRCMODE_NEAREST,
+ SRCMODE_LINEAR,
+ SRCMODE_SPLINE,
+ SRCMODE_POLYPHASE,
+ SRCMODE_FIRFILTER, //rewbs.resamplerConf
+ SRCMODE_DEFAULT,
+ NUM_SRC_MODES
+};
+
+enum {
+ ENV_RESET_ALL,
+ ENV_RESET_VOL,
+ ENV_RESET_PAN,
+ ENV_RESET_PITCH,
+ ENV_RELEASE_NODE_UNSET=0xFF,
+ NOT_YET_RELEASED=-1
+};
+
+enum {
+ CHANNEL_ONLY = 0,
+ INSTRUMENT_ONLY = 1,
+ PRIORITISE_INSTRUMENT = 2,
+ PRIORITISE_CHANNEL = 3,
+ EVEN_IF_MUTED = false,
+ RESPECT_MUTES = true,
+};
+
+//Plugin velocity handling options
+enum PLUGVELOCITYHANDLING
+{
+ PLUGIN_VELOCITYHANDLING_CHANNEL = 0,
+ PLUGIN_VELOCITYHANDLING_VOLUME
+};
+
+//Plugin volumecommand handling options
+enum PLUGVOLUMEHANDLING
+{
+ PLUGIN_VOLUMEHANDLING_MIDI = 0,
+ PLUGIN_VOLUMEHANDLING_DRYWET,
+ PLUGIN_VOLUMEHANDLING_IGNORE,
+};
+
+// filtermodes
+/*enum {
+ INST_FILTERMODE_DEFAULT=0,
+ INST_FILTERMODE_HIGHPASS,
+ INST_FILTERMODE_LOWPASS,
+ INST_NUMFILTERMODES
+};*/
+
+#endif
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -7,364 +7,21 @@
* OpenMPT devs
*/
+#ifndef __SNDFILE_H
+#define __SNDFILE_H
+
#include "../mptrack/SoundFilePlayConfig.h"
#include "../mptrack/misc_util.h"
#include "mod_specifications.h"
#include <vector>
#include <bitset>
#include "midi.h"
+#include "Snd_defs.h"
class CTuningBase;
typedef CTuningBase CTuning;
-using std::bitset;
-#ifndef __SNDFILE_H
-#define __SNDFILE_H
-
-#ifndef LPCBYTE
-typedef const BYTE * LPCBYTE;
-#endif
-
-// -> CODE#0008
-// -> DESC="#define to set pattern size"
-#define MAX_PATTERN_ROWS 1024
-// -! BEHAVIOUR_CHANGE#0008
-
-#define MOD_AMIGAC2 0x1AB
-// -> CODE#0006
-// -> DESC="misc quantity changes"
-#define MAX_SAMPLE_LENGTH 0x10000000 // 0x04000000 (64MB -> now 256MB).
- // Note: Sample size in bytes can be more than 256 MB.
-// -! BEHAVIOUR_CHANGE#0006
-#define MAX_SAMPLE_RATE 100000
-#define MAX_ORDERS 256
-#define MAX_PATTERNS 240
-#define MAX_SAMPLES 4000
-// -> CODE#0006
-// -> DESC="misc quantity changes"
-#define MAX_INSTRUMENTS 256 //200
-// -! BEHAVIOUR_CHANGE#0006
-//#ifdef FASTSOUNDLIB
-//#define MAX_CHANNELS 80
-//#else
-// -> CODE#0006
-// -> DESC="misc quantity changes"
-#define MAX_CHANNELS 256 //200 //Note: This is the maximum number of sound channels,
- // see MAX_BASECHANNELS for max pattern channels.
-// -! BEHAVIOUR_CHANGE#0006
-//#endif
-// -> CODE#0006
-// -> DESC="misc quantity changes"
-//#ifdef FASTSOUNDLIB
-//#define MAX_BASECHANNELS 64
-//#else
-#define MAX_BASECHANNELS 127 //Max pattern channels.
-//#endif
-// -! BEHAVIOUR_CHANGE#0006
-#define MAX_ENVPOINTS 32
-#define MIN_PERIOD 0x0020
-#define MAX_PERIOD 0xFFFF
-#define MAX_PATTERNNAME 32
-#define MAX_CHANNELNAME 20
-#define MAX_INFONAME 80
-#define MAX_EQ_BANDS 6
-// -> CODE#0006
-// -> DESC="misc quantity changes"
-#define MAX_MIXPLUGINS 100 //50
-// -! BEHAVIOUR_CHANGE#0006
-#define MAX_PLUGPRESETS 1000 //rewbs.plugPresets
-
-#define MOD_TYPE_NONE 0x00
-#define MOD_TYPE_MOD 0x01
-#define MOD_TYPE_S3M 0x02
-#define MOD_TYPE_XM 0x04
-#define MOD_TYPE_MED 0x08
-#define MOD_TYPE_MTM 0x10
-#define MOD_TYPE_IT 0x20
-#define MOD_TYPE_669 0x40
-#define MOD_TYPE_ULT 0x80
-#define MOD_TYPE_STM 0x100
-#define MOD_TYPE_FAR 0x200
-#define MOD_TYPE_WAV 0x400
-#define MOD_TYPE_AMF 0x800
-#define MOD_TYPE_AMS 0x1000
-#define MOD_TYPE_DSM 0x2000
-#define MOD_TYPE_MDL 0x4000
-#define MOD_TYPE_OKT 0x8000
-#define MOD_TYPE_MID 0x10000
-#define MOD_TYPE_DMF 0x20000
-#define MOD_TYPE_PTM 0x40000
-#define MOD_TYPE_DBM 0x80000
-#define MOD_TYPE_MT2 0x100000
-#define MOD_TYPE_AMF0 0x200000
-#define MOD_TYPE_PSM 0x400000
-#define MOD_TYPE_J2B 0x800000
-#define MOD_TYPE_MPT 0x1000000
-#define MOD_TYPE_UMX 0x80000000 // Fake type
-#define MAX_MODTYPE 24
-
-// For compatibility mode
-#define TRK_IMPULSETRACKER MOD_TYPE_IT | MOD_TYPE_MPT
-#define TRK_FASTTRACKER2 MOD_TYPE_XM
-#define TRK_SCREAMTRACKER MOD_TYPE_S3M
-#define TRK_PROTRACKER MOD_TYPE_MOD
-#define TRK_ALLTRACKERS TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER | TRK_PROTRACKER
-
-
-
-// Channel flags:
-// Bits 0-7: Sample Flags
-#define CHN_16BIT 0x01
-#define CHN_LOOP 0x02
-#define CHN_PINGPONGLOOP 0x04
-#define CHN_SUSTAINLOOP 0x08
-#define CHN_PINGPONGSUSTAIN 0x10
-#define CHN_PANNING 0x20
-#define CHN_STEREO 0x40
-#define CHN_PINGPONGFLAG 0x80 //When flag is on, bidiloop is processed backwards?
-// Bits 8-31: Channel Flags
-#define CHN_MUTE 0x100
-#define CHN_KEYOFF 0x200
-#define CHN_NOTEFADE 0x400
-#define CHN_SURROUND 0x800
-#define CHN_NOIDO 0x1000
-#define CHN_HQSRC 0x2000
-#define CHN_FILTER 0x4000
-#define CHN_VOLUMERAMP 0x8000
-#define CHN_VIBRATO 0x10000
-#define CHN_TREMOLO 0x20000
-#define CHN_PANBRELLO 0x40000
-#define CHN_PORTAMENTO 0x80000
-#define CHN_GLISSANDO 0x100000
-#define CHN_VOLENV 0x200000
-#define CHN_PANENV 0x400000
-#define CHN_PITCHENV 0x800000
-#define CHN_FASTVOLRAMP 0x1000000
-#define CHN_EXTRALOUD 0x2000000
-#define CHN_REVERB 0x4000000
-#define CHN_NOREVERB 0x8000000
-// -> CODE#0012
-// -> DESC="midi keyboard split"
-#define CHN_SOLO 0x10000000
-// -! NEW_FEATURE#0012
-
-// -> CODE#0015
-// -> DESC="channels management dlg"
-#define CHN_NOFX 0x20000000
-// -! NEW_FEATURE#0015
-
-#define CHN_SYNCMUTE 0x40000000
-
-#define ENV_VOLUME 0x0001
-#define ENV_VOLSUSTAIN 0x0002
-#define ENV_VOLLOOP 0x0004
-#define ENV_PANNING 0x0008
-#define ENV_PANSUSTAIN 0x0010
-#define ENV_PANLOOP 0x0020
-#define ENV_PITCH 0x0040
-#define ENV_PITCHSUSTAIN 0x0080
-#define ENV_PITCHLOOP 0x0100
-#define ENV_SETPANNING 0x0200
-#define ENV_FILTER 0x0400
-#define ENV_VOLCARRY 0x0800
-#define ENV_PANCARRY 0x1000
-#define ENV_PITCHCARRY 0x2000
-#define ENV_MUTE 0x4000
-
-
-// Filter Modes
-#define FLTMODE_UNCHANGED 0xFF
-#define FLTMODE_LOWPASS 0
-#define FLTMODE_HIGHPASS 1
-#define FLTMODE_BANDPASS 2
-
-
-#define RSF_16BIT 0x04
-#define RSF_STEREO 0x08
-
-#define RS_PCM8S 0 // 8-bit signed
-#define RS_PCM8U 1 // 8-bit unsigned
-#define RS_PCM8D 2 // 8-bit delta values
-#define RS_ADPCM4 3 // 4-bit ADPCM-packed
-#define RS_PCM16D 4 // 16-bit delta values
-#define RS_PCM16S 5 // 16-bit signed
-#define RS_PCM16U 6 // 16-bit unsigned
-#define RS_PCM16M 7 // 16-bit motorola order
-#define RS_STPCM8S (RS_PCM8S|RSF_STEREO) // stereo 8-bit signed
-#define RS_STPCM8U (RS_PCM8U|RSF_STEREO) // stereo 8-bit unsigned
-#define RS_STPCM8D (RS_PCM8D|RSF_STEREO) // stereo 8-bit delta values
-#define RS_STPCM16S (RS_PCM16S|RSF_STEREO) // stereo 16-bit signed
-#define RS_STPCM16U (RS_PCM16U|RSF_STEREO) // stereo 16-bit unsigned
-#define RS_STPCM16D (RS_PCM16D|RSF_STEREO) // stereo 16-bit delta values
-#define RS_STPCM16M (RS_PCM16M|RSF_STEREO) // stereo 16-bit signed big endian
-// IT 2.14 compressed samples
-#define RS_IT2148 0x10
-#define RS_IT21416 0x14
-#define RS_IT2158 0x12
-#define RS_IT21516 0x16
-// AMS Packed Samples
-#define RS_AMS8 0x11
-#define RS_AMS16 0x15
-// DMF Huffman compression
-#define RS_DMF8 0x13
-#define RS_DMF16 0x17
-// MDL Huffman compression
-#define RS_MDL8 0x20
-#define RS_MDL16 0x24
-#define RS_PTM8DTO16 0x25
-// Stereo Interleaved Samples
-#define RS_STIPCM8S (RS_PCM8S|0x40|RSF_STEREO) // stereo 8-bit signed
-#define RS_STIPCM8U (RS_PCM8U|0x40|RSF_STEREO) // stereo 8-bit unsigned
-#define RS_STIPCM16S (RS_PCM16S|0x40|RSF_STEREO) // stereo 16-bit signed
-#define RS_STIPCM16U (RS_PCM16U|0x40|RSF_STEREO) // stereo 16-bit unsigned
-#define RS_STIPCM16M (RS_PCM16M|0x40|RSF_STEREO) // stereo 16-bit signed big endian
-// 24-bit signed
-#define RS_PCM24S (RS_PCM16S|0x80) // mono 24-bit signed
-#define RS_STIPCM24S (RS_PCM16S|0x80|RSF_STEREO) // stereo 24-bit signed
-// 32-bit
-#define RS_PCM32S (RS_PCM16S|0xC0) // mono 32-bit signed
-#define RS_STIPCM32S (RS_PCM16S|0xC0|RSF_STEREO) // stereo 32-bit signed
-
-
-
-// NNA types (New Note Action)
-#define NNA_NOTECUT 0
-#define NNA_CONTINUE 1
-#define NNA_NOTEOFF 2
-#define NNA_NOTEFADE 3
-
-// DCT types (Duplicate Check Types)
-#define DCT_NONE 0
-#define DCT_NOTE 1
-#define DCT_SAMPLE 2
-#define DCT_INSTRUMENT 3
-#define DCT_PLUGIN 4 //rewbs.VSTiNNA
-
-// DNA types (Duplicate Note Action)
-#define DNA_NOTECUT 0
-#define DNA_NOTEOFF 1
-#define DNA_NOTEFADE 2
-
-// Mixer Hardware-Dependent features
-#define SYSMIX_ENABLEMMX 0x01
-#define SYSMIX_SLOWCPU 0x02
-#define SYSMIX_FASTCPU 0x04
-#define SYSMIX_MMXEX 0x08
-#define SYSMIX_3DNOW 0x10
-#define SYSMIX_SSE 0x20
-
-// Module flags
-#define SONG_EMBEDMIDICFG 0x0001
-#define SONG_FASTVOLSLIDES 0x0002
-#define SONG_ITOLDEFFECTS 0x0004
-#define SONG_ITCOMPATMODE 0x0008
-#define SONG_LINEARSLIDES 0x0010
-#define SONG_PATTERNLOOP 0x0020
-#define SONG_STEP 0x0040
-#define SONG_PAUSED 0x0080
-#define SONG_FADINGSONG 0x0100
-#define SONG_ENDREACHED 0x0200
-#define SONG_GLOBALFADE 0x0400
-#define SONG_CPUVERYHIGH 0x0800
-#define SONG_FIRSTTICK 0x1000
-#define SONG_MPTFILTERMODE 0x2000
-#define SONG_SURROUNDPAN 0x4000
-#define SONG_EXFILTERRANGE 0x8000
-#define SONG_AMIGALIMITS 0x10000
-// -> CODE#0023
-// -> DESC="IT project files (.itp)"
-#define SONG_ITPROJECT 0x20000
-#define SONG_ITPEMBEDIH 0x40000
-// -! NEW_FEATURE#0023
-#define SONG_BREAKTOROW 0x80000
-#define SONG_POSJUMP 0x100000
-
-// Global Options (Renderer)
-#define SNDMIX_REVERSESTEREO 0x0001
-#define SNDMIX_NOISEREDUCTION 0x0002
-#define SNDMIX_AGC 0x0004
-#define SNDMIX_NORESAMPLING 0x0008
-// SNDMIX_NOLINEARSRCMODE is the default
-//#define SNDMIX_HQRESAMPLER 0x0010 //rewbs.resamplerConf: renamed SNDMIX_HQRESAMPLER to SNDMIX_SPLINESRCMODE
-#define SNDMIX_SPLINESRCMODE 0x0010
-#define SNDMIX_MEGABASS 0x0020
-#define SNDMIX_SURROUND 0x0040
-#define SNDMIX_REVERB 0x0080
-#define SNDMIX_EQ 0x0100
-#define SNDMIX_SOFTPANNING 0x0200
-//#define SNDMIX_ULTRAHQSRCMODE 0x0400 //rewbs.resamplerConf: renamed SNDMIX_ULTRAHQSRCMODE to SNDMIX_POLYPHASESRCMODE
-#define SNDMIX_POLYPHASESRCMODE 0x0400
-#define SNDMIX_FIRFILTERSRCMODE 0x0800 //rewbs: added SNDMIX_FIRFILTERSRCMODE
-
-//rewbs.resamplerConf: for stuff that applies to cubic spline, polyphase and FIR
-#define SNDMIX_HQRESAMPLER (SNDMIX_SPLINESRCMODE|SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE)
-
-////rewbs.resamplerConf: for stuff that applies to polyphase and FIR
-#define SNDMIX_ULTRAHQSRCMODE (SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE)
-
-// Misc Flags (can safely be turned on or off)
-#define SNDMIX_DIRECTTODISK 0x10000
-#define SNDMIX_ENABLEMMX 0x20000
-#define SNDMIX_NOBACKWARDJUMPS 0x40000
-#define SNDMIX_MAXDEFAULTPAN 0x80000 // Used by the MOD loader
-#define SNDMIX_MUTECHNMODE 0x100000 // Notes are not played on muted channels
-#define SNDMIX_EMULATE_MIX_BUGS 0x200000 // rewbs.emulateMixBugs
-
-#define MAX_GLOBAL_VOLUME 256
-
-// Resampling modes
-enum {
- SRCMODE_NEAREST,
- SRCMODE_LINEAR,
- SRCMODE_SPLINE,
- SRCMODE_POLYPHASE,
- SRCMODE_FIRFILTER, //rewbs.resamplerConf
- SRCMODE_DEFAULT,
- NUM_SRC_MODES
-};
-
-enum {
- ENV_RESET_ALL,
- ENV_RESET_VOL,
- ENV_RESET_PAN,
- ENV_RESET_PITCH,
- ENV_RELEASE_NODE_UNSET=0xFF,
- NOT_YET_RELEASED=-1
-};
-
-enum {
- CHANNEL_ONLY = 0,
- INSTRUMENT_ONLY = 1,
- PRIORITISE_INSTRUMENT = 2,
- PRIORITISE_CHANNEL = 3,
- EVEN_IF_MUTED = false,
- RESPECT_MUTES = true,
-};
-
-//Plugin velocity handling options
-enum PLUGVELOCITYHANDLING
-{
- PLUGIN_VELOCITYHANDLING_CHANNEL = 0,
- PLUGIN_VELOCITYHANDLING_VOLUME
-};
-
-//Plugin volumecommand handling options
-enum PLUGVOLUMEHANDLING
-{
- PLUGIN_VOLUMEHANDLING_MIDI = 0,
- PLUGIN_VOLUMEHANDLING_DRYWET,
- PLUGIN_VOLUMEHANDLING_IGNORE,
-};
-
-// filtermodes
-/*enum {
- INST_FILTERMODE_DEFAULT=0,
- INST_FILTERMODE_HIGHPASS,
- INST_FILTERMODE_LOWPASS,
- INST_NUMFILTERMODES
-};*/
-
// Sample Struct
struct MODSAMPLE
{
@@ -774,12 +431,11 @@
#include "pattern.h"
#include "patternContainer.h"
-#include "ordertopatterntable.h"
+#include "ModSequence.h"
+#include "PlaybackEventer.h"
-#include "playbackEventer.h"
-
class CSoundFile;
//======================
@@ -1022,10 +678,7 @@
bool ReadSTM(LPCBYTE lpStream, DWORD dwMemLength);
bool ReadIT(LPCBYTE lpStream, const DWORD dwMemLength);
//bool ReadMPT(LPCBYTE lpStream, const DWORD dwMemLength);
-// -> CODE#0023
-// -> DESC="IT project files (.itp)"
- bool ReadITProject(LPCBYTE lpStream, const DWORD dwMemLength);
-// -! NEW_FEATURE#0023
+ bool ReadITProject(LPCBYTE lpStream, const DWORD dwMemLength); // -> CODE#0023 -> DESC="IT project files (.itp)" -! NEW_FEATURE#0023
bool Read669(LPCBYTE lpStream, DWORD dwMemLength);
bool ReadUlt(LPCBYTE lpStream, DWORD dwMemLength);
bool ReadWav(LPCBYTE lpStream, DWORD dwMemLength);
@@ -1055,10 +708,7 @@
bool SaveMod(LPCSTR lpszFileName, UINT nPacking=0, const bool bCompatibilityExport = false);
bool SaveIT(LPCSTR lpszFileName, UINT nPacking=0);
bool SaveCompatIT(LPCSTR lpszFileName);
-// -> CODE#0023
-// -> DESC="IT project files (.itp)"
- bool SaveITProject(LPCSTR lpszFileName);
-// -! NEW_FEATURE#0023
+ bool SaveITProject(LPCSTR lpszFileName); // -> CODE#0023 -> DESC="IT project files (.itp)" -! NEW_FEATURE#0023
UINT SaveMixPlugins(FILE *f=NULL, BOOL bUpdate=TRUE);
void WriteInstrumentPropertyForAllInstruments(__int32 code, __int16 size, FILE* f, MODINSTRUMENT* instruments[], UINT nInstruments);
void SaveExtendedInstrumentProperties(MODINSTRUMENT *instruments[], UINT nInstruments, FILE* f);
Modified: trunk/OpenMPT/soundlib/mod_specifications.h
===================================================================
--- trunk/OpenMPT/soundlib/mod_specifications.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -1,6 +1,7 @@
#ifndef MOD_SPECIFICATIONS_H
#define MOD_SPECIFICATIONS_H
+#include "Snd_defs.h"
#include "modcommand.h" //
#include "../mptrack/SoundFilePlayConfig.h" // mixlevel constants.
Modified: trunk/OpenMPT/soundlib/pattern.h
===================================================================
--- trunk/OpenMPT/soundlib/pattern.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/pattern.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -3,6 +3,7 @@
#include <vector>
#include "modcommand.h"
+#include "Snd_defs.h"
using std::vector;
Modified: trunk/OpenMPT/soundlib/patternContainer.h
===================================================================
--- trunk/OpenMPT/soundlib/patternContainer.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/patternContainer.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -2,6 +2,7 @@
#define PATTERNCONTAINER_H
#include "pattern.h"
+#include "Snd_defs.h"
class CSoundFile;
typedef CPattern MODPATTERN;
@@ -25,7 +26,7 @@
//BEGIN: INTERFACE METHODS
public:
- CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) {m_Patterns.assign(240, MODPATTERN(*this));}
+ CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) {m_Patterns.assign(MAX_PATTERNS, MODPATTERN(*this));}
// Clears existing patterns and resizes array to default size.
void Init();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-30 22:27:26
|
Revision: 350
http://modplug.svn.sourceforge.net/modplug/?rev=350&view=rev
Author: saga-games
Date: 2009-08-30 22:27:15 +0000 (Sun, 30 Aug 2009)
Log Message:
-----------
[Fix] S3M Loader: Small modifications to pattern loader to load somewhat broken S3M files
[Fix] S3M Loader: Don't reset global volume to max if it is min for "new" modules
[Fix] S3M Loader: Smarter Zxx conversion
[Fix] S3M Saver: Was completely broken for a reason that's beyond my understanding :) (order size only has to be multiple of 2, not 16!)
[Imp] Mod Conversion: Convert 500/600 commands properly from MOD to any format, Adjust sustain loops for XM files, removed XM arpeggio conversion (it might be unwanted)
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/soundlib/Load_s3m.cpp
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-30 14:29:58 UTC (rev 349)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-30 22:27:15 UTC (rev 350)
@@ -396,15 +396,22 @@
} // End if (oldTypeIsIT_MPT && newTypeIsS3M)
- ////////////////////////
- // Convert XM arpeggio
- if(m->command == CMD_ARPEGGIO && (newTypeIsXM || oldTypeIsXM))
+
+ ///////////////////////////////////////////////////
+ // Convert MOD to anything - adjust effect memory
+ if (oldTypeIsMOD)
{
- // swap notes
- m->param = ((m->param & 0x0F) << 4) | ((m->param & 0xF0) >> 4);
- }
+ switch(m->command)
+ {
+ case CMD_TONEPORTAVOL: // lacks memory -> 500 is the same as 300
+ if(m->param == 0x00) m->command = CMD_TONEPORTAMENTO;
+ break;
+ case CMD_VIBRATOVOL: // lacks memory -> 600 is the same as 400
+ if(m->param == 0x00) m->command = CMD_VIBRATO;
+ break;
+ }
+ } // End if (oldTypeIsMOD && newTypeIsXM)
-
/////////////////////////////////////////////////////////////////////////////////
// Convert anything to MOD - remove volume column, adjust retrig, effect memory
if (newTypeIsMOD)
@@ -664,26 +671,38 @@
CSoundFile::FrequencyToTranspose(&m_SndFile.Samples[i]);
if (!(m_SndFile.Samples[i].uFlags & CHN_PANNING)) m_SndFile.Samples[i].nPan = 128;
}
- BOOL bBrokenNoteMap = FALSE;
- for (UINT j=1; j<=m_SndFile.m_nInstruments; j++)
+ bool bBrokenNoteMap = false, bBrokenSustainLoop = false;
+ for (UINT j = 1; j <= m_SndFile.m_nInstruments; j++)
{
MODINSTRUMENT *pIns = m_SndFile.Instruments[j];
if (pIns)
{
- for (UINT k=0; k<NOTE_MAX; k++)
+ for (UINT k = 0; k < NOTE_MAX; k++)
{
if ((pIns->NoteMap[k]) && (pIns->NoteMap[k] != (BYTE)(k+1)))
{
- bBrokenNoteMap = TRUE;
+ bBrokenNoteMap = true;
break;
}
}
+ // Convert sustain loops to sustain "points"
+ if(pIns->VolEnv.nSustainStart != pIns->VolEnv.nSustainEnd)
+ {
+ pIns->VolEnv.nSustainEnd = pIns->VolEnv.nSustainStart;
+ bBrokenSustainLoop = true;
+ }
+ if(pIns->PanEnv.nSustainStart != pIns->PanEnv.nSustainEnd)
+ {
+ pIns->PanEnv.nSustainEnd = pIns->PanEnv.nSustainStart;
+ bBrokenSustainLoop = true;
+ }
pIns->dwFlags &= ~(ENV_SETPANNING|ENV_VOLCARRY|ENV_PANCARRY|ENV_PITCHCARRY|ENV_FILTER|ENV_PITCH);
pIns->nIFC &= 0x7F;
pIns->nIFR &= 0x7F;
}
}
if (bBrokenNoteMap) AddToLog("WARNING: Note Mapping will be lost when saving as XM.\n");
+ if (bBrokenSustainLoop) AddToLog("WARNING: Sustain loops were converted to sustain points.\n");
}
if(newTypeIsMOD)
Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-30 14:29:58 UTC (rev 349)
+++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-30 22:27:15 UTC (rev 350)
@@ -18,43 +18,6 @@
extern WORD S3MFineTuneTable[16];
-static void HandleZxx(uint8& nType, MODCOMMAND* const m)
-//-------------------------------------------------------------------
-{
- if(nType == 0)
- {
- CString str;
- str.Format(GetStrI18N("The S3M file contains Zxx effect. "
- "It can be processed in the following ways:\n"
- "Yes : Convert Zxx to S8x(set panning)-effects (PixPlay)\n"
- "No : Remove Zxx effects\n"
- "Cancel: Keep Zxx effects\n"
- "\nNote that options (yes) and (no) modify the loaded pattern data."
- ));
- const int nResult = ::AfxMessageBox(str, MB_YESNOCANCEL|MB_ICONINFORMATION);
-
- if(nResult == IDYES)
- nType = 2;
- else if(nResult == IDNO)
- nType = 3;
- else
- nType = 1;
- }
- if(nType != 1)
- {
- if(nType == 2)
- {
- m->command = CMD_S3MCMDEX;
- m->param = 0x80 + (m->param & 0xF);
- }
- else
- {
- m->command = 0;
- m->param = 0;
- }
- }
-}
-
//////////////////////////////////////////////////////
// ScreamTracker S3M file support
@@ -264,6 +227,7 @@
DWORD dwMemPos;
BYTE insflags[128], inspack[128];
S3MFILEHEADER psfh = *(S3MFILEHEADER *)lpStream;
+ bool bKeepMidiMacros = false;
psfh.reserved1 = LittleEndianW(psfh.reserved1);
psfh.ordnum = LittleEndianW(psfh.ordnum);
@@ -278,8 +242,26 @@
if (psfh.scrm != 0x4D524353) return false;
if((psfh.cwtv & 0xF000) == 0x5000) // OpenMPT Version number (Major.Minor)
+ {
m_dwLastSavedWithVersion = (psfh.cwtv & 0x0FFF) << 16;
+ bKeepMidiMacros = true; // simply load Zxx commands
+ }
+ if(psfh.cwtv == 0x1320 && psfh.special == 0 && (psfh.ordnum & 0x0F) == 0 && psfh.ultraclicks == 0 && (psfh.flags & ~0x50) == 0)
+ {
+ // MPT 1.16 and older versions of OpenMPT
+ m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00);
+ bKeepMidiMacros = true; // simply load Zxx commands
+ }
+ if((psfh.cwtv & 0xF000) >= 0x2000)
+ {
+ // 2xyy - Orpheus, 3xyy - IT, 4xyy - Schism, 5xyy - OpenMPT
+ bKeepMidiMacros = true; // simply load Zxx commands
+ }
+
+ if(!bKeepMidiMacros) // Remove macros so they don't interfere with other tunes
+ memset(&m_MidiCfg, 0, sizeof(m_MidiCfg));
+
dwMemPos = 0x60;
m_nType = MOD_TYPE_S3M;
memset(m_szNames,0,sizeof(m_szNames));
@@ -292,7 +274,8 @@
m_nDefaultTempo = CLAMP(m_nDefaultTempo, 32, 255);
// Global Volume
m_nDefaultGlobalVolume = psfh.globalvol << 2;
- if ((!m_nDefaultGlobalVolume) || (m_nDefaultGlobalVolume > 256)) m_nDefaultGlobalVolume = 256;
+ if(!m_nDefaultGlobalVolume && psfh.cwtv < 0x1320) m_nDefaultGlobalVolume = 256; // not very reliable, but it fixes a few tunes
+ if(m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256;
m_nSamplePreAmp = psfh.mastervol & 0x7F; // Bit 8 = Stereo (we always use stereo)
// Channels
m_nChannels = 4;
@@ -386,8 +369,14 @@
//ASSERT(iLooplength == 0 || iLooplength > 4);
}
}
+
+ /* Try to find out if Zxx commands are supposed to be panning commands (PixPlay).
+ We won't convert if there are not enough Zxx commands, too "high" Zxx commands
+ or there are only "left" or "right" pannings (we assume that stereo should be somewhat balanced) */
+ bool bDoNotConvertZxx = false;
+ int iZxxCountRight = 0, iZxxCountLeft = 0;
+
// Reading patterns
- uint8 nZxxHandling = 0;
for (UINT iPat=0; iPat<patnum; iPat++)
{
UINT nInd = ((DWORD)ptr[nins+iPat]) << 4;
@@ -402,8 +391,9 @@
MODCOMMAND *p = Patterns[iPat];
UINT row = 0;
UINT j = 0;
- while (j < len)
+ while (row < 64) // this fixes ftp://us.aminet.net/pub/aminet/mods/8voic/s3m_hunt.lha (was: while (j < len))
{
+ if(j + nInd + 1 >= dwMemLength) break;
BYTE b = src[j++];
if (!b)
{
@@ -416,6 +406,7 @@
MODCOMMAND *m = &p[row*m_nChannels+chn];
if (b & 0x20)
{
+ if(j + nInd + 2 >= dwMemLength) break;
m->note = src[j++];
if (m->note < 0xF0) m->note = (m->note & 0x0F) + 12*(m->note >> 4) + 13;
else if (m->note == 0xFF) m->note = NOTE_NONE;
@@ -423,6 +414,7 @@
}
if (b & 0x40)
{
+ if(j + nInd + 1 >= dwMemLength) break;
UINT vol = src[j++];
if ((vol >= 128) && (vol <= 192))
{
@@ -437,12 +429,22 @@
}
if (b & 0x80)
{
+ if(j + nInd + 2 >= dwMemLength) break;
m->command = src[j++];
m->param = src[j++];
if (m->command) S3MConvert(m, FALSE);
if(m->command == CMD_MIDI)
{
- HandleZxx(nZxxHandling, m);
+ if(m->param > 0x0F)
+ {
+ // PixPlay has Z00 to Z0F panning, so we ignore this.
+ bDoNotConvertZxx = true;
+ }
+ else
+ {
+ if(m->param < 0x08) iZxxCountLeft++;
+ if(m->param > 0x08) iZxxCountRight++;
+ }
}
}
} else
@@ -451,10 +453,27 @@
if (b & 0x40) j++;
if (b & 0x80) j += 2;
}
- if (j >= len) break;
}
}
}
+
+ if((UINT)(iZxxCountLeft + iZxxCountRight) >= m_nChannels && !bDoNotConvertZxx && (iZxxCountLeft - iZxxCountRight > -(int)m_nChannels))
+ {
+ // there are enough Zxx commands, so let's assume this was made to be played with PixPlay
+ for(PATTERNINDEX nPat = 0; nPat < Patterns.Size(); nPat++) if(Patterns[nPat])
+ {
+ MODCOMMAND *m = Patterns[nPat];
+ for(UINT len = PatternSize[nPat] * m_nChannels; len; m++, len--)
+ {
+ if(m->command == CMD_MIDI)
+ {
+ m->command = CMD_S3MCMDEX;
+ m->param |= 0x80;
+ }
+ }
+ }
+ }
+
// Reading samples
for (UINT iRaw=1; iRaw<=insnum; iRaw++) if ((Samples[iRaw].nLength) && (insfile[iRaw]))
{
@@ -469,11 +488,6 @@
m_nMaxPeriod = 32767;
if (psfh.flags & 0x10) m_dwSongFlags |= SONG_AMIGALIMITS;
- if(nZxxHandling != 0 && nZxxHandling != 1 && GetpModDoc() != 0)
- {
- GetpModDoc()->SetModified();
- GetpModDoc()->SetShowSaveDialog(true);
- }
return true;
}
@@ -507,15 +521,14 @@
header[0x1B] = 0;
header[0x1C] = 0x1A;
header[0x1D] = 0x10;
- // Changes to 1.17.02.53:
- // -Try to save whole sequence instead of stopping on first empty order.
- // -With more than 0xF0 orders, limit sequence to 0xF0 instead of just masking with 0xF0.
- //TODO: Check whether the 0xF0 mask is correct.
- // (there are two bytes reserved from the header, so why 0xF0 mask?).
- //nbo = (GetNumPatterns() + 15) & 0xF0;
+
nbo = Order.GetLengthTailTrimmed();
- if(nbo > 0xF0) nbo = 0xF0;
- if (!nbo) nbo = 1;
+ if (nbo < 2)
+ nbo = 2;
+ else if (nbo & 1) // number of orders must be even
+ nbo++;
+ nbo = (nbo + 15) & 0xF0; // TODO why does it not work otherwise? nbo should be multiple of 2, not 16!
+ if(nbo > 0xF0) nbo = 0xF0; // sequence too long
header[0x20] = nbo & 0xFF;
header[0x21] = nbo >> 8;
nbi = m_nInstruments;
@@ -536,7 +549,7 @@
// Following: One nibble = Major version, one byte = Minor version (hex)
MptVersion::VersionNum vVersion = MptVersion::num;
header[0x28] = (BYTE)((vVersion >> 16) & 0xFF); // the "17" in OpenMPT 1.17
- header[0x29] = 0x50 | (BYTE)((vVersion >> 24) & 0x0F); // the "1" in OpenMPT 1.17 + OpenMPT Identifier 5 (works only for versions up to 15.99 :))
+ header[0x29] = 0x50 | (BYTE)((vVersion >> 24) & 0x0F); // the "1." in OpenMPT 1.17 + OpenMPT Identifier 5 (works only for versions up to 9.99 :))
header[0x2A] = 0x02; // Version = 1 => Signed samples
header[0x2B] = 0x00;
header[0x2C] = 'S';
@@ -548,7 +561,7 @@
header[0x32] = CLAMP(m_nDefaultTempo, 32, 255);
header[0x33] = CLAMP(m_nSamplePreAmp, 0x10, 0x7F) | 0x80; // Bit 8 = Stereo
header[0x34] = 0x10; // 16 Channels for UltraClick removal
- header[0x35] = 0xFC;
+ header[0x35] = 0xFC; // Write pan positions
for (i=0; i<32; i++)
{
if (i < m_nChannels)
@@ -562,7 +575,7 @@
memset(patptr, 0, sizeof(patptr));
memset(insptr, 0, sizeof(insptr));
UINT ofs0 = 0x60 + nbo;
- UINT ofs1 = ((0x60 + nbo + nbi*2 + nbp*2 + 15) & 0xFFF0) + 0x20;
+ UINT ofs1 = ((0x60 + nbo + nbi * 2 + nbp * 2 + 15) & 0xFFF0) + ((header[0x35] == 0xFC) ? 0x20 : 0);
UINT ofs = ofs1;
for (i=0; i<nbi; i++) insptr[i] = (WORD)((ofs + i*0x50) / 16);
for (i=0; i<nbp; i++) patptr[i] = (WORD)((ofs + nbi*0x50) / 16);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-30 14:30:04
|
Revision: 349
http://modplug.svn.sourceforge.net/modplug/?rev=349&view=rev
Author: saga-games
Date: 2009-08-30 14:29:58 +0000 (Sun, 30 Aug 2009)
Log Message:
-----------
[Fix] XM Compatibility: Compatible Arpeggio was done wrong
[Fix] XM Compatibility: More compatible "Note Off + Something"
[Fix] IT COmpatibility: Removed a "fix" again that was causing to completely destroy panbrello
[Imp] Comments tab: Only switch only to instrument list in XM modules if there are actually instruments
Modified Paths:
--------------
trunk/OpenMPT/mptrack/view_com.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/mptrack/view_com.cpp
===================================================================
--- trunk/OpenMPT/mptrack/view_com.cpp 2009-08-30 00:07:19 UTC (rev 348)
+++ trunk/OpenMPT/mptrack/view_com.cpp 2009-08-30 14:29:58 UTC (rev 349)
@@ -114,7 +114,7 @@
if(pModDoc)
{
pSndFile= pModDoc->GetSoundFile();
- if(pSndFile && (pSndFile->m_nType & MOD_TYPE_XM))
+ if(pSndFile && (pSndFile->m_nType & MOD_TYPE_XM) && pSndFile->m_nInstruments > 0)
{
m_nListId = IDC_LIST_INSTRUMENTS;
}
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-30 00:07:19 UTC (rev 348)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-30 14:29:58 UTC (rev 349)
@@ -1233,8 +1233,8 @@
note = instr = 0;
}
- // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number is present!)
- if ((note == NOTE_KEYOFF) && (!pChn->pModInstrument || !IsCompatibleMode(TRK_FASTTRACKER2)) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME))))
+ // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number or volume effect is present!)
+ if ((note == NOTE_KEYOFF) && ((!instr && !vol && cmd != CMD_VOLUME) || !IsCompatibleMode(TRK_FASTTRACKER2)) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME))))
{
pChn->dwFlags |= CHN_FASTVOLRAMP;
pChn->nVolume = 0;
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-30 00:07:19 UTC (rev 348)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-30 14:29:58 UTC (rev 349)
@@ -951,8 +951,7 @@
pChn->nRealPan = pChn->nPan;
}
- if (pChn->nRealPan < 0) pChn->nRealPan = 0;
- if (pChn->nRealPan > 256) pChn->nRealPan = 256;
+ pChn->nRealPan = CLAMP(pChn->nRealPan, 0, 256);
pChn->nRampLength = 0;
//Aux variables
@@ -1231,7 +1230,7 @@
if (!(m_dwSongFlags & SONG_FIRSTTICK))
{
- arpPos = (m_nTickCount - m_nMusicSpeed) % 3;
+ arpPos = ((int)m_nTickCount - (int)m_nMusicSpeed) % 3;
if(arpPos < 0) arpPos += 3;
switch(arpPos)
{
@@ -1445,7 +1444,7 @@
pdelta += pChn->nRealPan;
pChn->nRealPan = CLAMP(pdelta, 0, 256);
- if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan;
+ //if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan; // TODO
}
int nPeriodFrac = 0;
// Instrument Auto-Vibrato
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-30 00:07:38
|
Revision: 348
http://modplug.svn.sourceforge.net/modplug/?rev=348&view=rev
Author: saga-games
Date: 2009-08-30 00:07:19 +0000 (Sun, 30 Aug 2009)
Log Message:
-----------
[Fix] Rearrange Samples: Also remap samples on instrument "keyboard" that were removed, so that f.e. instruments with VSTis won't have unwanted samples suddenly
[Fix] Order list: After inserting a single order, the list is now no more in multi-order mode.
[Imp] Order list: Enable multi-order mode also when using shift + cursor keys
[Ref] Some internal refactoring
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_pat.h
trunk/OpenMPT/mptrack/Ctrl_seq.cpp
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/tagging.cpp
Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-08-29 14:56:14 UTC (rev 347)
+++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-08-30 00:07:19 UTC (rev 348)
@@ -44,6 +44,9 @@
void InvalidateSelection() const;
UINT GetCurrentPattern() const;
ORD_SELECTION GetCurSel(bool bIgnoreSelection) const;
+ // make the current selection the secondary selection (used for keyboard orderlist navigation)
+ inline void SetCurSelTo2ndSel()
+ {if(m_bShift && m_nScrollPos2nd == ORDERINDEX_INVALID) m_nScrollPos2nd = m_nScrollPos; else if(!m_bShift && m_nScrollPos2nd != ORDERINDEX_INVALID) m_nScrollPos2nd = ORDERINDEX_INVALID;};
bool SetCurSel(ORDERINDEX sel, bool bEdit = true, bool bShiftClick = false);
BOOL ProcessKeyDown(UINT nChar);
BOOL ProcessChar(UINT nChar);
@@ -71,7 +74,7 @@
// Returns the number of sequence items visible in the list.
BYTE GetLength();
- // Return true iff given order is in margins given that first shown order
+ // Return true if given order is in margins given that first shown order
// is 'startOrder'. Begin part of the whole sequence
// is not interpreted to be in margins regardless of the margin value.
bool IsOrderInMargins(int order, int startOrder);
Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-29 14:56:14 UTC (rev 347)
+++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-30 00:07:19 UTC (rev 348)
@@ -307,10 +307,10 @@
switch(nChar)
{
case VK_UP:
- case VK_LEFT: SetCurSel(m_nScrollPos - 1); break;
+ case VK_LEFT: SetCurSelTo2ndSel(); SetCurSel(m_nScrollPos - 1); break;
case VK_DOWN:
- case VK_RIGHT: SetCurSel(m_nScrollPos + 1); break;
- case VK_HOME: SetCurSel(0); break;
+ case VK_RIGHT: SetCurSelTo2ndSel(); SetCurSel(m_nScrollPos + 1); break;
+ case VK_HOME: SetCurSelTo2ndSel(); SetCurSel(0); break;
case VK_END:
if (m_pModDoc)
{
@@ -318,6 +318,7 @@
ORDERINDEX i = 0;
const int nSeqLength = pSndFile->Order.size();
for (i=0; i+1 < nSeqLength; i++) if (pSndFile->Order[i+1] == pSndFile->Order.GetInvalidPatIndex()) break;
+ SetCurSelTo2ndSel();
SetCurSel(i);
}
break;
@@ -928,7 +929,10 @@
pSndFile->Order[nInsertEnd + i + 1] = pSndFile->Order[nInsertEnd - nInsertCount + i];
}
m_nScrollPos = min(nInsertEnd + 1, pSndFile->Order.GetCount() - 1);
- m_nScrollPos2nd = min(m_nScrollPos + nInsertCount, pSndFile->Order.GetCount() - 1);
+ if(nInsertCount > 0)
+ m_nScrollPos2nd = min(m_nScrollPos + nInsertCount, pSndFile->Order.GetCount() - 1);
+ else
+ m_nScrollPos2nd = ORDERINDEX_INVALID;
InvalidateRect(NULL, FALSE);
m_pModDoc->SetModified();
m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this);
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-29 14:56:14 UTC (rev 347)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-30 00:07:19 UTC (rev 348)
@@ -1060,7 +1060,7 @@
nSampleMap[i] = i;
// First, find out which sample slots are unused and create the new sample map
- for(UINT i = 1 ; i <= m_SndFile.m_nSamples; i++) {
+ for(SAMPLEINDEX i = 1 ; i <= m_SndFile.m_nSamples; i++) {
if(!m_SndFile.Samples[i].pSample)
{
// Move all following samples
@@ -1077,21 +1077,21 @@
BEGIN_CRITICAL();
// Now, move everything around
- for(UINT i = 1; i <= m_SndFile.m_nSamples; i++)
+ for(SAMPLEINDEX i = 1; i <= m_SndFile.m_nSamples; i++)
{
- if(nSampleMap[i] && nSampleMap[i] != i)
+ if(nSampleMap[i] != i)
{
// This gotta be moved
m_SndFile.MoveSample(i, nSampleMap[i]);
m_SndFile.Samples[i].pSample = nullptr;
strcpy(m_SndFile.m_szNames[nSampleMap[i]], m_SndFile.m_szNames[i]);
- m_SndFile.m_szNames[i][0] = '\0';
+ memset(m_SndFile.m_szNames[i], 0, sizeof(m_SndFile.m_szNames[i]));
// Also update instrument mapping (if module is in instrument mode)
- for(UINT iInstr = 1; iInstr <= m_SndFile.m_nInstruments; iInstr++){
+ for(INSTRUMENTINDEX iInstr = 1; iInstr <= m_SndFile.m_nInstruments; iInstr++){
if(m_SndFile.Instruments[iInstr]){
MODINSTRUMENT *p = m_SndFile.Instruments[iInstr];
- for(WORD iNote =0; iNote < 128; iNote++)
+ for(WORD iNote = 0; iNote < 128; iNote++)
if(p->Keyboard[iNote] == i) p->Keyboard[iNote] = nSampleMap[i];
}
}
@@ -1101,12 +1101,12 @@
// Go through the patterns and remap samples (if module is in sample mode)
if(!m_SndFile.m_nInstruments)
{
- for (UINT nPat=0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
+ for (PATTERNINDEX nPat = 0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
{
MODCOMMAND *m = m_SndFile.Patterns[nPat];
- for (UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--)
+ for(UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--)
{
- if(nSampleMap[m->instr]) m->instr = nSampleMap[m->instr];
+ if(m->instr <= m_SndFile.m_nSamples) m->instr = nSampleMap[m->instr];
}
}
}
@@ -1698,7 +1698,7 @@
}
if ((!m_SndFile.m_nInstruments) && ((m_SndFile.m_nSamples > 1) || (m_SndFile.Samples[1].pSample)))
{
- if (pDup) return -1;
+ if (pDup) return INSTRUMENTINDEX_INVALID;
UINT n = CMainFrame::GetMainFrame()->MessageBox("Convert existing samples to instruments first?", NULL, MB_YESNOCANCEL|MB_ICONQUESTION);
if (n == IDYES)
{
@@ -1713,7 +1713,7 @@
if (!p)
{
ErrorBox(IDS_ERR_OUTOFMEMORY, CMainFrame::GetMainFrame());
- return -1;
+ return INSTRUMENTINDEX_INVALID;
}
InitializeInstrument(p, smp);
m_SndFile.Instruments[smp] = p;
Modified: trunk/OpenMPT/mptrack/tagging.cpp
===================================================================
--- trunk/OpenMPT/mptrack/tagging.cpp 2009-08-29 14:56:14 UTC (rev 347)
+++ trunk/OpenMPT/mptrack/tagging.cpp 2009-08-30 00:07:19 UTC (rev 348)
@@ -1,5 +1,5 @@
/*
- * Purpose: File tagging (ID3v2, RIFF + more iIn the future)
+ * Purpose: File tagging (ID3v2, RIFF + more in the future)
* Authors: OpenMPT Devs
*/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-29 14:56:28
|
Revision: 347
http://modplug.svn.sourceforge.net/modplug/?rev=347&view=rev
Author: saga-games
Date: 2009-08-29 14:56:14 +0000 (Sat, 29 Aug 2009)
Log Message:
-----------
[Fix] MP3 Tagging: Synchsafe integers were calculated wrong; Writing the comments field last so the chance of fucking up everything is lower (Winamp's tag reader seems to have some problems with my long comments, but they seem to be encoded correctly? :-S)
[Fix] XM Compatibility: Note Off with instrument number causes fadeout for samples that have no envelope.
[Imp] Comments tab: Default view mode is instruments instead of samples for XM files.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/tagging.cpp
trunk/OpenMPT/mptrack/view_com.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/mptrack/tagging.cpp
===================================================================
--- trunk/OpenMPT/mptrack/tagging.cpp 2009-08-29 00:40:26 UTC (rev 346)
+++ trunk/OpenMPT/mptrack/tagging.cpp 2009-08-29 14:56:14 UTC (rev 347)
@@ -1,5 +1,5 @@
/*
- * Purpose: File tagging (ID3v2, RIFF + more in the future)
+ * Purpose: File tagging (ID3v2, RIFF + more iIn the future)
* Authors: OpenMPT Devs
*/
@@ -23,15 +23,15 @@
// Convert Integer to Synchsafe Integer (see ID3v2.4 specs)
// Basically, it's a BigEndian integer, but the MSB of all bytes is 0.
// Thus, a 32-bit integer turns into a 28-bit integer.
-UINT32 CFileTagging::intToSynchsafe(UINT32 in)
+UINT32 CFileTagging::intToSynchsafe(UINT32 iIn)
{
- in = LittleEndian(in);
- UINT32 out = 0;
+ iIn = LittleEndian(iIn);
+ UINT32 iOut = 0, iSteps = 0;
do {
- out <<= 8;
- out |= (in & 0x7F);
- } while(in >>= 7);
- return BigEndian(out);
+ iOut |= (iIn & 0x7F) << iSteps;
+ iSteps += 8;
+ } while(iIn >>= 7);
+ return BigEndian(iOut);
}
// Write Tags
@@ -53,7 +53,7 @@
tHeader.flags = 0x00; // No flags
fwrite(&tHeader, 1, sizeof(tHeader), f);
- // Write TIT2 (Title), TCOM / TPE1 (Composer), TALB (Album), TCON (Genre), TYER (Date), WXXX (URL), COMM (Comment), TENC (Encoder)
+ // Write TIT2 (Title), TCOM / TPE1 (Composer), TALB (Album), TCON (Genre), TYER (Date), WXXX (URL), TENC (Encoder), COMM (Comment)
WriteID3v2Frame("TIT2", title, f);
WriteID3v2Frame("TPE1", artist, f);
WriteID3v2Frame("TCOM", artist, f);
@@ -61,8 +61,8 @@
WriteID3v2Frame("TCON", genre, f);
WriteID3v2Frame("TYER", year, f);
WriteID3v2Frame("WXXX", url, f);
+ WriteID3v2Frame("TENC", encoder, f);
WriteID3v2Frame("COMM", comments, f);
- WriteID3v2Frame("TENC", encoder, f);
// Write Padding
for(UINT i = 0; i < ID3v2_PADDING; i++)
Modified: trunk/OpenMPT/mptrack/view_com.cpp
===================================================================
--- trunk/OpenMPT/mptrack/view_com.cpp 2009-08-29 00:40:26 UTC (rev 346)
+++ trunk/OpenMPT/mptrack/view_com.cpp 2009-08-29 14:56:14 UTC (rev 347)
@@ -97,13 +97,30 @@
//----------------------------
{
m_nCurrentListId = 0;
- m_nListId = IDC_LIST_SAMPLES;
+ m_nListId = 0;//IDC_LIST_SAMPLES;
}
void CViewComments::OnInitialUpdate()
//-----------------------------------
{
+ if(m_nListId == 0)
+ {
+ m_nListId = IDC_LIST_SAMPLES;
+
+ // For XM, set the instrument list as the default list
+ CModDoc *pModDoc = GetDocument();
+ CSoundFile *pSndFile;
+ if(pModDoc)
+ {
+ pSndFile= pModDoc->GetSoundFile();
+ if(pSndFile && (pSndFile->m_nType & MOD_TYPE_XM))
+ {
+ m_nListId = IDC_LIST_INSTRUMENTS;
+ }
+ }
+ }
+
CChildFrame *pFrame = (CChildFrame *)GetParentFrame();
CRect rect;
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-29 00:40:26 UTC (rev 346)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-29 14:56:14 UTC (rev 347)
@@ -15,6 +15,7 @@
* - Sinaria - Seems to work (never played the game, so I can't really tell...)
*
* Effect conversion should be about right...
+ * If OpenMPT will ever support subtunes properly, the subtune crap should be rewritten completely.
*/
#include "stdafx.h"
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-29 00:40:26 UTC (rev 346)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-29 14:56:14 UTC (rev 347)
@@ -1233,8 +1233,8 @@
note = instr = 0;
}
- // XM: Key-Off + Sample == Note Cut
- if ((note == NOTE_KEYOFF) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME))))
+ // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number is present!)
+ if ((note == NOTE_KEYOFF) && (!pChn->pModInstrument || !IsCompatibleMode(TRK_FASTTRACKER2)) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME))))
{
pChn->dwFlags |= CHN_FASTVOLRAMP;
pChn->nVolume = 0;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-29 00:40:36
|
Revision: 346
http://modplug.svn.sourceforge.net/modplug/?rev=346&view=rev
Author: saga-games
Date: 2009-08-29 00:40:26 +0000 (Sat, 29 Aug 2009)
Log Message:
-----------
[Fix] IT Compatibility: Don't reset channel panning if panbrello ends (experimental)
[Imp] PSM Loader: I think it's finished... finally. Subsongs should work perfectly, a few other things have also been fixed / improved.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-26 22:04:14 UTC (rev 345)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-29 00:40:26 UTC (rev 346)
@@ -354,9 +354,9 @@
case MOD_TYPE_STM:
case MOD_TYPE_DSM:
case MOD_TYPE_AMF:
- case MOD_TYPE_PSM:
m_SndFile.ChangeModTypeTo(MOD_TYPE_S3M);
break;
+ case MOD_TYPE_PSM:
default:
m_SndFile.ChangeModTypeTo(MOD_TYPE_IT);
}
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-26 22:04:14 UTC (rev 345)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-29 00:40:26 UTC (rev 346)
@@ -8,12 +8,11 @@
*
* What's playing?
* - Epic Pinball - Perfect! (the old tunes in PSM16 format are not supported)
- * - Extreme Pinball - Default tempo / speed / restart position of subtunes is missing.
- * I'm using the last default values, restart position is still completely missing
+ * - Extreme Pinball - Perfect! (subtunes included!)
* - Jazz Jackrabbit - Perfect!
- * - One Must Fall! - Perfect! (I modelled the volume slide and portamento conversion after this, as I got the original MTM files)
+ * - One Must Fall! - Perfect! (it helped a lot to have the original MTM files...)
* - Silverball - Currently not supported (old PSM16 format)
- * - Sinaria - Seems to work more or less (never played the game, so I can't really tell...)
+ * - Sinaria - Seems to work (never played the game, so I can't really tell...)
*
* Effect conversion should be about right...
*/
@@ -77,6 +76,26 @@
};
#pragma pack()
+struct PSMSUBSONG // For internal use (pattern conversion)
+{
+ BYTE channelPanning[MAX_BASECHANNELS], channelVolume[MAX_BASECHANNELS];
+ bool channelSurround[MAX_BASECHANNELS];
+ BYTE defaultTempo, defaultSpeed;
+ CHAR songName[10];
+ ORDERINDEX startOrder, endOrder, restartPos;
+
+ PSMSUBSONG() {
+ memset(channelPanning, 128, sizeof(channelPanning));
+ memset(channelVolume, 64, sizeof(channelVolume));
+ memset(channelSurround, false, sizeof(channelSurround));
+ memset(songName, 0, sizeof(songName));
+ defaultTempo = 125;
+ defaultSpeed = 6;
+ startOrder = endOrder = restartPos = ORDERINDEX_INVALID;
+ }
+};
+
+// Portamento effect conversion (depending on format version)
inline BYTE convert_psm_porta(BYTE param, bool bNewFormat)
{
return ((bNewFormat) ? (param) : ((param < 4) ? (param | 0xF0) : (param >> 2)));
@@ -100,7 +119,8 @@
) return false;
// Yep, this seems to be a valid file.
- m_nType = MOD_TYPE_PSM;
+ m_nType = MOD_TYPE_IT;
+ SetModFlag(MSF_COMPATIBLE_PLAY, true);
m_nChannels = 0;
dwMemPos += 12;
@@ -110,15 +130,18 @@
m_nVSTiVolume = m_nSamplePreAmp = 48; // not supported in this format, so use a good default value
// pattern offset and identifier
- PATTERNINDEX numPatterns = 0;
- vector<DWORD> patternOffsets;
- vector<DWORD> patternIDs;
+ PATTERNINDEX numPatterns = 0; // used for setting up the orderlist - final pattern count
+ vector<DWORD> patternOffsets; // pattern offsets (sorted as they occour in the file)
+ vector<DWORD> patternIDs; // pattern IDs (sorted as they occour in the file)
+ vector<DWORD> orderOffsets; // combine the upper two vectors to get the offsets for each order item
patternOffsets.clear();
patternIDs.clear();
+ orderOffsets.clear();
Order.clear();
+ // subsong setup
+ vector<PSMSUBSONG> subsongs;
+ bool bSubsongPanningDiffers = false; // do we have subsongs with different panning positions?
- std::string sComment; // we will store some information about the tune here
-
while(dwMemPos + 8 < dwMemLength)
{
// Skip through the chunks
@@ -141,39 +164,37 @@
break;
case 0x444F4250: // "PBOD" - Pattern data of a single pattern
- if(chunkSize < 4 || chunkSize != LittleEndian(*(DWORD *)(lpStream + dwMemPos))) return false; // same value twice
+ if(chunkSize < 8 || chunkSize != LittleEndian(*(DWORD *)(lpStream + dwMemPos))) return false; // same value twice
- // Pattern ID (something like "P0 " or "P13 ") follows
+ // Pattern ID (something like "P0 " or "P13 ", or "PATT0 " in Sinaria) follows
if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false;
if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bNewFormat = true;
+ if(bNewFormat && chunkSize < 12) return false; // 4 additional bytes
+
char patternID[4];
memcpy(patternID, lpStream + dwMemPos + 5 + (bNewFormat ? 3 : 0), 3);
patternID[3] = 0;
+ patternIDs.push_back(atoi(patternID));
patternOffsets.push_back(dwMemPos + 8 + (bNewFormat ? 4 : 0));
- patternIDs.push_back(atoi(patternID));
- numPatterns++;
// Convert later as we have to know how many channels there are.
break;
- case 0x474E4F53: // "SONG" - Information about this file (channel count etc)
- // We will not check for the "song type", because it is not ALWAYS "MAINSONG " (Extreme Pinball seems to use other song types for the sub songs)
- // However, the last char always seems to be a space char.
+ case 0x474E4F53: // "SONG" - Subsong information (channel count etc)
{
if(chunkSize < sizeof(PSMSONGHEADER)) return false;
PSMSONGHEADER *pSong = (PSMSONGHEADER *)(lpStream + dwMemPos);
- if(pSong->compression != 0x01) return false;
- m_nChannels = max(m_nChannels, pSong->numChannels); // subsongs *might* have different channel count
+ if(pSong->compression != 0x01) return false; // no compression for PSM files
+ m_nChannels = CLAMP(pSong->numChannels, m_nChannels, MAX_BASECHANNELS); // subsongs *might* have different channel count
- CHAR cSongName[10];
- memcpy(cSongName, &pSong->songType, 9);
- cSongName[9] = 0;
- sComment += "\r\nSubsong: ";
- sComment += cSongName;
+ PSMSUBSONG subsong;
+ subsong.restartPos = (ORDERINDEX)Order.size(); // restart order "offset": current orderlist length
+ memcpy(subsong.songName, &pSong->songType, 9); // subsong name
+ subsong.songName[9] = 0;
DWORD dwChunkPos = dwMemPos + sizeof(PSMSONGHEADER);
- // Sub chunks
+ // "Sub sub chunks"
while(dwChunkPos + 8 < dwMemPos + chunkSize)
{
DWORD subChunkID = LittleEndian(*(DWORD *)(lpStream + dwChunkPos));
@@ -190,20 +211,11 @@
memcpy(cversion, lpStream + dwChunkPos, 6);
cversion[6] = 0;
int version = atoi(cversion);
- // Sinaria song dates
+ // Sinaria song dates (just to go sure...)
if(version == 800211 || version == 940902 || version == 940903 ||
version == 940906 || version == 940914 || version == 941213)
bNewFormat = true;
}
- #ifdef DEBUG
- CHAR cDate[7];
- memcpy(cDate, lpStream + dwChunkPos, 6);
- cDate[6] = 0;
- sComment += " - Build Date: ";
- sComment += cDate;
- if(bNewFormat) sComment += " (New Format)";
- else sComment += " (Old Format)";
- #endif
break;
case 0x484C504F: // "OPLH" - Order list, channel + module settings
@@ -215,6 +227,8 @@
// Now, the interesting part begins!
DWORD dwSettingsOffset = dwChunkPos + 2;
WORD nChunkCount = 0, nFirstOrderChunk = (WORD)-1;
+
+ // "Sub sub sub chunks" (grrrr, silly format)
while(dwSettingsOffset - dwChunkPos + 1 < subChunkSize)
{
switch(lpStream[dwSettingsOffset])
@@ -226,57 +240,62 @@
case 0x01: // Order list item
if(dwSettingsOffset - dwChunkPos + 5 > subChunkSize) return false;
// Pattern name follows - find pattern (this is the orderlist)
- for(PATTERNINDEX i = 0; i < patternIDs.size(); i++)
{
- char patternID[4];
+ char patternID[4]; // temporary
memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bNewFormat ? 3 : 0), 3);
patternID[3] = 0;
DWORD nPattern = atoi(patternID);
- if(patternIDs[i] == nPattern)
+
+ // seek which pattern has this ID
+ for(uint32 i = 0; i < patternIDs.size(); i++)
{
- Order.push_back(i);
- break;
+ if(patternIDs[i] == nPattern)
+ {
+ // found the right pattern, copy offset + start / end positions.
+ if(subsong.startOrder == ORDERINDEX_INVALID)
+ subsong.startOrder = (ORDERINDEX)orderOffsets.size();
+ subsong.endOrder = (ORDERINDEX)orderOffsets.size();
+
+ // every pattern in the order will be unique, so store the pointer + pattern ID
+ orderOffsets.push_back(patternOffsets[i]);
+ Order.push_back(numPatterns);
+ numPatterns++;
+ break;
+ }
}
}
+ // decide whether this is the first order chunk or not (for finding out the correct restart position)
if(nFirstOrderChunk == (WORD)-1) nFirstOrderChunk = nChunkCount;
dwSettingsOffset += 5 + (bNewFormat ? 4 : 0);
break;
case 0x04: // Restart position
{
- // NOTE: This should not be global! (Extreme Pinball!!!)
WORD nRestartChunk = LittleEndian(*(WORD *)(lpStream + dwSettingsOffset + 1));
ORDERINDEX nRestartPosition = 0;
- if(nRestartChunk == 0) nRestartPosition = 0;
- else if(nRestartChunk >= nFirstOrderChunk) nRestartPosition = (ORDERINDEX)(nRestartChunk - nFirstOrderChunk);
- #ifdef DEBUG
- {
- char s[32];
- wsprintf(s, " - restart pos %d", nRestartPosition);
- sComment += s;
- }
- #endif
+ if(nRestartChunk >= nFirstOrderChunk) nRestartPosition = (ORDERINDEX)(nRestartChunk - nFirstOrderChunk);
+ subsong.restartPos += nRestartPosition;
+ m_nRestartPos = subsong.restartPos;
}
dwSettingsOffset += 3;
break;
case 0x07: // Default Speed
if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
- // Same note as above!
- m_nDefaultSpeed = lpStream[dwSettingsOffset + 1];
+ m_nDefaultSpeed = subsong.defaultSpeed = lpStream[dwSettingsOffset + 1];
dwSettingsOffset += 2;
break;
case 0x08: // Default Tempo
if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
- // Same note as above!
- m_nDefaultTempo = lpStream[dwSettingsOffset + 1];
+ m_nDefaultTempo = subsong.defaultTempo = lpStream[dwSettingsOffset + 1];
dwSettingsOffset += 2;
break;
case 0x0C: // Sample map table (???)
if(dwSettingsOffset - dwChunkPos + 7 > subChunkSize) break;
+ // Never seems to be different, so...
if (lpStream[dwSettingsOffset + 1] != 0x00 || lpStream[dwSettingsOffset + 2] != 0xFF ||
lpStream[dwSettingsOffset + 3] != 0x00 || lpStream[dwSettingsOffset + 4] != 0x00 ||
lpStream[dwSettingsOffset + 5] != 0x01 || lpStream[dwSettingsOffset + 6] != 0x00)
@@ -287,31 +306,44 @@
case 0x0D: // Channel panning table
if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) break;
+ if(lpStream[dwSettingsOffset + 1] < MAX_BASECHANNELS)
{
- CHANNELINDEX nChn = min(lpStream[dwSettingsOffset + 1], pSong->numChannels);
+ CHANNELINDEX nChn = lpStream[dwSettingsOffset + 1];
switch(lpStream[dwSettingsOffset + 3])
{
- case 0:
- ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2] ^ 128;
+ case 0: // use panning
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = lpStream[dwSettingsOffset + 2] ^ 128;
+ ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelSurround[nChn] = false;
break;
- case 2:
- ChnSettings[nChn].nPan = 128;
+ case 2: // surround
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
ChnSettings[nChn].dwFlags |= CHN_SURROUND;
+ subsong.channelSurround[nChn] = true;
break;
- case 4:
- ChnSettings[nChn].nPan = 128;
+ case 4: // center
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
+ ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelSurround[nChn] = false;
break;
}
+ if(bSubsongPanningDiffers == false && subsongs.size() > 0)
+ {
+ if(subsongs.back().channelPanning[nChn] != subsong.channelPanning[nChn]
+ || subsongs.back().channelSurround[nChn] != subsong.channelSurround[nChn])
+ bSubsongPanningDiffers = true;
+ }
}
dwSettingsOffset += 4;
break;
- case 0x0E: // Channel volume table
+ case 0x0E: // Channel volume table (0...255)
if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break;
- ChnSettings[min(lpStream[dwSettingsOffset + 1], pSong->numChannels)].nVolume = (lpStream[dwSettingsOffset + 2] >> 2) + 1;
+ if(lpStream[dwSettingsOffset + 1] < MAX_BASECHANNELS)
+ ChnSettings[lpStream[dwSettingsOffset + 1]].nVolume = subsong.channelVolume[lpStream[dwSettingsOffset + 1]] = (lpStream[dwSettingsOffset + 2] >> 2) + 1;
dwSettingsOffset += 3;
break;
@@ -320,12 +352,15 @@
CString s;
s.Format("Please report to the OpenMPT team: Unknown chunk %d found at position %d (in the OPLH chunk of this PSM file)", lpStream[dwSettingsOffset], dwSettingsOffset);
MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
+ // anyway, in such cases, we have to quit as we don't know how big the chunk really is.
return false;
break;
}
nChunkCount++;
}
+ // separate subsongs by "---" patterns
+ orderOffsets.push_back(nullptr);
Order.push_back(Order.GetInvalidPatIndex());
}
break;
@@ -334,20 +369,26 @@
if(subChunkSize & 1) return false;
for(DWORD i = 0; i < subChunkSize; i += 2)
{
- if((i >> 1) >= m_nChannels) break;
+ CHANNELINDEX nChn = (CHANNELINDEX)(i >> 1);
+ if(nChn >= m_nChannels) break;
switch(lpStream[dwChunkPos + i])
{
- case 0:
- ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] ^ 128;
+ case 0: // use panning
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = lpStream[dwChunkPos + i + 1] ^ 128;
+ ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelSurround[nChn] = false;
break;
- case 2:
- ChnSettings[i >> 1].nPan = 128;
- ChnSettings[i >> 1].dwFlags |= CHN_SURROUND;
+ case 2: // surround
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
+ ChnSettings[nChn].dwFlags |= CHN_SURROUND;
+ subsong.channelSurround[nChn] = true;
break;
- case 4:
- ChnSettings[i >> 1].nPan = 128;
+ case 4: // center
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
+ ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelSurround[nChn] = false;
break;
}
}
@@ -368,6 +409,9 @@
dwChunkPos += subChunkSize;
}
+
+ // attach this subsong to the subsong list - finally, all "sub sub sub ..." chunks are parsed.
+ subsongs.push_back(subsong);
}
break;
@@ -375,6 +419,7 @@
case 0x504D5344: // DSMP - Samples
if(!bNewFormat)
{
+ // original header
if(chunkSize < sizeof(PSMOLDSAMPLEHEADER)) return false;
PSMOLDSAMPLEHEADER *pSample = (PSMOLDSAMPLEHEADER *)(lpStream + dwMemPos);
SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
@@ -434,10 +479,14 @@
if(m_nChannels == 0)
return false;
+
// Now that we know the number of channels, we can go through all the patterns.
- for(PATTERNINDEX nPat = 0; nPat < numPatterns; nPat++)
+ // This is a bit stupid since we will even read duplicate patterns twice, but hey, we do this just once... so who cares?
+ PATTERNINDEX nPat = 0;
+ for(ORDERINDEX nOrd = 0; nOrd < Order.size(); nOrd++)
{
- DWORD dwPatternOffset = patternOffsets[nPat];
+ if(orderOffsets[nOrd] == nullptr) continue;
+ DWORD dwPatternOffset = orderOffsets[nOrd];
if(dwPatternOffset + 2 > dwMemLength) return false;
WORD patternSize = LittleEndianW(*(WORD *)(lpStream + dwPatternOffset));
dwPatternOffset += 2;
@@ -659,11 +708,7 @@
break;
default:
- #ifdef DEBUG
- ASSERT(false);
- #else
command = CMD_NONE;
- #endif
break;
}
@@ -679,17 +724,52 @@
row_data += m_nChannels;
dwPatternOffset += rowSize;
}
-
+ nPat++;
}
- if(!sComment.empty())
+ // write subsong "configuration" to patterns
+ for(uint32 i = 0; i < subsongs.size(); i++)
{
- m_lpszSongComments = new char[sComment.length() + 1];
- if (m_lpszSongComments)
+ PATTERNINDEX startPattern = Order[subsongs[i].startOrder], endPattern = Order[subsongs[i].endOrder];
+ if(startPattern == PATTERNINDEX_INVALID || endPattern == PATTERNINDEX_INVALID) continue; // what, invalid subtune?
+
+ // set the subsong name to all pattern names
+ for(PATTERNINDEX nPat = startPattern; nPat <= endPattern; nPat++)
{
- memset(m_lpszSongComments, 0, sComment.length() + 1);
- memcpy(m_lpszSongComments, sComment.c_str(), sComment.length());
+ SetPatternName(nPat, subsongs[i].songName);
}
+
+ // subsongs with different panning setup -> write to pattern (MUSIC_C.PSM)
+ if(bSubsongPanningDiffers)
+ {
+ for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++)
+ {
+ if(subsongs[i].channelSurround[nChn] == true)
+ TryWriteEffect(startPattern, 0, CMD_S3MCMDEX, 0x91, false, nChn, false, true);
+ else
+ TryWriteEffect(startPattern, 0, CMD_PANNING8, subsongs[i].channelPanning[nChn], false, nChn, false, true);
+ }
+ }
+ // write default tempo/speed to pattern
+ TryWriteEffect(startPattern, 0, CMD_SPEED, subsongs[i].defaultSpeed, false, CHANNELINDEX_INVALID, false, true);
+ TryWriteEffect(startPattern, 0, CMD_TEMPO, subsongs[i].defaultTempo, false, CHANNELINDEX_INVALID, false, true);
+
+ // don't write channel volume for now, as it's always set to 100% anyway
+
+ // there's a restart pos, so let's try to insert a Bxx command in the last pattern
+ if(subsongs[i].restartPos != ORDERINDEX_INVALID)
+ {
+ ROWINDEX lastRow = Patterns[endPattern].GetNumRows() - 1;
+ MODCOMMAND *row_data;
+ row_data = Patterns[endPattern];
+ for(uint32 nCell = 0; nCell < m_nChannels * Patterns[endPattern].GetNumRows(); nCell++)
+ {
+ if(row_data->command == CMD_PATTERNBREAK || row_data->command == CMD_POSITIONJUMP)
+ lastRow = nCell / m_nChannels;
+ row_data++;
+ }
+ TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, true);
+ }
}
return true;
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-26 22:04:14 UTC (rev 345)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-29 00:40:26 UTC (rev 346)
@@ -3119,7 +3119,7 @@
if(m_nType & MOD_TYPE_S3M && nParam > 0x80)
break;
- m->volcmd = VOLCMD_VOLUME;
+ m->volcmd = VOLCMD_PANNING;
m->command = nEffect;
if(m_nType & MOD_TYPE_S3M)
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-26 22:04:14 UTC (rev 345)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-29 00:40:26 UTC (rev 346)
@@ -1445,6 +1445,7 @@
pdelta += pChn->nRealPan;
pChn->nRealPan = CLAMP(pdelta, 0, 256);
+ if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan;
}
int nPeriodFrac = 0;
// Instrument Auto-Vibrato
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-26 22:04:33
|
Revision: 345
http://modplug.svn.sourceforge.net/modplug/?rev=345&view=rev
Author: saga-games
Date: 2009-08-26 22:04:14 +0000 (Wed, 26 Aug 2009)
Log Message:
-----------
[Imp] IT Compatibility: More improvements to Vibrato, Tremolo and Panbrello. Using the tables from IT_TECH.TXT.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
trunk/OpenMPT/soundlib/Tables.cpp
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-26 20:40:27 UTC (rev 344)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-26 22:04:14 UTC (rev 345)
@@ -717,7 +717,7 @@
}
pChn->nPos = 0;
pChn->nPosLo = 0;
- if (pChn->nVibratoType < 4) pChn->nVibratoPos = ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))) ? 0x10 : 0;
+ if (pChn->nVibratoType < 4) pChn->nVibratoPos = ((!IsCompatibleMode(TRK_IMPULSETRACKER)) && (m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))) ? 0x10 : 0;
if(!IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->nTremoloType < 4) pChn->nTremoloPos = 0;
}
if (pChn->nPos >= pChn->nLength) pChn->nPos = pChn->nLoopStart;
@@ -1859,6 +1859,7 @@
// IMF Commands
case CMD_NOTESLIDEUP:
NoteSlide(pChn, param, 1);
+ break;
case CMD_NOTESLIDEDOWN:
NoteSlide(pChn, param, -1);
break;
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-26 20:40:27 UTC (rev 344)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-26 22:04:14 UTC (rev 345)
@@ -985,10 +985,10 @@
// Tremolo
if (pChn->dwFlags & CHN_TREMOLO)
{
- UINT trempos = pChn->nTremoloPos & 0x3F;
+ UINT trempos = pChn->nTremoloPos;
if (vol > 0 || IsCompatibleMode(TRK_IMPULSETRACKER))
{
- int tremattn = (m_nType & MOD_TYPE_XM) ? 5 : 6;
+ const int tremattn = (m_nType & MOD_TYPE_XM || IsCompatibleMode(TRK_IMPULSETRACKER)) ? 5 : 6;
switch (pChn->nTremoloType & 0x03)
{
case 1:
@@ -1000,7 +1000,7 @@
case 3:
//IT compatibility 19. Use random values
if(IsCompatibleMode(TRK_IMPULSETRACKER))
- vol += (((rand() & 0xFF) - 0x7F) * (int)pChn->nTremoloDepth) >> tremattn;
+ vol += (((rand() & 0x7F) - 0x40) * (int)pChn->nTremoloDepth) >> tremattn;
else
vol += (ModRandomTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
break;
@@ -1010,7 +1010,10 @@
}
if ((m_nTickCount) || ((m_nType & (MOD_TYPE_STM|MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
{
- pChn->nTremoloPos = (pChn->nTremoloPos + pChn->nTremoloSpeed) & 0x3F;
+ if(IsCompatibleMode(TRK_IMPULSETRACKER))
+ pChn->nTremoloPos = (pChn->nTremoloPos + 4 * pChn->nTremoloSpeed) & 0xFF;
+ else
+ pChn->nTremoloPos = (pChn->nTremoloPos + pChn->nTremoloSpeed) & 0x3F;
}
}
@@ -1340,20 +1343,20 @@
switch (pChn->nVibratoType & 0x03)
{
case 1:
- vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[(vibpos + 48) % 64] : ModRampDownTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[vibpos] : ModRampDownTable[vibpos];
break;
case 2:
- vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[(vibpos + 48) % 64] : ModSquareTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[vibpos] : ModSquareTable[vibpos];
break;
case 3:
//IT compatibility 19. Use random values
if(IsCompatibleMode(TRK_IMPULSETRACKER))
- vdelta = (rand() & 0xFF) - 0x7F;
+ vdelta = (rand() & 0x7F) - 0x40;
else
vdelta = ModRandomTable[vibpos];
break;
default:
- vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[(vibpos + 48) % 64] : ModSinusTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[vibpos] : ModSinusTable[vibpos];
}
if(m_nType == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning)
@@ -1369,7 +1372,22 @@
}
else //Original behavior
{
- UINT vdepth = ((!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) ? 6 : 7;
+ UINT vdepth;
+ if(IsCompatibleMode(TRK_IMPULSETRACKER))
+ {
+ if(m_dwSongFlags & SONG_ITOLDEFFECTS)
+ {
+ vdepth = 5;
+ vdelta = -vdelta;
+ } else
+ {
+ vdepth = 6;
+ }
+ }
+ else
+ {
+ vdepth = ((!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) ? 6 : 7;
+ }
vdelta = (vdelta * (int)pChn->nVibratoDepth) >> vdepth;
if ((m_dwSongFlags & SONG_LINEARSLIDES) && (m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)))
{
@@ -1385,20 +1403,24 @@
if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideUpTable[l & 0x03], 0x10000) - period;
}
}
- if(IsCompatibleMode(TRK_ALLTRACKERS))
- period -= vdelta;
- else
- period += vdelta;
+ period += vdelta;
}
if ((m_nTickCount) || ((m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
{
- pChn->nVibratoPos = (pChn->nVibratoPos + pChn->nVibratoSpeed) & 0x3F;
+ if(IsCompatibleMode(TRK_IMPULSETRACKER))
+ pChn->nVibratoPos = (vibpos + 4 * pChn->nVibratoSpeed) & 0xFF;
+ else
+ pChn->nVibratoPos = (vibpos + pChn->nVibratoSpeed) & 0x3F;
}
}
// Panbrello
if (pChn->dwFlags & CHN_PANBRELLO)
{
- UINT panpos = ((pChn->nPanbrelloPos+0x10) >> 2) & 0x3F;
+ UINT panpos;
+ if(IsCompatibleMode(TRK_IMPULSETRACKER))
+ panpos = pChn->nPanbrelloPos & 0xFF;
+ else
+ panpos = ((pChn->nPanbrelloPos + 0x10) >> 2) & 0x3F;
LONG pdelta;
switch (pChn->nPanbrelloType & 0x03)
{
@@ -1411,7 +1433,7 @@
case 3:
//IT compatibility 19. Use random values
if(IsCompatibleMode(TRK_IMPULSETRACKER))
- pdelta = (rand() & 0xFF) - 0x7F;
+ pdelta = (rand() & 0x7f) - 0x40;
else
pdelta = ModRandomTable[panpos];
break;
@@ -1419,7 +1441,7 @@
pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[panpos] : ModSinusTable[panpos];
}
pChn->nPanbrelloPos += pChn->nPanbrelloSpeed;
- pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> (IsCompatibleMode(TRK_IMPULSETRACKER) ? 4 : 3);
+ pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3;
pdelta += pChn->nRealPan;
pChn->nRealPan = CLAMP(pdelta, 0, 256);
Modified: trunk/OpenMPT/soundlib/Tables.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Tables.cpp 2009-08-26 20:40:27 UTC (rev 344)
+++ trunk/OpenMPT/soundlib/Tables.cpp 2009-08-26 22:04:14 UTC (rev 345)
@@ -154,33 +154,69 @@
42,-34,89,-4,-51,-72,21,-29,112,123,84,-101,-92,98,-54,-95
};
-// Impulse Tracker tables
+// Impulse Tracker tables (ITTECH.TXT)
// Sinus table
-short int ITSinusTable[64] =
+short int ITSinusTable[256] =
{
- 0,12,25,37,49,60,71,81,90,98,106,112,117,122,125,126,
- 127,126,125,122,117,112,106,98,90,81,71,60,49,37,25,12,
- 0,-12,-25,-37,-49,-60,-71,-81,-90,-98,-106,-112,-117,-122,-125,-126,
- -127,-126,-125,-122,-117,-112,-106,-98,-90,-81,-71,-60,-49,-37,-25,-12
+ 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23,
+ 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59,
+ 59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60,
+ 59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46,
+ 45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26,
+ 24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2,
+ 0, -2, -3, -5, -6, -8, -9,-11,-12,-14,-16,-17,-19,-20,-22,-23,
+ -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44,
+ -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59,
+ -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64,
+ -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60,
+ -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,
+ -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26,
+ -24,-23,-22,-20,-19,-17,-16,-14,-12,-11, -9, -8, -6, -5, -3, -2,
};
// Triangle wave table (ramp down)
-short int ITRampDownTable[64] =
+short int ITRampDownTable[256] =
{
- 127,123,119,115,111,107,103,99,95,91,87,83,79,75,71,67,
- 63,59,55,51,47,43,39,35,31,27,23,19,15,11,7,3,
- 0,-4,-8,-12,-16,-20,-24,-28,-32,-36,-40,-44,-48,-52,-56,-60,
- -64,-68,-72,-76,-80,-84,-88,-92,-96,-100,-104,-108,-112,-116,-120,-124
+ 64, 63, 63, 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 57, 57, 56,
+ 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48,
+ 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 40,
+ 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 32,
+ 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24,
+ 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16,
+ 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8,
+ 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
+ 0, -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8,
+ -8, -9, -9,-10,-10,-11,-11,-12,-12,-13,-13,-14,-14,-15,-15,-16,
+ -16,-17,-17,-18,-18,-19,-19,-20,-20,-21,-21,-22,-22,-23,-23,-24,
+ -24,-25,-25,-26,-26,-27,-27,-28,-28,-29,-29,-30,-30,-31,-31,-32,
+ -32,-33,-33,-34,-34,-35,-35,-36,-36,-37,-37,-38,-38,-39,-39,-40,
+ -40,-41,-41,-42,-42,-43,-43,-44,-44,-45,-45,-46,-46,-47,-47,-48,
+ -48,-49,-49,-50,-50,-51,-51,-52,-52,-53,-53,-54,-54,-55,-55,-56,
+ -56,-57,-57,-58,-58,-59,-59,-60,-60,-61,-61,-62,-62,-63,-63,-64,
};
// Square wave table
-short int ITSquareTable[64] =
+short int ITSquareTable[256] =
{
- 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
- 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
// volume fade tables for Retrig Note:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-08-26 20:40:41
|
Revision: 344
http://modplug.svn.sourceforge.net/modplug/?rev=344&view=rev
Author: relabsoluness
Date: 2009-08-26 20:40:27 +0000 (Wed, 26 Aug 2009)
Log Message:
-----------
[New] MIDI mapping: Editing a plug param in its editor while holding shift key will now open MIDI mapping dialog.
[Fix] MIDI mapping: Some minor tweaks and fixes to the MIDI mapping dialog.
[Fix] Pattern tab: Fixed possible crash occurring if echo pattern in echo paste doesn't exist.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp
trunk/OpenMPT/mptrack/MIDIMappingDialog.h
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/Mpt_midi.cpp
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/Vstplug.cpp
trunk/OpenMPT/soundlib/midi.h
trunk/OpenMPT/soundlib/patternContainer.h
Modified: trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp 2009-08-26 20:40:27 UTC (rev 344)
@@ -65,6 +65,7 @@
m_ChannelCBox.SetCurSel(1+GetFromMIDIMsg_Channel(dwMidiDataParam));
m_EventCBox.SetCurSel(0);
m_ControllerCBox.SetCurSel(GetFromMIDIMsg_DataByte1(dwMidiDataParam));
+ OnCbnSelchangeComboChannel();
OnCbnSelchangeComboEvent();
OnCbnSelchangeComboController();
UpdateString();
@@ -78,16 +79,6 @@
{
CDialog::OnInitDialog();
- if (m_rMIDIMapper.GetCount() > 0)
- m_Setting = m_rMIDIMapper.GetDirective(0);
-
- m_ChannelCBox.SetCurSel(m_Setting.GetChannel());
-
- CheckDlgButton(IDC_CHECKACTIVE, m_Setting.IsActive() ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(IDC_CHECKCAPTURE, m_Setting.GetCaptureMIDI() ? BST_CHECKED : BST_UNCHECKED);
- GetDlgItem(IDC_CHECK_PATRECORD)->ShowWindow((m_rSndFile.GetType() == MOD_TYPE_MPT) ? SW_SHOW : SW_HIDE);
- CheckDlgButton(IDC_CHECK_PATRECORD, m_Setting.GetAllowPatternEdit() ? BST_CHECKED : BST_UNCHECKED);
-
m_EventCBox.SetCurSel(0);
//Add controller names.
@@ -97,14 +88,13 @@
temp.Format("%3d %s", i, MidiCCNames[i]);
m_ControllerCBox.AddString(temp);
}
- m_ControllerCBox.SetCurSel(m_Setting.GetController());
//Add Pluginnames
AddPluginNamesToCombobox(m_PluginCBox, m_rSndFile.m_MixPlugins);
m_PluginCBox.SetCurSel(m_Setting.GetPlugIndex()-1);
//Add plugin parameter names
- AddPluginParameternamesToCombobox(m_PlugParamCBox, m_rSndFile.m_MixPlugins[0]);
+ AddPluginParameternamesToCombobox(m_PlugParamCBox, m_rSndFile.m_MixPlugins[(m_Setting.GetPlugIndex() <= MAX_MIXPLUGINS) ? m_Setting.GetPlugIndex() - 1 : 0]);
m_PlugParamCBox.SetCurSel(m_Setting.GetParamIndex());
//Add directives to list.
@@ -113,16 +103,26 @@
{
m_List.AddString(CreateListString(*iter));
}
- if(m_rMIDIMapper.GetCount() > 0)
+ if(m_rMIDIMapper.GetCount() > 0 && m_Setting.IsDefault())
{
m_List.SetCurSel(0);
OnLbnSelchangeList1();
- m_Setting = m_rMIDIMapper.GetDirective(0);
}
+ else
+ {
+ m_ChannelCBox.SetCurSel(m_Setting.GetChannel());
+ m_ControllerCBox.SetCurSel(m_Setting.GetController());
+ CheckDlgButton(IDC_CHECKACTIVE, m_Setting.IsActive() ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(IDC_CHECKCAPTURE, m_Setting.GetCaptureMIDI() ? BST_CHECKED : BST_UNCHECKED);
+ GetDlgItem(IDC_CHECK_PATRECORD)->ShowWindow((m_rSndFile.GetType() == MOD_TYPE_MPT) ? SW_SHOW : SW_HIDE);
+ CheckDlgButton(IDC_CHECK_PATRECORD, m_Setting.GetAllowPatternEdit() ? BST_CHECKED : BST_UNCHECKED);
+ }
UpdateString();
CMainFrame::GetMainFrame()->SetMidiRecordWnd(GetSafeHwnd());
+
+ CheckDlgButton(IDC_CHECK_MIDILEARN, BST_CHECKED);
return TRUE; // return TRUE unless you set the focus to a control
}
Modified: trunk/OpenMPT/mptrack/MIDIMappingDialog.h
===================================================================
--- trunk/OpenMPT/mptrack/MIDIMappingDialog.h 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/MIDIMappingDialog.h 2009-08-26 20:40:27 UTC (rev 344)
@@ -21,6 +21,8 @@
// Dialog Data
enum { IDD = IDD_MIDIPARAMCONTROL };
+ CMIDIMappingDirective m_Setting;
+
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
@@ -49,7 +51,7 @@
CSpinButtonCtrl m_SpinMoveMapping;
- CMIDIMappingDirective m_Setting;
+
public:
afx_msg void OnLbnSelchangeList1();
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-26 20:40:27 UTC (rev 344)
@@ -2304,7 +2304,7 @@
ORDERINDEX oNextOrder = m_SndFile.Order.GetNextOrderIgnoringSkips(oCurrentOrder);
if((oNextOrder <= 0) || (oNextOrder >= m_SndFile.Order.size())) goto PasteDone;
nPattern = m_SndFile.Order[oNextOrder];
- if(m_SndFile.Patterns.IsValidIndex(nPattern) == false) goto PasteDone;
+ if(m_SndFile.Patterns.IsValidPat(nPattern) == false) goto PasteDone;
m = m_SndFile.Patterns[nPattern];
PrepareUndo(nPattern, 0,0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]);
oCurrentOrder = oNextOrder;
Modified: trunk/OpenMPT/mptrack/Mpt_midi.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-08-26 20:40:27 UTC (rev 344)
@@ -165,6 +165,20 @@
//----------------------------------------------------------------------------
+CString CMIDIMappingDirective::ToString() const
+//---------------------------------------------
+{
+ CString str; str.Preallocate(20);
+ char flags[4] = "000";
+ if(m_Active) flags[0] = '1';
+ if(m_CaptureMIDI) flags[1] = '1';
+ if(m_AllowPatternEdit) flags[2] = '1';
+ str.Format("%s:%d:%x:%d:%d:%d", flags, (int)GetChannel(), (int)GetEvent(), (int)GetController(), (int)m_PluginIndex, m_Parameter);
+ str.Trim();
+ return str;
+}
+
+
size_t CMIDIMapper::GetSerializationSize() const
//---------------------------------------------
{
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-08-26 20:40:27 UTC (rev 344)
@@ -3018,7 +3018,7 @@
//--------------------------------------------------------------------------------
{
static MODCOMMAND m;
- if (rSf.Patterns.IsValidIndex(pos.nPat) && pos.nRow < rSf.Patterns[pos.nPat].GetNumRows() && pos.nChn < rSf.GetNumChannels())
+ if (rSf.Patterns.IsValidPat(pos.nPat) && pos.nRow < rSf.Patterns[pos.nPat].GetNumRows() && pos.nChn < rSf.GetNumChannels())
return rSf.Patterns[pos.nPat].GetpModCommand(pos.nRow, pos.nChn);
else
return &m;
@@ -5125,7 +5125,7 @@
const ROWINDEX iRowCandidate, const PATTERNINDEX iPatCandidate) const
//-------------------------------------------------------------------------------------------
{
- if(rSndFile.Patterns.IsValidIndex(iPatCandidate) && rSndFile.Patterns[iPatCandidate].IsValidRow(iRowCandidate))
+ if(rSndFile.Patterns.IsValidPat(iPatCandidate) && rSndFile.Patterns[iPatCandidate].IsValidRow(iRowCandidate))
{ // Case: Edit position candidates are valid -- use them.
iPat = iPatCandidate;
iRow = iRowCandidate;
Modified: trunk/OpenMPT/mptrack/Vstplug.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Vstplug.cpp 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/Vstplug.cpp 2009-08-26 20:40:27 UTC (rev 344)
@@ -14,6 +14,7 @@
#include "defaultvsteditor.h" //rewbs.defaultPlugGUI
#include "midi.h"
#include "version.h"
+#include "midimappingdialog.h"
#ifdef VST_USE_ALTERNATIVE_MAGIC //Pelya's plugin ID fix. Breaks fx presets, so let's avoid it for now.
#include "Unzip32.h" //For CRC calculation (to detect plugins with same UID)
#endif
@@ -677,6 +678,18 @@
pModDoc->RecordParamChange(pVstPlugin->GetSlot(), index);
}
+ if (CMainFrame::GetInputHandler()->ShiftPressed())
+ {
+ CMainFrame::GetInputHandler()->SetModifierMask(0); // Make sure that the dialog will open only once.
+ CAbstractVstEditor *pVstEditor = pVstPlugin->GetEditor();
+ const HWND oldMIDIRecondWnd = CMainFrame::GetMainFrame()->GetMidiRecordWnd();
+ CMIDIMappingDialog dlg(pVstEditor, *pModDoc->GetSoundFile());
+ dlg.m_Setting.SetParamIndex(index);
+ dlg.m_Setting.SetPlugIndex(pVstPlugin->GetSlot()+1);
+ dlg.DoModal();
+ CMainFrame::GetMainFrame()->SetMidiRecordWnd(oldMIDIRecondWnd);
+ }
+
// Learn macro
CAbstractVstEditor *pVstEditor = pVstPlugin->GetEditor();
if (pVstEditor) {
Modified: trunk/OpenMPT/soundlib/midi.h
===================================================================
--- trunk/OpenMPT/soundlib/midi.h 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/soundlib/midi.h 2009-08-26 20:40:27 UTC (rev 344)
@@ -63,20 +63,12 @@
void SetParamIndex(const int i) {m_Parameter = i;}
uint32 GetParamIndex() const {return m_Parameter;}
- bool operator==(const CMIDIMappingDirective& d) {return memcmp(this, &d, sizeof(CMIDIMappingDirective)) == 0;}
+ bool IsDefault() const {return *this == CMIDIMappingDirective();}
- CString ToString() const
- {
- CString str; str.Preallocate(20);
- char flags[4] = "000";
- if(m_Active) flags[0] = '1';
- if(m_CaptureMIDI) flags[1] = '1';
- if(m_AllowPatternEdit) flags[2] = '1';
- str.Format("%s:%d:%x:%d:%d:%d", flags, (int)GetChannel(), (int)GetEvent(), (int)GetController(), (int)m_PluginIndex, m_Parameter);
- str.Trim();
- return str;
- }
+ bool operator==(const CMIDIMappingDirective& d) const {return memcmp(this, &d, sizeof(CMIDIMappingDirective)) == 0;}
+ CString ToString() const;
+
BYTE GetChnEvent() const {return m_ChnEvent;}
private:
Modified: trunk/OpenMPT/soundlib/patternContainer.h
===================================================================
--- trunk/OpenMPT/soundlib/patternContainer.h 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/soundlib/patternContainer.h 2009-08-26 20:40:27 UTC (rev 344)
@@ -55,6 +55,9 @@
// Return true if pattern can be accessed with operator[](iPat), false otherwise.
bool IsValidIndex(const PATTERNINDEX iPat) const {return (iPat < Size());}
+
+ // Return true if IsValidIndex() is true and the corresponding pattern has allocated modcommand array, false otherwise.
+ bool IsValidPat(const PATTERNINDEX iPat) const {return IsValidIndex(iPat) && (*this)[iPat];}
void ResizeArray(const PATTERNINDEX newSize);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-08-25 20:14:34
|
Revision: 343
http://modplug.svn.sourceforge.net/modplug/?rev=343&view=rev
Author: relabsoluness
Date: 2009-08-25 20:14:24 +0000 (Tue, 25 Aug 2009)
Log Message:
-----------
[Fix] IT loader: Loading song and instrument extensions was broken (since rev. 340).
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_it.cpp
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-25 01:18:21 UTC (rev 342)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-25 20:14:24 UTC (rev 343)
@@ -1285,7 +1285,7 @@
}
// Load instrument and song extensions.
- if(mptStartPos >= dwMemPos && mptStartPos < dwMemLength)
+ if(mptStartPos >= dwMemPos)
{
LPCBYTE ptr = LoadExtendedInstrumentProperties(lpStream + dwMemPos, lpStream + mptStartPos, &interpretModplugmade);
LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos, &interpretModplugmade);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-25 01:18:28
|
Revision: 342
http://modplug.svn.sourceforge.net/modplug/?rev=342&view=rev
Author: saga-games
Date: 2009-08-25 01:18:21 +0000 (Tue, 25 Aug 2009)
Log Message:
-----------
[Fix] IT Compatibility: Don't reset Tremolo on new note, don't ignore tremolo if note volume is 0
[Fix] IT Compatibility: Fixed Tremolo, Vibrato and Panbrello tables
[Fix] IT Compatibility: Ignore S[345]x with x > 3
[Imp] XM Loader: detect a very old MPT version
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
trunk/OpenMPT/soundlib/Tables.cpp
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -2742,6 +2742,11 @@
case 0x30: // vibrato waveform
case 0x40: // tremolo waveform
case 0x50: // panbrello waveform
+ if(((param & 0x0F) > 0x03) && m_SndFile.IsCompatibleMode(TRK_IMPULSETRACKER))
+ {
+ strcpy(s, "ignore");
+ break;
+ }
switch(param & 0x0F)
{
case 0x00: case 0x04: case 0x08: case 0x0C: strcpy(s, "sine wave"); break;
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -186,18 +186,10 @@
if(subChunkSize != 6) break;
{
- int version;
- for(DWORD i = 0; i < subChunkSize; i++)
- {
- if(lpStream[dwChunkPos + i] >= '0' && lpStream[dwChunkPos + i] <= '9')
- {
- version = (version * 10) + (lpStream[dwChunkPos + i] - '0');
- } else
- {
- version = 0;
- break;
- }
- }
+ CHAR cversion[7];
+ memcpy(cversion, lpStream + dwChunkPos, 6);
+ cversion[6] = 0;
+ int version = atoi(cversion);
// Sinaria song dates
if(version == 800211 || version == 940902 || version == 940903 ||
version == 940906 || version == 940914 || version == 941213)
Modified: trunk/OpenMPT/soundlib/Load_xm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -108,9 +108,6 @@
for(int i = 0; i < 20; i++)
if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true;
- if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
- if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8)) bMadeWithModPlug = true;
-
dwHdrSize = LittleEndian(*((DWORD *)(lpStream+60)));
norders = LittleEndianW(*((WORD *)(lpStream+64)));
if ((!norders) || (norders > MAX_ORDERS)) return false;
@@ -121,6 +118,23 @@
// if ((!channels) || (channels > 64)) return false;
if ((!channels) || (channels > MAX_BASECHANNELS)) return false;
// -! BEHAVIOUR_CHANGE#0006
+
+ if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
+ if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v 2.00 ", 20))
+ {
+ bMadeWithModPlug = true;
+ m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, 00);
+ }
+
+ if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8))
+ {
+ //bMadeWithModPlug = true; // Don't set it - it's also used by compatibility export
+ CHAR sVersion[13];
+ memcpy(sVersion, lpStream + 0x26 + 8, 12);
+ sVersion[12] = 0;
+ m_dwLastSavedWithVersion = MptVersion::ToNum(sVersion);
+ }
+
m_nType = MOD_TYPE_XM;
m_nMinPeriod = 27;
m_nMaxPeriod = 54784;
@@ -637,7 +651,7 @@
if(bMadeWithModPlug)
{
SetModFlag(MSF_COMPATIBLE_PLAY, false);
- m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00);
+ if(!m_dwLastSavedWithVersion) m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00);
}
// -> CODE#0027
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -718,7 +718,7 @@
pChn->nPos = 0;
pChn->nPosLo = 0;
if (pChn->nVibratoType < 4) pChn->nVibratoPos = ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))) ? 0x10 : 0;
- if (pChn->nTremoloType < 4) pChn->nTremoloPos = 0;
+ if(!IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->nTremoloType < 4) pChn->nTremoloPos = 0;
}
if (pChn->nPos >= pChn->nLength) pChn->nPos = pChn->nLoopStart;
}
@@ -2541,11 +2541,11 @@
if (pChn->nPeriod) pChn->nPeriod = GetPeriodFromNote(pChn->nNote, pChn->nFineTune, pChn->nC5Speed);
break;
// S3x: Set Vibrato WaveForm
- case 0x30: pChn->nVibratoType = param & 0x07; break;
+ case 0x30: if(((param & 0x0F) < 0x04) || !IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nVibratoType = param & 0x07; break;
// S4x: Set Tremolo WaveForm
- case 0x40: pChn->nTremoloType = param & 0x07; break;
+ case 0x40: if(((param & 0x0F) < 0x04) || !IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nTremoloType = param & 0x07; break;
// S5x: Set Panbrello WaveForm
- case 0x50: pChn->nPanbrelloType = param & 0x07; break;
+ case 0x50: if(((param & 0x0F) < 0x04) || !IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPanbrelloType = param & 0x07; break;
// S6x: Pattern Delay for x frames
case 0x60: m_nFrameDelay = param; break;
// S7x: Envelope Control
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -1190,6 +1190,7 @@
Chn[j].nCommand = 0;
Chn[j].nPatternLoopCount = 0;
Chn[j].nPatternLoop = 0;
+ Chn[j].nVibratoPos = Chn[j].nTremoloPos = Chn[j].nPanbrelloPos = 0;
//IT compatibility 15. Retrigger
if(IsCompatibleMode(TRK_IMPULSETRACKER))
{
@@ -1482,6 +1483,7 @@
Chn[i].nNewLeftVol = Chn[i].nNewRightVol = 0;
Chn[i].nLeftRamp = Chn[i].nRightRamp = 0;
Chn[i].nVolume = 256;
+ Chn[i].nVibratoPos = Chn[i].nTremoloPos = Chn[i].nPanbrelloPos = 0;
//-->Custom tuning related
Chn[i].m_ReCalculateFreqOnFirstTick = false;
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -68,6 +68,9 @@
extern short int ModRampDownTable[64];
extern short int ModSquareTable[64];
extern short int ModRandomTable[64];
+extern short int ITSinusTable[64];
+extern short int ITRampDownTable[64];
+extern short int ITSquareTable[64];
extern DWORD LinearSlideUpTable[256];
extern DWORD LinearSlideDownTable[256];
extern DWORD FineLinearSlideUpTable[16];
@@ -983,16 +986,16 @@
if (pChn->dwFlags & CHN_TREMOLO)
{
UINT trempos = pChn->nTremoloPos & 0x3F;
- if (vol > 0)
+ if (vol > 0 || IsCompatibleMode(TRK_IMPULSETRACKER))
{
int tremattn = (m_nType & MOD_TYPE_XM) ? 5 : 6;
switch (pChn->nTremoloType & 0x03)
{
case 1:
- vol += (ModRampDownTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
+ vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[trempos] : ModRampDownTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn;
break;
case 2:
- vol += (ModSquareTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
+ vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[trempos] : ModSquareTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn;
break;
case 3:
//IT compatibility 19. Use random values
@@ -1002,12 +1005,12 @@
vol += (ModRandomTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
break;
default:
- vol += (ModSinusTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
+ vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[trempos] : ModSinusTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn;
}
}
if ((m_nTickCount) || ((m_nType & (MOD_TYPE_STM|MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
{
- pChn->nTremoloPos = (trempos + pChn->nTremoloSpeed) & 0x3F;
+ pChn->nTremoloPos = (pChn->nTremoloPos + pChn->nTremoloSpeed) & 0x3F;
}
}
@@ -1337,13 +1340,10 @@
switch (pChn->nVibratoType & 0x03)
{
case 1:
- if(IsCompatibleMode(TRK_ALLTRACKERS))
- vdelta = -ModRampDownTable[(vibpos+16) % 64];
- else
- vdelta = ModRampDownTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[(vibpos + 48) % 64] : ModRampDownTable[vibpos];
break;
case 2:
- vdelta = ModSquareTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[(vibpos + 48) % 64] : ModSquareTable[vibpos];
break;
case 3:
//IT compatibility 19. Use random values
@@ -1353,7 +1353,7 @@
vdelta = ModRandomTable[vibpos];
break;
default:
- vdelta = ModSinusTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[(vibpos + 48) % 64] : ModSinusTable[vibpos];
}
if(m_nType == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning)
@@ -1385,11 +1385,14 @@
if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideUpTable[l & 0x03], 0x10000) - period;
}
}
- period += vdelta;
+ if(IsCompatibleMode(TRK_ALLTRACKERS))
+ period -= vdelta;
+ else
+ period += vdelta;
}
if ((m_nTickCount) || ((m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
{
- pChn->nVibratoPos = (vibpos + pChn->nVibratoSpeed) & 0x3F;
+ pChn->nVibratoPos = (pChn->nVibratoPos + pChn->nVibratoSpeed) & 0x3F;
}
}
// Panbrello
@@ -1400,10 +1403,10 @@
switch (pChn->nPanbrelloType & 0x03)
{
case 1:
- pdelta = ModRampDownTable[panpos];
+ pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[panpos] : ModRampDownTable[panpos];
break;
case 2:
- pdelta = ModSquareTable[panpos];
+ pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[panpos] : ModSquareTable[panpos];
break;
case 3:
//IT compatibility 19. Use random values
@@ -1413,10 +1416,10 @@
pdelta = ModRandomTable[panpos];
break;
default:
- pdelta = ModSinusTable[panpos];
+ pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[panpos] : ModSinusTable[panpos];
}
pChn->nPanbrelloPos += pChn->nPanbrelloSpeed;
- pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3;
+ pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> (IsCompatibleMode(TRK_IMPULSETRACKER) ? 4 : 3);
pdelta += pChn->nRealPan;
pChn->nRealPan = CLAMP(pdelta, 0, 256);
Modified: trunk/OpenMPT/soundlib/Tables.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Tables.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Tables.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -154,7 +154,35 @@
42,-34,89,-4,-51,-72,21,-29,112,123,84,-101,-92,98,-54,-95
};
+// Impulse Tracker tables
+// Sinus table
+short int ITSinusTable[64] =
+{
+ 0,12,25,37,49,60,71,81,90,98,106,112,117,122,125,126,
+ 127,126,125,122,117,112,106,98,90,81,71,60,49,37,25,12,
+ 0,-12,-25,-37,-49,-60,-71,-81,-90,-98,-106,-112,-117,-122,-125,-126,
+ -127,-126,-125,-122,-117,-112,-106,-98,-90,-81,-71,-60,-49,-37,-25,-12
+};
+
+// Triangle wave table (ramp down)
+short int ITRampDownTable[64] =
+{
+ 127,123,119,115,111,107,103,99,95,91,87,83,79,75,71,67,
+ 63,59,55,51,47,43,39,35,31,27,23,19,15,11,7,3,
+ 0,-4,-8,-12,-16,-20,-24,-28,-32,-36,-40,-44,-48,-52,-56,-60,
+ -64,-68,-72,-76,-80,-84,-88,-92,-96,-100,-104,-108,-112,-116,-120,-124
+};
+
+// Square wave table
+short int ITSquareTable[64] =
+{
+ 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+ 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
// volume fade tables for Retrig Note:
signed char retrigTable1[16] =
{ 0, 0, 0, 0, 0, 0, 10, 8, 0, 0, 0, 0, 0, 0, 24, 32 };
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-24 20:58:07
|
Revision: 341
http://modplug.svn.sourceforge.net/modplug/?rev=341&view=rev
Author: saga-games
Date: 2009-08-24 20:57:36 +0000 (Mon, 24 Aug 2009)
Log Message:
-----------
[Fix] MOD / XM Loading / Saving: More intelligent conversion of Speed / Tempo commands
[Fix] MOD Loading: Last pattern was not loading in .MODs that have no samples
[Ref] Made some CSoundFile functions private
Modified Paths:
--------------
trunk/OpenMPT/mptrack/typedefs.h
trunk/OpenMPT/soundlib/Load_mod.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Modified: trunk/OpenMPT/mptrack/typedefs.h
===================================================================
--- trunk/OpenMPT/mptrack/typedefs.h 2009-08-24 11:43:54 UTC (rev 340)
+++ trunk/OpenMPT/mptrack/typedefs.h 2009-08-24 20:57:36 UTC (rev 341)
@@ -34,6 +34,8 @@
typedef uint32 ROWINDEX;
const ROWINDEX ROWINDEX_MAX = uint32_max;
typedef uint16 CHANNELINDEX;
+ const CHANNELINDEX CHANNELINDEX_MAX = uint16_max;
+ const CHANNELINDEX CHANNELINDEX_INVALID = CHANNELINDEX_MAX;
typedef uint16 ORDERINDEX;
const ORDERINDEX ORDERINDEX_MAX = uint16_max;
const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX;
Modified: trunk/OpenMPT/soundlib/Load_mod.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-24 11:43:54 UTC (rev 340)
+++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-24 20:57:36 UTC (rev 341)
@@ -41,7 +41,7 @@
case 0x0D: command = CMD_PATTERNBREAK; param = ((param >> 4) * 10) + (param & 0x0F); break;
case 0x0E: command = CMD_MODCMDEX; break;
case 0x0F: command = (param <= (UINT)((m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? 0x1F : 0x20)) ? CMD_SPEED : CMD_TEMPO;
- if ((param == 0xFF) && (m_nSamples == 15)) command = 0; break; //<rewbs> what the hell is this?! :) //<jojo> it's the "stop tune" command! :-P
+ if ((param == 0xFF) && (m_nSamples == 15) && (m_nType & MOD_TYPE_MOD)) command = 0; break; //<rewbs> what the hell is this?! :) //<jojo> it's the "stop tune" command! :-P
// Extension for XM extended effects
case 'G' - 55: command = CMD_GLOBALVOLUME; break; //16
case 'H' - 55: command = CMD_GLOBALVOLSLIDE; if (param & 0xF0) param &= 0xF0; break;
@@ -97,16 +97,24 @@
case CMD_TREMOLO: command = 0x07; break;
case CMD_PANNING8:
command = 0x08;
- if (bXM)
+ if(m_nType & MOD_TYPE_S3M)
{
- if (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (m_nType != MOD_TYPE_XM) && (param <= 0x80))
+ if(param <= 0x80)
{
- param <<= 1;
- if (param > 255) param = 255;
+ param = min(param << 1, 0xFF);
}
- } else
- {
- if ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) || (m_nType == MOD_TYPE_XM)) param >>= 1;
+ else if(param == 0xA4)
+ {
+ if(bCompatibilityExport || !bXM)
+ {
+ command = param = 0;
+ }
+ else
+ {
+ command = 'X' - 55;
+ param = 91;
+ }
+ }
}
break;
case CMD_OFFSET: command = 0x09; break;
@@ -115,8 +123,8 @@
case CMD_VOLUME: command = 0x0C; break;
case CMD_PATTERNBREAK: command = 0x0D; param = ((param / 10) << 4) | (param % 10); break;
case CMD_MODCMDEX: command = 0x0E; break;
- case CMD_SPEED: command = 0x0F; if (param > 0x20) param = 0x20; break;
- case CMD_TEMPO: if (param >= 0x20) { command = 0x0F; break; }
+ case CMD_SPEED: command = 0x0F; param = min(param, (bXM) ? 0x1F : 0x20); break;
+ case CMD_TEMPO: command = 0x0F; param = max(param, (bXM) ? 0x20 : 0x21); break;
case CMD_GLOBALVOLUME: command = 'G' - 55; break;
case CMD_GLOBALVOLSLIDE: command = 'H' - 55; break;
case CMD_KEYOFF: command = 'K' - 55; break;
@@ -355,7 +363,7 @@
if (ipat < MAX_PATTERNS)
{
if(Patterns.Insert(ipat, 64)) break;
- if (dwMemPos + m_nChannels*256 >= dwMemLength) break;
+ if (dwMemPos + m_nChannels * 256 > dwMemLength) break;
MODCOMMAND *m = Patterns[ipat];
LPCBYTE p = lpStream + dwMemPos;
for (UINT j=m_nChannels*64; j; m++,p+=4,j--)
@@ -371,18 +379,21 @@
}
dwMemPos += m_nChannels*256;
}
- // Reading instruments
+
+ // Reading samples
DWORD dwErrCheck = 0;
- for (UINT ismp=1; ismp<=m_nSamples; ismp++) if (Samples[ismp].nLength)
+ for (UINT ismp = 1; ismp <= m_nSamples; ismp++) if (Samples[ismp].nLength)
{
- LPSTR p = (LPSTR)(lpStream+dwMemPos);
+ LPSTR p = (LPSTR)(lpStream + dwMemPos);
UINT flags = 0;
- if (dwMemPos + 5 >= dwMemLength) break;
- if (!_strnicmp(p, "ADPCM", 5))
+ if (dwMemPos + 5 <= dwMemLength)
{
- flags = 3;
- p += 5;
- dwMemPos += 5;
+ if (!_strnicmp(p, "ADPCM", 5))
+ {
+ flags = 3;
+ p += 5;
+ dwMemPos += 5;
+ }
}
DWORD dwSize = ReadSample(&Samples[ismp], flags, p, dwMemLength - dwMemPos);
if (dwSize)
@@ -394,7 +405,7 @@
#ifdef MODPLUG_TRACKER
return true;
#else
- return (dwErrCheck) ? TRUE : FALSE;
+ return (dwErrCheck) ? true : false;
#endif
}
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 11:43:54 UTC (rev 340)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 20:57:36 UTC (rev 341)
@@ -77,17 +77,9 @@
};
#pragma pack()
-BYTE convert_psm_porta(BYTE param, bool bNewFormat)
+inline BYTE convert_psm_porta(BYTE param, bool bNewFormat)
{
- if(bNewFormat)
- {
- return param;
- }
- else
- {
- if(param < 4) return param | 0xF0;
- else return (param >> 2);
- }
+ return ((bNewFormat) ? (param) : ((param < 4) ? (param | 0xF0) : (param >> 2)));
}
bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength)
@@ -109,7 +101,6 @@
// Yep, this seems to be a valid file.
m_nType = MOD_TYPE_PSM;
- //m_dwSongFlags |= SONG_LINEARSLIDES; // TODO
m_nChannels = 0;
dwMemPos += 12;
@@ -207,6 +198,7 @@
break;
}
}
+ // Sinaria song dates
if(version == 800211 || version == 940902 || version == 940903 ||
version == 940906 || version == 940914 || version == 941213)
bNewFormat = true;
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-24 11:43:54 UTC (rev 340)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-24 20:57:36 UTC (rev 341)
@@ -3040,3 +3040,152 @@
return *p;
}
+/* Try to write an (volume) effect in a given channel or any channel of a pattern in a specific row.
+ Usage: nPat - Pattern that should be modified
+ nRow - Row that should be modified
+ nEffect - (Volume) Effect that should be written
+ nParam - Effect that should be written
+ bIsVolumeEffect - Indicates whether the given effect is a volume effect or not
+ nChn - Channel that should be modified - use CHANNELINDEX_INVALID to allow all channels of the given row
+ bAllowMultipleEffects - If false, No effect will be written if an effect of the same type is already present in the channel(s)
+ bAllowNextRow - Indicates whether it is allowed to use the next row if there's no space for the effect
+ bRetry - For internal use only. Indicates whether an effect "rewrite" has already taken place (for recursive calls)
+*/
+bool CSoundFile::TryWriteEffect(PATTERNINDEX nPat, ROWINDEX nRow, BYTE nEffect, BYTE nParam, bool bIsVolumeEffect, CHANNELINDEX nChn, bool bAllowMultipleEffects, bool bAllowNextRow, bool bRetry)
+//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+{
+ // NOTE: Effect remapping is only implemented for a few basic effects.
+ CHANNELINDEX nScanChnMin = nChn, nScanChnMax = nChn;
+ MODCOMMAND *p = Patterns[nPat], *m;
+
+ // Scan all channels
+ if(nChn == CHANNELINDEX_INVALID)
+ {
+ nScanChnMin = 0;
+ nScanChnMax = m_nChannels - 1;
+ }
+
+ // Scan channel(s) for same effect type - if an effect of the same type is already present, exit.
+ if(bAllowMultipleEffects == false)
+ {
+ for(CHANNELINDEX i = nScanChnMin; i <= nScanChnMax; i++)
+ {
+ m = p + nRow * m_nChannels + i;
+ if(!bIsVolumeEffect && m->command == nEffect)
+ return true;
+ if(bIsVolumeEffect && m->volcmd == nEffect)
+ return true;
+ }
+ }
+
+ // Easy case: check if there's some space left to put the effect somewhere
+ for(CHANNELINDEX i = nScanChnMin; i <= nScanChnMax; i++)
+ {
+ m = p + nRow * m_nChannels + i;
+ if(!bIsVolumeEffect && m->command == CMD_NONE)
+ {
+ m->command = nEffect;
+ m->param = nParam;
+ return true;
+ }
+ if(bIsVolumeEffect && m->volcmd == VOLCMD_NONE)
+ {
+ m->volcmd = nEffect;
+ m->vol = nParam;
+ return true;
+ }
+ }
+
+ // Ok, apparently there's no space. If we haven't tried already, try to map it to the volume column or effect column instead.
+ if(bRetry == true) {
+ // Move some effects that also work in the volume column, so there's place for our new effect.
+ if(!bIsVolumeEffect)
+ {
+ for(CHANNELINDEX i = nScanChnMin; i <= nScanChnMax; i++)
+ {
+ m = p + nRow * m_nChannels + i;
+ switch(m->command)
+ {
+ case CMD_VOLUME:
+ m->volcmd = VOLCMD_VOLUME;
+ m->vol = m->param;
+ m->command = nEffect;
+ m->param = nParam;
+ return true;
+
+ case CMD_PANNING8:
+ if(m_nType & MOD_TYPE_S3M && nParam > 0x80)
+ break;
+
+ m->volcmd = VOLCMD_VOLUME;
+ m->command = nEffect;
+
+ if(m_nType & MOD_TYPE_S3M)
+ {
+ m->vol = m->param >> 1;
+ }
+ else
+ {
+ m->vol = (m->param >> 2) + 1;
+ }
+
+ m->param = nParam;
+ return true;
+ }
+ }
+ }
+
+ // Let's try it again by writing into the "other" effect column.
+ BYTE nNewEffect = CMD_NONE;
+ if(bIsVolumeEffect)
+ {
+ switch(nEffect)
+ {
+ case VOLCMD_PANNING:
+ nNewEffect = CMD_PANNING8;
+ if(m_nType & MOD_TYPE_S3M)
+ nParam <<= 1;
+ else
+ nParam = min(nParam << 2, 0xFF);
+ break;
+ case VOLCMD_VOLUME:
+ nNewEffect = CMD_VOLUME;
+ break;
+ }
+ } else
+ {
+ switch(nEffect)
+ {
+ case CMD_PANNING8:
+ nNewEffect = VOLCMD_PANNING;
+ if(m_nType & MOD_TYPE_S3M)
+ {
+ if(nParam <= 0x80)
+ nParam >>= 1;
+ else
+ nNewEffect = CMD_NONE;
+ }
+ else
+ {
+ nParam = (nParam >> 2) + 1;
+ }
+ break;
+ case CMD_VOLUME:
+ nNewEffect = CMD_VOLUME;
+ break;
+ }
+ }
+ if(nNewEffect != CMD_NONE)
+ {
+ if(TryWriteEffect(nPat, nRow, nNewEffect, nParam, !bIsVolumeEffect, nChn, bAllowMultipleEffects, bAllowNextRow, false) == true) return true;
+ }
+ }
+
+ // Try in the next row if possible (this may also happen if we already retried)
+ if(bAllowNextRow && (nRow + 1 < Patterns[nPat].GetNumRows()))
+ {
+ return TryWriteEffect(nPat, nRow + 1, nEffect, nParam, bIsVolumeEffect, nChn, bAllowMultipleEffects, bAllowNextRow, bRetry);
+ }
+
+ return false;
+}
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2009-08-24 11:43:54 UTC (rev 340)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2009-08-24 20:57:36 UTC (rev 341)
@@ -1148,7 +1148,15 @@
void CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut);
void NoteChange(UINT nChn, int note, BOOL bPorta=FALSE, BOOL bResetEnv=TRUE, BOOL bManual=FALSE);
void InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta=FALSE,BOOL bUpdVol=TRUE,BOOL bResetEnv=TRUE);
+
// Channel Effects
+ void KeyOff(UINT nChn);
+ // Global Effects
+ void SetTempo(UINT param, bool setAsNonModcommand = false);
+ void SetSpeed(UINT param);
+
+private:
+ // Channel Effects
void PortamentoUp(MODCHANNEL *pChn, UINT param, const bool fineAsRegular = false);
void PortamentoDown(MODCHANNEL *pChn, UINT param, const bool fineAsRegular = false);
void MidiPortamento(MODCHANNEL *pChn, int param);
@@ -1170,7 +1178,6 @@
void RetrigNote(UINT nChn, UINT param, UINT offset=0); //rewbs.volOffset: added last param
void SampleOffset(UINT nChn, UINT param, bool bPorta); //rewbs.volOffset: moved offset code to own method
void NoteCut(UINT nChn, UINT nTick);
- void KeyOff(UINT nChn);
int PatternLoop(MODCHANNEL *, UINT param);
void ExtendedMODCommands(UINT nChn, UINT param);
void ExtendedS3MCommands(UINT nChn, UINT param);
@@ -1180,12 +1187,14 @@
void SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier=256) const;
// Low-Level effect processing
void DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide);
- // Global Effects
- void SetTempo(UINT param, bool setAsNonModcommand = false);
- void SetSpeed(UINT param);
void GlobalVolSlide(UINT param, UINT * nOldGlobalVolSlide);
DWORD IsSongFinished(UINT nOrder, UINT nRow) const;
BOOL IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const;
+public:
+
+ // Write pattern effect functions
+ bool TryWriteEffect(PATTERNINDEX nPat, ROWINDEX nRow, BYTE nEffect, BYTE nParam, bool bIsVolumeEffect, CHANNELINDEX nChn = CHANNELINDEX_INVALID, bool bAllowMultipleEffects = true, bool bAllowNextRow = false, bool bRetry = true);
+
// Read/Write sample functions
char GetDeltaValue(char prev, UINT n) const { return (char)(prev + CompressionTable[n & 0x0F]); }
UINT PackSample(int &sample, int next);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-24 11:44:05
|
Revision: 340
http://modplug.svn.sourceforge.net/modplug/?rev=340&view=rev
Author: saga-games
Date: 2009-08-24 11:43:54 +0000 (Mon, 24 Aug 2009)
Log Message:
-----------
[Fix] IT Loader: Unset release env nodes for IT files made with IT 1.x, fix fadeout values
[Imp] PSM Loader: Several fixes for "new new" PSM format, channel panning, etc.
[Imp] S3M Loader: Don't write unnecessary invalid order items in the order table
[Imp] LHA Decoder: Several fixes (patch by kode54)
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_s3m.cpp
trunk/OpenMPT/unlha/EXTRACT.CPP
trunk/OpenMPT/unlha/HUF.CPP
trunk/OpenMPT/unlha/LHEXT.CPP
trunk/OpenMPT/unlha/SLIDE.CPP
trunk/OpenMPT/unlha/SLIDEHUF.H
trunk/OpenMPT/unlha/UNLHA32.H
trunk/OpenMPT/unlha/Unlha.cpp
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-24 11:43:54 UTC (rev 340)
@@ -230,7 +230,7 @@
const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p;
memcpy(pIns->name, pis->name, 26);
memcpy(pIns->filename, pis->filename, 12);
- pIns->nFadeOut = pis->fadeout << 6;
+ pIns->nFadeOut = pis->fadeout << 7;
pIns->nGlobalVol = 64;
for (UINT j=0; j<NOTE_MAX; j++)
{
@@ -260,6 +260,10 @@
pIns->nNNA = pis->nna;
pIns->nDCT = pis->dnc;
pIns->nPan = 0x80;
+
+ pIns->VolEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
+ pIns->PanEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
+ pIns->PitchEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
} else
{
const ITINSTRUMENT *pis = (const ITINSTRUMENT *)p;
@@ -276,7 +280,7 @@
}
if (pis->mbank<=128)
pIns->wMidiBank = pis->mbank;
- pIns->nFadeOut = pis->fadeout << 5;
+ pIns->nFadeOut = pis->fadeout << 5; // should be 6?
pIns->nGlobalVol = pis->gbv >> 1;
if (pIns->nGlobalVol > 64) pIns->nGlobalVol = 64;
for (UINT j=0; j<NOTE_MAX; j++)
@@ -1281,7 +1285,7 @@
}
// Load instrument and song extensions.
- if(mptStartPos >= dwMemPos)
+ if(mptStartPos >= dwMemPos && mptStartPos < dwMemLength)
{
LPCBYTE ptr = LoadExtendedInstrumentProperties(lpStream + dwMemPos, lpStream + mptStartPos, &interpretModplugmade);
LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos, &interpretModplugmade);
@@ -2001,7 +2005,7 @@
//if (pIns->nDCT<DCT_PLUGIN) iti.dct = pIns->nDCT; else iti.dct =0;
iti.dct = pIns->nDCT; //rewbs.instroVSTi: will other apps barf if they get an unknown DCT?
iti.dca = pIns->nDNA;
- iti.fadeout = pIns->nFadeOut >> 5;
+ iti.fadeout = pIns->nFadeOut >> 5; // should be 6?
iti.pps = pIns->nPPS;
iti.ppc = pIns->nPPC;
iti.gbv = (BYTE)(pIns->nGlobalVol << 1);
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 11:43:54 UTC (rev 340)
@@ -38,7 +38,7 @@
};
-struct PSMSAMPLEHEADER // Regular sample header
+struct PSMOLDSAMPLEHEADER // Regular sample header
{
BYTE flags;
CHAR fileName[8]; // Filename of the original module (without extension)
@@ -49,14 +49,15 @@
DWORD sampleLength;
DWORD loopStart;
DWORD loopEnd; // FF FF FF FF = end of sample
- WORD unknown3;
+ BYTE unknown3;
+ BYTE defaulPan; // unused?
BYTE defaultVolume;
DWORD unknown4;
WORD C5Freq;
CHAR unknown5[21]; // 00 ... 00
};
-struct PSMSAMPLEHEADERSINARIA // Sinaria sample header
+struct PSMNEWSAMPLEHEADER // Sinaria sample header (and possibly other games)
{
BYTE flags;
CHAR fileName[8]; // Filename of the original module (without extension)
@@ -68,20 +69,25 @@
DWORD loopStart;
DWORD loopEnd;
WORD unknown3;
- BYTE unknown4;
+ BYTE defaultPan; // unused?
BYTE defaultVolume;
- DWORD unknown5;
+ DWORD unknown4;
WORD C5Freq;
- CHAR unknown6[16]; // 00 ... 00
+ CHAR unknown5[16]; // 00 ... 00
};
#pragma pack()
-BYTE convert_psm_effect(BYTE param, bool bIsSinaria)
+BYTE convert_psm_porta(BYTE param, bool bNewFormat)
{
- if(bIsSinaria)
+ if(bNewFormat)
+ {
return param;
+ }
else
- return (param >> 2);
+ {
+ if(param < 4) return param | 0xF0;
+ else return (param >> 2);
+ }
}
bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength)
@@ -91,7 +97,7 @@
if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false;
DWORD dwMemPos = 0;
- bool bIsSinaria = false; // The game "Sinaria" uses a slightly modified PSM structure
+ bool bNewFormat = false; // The game "Sinaria" uses a slightly modified PSM structure
ASSERT_CAN_READ(12);
PSMHEADER shdr;
@@ -148,11 +154,11 @@
// Pattern ID (something like "P0 " or "P13 ") follows
if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false;
- if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bIsSinaria = true;
+ if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bNewFormat = true;
char patternID[4];
- memcpy(patternID, lpStream + dwMemPos + 5 + (bIsSinaria ? 3 : 0), 3);
+ memcpy(patternID, lpStream + dwMemPos + 5 + (bNewFormat ? 3 : 0), 3);
patternID[3] = 0;
- patternOffsets.push_back(dwMemPos + 8 + (bIsSinaria ? 4 : 0));
+ patternOffsets.push_back(dwMemPos + 8 + (bNewFormat ? 4 : 0));
patternIDs.push_back(atoi(patternID));
numPatterns++;
@@ -185,23 +191,46 @@
switch(subChunkID)
{
- case 0x45544144: // "DATE" - Song date (YYMMDD)
- if(subChunkSize < 6) break;
+ case 0x45544144: // "DATE" - Conversion date (YYMMDD)
+ if(subChunkSize != 6) break;
+ {
+ int version;
+ for(DWORD i = 0; i < subChunkSize; i++)
+ {
+ if(lpStream[dwChunkPos + i] >= '0' && lpStream[dwChunkPos + i] <= '9')
+ {
+ version = (version * 10) + (lpStream[dwChunkPos + i] - '0');
+ } else
+ {
+ version = 0;
+ break;
+ }
+ }
+ if(version == 800211 || version == 940902 || version == 940903 ||
+ version == 940906 || version == 940914 || version == 941213)
+ bNewFormat = true;
+ }
+ #ifdef DEBUG
CHAR cDate[7];
memcpy(cDate, lpStream + dwChunkPos, 6);
cDate[6] = 0;
- sComment += " - Date: ";
+ sComment += " - Build Date: ";
sComment += cDate;
+ if(bNewFormat) sComment += " (New Format)";
+ else sComment += " (Old Format)";
+ #endif
break;
case 0x484C504F: // "OPLH" - Order list, channel + module settings
{
if(subChunkSize < 9) return false;
- // First two bytes = "Memory alloc, roughly ordlen + 10, if too small, song freezes"
+ // First two bytes = Number of chunks that follow
+ //WORD nTotalChunks = LittleEndian(*(WORD *)(lpStream + dwChunkPos));
// Now, the interesting part begins!
DWORD dwSettingsOffset = dwChunkPos + 2;
+ WORD nChunkCount = 0, nFirstOrderChunk = (WORD)-1;
while(dwSettingsOffset - dwChunkPos + 1 < subChunkSize)
{
switch(lpStream[dwSettingsOffset])
@@ -216,7 +245,7 @@
for(PATTERNINDEX i = 0; i < patternIDs.size(); i++)
{
char patternID[4];
- memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bIsSinaria ? 3 : 0), 3);
+ memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bNewFormat ? 3 : 0), 3);
patternID[3] = 0;
DWORD nPattern = atoi(patternID);
if(patternIDs[i] == nPattern)
@@ -225,23 +254,25 @@
break;
}
}
- dwSettingsOffset += 5 + (bIsSinaria ? 4 : 0);
+ if(nFirstOrderChunk == (WORD)-1) nFirstOrderChunk = nChunkCount;
+ dwSettingsOffset += 5 + (bNewFormat ? 4 : 0);
break;
- case 0x04:
- /* It looks like the 2nd number of this chunk could be the restart position,
- where position = ((number < 15) ? 0 : (number - 15)) */
-
- //uint32 pos = lpStream[dwSettingsOffset + 1] | (lpStream[dwSettingsOffset + 2] << 8);
-
- // NOTE: This should not be global! (Extreme Pinball!!!)
- #ifdef DEBUG
+ case 0x04: // Restart position
{
- char s[32];
- wsprintf(s, " - restart %d", (lpStream[dwSettingsOffset + 1] < 15) ? 0 : lpStream[dwSettingsOffset + 1] - 15);
- sComment += s;
+ // NOTE: This should not be global! (Extreme Pinball!!!)
+ WORD nRestartChunk = LittleEndian(*(WORD *)(lpStream + dwSettingsOffset + 1));
+ ORDERINDEX nRestartPosition = 0;
+ if(nRestartChunk == 0) nRestartPosition = 0;
+ else if(nRestartChunk >= nFirstOrderChunk) nRestartPosition = (ORDERINDEX)(nRestartChunk - nFirstOrderChunk);
+ #ifdef DEBUG
+ {
+ char s[32];
+ wsprintf(s, " - restart pos %d", nRestartPosition);
+ sComment += s;
+ }
+ #endif
}
- #endif
dwSettingsOffset += 3;
break;
@@ -277,7 +308,7 @@
switch(lpStream[dwSettingsOffset + 3])
{
case 0:
- ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2];
+ ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2] ^ 128;
break;
case 2:
@@ -309,6 +340,7 @@
break;
}
+ nChunkCount++;
}
Order.push_back(Order.GetInvalidPatIndex());
}
@@ -322,7 +354,7 @@
switch(lpStream[dwChunkPos + i])
{
case 0:
- ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] - 128;
+ ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] ^ 128;
break;
case 2:
@@ -357,10 +389,10 @@
break;
case 0x504D5344: // DSMP - Samples
- if(!bIsSinaria)
+ if(!bNewFormat)
{
- if(chunkSize < sizeof(PSMSAMPLEHEADER)) return false;
- PSMSAMPLEHEADER *pSample = (PSMSAMPLEHEADER *)(lpStream + dwMemPos);
+ if(chunkSize < sizeof(PSMOLDSAMPLEHEADER)) return false;
+ PSMOLDSAMPLEHEADER *pSample = (PSMOLDSAMPLEHEADER *)(lpStream + dwMemPos);
SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
m_nSamples = max(m_nSamples, smp);
memcpy(m_szNames[smp], pSample->sampleName, 31);
@@ -379,12 +411,12 @@
if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength;
// Delta-encoded samples
- ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADER)), Samples[smp].nLength);
+ ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMOLDSAMPLEHEADER)), Samples[smp].nLength);
} else
{
// Sinaria uses a slightly different sample header
- if(chunkSize < sizeof(PSMSAMPLEHEADERSINARIA)) return false;
- PSMSAMPLEHEADERSINARIA *pSample = (PSMSAMPLEHEADERSINARIA *)(lpStream + dwMemPos);
+ if(chunkSize < sizeof(PSMNEWSAMPLEHEADER)) return false;
+ PSMNEWSAMPLEHEADER *pSample = (PSMNEWSAMPLEHEADER *)(lpStream + dwMemPos);
SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
m_nSamples = max(m_nSamples, smp);
memcpy(m_szNames[smp], pSample->sampleName, 31);
@@ -403,7 +435,7 @@
if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength;
// Delta-encoded samples
- ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADERSINARIA)), Samples[smp].nLength);
+ ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMNEWSAMPLEHEADER)), Samples[smp].nLength);
}
break;
@@ -419,24 +451,24 @@
if(m_nChannels == 0)
return false;
// Now that we know the number of channels, we can go through all the patterns.
- for(PATTERNINDEX i = 0; i < numPatterns; i++)
+ for(PATTERNINDEX nPat = 0; nPat < numPatterns; nPat++)
{
- DWORD dwPatternOffset = patternOffsets[i];
+ DWORD dwPatternOffset = patternOffsets[nPat];
if(dwPatternOffset + 2 > dwMemLength) return false;
WORD patternSize = LittleEndianW(*(WORD *)(lpStream + dwPatternOffset));
dwPatternOffset += 2;
- if(Patterns.Insert(i, patternSize))
+ if(Patterns.Insert(nPat, patternSize))
{
CString s;
- s.Format(TEXT("Allocating patterns failed starting from pattern %u"), i);
+ s.Format(TEXT("Allocating patterns failed starting from pattern %u"), nPat);
MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
break;
}
// Read pattern.
MODCOMMAND *row_data;
- row_data = Patterns[i];
+ row_data = Patterns[nPat];
for(int nRow = 0; nRow < patternSize; nRow++)
{
@@ -458,15 +490,15 @@
if(dwRowOffset + 1 > dwMemLength) return false;
// Note present
BYTE bNote = lpStream[dwRowOffset];
- if(!bIsSinaria)
+ if(!bNewFormat)
{
if(bNote == 0xFF)
bNote = NOTE_NOTECUT;
else
- bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ if(bNote < 129) bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
} else
{
- bNote += 36;
+ if(bNote < 85) bNote += 36;
}
m->note = bNote;
dwRowOffset++;
@@ -500,41 +532,45 @@
// Volslides
case 0x01: // fine volslide up
command = CMD_VOLUMESLIDE;
- param = (param << 3) | 0x0F;
+ if (bNewFormat) param = (param << 4) | 0x0F;
+ else param = ((param & 0x1E) << 3) | 0x0F;
break;
case 0x02: // volslide up
command = CMD_VOLUMESLIDE;
- param = (param << 3);
+ if (bNewFormat) param = 0xF0 & (param << 4);
+ else param = 0xF0 & (param << 3);
break;
case 0x03: // fine volslide down
command = CMD_VOLUMESLIDE;
- param = 0xF0 | (param >> 1);
+ if (bNewFormat) param |= 0xF0;
+ else param = 0xF0 | (param >> 1);
break;
case 0x04: // volslide down
command = CMD_VOLUMESLIDE;
- param >>= 1;
+ if (bNewFormat) param &= 0x0F;
+ else param = (param >> 1) & 0x0F;
break;
// Portamento
case 0x0B: // fine portamento up
command = CMD_PORTAMENTOUP;
- param = 0xF0 | convert_psm_effect(param, bIsSinaria);
+ param = 0xF0 | convert_psm_porta(param, bNewFormat);
break;
case 0x0C: // portamento up
command = CMD_PORTAMENTOUP;
- param = convert_psm_effect(param, bIsSinaria);
+ param = convert_psm_porta(param, bNewFormat);
break;
case 0x0D: // fine portamento down
command = CMD_PORTAMENTODOWN;
- param = 0xF0 | convert_psm_effect(param, bIsSinaria);
+ param = 0xF0 | convert_psm_porta(param, bNewFormat);
break;
case 0x0E: // portamento down
command = CMD_PORTAMENTODOWN;
- param = convert_psm_effect(param, bIsSinaria);
+ param = convert_psm_porta(param, bNewFormat);
break;
case 0x0F: // tone portamento
command = CMD_TONEPORTAMENTO;
- param = convert_psm_effect(param, bIsSinaria);
+ if(!bNewFormat) param >>= 2;
break;
case 0x11: // glissando control
command = CMD_S3MCMDEX;
Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-24 11:43:54 UTC (rev 340)
@@ -513,10 +513,9 @@
//TODO: Check whether the 0xF0 mask is correct.
// (there are two bytes reserved from the header, so why 0xF0 mask?).
//nbo = (GetNumPatterns() + 15) & 0xF0;
- nbo = Order.GetLengthTailTrimmed() + 15;
+ nbo = Order.GetLengthTailTrimmed();
if(nbo > 0xF0) nbo = 0xF0;
- nbo = nbo & 0xF0;
- if (!nbo) nbo = 16;
+ if (!nbo) nbo = 1;
header[0x20] = nbo & 0xFF;
header[0x21] = nbo >> 8;
nbi = m_nInstruments;
Modified: trunk/OpenMPT/unlha/EXTRACT.CPP
===================================================================
--- trunk/OpenMPT/unlha/EXTRACT.CPP 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/EXTRACT.CPP 2009-08-24 11:43:54 UTC (rev 340)
@@ -16,7 +16,7 @@
switch (method)
{
case 0:
- case 8:
+ case 10:
{
int len1 = m_dwOutputLen - (int)(outfp - m_lpOutputFile);
int len2 = m_dwStreamLen - infp;
@@ -30,14 +30,22 @@
crc = 0;
}
break;
- case 6: // -lzs-
+ case 8: // -lzs-
LzInterface.dicbit = 11;
decode(&LzInterface);
break;
case 1: // -lh1-
case 4: // -lh4-
- case 7: // -lz5-
+ case 9: // -lz5-
LzInterface.dicbit = 12;
+ decode(&LzInterface);
+ break;
+ case 6: // -lh6-
+ LzInterface.dicbit = 15;
+ decode(&LzInterface);
+ break;
+ case 7: // -lh7-
+ LzInterface.dicbit = 16;
default:
decode(&LzInterface);
}
Modified: trunk/OpenMPT/unlha/HUF.CPP
===================================================================
--- trunk/OpenMPT/unlha/HUF.CPP 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/HUF.CPP 2009-08-24 11:43:54 UTC (rev 340)
@@ -4,7 +4,7 @@
#define NP (MAX_DICBIT + 1)
#define NT (USHRT_BIT + 3)
-#define PBIT 4 /* smallest integer such that (1 << PBIT) > NP */
+//#define PBIT 4 /* smallest integer such that (1 << PBIT) > NP */
#define TBIT 5 /* smallest integer such that (1 << TBIT) > NT */
#define NPT 0x80
@@ -16,8 +16,10 @@
t_freq[2 * NT - 1];
} HUFDATA;
-HUFDATA *gpHufData = NULL;
+//HUFDATA *gpHufData = NULL;
+#define gpHufData (*((HUFDATA **)&m_pHufData))
+
VOID CLhaArchive::InitHufTables()
{
gpHufData = (HUFDATA *)(m_pDecoderData + 4096);
@@ -104,7 +106,7 @@
blocksize = getbits(16);
read_pt_len(NT, TBIT, 3);
read_c_len();
- read_pt_len(NP, PBIT, -1);
+ read_pt_len(np, pbit, -1);
}
blocksize--;
j = gpHufData->c_table[bitbuf >> 4];
@@ -125,21 +127,28 @@
unsigned short j, mask;
j = gpHufData->pt_table[bitbuf >> (16 - 8)];
- if (j < NP) fillbuf(gpHufData->pt_len[j]);
+ if (j < np) fillbuf(gpHufData->pt_len[j]);
else {
fillbuf(8); mask = 1 << (16 - 1);
do {
j = (bitbuf & mask) ? right[j] : left[j];
mask >>= 1;
- } while (j >= NP);
+ } while (j >= np);
fillbuf(gpHufData->pt_len[j] - 8);
}
if (j != 0) j = (1 << (j - 1)) + getbits(j - 1);
return j;
}
-void CLhaArchive::decode_start_st1()
+void CLhaArchive::decode_start_st1(int dicbit)
{
+ switch (dicbit)
+ {
+ case 12:
+ case 13: pbit = 4; np = 14; break;
+ case 15: pbit = 5; np = 16; break;
+ case 16: pbit = 5; np = 17; break;
+ }
init_getbits();
blocksize = 0;
}
Modified: trunk/OpenMPT/unlha/LHEXT.CPP
===================================================================
--- trunk/OpenMPT/unlha/LHEXT.CPP 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/LHEXT.CPP 2009-08-24 11:43:54 UTC (rev 340)
@@ -26,10 +26,10 @@
}
-const char *methods[10] =
+const char *methods[12] =
{
- "-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-",
- "-lh5-", "-lzs-", "-lz5-", "-lz4-", NULL
+ "-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-", "-lh5-",
+ "-lh6-", "-lh7-", "-lzs-", "-lz5-", "-lz4-", NULL
};
Modified: trunk/OpenMPT/unlha/SLIDE.CPP
===================================================================
--- trunk/OpenMPT/unlha/SLIDE.CPP 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/SLIDE.CPP 2009-08-24 11:43:54 UTC (rev 340)
@@ -43,17 +43,19 @@
{
case 1: decode_start_dyn(); break;
case 2: decode_start_st0(); break;
- case 3: decode_start_st1(); break;
- case 4: decode_start_st1(); break;
- case 5: decode_start_lzs(); break;
- case 6: decode_start_lz5(text); break;
+ case 3: decode_start_st1(12); break;
+ case 4: decode_start_st1(13); break;
+ case 5: decode_start_st1(15); break;
+ case 6: decode_start_st1(16); break;
+ case 7: decode_start_lzs(); break;
+ case 8: decode_start_lz5(text); break;
default: decode_start_fix(); break;
}
#ifdef LHADEBUG
Log("Starting Decode (original size=%d)...\n", pinterface->original);
#endif
dicsiz1 = dicsiz - 1;
- offset = (pinterface->method == 6) ? 0x100 - 2 : 0x100 - 3;
+ offset = (pinterface->method == 8) ? 0x100 - 2 : 0x100 - 3;
count = 0;
loc = 0;
while (count < pinterface->original)
@@ -64,8 +66,10 @@
case 2: c = decode_c_st0(); break;
case 3: c = decode_c_st1(); break;
case 4: c = decode_c_st1(); break;
- case 5: c = decode_c_lzs(); break;
- case 6: c = decode_c_lz5(); break;
+ case 5: c = decode_c_st1(); break;
+ case 6: c = decode_c_st1(); break;
+ case 7: c = decode_c_lzs(); break;
+ case 8: c = decode_c_lz5(); break;
default: c = decode_c_dyn(); break;
}
if (c <= 255)
@@ -86,8 +90,10 @@
case 2: d = decode_p_st0(); break;
case 3: d = decode_p_st1(); break;
case 4: d = decode_p_st1(); break;
- case 5: d = decode_p_lzs(); break;
- case 6: d = decode_p_lz5(); break;
+ case 5: d = decode_p_st1(); break;
+ case 6: d = decode_p_st1(); break;
+ case 7: d = decode_p_lzs(); break;
+ case 8: d = decode_p_lz5(); break;
default: d = decode_p_st0(); break;
}
int j = c - offset;
Modified: trunk/OpenMPT/unlha/SLIDEHUF.H
===================================================================
--- trunk/OpenMPT/unlha/SLIDEHUF.H 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/SLIDEHUF.H 2009-08-24 11:43:54 UTC (rev 340)
@@ -11,7 +11,7 @@
/* from slide.c */
-#define MAX_DICBIT 13
+#define MAX_DICBIT 16 // 13
#define MAX_DICSIZ (1 << MAX_DICBIT)
#define MATCHBIT 8 /* bits for MAXMATCH - THRESHOLD */
Modified: trunk/OpenMPT/unlha/UNLHA32.H
===================================================================
--- trunk/OpenMPT/unlha/UNLHA32.H 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/UNLHA32.H 2009-08-24 11:43:54 UTC (rev 340)
@@ -72,9 +72,10 @@
unsigned short *freq;
unsigned char *buf;
unsigned short bufsiz, blocksize;
- unsigned int np;
+ unsigned int np, pbit;
+ void * m_pHufData;
int flag, flagcnt, matchpos, prev_char;
- unsigned short dicsiz, dicbit, maxmatch, loc;
+ unsigned int dicsiz, dicbit, maxmatch, loc;
unsigned short left[2 * NC - 1], right[2 * NC - 1];
protected:
@@ -113,7 +114,7 @@
protected:
// huf.cpp
VOID InitHufTables();
- void decode_start_st1();
+ void decode_start_st1(int dicbit);
void read_pt_len(short nn, short nbit, short i_special);
void read_c_len();
unsigned short decode_c_st1();
Modified: trunk/OpenMPT/unlha/Unlha.cpp
===================================================================
--- trunk/OpenMPT/unlha/Unlha.cpp 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/Unlha.cpp 2009-08-24 11:43:54 UTC (rev 340)
@@ -69,6 +69,8 @@
m_lpOutputFile = 0;
m_dwOutputLen = 0;
m_pDecoderData = NULL;
+
+ gpHufData = NULL;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-23 22:13:59
|
Revision: 339
http://modplug.svn.sourceforge.net/modplug/?rev=339&view=rev
Author: saga-games
Date: 2009-08-23 21:07:17 +0000 (Sun, 23 Aug 2009)
Log Message:
-----------
[Fix] PSM Loading: Didn't work at all in the release build (only debug mode worked). Many more fixes to the loader code to also load PSMs from the game Sinaria. Furthermore, effect conversion seems to be about right now.
[Fix] XM Compatibility: Volume command Ux should not enable Vibrato at all, it only sets the vibrato speed
[Fix] XM Compatibility: Pxy effect was too deep
[Imp] XM Loading: Detect MPT-made XMs more reliably
[Imp] XM Loading: Make XMs with strange pattern header sizes load correctly (removed some code that was there to make really, really broken XMs load - would this work at all?)
[Imp] XM Saveing: Include version number in "made with" string.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-22 22:47:59 UTC (rev 338)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-23 21:07:17 UTC (rev 339)
@@ -3,17 +3,19 @@
* Authors: Johannes Schultz
*
* This is partly based on http://www.shikadi.net/moddingwiki/ProTracker_Studio_Module
- * and partly reverse-engineered.
+ * and partly reverse-engineered. Also thanks to the author of foo_dumb, the source code
+ * gave me a few clues. :)
*
* What's playing?
- * - Epic Pinball - Seems to be working perfectly with linear freq slides enabled
+ * - Epic Pinball - Perfect! (the old tunes in PSM16 format are not supported)
* - Extreme Pinball - Default tempo / speed / restart position of subtunes is missing.
* I'm using the last default values, restart position is still completely missing
- * - Jazz Jackrabbit - Hmm, I don't like some of the portas (BONUS.PSM - the guitar portamento is too "deep"), but apart from that it's great.
+ * - Jazz Jackrabbit - Perfect!
* - One Must Fall! - Perfect! (I modelled the volume slide and portamento conversion after this, as I got the original MTM files)
* - Silverball - Currently not supported (old PSM16 format)
+ * - Sinaria - Seems to work more or less (never played the game, so I can't really tell...)
*
- * Effect conversion should be about right, however I have my doubts wheter linear freq slides are used or not.
+ * Effect conversion should be about right...
*/
#include "stdafx.h"
@@ -36,44 +38,52 @@
};
-struct PSMSAMPLEHEADERTEST // apparently, this is wrong.
+struct PSMSAMPLEHEADER // Regular sample header
{
- CHAR sampleFormat[9];
+ BYTE flags;
+ CHAR fileName[8]; // Filename of the original module (without extension)
DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal)
CHAR sampleName[33];
CHAR unknown1[6]; // 00 00 00 00 00 FF
WORD sampleNumber;
+ DWORD sampleLength;
DWORD loopStart;
- CHAR loop; // 1 = loop
- CHAR unknown2[3]; // 00 00 00 00 00 FF
DWORD loopEnd; // FF FF FF FF = end of sample
WORD unknown3;
- CHAR defaultVolume;
+ BYTE defaultVolume;
DWORD unknown4;
WORD C5Freq;
- CHAR padding[21]; // 00 ... 00
+ CHAR unknown5[21]; // 00 ... 00
};
-struct PSMSAMPLEHEADER // Use this instead
+struct PSMSAMPLEHEADERSINARIA // Sinaria sample header
{
BYTE flags;
- CHAR fileName[8];
- DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal)
+ CHAR fileName[8]; // Filename of the original module (without extension)
+ CHAR sampleID[8]; // INS0...INS99999
CHAR sampleName[33];
CHAR unknown1[6]; // 00 00 00 00 00 FF
WORD sampleNumber;
DWORD sampleLength;
DWORD loopStart;
- DWORD loopEnd; // FF FF FF FF = end of sample
+ DWORD loopEnd;
WORD unknown3;
- CHAR defaultVolume;
- DWORD unknown4;
+ BYTE unknown4;
+ BYTE defaultVolume;
+ DWORD unknown5;
WORD C5Freq;
- CHAR unknown5[21]; // 00 ... 00
+ CHAR unknown6[16]; // 00 ... 00
};
-
#pragma pack()
+BYTE convert_psm_effect(BYTE param, bool bIsSinaria)
+{
+ if(bIsSinaria)
+ return param;
+ else
+ return (param >> 2);
+}
+
bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength)
//-----------------------------------------------------------------------
{
@@ -81,6 +91,7 @@
if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false;
DWORD dwMemPos = 0;
+ bool bIsSinaria = false; // The game "Sinaria" uses a slightly modified PSM structure
ASSERT_CAN_READ(12);
PSMHEADER shdr;
@@ -92,7 +103,7 @@
// Yep, this seems to be a valid file.
m_nType = MOD_TYPE_PSM;
- m_dwSongFlags |= SONG_LINEARSLIDES; // Seems to be correct for Epic Pinball and Jazz Jackrabbit?
+ //m_dwSongFlags |= SONG_LINEARSLIDES; // TODO
m_nChannels = 0;
dwMemPos += 12;
@@ -137,10 +148,11 @@
// Pattern ID (something like "P0 " or "P13 ") follows
if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false;
+ if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bIsSinaria = true;
char patternID[4];
- memcpy(patternID, lpStream + dwMemPos + 5, 3);
+ memcpy(patternID, lpStream + dwMemPos + 5 + (bIsSinaria ? 3 : 0), 3);
patternID[3] = 0;
- patternOffsets.push_back(dwMemPos + 8);
+ patternOffsets.push_back(dwMemPos + 8 + (bIsSinaria ? 4 : 0));
patternIDs.push_back(atoi(patternID));
numPatterns++;
@@ -179,25 +191,22 @@
CHAR cDate[7];
memcpy(cDate, lpStream + dwChunkPos, 6);
cDate[6] = 0;
- sComment += "\r\nDate: ";
+ sComment += " - Date: ";
sComment += cDate;
break;
case 0x484C504F: // "OPLH" - Order list, channel + module settings
{
if(subChunkSize < 9) return false;
- // First byte = "Memory alloc, roughly ordlen + 10, if too small, song freezes"
- if(LittleEndian(*(DWORD *)(lpStream + dwChunkPos + 1)) != 0xFF000C00 // "Something"
- || LittleEndian(*(DWORD *)(lpStream + dwChunkPos + 5)) != 0x00010000) // "Something"
- return false;
+ // First two bytes = "Memory alloc, roughly ordlen + 10, if too small, song freezes"
// Now, the interesting part begins!
- DWORD dwSettingsOffset = dwChunkPos + 9;
+ DWORD dwSettingsOffset = dwChunkPos + 2;
while(dwSettingsOffset - dwChunkPos + 1 < subChunkSize)
{
switch(lpStream[dwSettingsOffset])
{
- case 0x00: // Seems to be the End item
+ case 0x00: // End
dwSettingsOffset += 1;
break;
@@ -207,7 +216,7 @@
for(PATTERNINDEX i = 0; i < patternIDs.size(); i++)
{
char patternID[4];
- memcpy(patternID, lpStream + dwSettingsOffset + 2, 3);
+ memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bIsSinaria ? 3 : 0), 3);
patternID[3] = 0;
DWORD nPattern = atoi(patternID);
if(patternIDs[i] == nPattern)
@@ -216,25 +225,29 @@
break;
}
}
- dwSettingsOffset += 5;
+ dwSettingsOffset += 5 + (bIsSinaria ? 4 : 0);
break;
case 0x04:
/* It looks like the 2nd number of this chunk could be the restart position,
where position = ((number < 15) ? 0 : (number - 15)) */
+
+ //uint32 pos = lpStream[dwSettingsOffset + 1] | (lpStream[dwSettingsOffset + 2] << 8);
+
+ // NOTE: This should not be global! (Extreme Pinball!!!)
#ifdef DEBUG
{
char s[32];
wsprintf(s, " - restart %d", (lpStream[dwSettingsOffset + 1] < 15) ? 0 : lpStream[dwSettingsOffset + 1] - 15);
sComment += s;
- dwSettingsOffset += 3;
}
#endif
+ dwSettingsOffset += 3;
break;
case 0x07: // Default Speed
if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
- // NOTE: This should not be global! (Extreme Pinball!!!)
+ // Same note as above!
m_nDefaultSpeed = lpStream[dwSettingsOffset + 1];
dwSettingsOffset += 2;
break;
@@ -246,19 +259,49 @@
dwSettingsOffset += 2;
break;
- case 0x0D: // This is a channel header
+ case 0x0C: // Sample map table (???)
+ if(dwSettingsOffset - dwChunkPos + 7 > subChunkSize) break;
+
+ if (lpStream[dwSettingsOffset + 1] != 0x00 || lpStream[dwSettingsOffset + 2] != 0xFF ||
+ lpStream[dwSettingsOffset + 3] != 0x00 || lpStream[dwSettingsOffset + 4] != 0x00 ||
+ lpStream[dwSettingsOffset + 5] != 0x01 || lpStream[dwSettingsOffset + 6] != 0x00)
+ return false;
+ dwSettingsOffset += 7;
+ break;
+
+ case 0x0D: // Channel panning table
if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) break;
- ChnSettings[min(lpStream[dwSettingsOffset + 1], pSong->numChannels)].nPan = lpStream[dwSettingsOffset + 2];
- // Last byte: "either 0, 2 or 4 (Some sort of priority?)"
+
+ {
+ CHANNELINDEX nChn = min(lpStream[dwSettingsOffset + 1], pSong->numChannels);
+ switch(lpStream[dwSettingsOffset + 3])
+ {
+ case 0:
+ ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2];
+ break;
+
+ case 2:
+ ChnSettings[nChn].nPan = 128;
+ ChnSettings[nChn].dwFlags |= CHN_SURROUND;
+ break;
+
+ case 4:
+ ChnSettings[nChn].nPan = 128;
+ break;
+
+ }
+ }
dwSettingsOffset += 4;
break;
- case 0x0E: // Unknown - "0E <ChnID> FF"
+ case 0x0E: // Channel volume table
if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break;
+ ChnSettings[min(lpStream[dwSettingsOffset + 1], pSong->numChannels)].nVolume = (lpStream[dwSettingsOffset + 2] >> 2) + 1;
+
dwSettingsOffset += 3;
break;
- default: // How the hell should this happen? I've listened through all existing (original) PSM files. :)
+ default: // How the hell should this happen? I've listened through almost all existing (original) PSM files. :)
CString s;
s.Format("Please report to the OpenMPT team: Unknown chunk %d found at position %d (in the OPLH chunk of this PSM file)", lpStream[dwSettingsOffset], dwSettingsOffset);
MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
@@ -271,6 +314,29 @@
}
break;
+ case 0x4E415050: // PPAN - Channel panning table (used in Sinaria)
+ if(subChunkSize & 1) return false;
+ for(DWORD i = 0; i < subChunkSize; i += 2)
+ {
+ if((i >> 1) >= m_nChannels) break;
+ switch(lpStream[dwChunkPos + i])
+ {
+ case 0:
+ ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] - 128;
+ break;
+
+ case 2:
+ ChnSettings[i >> 1].nPan = 128;
+ ChnSettings[i >> 1].dwFlags |= CHN_SURROUND;
+ break;
+
+ case 4:
+ ChnSettings[i >> 1].nPan = 128;
+ break;
+ }
+ }
+ break;
+
case 0x54544150: // PATT - Pattern list
// We don't really need this.
break;
@@ -291,7 +357,7 @@
break;
case 0x504D5344: // DSMP - Samples
-
+ if(!bIsSinaria)
{
if(chunkSize < sizeof(PSMSAMPLEHEADER)) return false;
PSMSAMPLEHEADER *pSample = (PSMSAMPLEHEADER *)(lpStream + dwMemPos);
@@ -310,11 +376,34 @@
Samples[smp].nPan = 128;
Samples[smp].nVolume = (pSample->defaultVolume + 1) << 1;
Samples[smp].uFlags = (pSample->flags & 0x80) ? CHN_LOOP : 0;
- if(Samples[smp].nLoopStart > 0) Samples[smp].nLoopStart--;
if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength;
// Delta-encoded samples
ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADER)), Samples[smp].nLength);
+ } else
+ {
+ // Sinaria uses a slightly different sample header
+ if(chunkSize < sizeof(PSMSAMPLEHEADERSINARIA)) return false;
+ PSMSAMPLEHEADERSINARIA *pSample = (PSMSAMPLEHEADERSINARIA *)(lpStream + dwMemPos);
+ SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
+ m_nSamples = max(m_nSamples, smp);
+ memcpy(m_szNames[smp], pSample->sampleName, 31);
+ m_szNames[smp][31] = 0;
+ memcpy(Samples[smp].filename, pSample->fileName, 8);
+ Samples[smp].filename[8] = 0;
+
+ Samples[smp].nGlobalVol = 0x40;
+ Samples[smp].nC5Speed = LittleEndianW(pSample->C5Freq);
+ Samples[smp].nLength = LittleEndian(pSample->sampleLength);
+ Samples[smp].nLoopStart = LittleEndian(pSample->loopStart);
+ Samples[smp].nLoopEnd = LittleEndian(pSample->loopEnd);
+ Samples[smp].nPan = 128;
+ Samples[smp].nVolume = (pSample->defaultVolume + 1) << 1;
+ Samples[smp].uFlags = (pSample->flags & 0x80) ? CHN_LOOP : 0;
+ if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength;
+
+ // Delta-encoded samples
+ ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADERSINARIA)), Samples[smp].nLength);
}
break;
@@ -369,10 +458,16 @@
if(dwRowOffset + 1 > dwMemLength) return false;
// Note present
BYTE bNote = lpStream[dwRowOffset];
- if(bNote == 0xFF)
- bNote = NOTE_NOTECUT;
- else
- bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ if(!bIsSinaria)
+ {
+ if(bNote == 0xFF)
+ bNote = NOTE_NOTECUT;
+ else
+ bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ } else
+ {
+ bNote += 36;
+ }
m->note = bNote;
dwRowOffset++;
}
@@ -423,23 +518,23 @@
// Portamento
case 0x0B: // fine portamento up
command = CMD_PORTAMENTOUP;
- param = 0xF0 | (param >> 1);
+ param = 0xF0 | convert_psm_effect(param, bIsSinaria);
break;
case 0x0C: // portamento up
command = CMD_PORTAMENTOUP;
- param >>= 1;
+ param = convert_psm_effect(param, bIsSinaria);
break;
case 0x0D: // fine portamento down
command = CMD_PORTAMENTODOWN;
- param = 0xF0 | (param >> 1);
+ param = 0xF0 | convert_psm_effect(param, bIsSinaria);
break;
case 0x0E: // portamento down
command = CMD_PORTAMENTODOWN;
- param >>= 1;
+ param = convert_psm_effect(param, bIsSinaria);
break;
case 0x0F: // tone portamento
command = CMD_TONEPORTAMENTO;
- param >>= 2;
+ param = convert_psm_effect(param, bIsSinaria);
break;
case 0x11: // glissando control
command = CMD_S3MCMDEX;
@@ -502,6 +597,7 @@
case 0x33: // position jump
command = CMD_POSITIONJUMP;
param >>= 1;
+ dwRowOffset += 1;
break;
case 0x34: // pattern break
command = CMD_PATTERNBREAK;
@@ -543,8 +639,11 @@
break;
default:
+ #ifdef DEBUG
ASSERT(false);
- //command = CMD_NONE;
+ #else
+ command = CMD_NONE;
+ #endif
break;
}
Modified: trunk/OpenMPT/soundlib/Load_xm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-22 22:47:59 UTC (rev 338)
+++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-23 21:07:17 UTC (rev 339)
@@ -109,7 +109,7 @@
if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true;
if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
- if (!memcmp((LPCSTR)lpStream + 0x26, "Open ModPlug Tracker", 20)) bMadeWithModPlug = true;
+ if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8)) bMadeWithModPlug = true;
dwHdrSize = LittleEndian(*((DWORD *)(lpStream+60)));
norders = LittleEndianW(*((WORD *)(lpStream+64)));
@@ -180,20 +180,20 @@
UINT ipatmap = pattern_map[ipat];
DWORD dwSize = 0;
WORD rows=64, packsize=0;
- dwSize = LittleEndian(*((DWORD *)(lpStream+dwMemPos)));
- while ((dwMemPos + dwSize >= dwMemLength) || (dwSize & 0xFFFFFF00))
+ dwSize = LittleEndian(*((DWORD *)(lpStream + dwMemPos)));
+ /*while ((dwMemPos + dwSize >= dwMemLength) || (dwSize & 0xFFFFFF00))
{
if (dwMemPos + 4 >= dwMemLength) break;
dwMemPos++;
dwSize = LittleEndian(*((DWORD *)(lpStream+dwMemPos)));
- }
- rows = LittleEndianW(*((WORD *)(lpStream+dwMemPos+5)));
+ }*/
+ rows = LittleEndianW(*((WORD *)(lpStream + dwMemPos + 5)));
// -> CODE#0008
// -> DESC="#define to set pattern size"
// if ((!rows) || (rows > 256)) rows = 64;
if ((!rows) || (rows > MAX_PATTERN_ROWS)) rows = 64;
// -> BEHAVIOUR_CHANGE#0008
- packsize = LittleEndianW(*((WORD *)(lpStream+dwMemPos+7)));
+ packsize = LittleEndianW(*((WORD *)(lpStream + dwMemPos + 7)));
if (dwMemPos + dwSize + 4 > dwMemLength) return true;
dwMemPos += dwSize;
if (dwMemPos + packsize > dwMemLength) return true;
@@ -694,9 +694,9 @@
fwrite("Extended Module: ", 17, 1, f);
fwrite(m_szNames[0], 20, 1, f);
s[0] = 0x1A;
- lstrcpy((LPSTR)&s[1], (nPacking) ? "MOD Plugin packed " : "Open ModPlug Tracker");
- s[21] = 0x04;
- s[22] = 0x01;
+ lstrcpy((LPSTR)&s[1], (nPacking) ? "MOD Plugin packed " : "OpenMPT " MPT_VERSION_STR " ");
+ s[21] = 0x04; // Version number
+ s[22] = 0x01; // XM Format v1.04
fwrite(&s[0], 23, 1, f);
// Writing song header
memset(&header, 0, sizeof(header));
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-22 22:47:59 UTC (rev 338)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-23 21:07:17 UTC (rev 339)
@@ -1420,7 +1420,10 @@
break;
case VOLCMD_VIBRATOSPEED:
- Vibrato(pChn, vol << 4);
+ if(IsCompatibleMode(TRK_FASTTRACKER2))
+ pChn->nVibratoSpeed = vol & 0x0F;
+ else
+ Vibrato(pChn, vol << 4);
break;
case VOLCMD_VIBRATODEPTH:
@@ -2386,6 +2389,8 @@
{
if (param & 0x0F) nPanSlide = -(int)((param & 0x0F) << 2);
else nPanSlide = (int)((param & 0xF0) >> 2);
+ if(IsCompatibleMode(TRK_FASTTRACKER2))
+ nPanSlide >>= 2;
}
}
if (nPanSlide)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-22 22:48:10
|
Revision: 338
http://modplug.svn.sourceforge.net/modplug/?rev=338&view=rev
Author: saga-games
Date: 2009-08-22 22:47:59 +0000 (Sat, 22 Aug 2009)
Log Message:
-----------
[Fix] Macro config: "Show All" FX display starts at 1 instead of 0, like all other FX enumerations
[Imp] PSM Loader: Several improvements; Near-perfect effect conversion.
[Imp] XM Loader: Detecting MPT-Made XM files more reliably
[Imp] Playback: If restart position is 0 and a subtune is played (i.e. a tune separated with a "---" pattern), OpenMPT will now try to jump back to the first order of this subtune instead.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/dlg_misc.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-08-22 10:21:22 UTC (rev 337)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-08-22 22:47:59 UTC (rev 338)
@@ -2096,7 +2096,7 @@
{
pVstPlugin->GetParamName(param, s, 256);
paramName = s;
- line.Format("FX%d: %s\t Param %d (%x): %s\n", plug, plugName, param, param+80, paramName);
+ line.Format("FX%d: %s\t Param %d (%x): %s\n", plug + 1, plugName, param, param+80, paramName);
message += line;
}
}
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-22 10:21:22 UTC (rev 337)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-22 22:47:59 UTC (rev 338)
@@ -6,12 +6,14 @@
* and partly reverse-engineered.
*
* What's playing?
- * - Epic Pinball - Seems to be working perfectly, apart from some portas? (esp. Deep Sea, Shareware Info - Linear freq slides needed!?)
+ * - Epic Pinball - Seems to be working perfectly with linear freq slides enabled
* - Extreme Pinball - Default tempo / speed / restart position of subtunes is missing.
* I'm using the last default values, restart position is still completely missing
- * - Jazz Jackrabbit - Hmm, I don't like some of the portas, but apart from that it's great. (same problem as Epic Pinball)
+ * - Jazz Jackrabbit - Hmm, I don't like some of the portas (BONUS.PSM - the guitar portamento is too "deep"), but apart from that it's great.
* - One Must Fall! - Perfect! (I modelled the volume slide and portamento conversion after this, as I got the original MTM files)
* - Silverball - Currently not supported (old PSM16 format)
+ *
+ * Effect conversion should be about right, however I have my doubts wheter linear freq slides are used or not.
*/
#include "stdafx.h"
@@ -55,7 +57,7 @@
struct PSMSAMPLEHEADER // Use this instead
{
BYTE flags;
- CHAR sampleFormat[8];
+ CHAR fileName[8];
DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal)
CHAR sampleName[33];
CHAR unknown1[6]; // 00 00 00 00 00 FF
@@ -72,13 +74,6 @@
#pragma pack()
-BYTE convert_psm_param(BYTE param)
-{
- // special conversion of some PSM parameters. is this done correctly?
- return param >> 1;
- //return (param + 1) >> 1;
-}
-
bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength)
//-----------------------------------------------------------------------
{
@@ -97,7 +92,7 @@
// Yep, this seems to be a valid file.
m_nType = MOD_TYPE_PSM;
- //m_dwSongFlags |= SONG_LINEARSLIDES; // TODO
+ m_dwSongFlags |= SONG_LINEARSLIDES; // Seems to be correct for Epic Pinball and Jazz Jackrabbit?
m_nChannels = 0;
dwMemPos += 12;
@@ -142,8 +137,11 @@
// Pattern ID (something like "P0 " or "P13 ") follows
if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false;
+ char patternID[4];
+ memcpy(patternID, lpStream + dwMemPos + 5, 3);
+ patternID[3] = 0;
patternOffsets.push_back(dwMemPos + 8);
- patternIDs.push_back(*(DWORD *)(lpStream + dwMemPos + 4));
+ patternIDs.push_back(atoi(patternID));
numPatterns++;
// Convert later as we have to know how many channels there are.
@@ -177,12 +175,12 @@
{
case 0x45544144: // "DATE" - Song date (YYMMDD)
if(subChunkSize < 6) break;
+
CHAR cDate[7];
memcpy(cDate, lpStream + dwChunkPos, 6);
cDate[6] = 0;
sComment += "\r\nDate: ";
sComment += cDate;
- // We don't care about the date.
break;
case 0x484C504F: // "OPLH" - Order list, channel + module settings
@@ -199,12 +197,20 @@
{
switch(lpStream[dwSettingsOffset])
{
+ case 0x00: // Seems to be the End item
+ dwSettingsOffset += 1;
+ break;
+
case 0x01: // Order list item
if(dwSettingsOffset - dwChunkPos + 5 > subChunkSize) return false;
// Pattern name follows - find pattern (this is the orderlist)
for(PATTERNINDEX i = 0; i < patternIDs.size(); i++)
{
- if(patternIDs[i] == *(DWORD *)(lpStream + dwSettingsOffset + 1))
+ char patternID[4];
+ memcpy(patternID, lpStream + dwSettingsOffset + 2, 3);
+ patternID[3] = 0;
+ DWORD nPattern = atoi(patternID);
+ if(patternIDs[i] == nPattern)
{
Order.push_back(i);
break;
@@ -213,9 +219,17 @@
dwSettingsOffset += 5;
break;
- case 0x04: // "end?" "04 03 00 00" in most cases (not Extreme Pinball - maybe restart positions are dumped here?)
- if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) return false;
- dwSettingsOffset += 4;
+ case 0x04:
+ /* It looks like the 2nd number of this chunk could be the restart position,
+ where position = ((number < 15) ? 0 : (number - 15)) */
+ #ifdef DEBUG
+ {
+ char s[32];
+ wsprintf(s, " - restart %d", (lpStream[dwSettingsOffset + 1] < 15) ? 0 : lpStream[dwSettingsOffset + 1] - 15);
+ sComment += s;
+ dwSettingsOffset += 3;
+ }
+ #endif
break;
case 0x07: // Default Speed
@@ -243,12 +257,8 @@
if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break;
dwSettingsOffset += 3;
break;
-
- case 0x00: // "end?"
- dwSettingsOffset += 1;
- break;
- default: // How the hell should this happen? I've listened through all existing PSM files. :)
+ default: // How the hell should this happen? I've listened through all existing (original) PSM files. :)
CString s;
s.Format("Please report to the OpenMPT team: Unknown chunk %d found at position %d (in the OPLH chunk of this PSM file)", lpStream[dwSettingsOffset], dwSettingsOffset);
MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
@@ -288,7 +298,9 @@
SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
m_nSamples = max(m_nSamples, smp);
memcpy(m_szNames[smp], pSample->sampleName, 31);
- m_szNames[0][31] = 0;
+ m_szNames[smp][31] = 0;
+ memcpy(Samples[smp].filename, pSample->fileName, 8);
+ Samples[smp].filename[8] = 0;
Samples[smp].nGlobalVol = 0x40;
Samples[smp].nC5Speed = LittleEndianW(pSample->C5Freq);
@@ -317,7 +329,6 @@
if(m_nChannels == 0)
return false;
-
// Now that we know the number of channels, we can go through all the patterns.
for(PATTERNINDEX i = 0; i < numPatterns; i++)
{
@@ -350,7 +361,7 @@
if(dwRowOffset + 1 > dwMemLength) return false;
BYTE mask = lpStream[dwRowOffset];
// Point to the correct channel
- MODCOMMAND *m = row_data + min(m_nChannels, lpStream[dwRowOffset + 1]);
+ MODCOMMAND *m = row_data + min(m_nChannels - 1, lpStream[dwRowOffset + 1]);
dwRowOffset += 2;
if(mask & 0x80)
@@ -358,7 +369,10 @@
if(dwRowOffset + 1 > dwMemLength) return false;
// Note present
BYTE bNote = lpStream[dwRowOffset];
- bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ if(bNote == 0xFF)
+ bNote = NOTE_NOTECUT;
+ else
+ bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
m->note = bNote;
dwRowOffset++;
}
@@ -376,7 +390,7 @@
if(dwRowOffset + 1 > dwMemLength) return false;
// Volume present
m->volcmd = VOLCMD_VOLUME;
- m->vol = (min(lpStream[dwRowOffset], 127)) >> 1;
+ m->vol = (min(lpStream[dwRowOffset], 127) + 1) >> 1;
dwRowOffset++;
}
@@ -409,29 +423,29 @@
// Portamento
case 0x0B: // fine portamento up
command = CMD_PORTAMENTOUP;
- param = 0xF0 | convert_psm_param(param);
+ param = 0xF0 | (param >> 1);
break;
case 0x0C: // portamento up
command = CMD_PORTAMENTOUP;
- param = convert_psm_param(param);
+ param >>= 1;
break;
case 0x0D: // fine portamento down
command = CMD_PORTAMENTODOWN;
- param = 0xF0 | convert_psm_param(param);
+ param = 0xF0 | (param >> 1);
break;
case 0x0E: // portamento down
command = CMD_PORTAMENTODOWN;
- param = convert_psm_param(param);
+ param >>= 1;
break;
case 0x0F: // tone portamento
command = CMD_TONEPORTAMENTO;
- param = convert_psm_param(param);
+ param >>= 2;
break;
- case 0x10: // glissando control
+ case 0x11: // glissando control
command = CMD_S3MCMDEX;
param = 0x10 | (param & 0x01);
break;
- case 0x11: // tone portamento + volslide up
+ case 0x10: // tone portamento + volslide up
command = CMD_TONEPORTAVOL;
param = param & 0xF0;
break;
@@ -472,9 +486,8 @@
param = lpStream[dwRowOffset + 2];
dwRowOffset += 2;
break;
- case 0x2A: // set finetune
- command = CMD_S3MCMDEX;
- param = 0x40 | (param & 0x0F);
+ case 0x2A: // retrigger
+ command = CMD_RETRIG;
break;
case 0x2B: // note cut
command = CMD_S3MCMDEX;
@@ -488,9 +501,11 @@
// Position change
case 0x33: // position jump
command = CMD_POSITIONJUMP;
+ param >>= 1;
break;
case 0x34: // pattern break
command = CMD_PATTERNBREAK;
+ param >>= 1;
break;
case 0x35: // loop pattern
command = CMD_S3MCMDEX;
@@ -514,16 +529,22 @@
command = CMD_ARPEGGIO;
break;
case 0x48: // set finetune
- command = CMD_MODCMDEX;
- param = 0x50 | (param & 0x0F);
+ command = CMD_S3MCMDEX;
+ param = 0x20 | (param & 0x0F);
break;
case 0x49: // set balance
command = CMD_S3MCMDEX;
param = 0x80 | (param & 0x0F);
break;
+ case CMD_MODCMDEX:
+ // for some strange home-made tunes
+ command = CMD_S3MCMDEX;
+ break;
+
default:
- //ASSERT(false);
+ ASSERT(false);
+ //command = CMD_NONE;
break;
}
Modified: trunk/OpenMPT/soundlib/Load_xm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-22 10:21:22 UTC (rev 337)
+++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-22 22:47:59 UTC (rev 338)
@@ -95,14 +95,22 @@
BYTE samples_used[(MAX_SAMPLES+7)/8];
UINT unused_samples;
- bool bMadeWithModPlug = false;
+ bool bMadeWithModPlug = false, bProbablyMadeWithModPlug = false;
// set this here already because XMs compressed with BoobieSqueezer will exit the function early
SetModFlag(MSF_COMPATIBLE_PLAY, true);
m_nChannels = 0;
if ((!lpStream) || (dwMemLength < 0xAA)) return false; // the smallest XM I know is 174 Bytes
if (_strnicmp((LPCSTR)lpStream, "Extended Module", 15)) return false;
+
memcpy(m_szNames[0], lpStream + 17, 20);
+ // look for null-terminated song name - that's most likely a tune made with modplug
+ for(int i = 0; i < 20; i++)
+ if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true;
+
+ if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
+ if (!memcmp((LPCSTR)lpStream + 0x26, "Open ModPlug Tracker", 20)) bMadeWithModPlug = true;
+
dwHdrSize = LittleEndian(*((DWORD *)(lpStream+60)));
norders = LittleEndianW(*((WORD *)(lpStream+64)));
if ((!norders) || (norders > MAX_ORDERS)) return false;
@@ -328,6 +336,7 @@
min(ihsize - sizeof(XMINSTRUMENTHEADER), sizeof(XMSAMPLEHEADER)));
xmsh.shsize = LittleEndian(xmsh.shsize);
+ if(xmsh.shsize == 0 && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
for (int i = 0; i < 24; ++i) {
xmsh.venv[i] = LittleEndianW(xmsh.venv[i]);
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-22 10:21:22 UTC (rev 337)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-22 22:47:59 UTC (rev 338)
@@ -645,6 +645,21 @@
if (!m_nRepeatCount) return FALSE;
+ ORDERINDEX nRestartPosOverride = m_nRestartPos;
+ if(!m_nRestartPos && m_nCurrentPattern <= Order.size())
+ {
+ // if we're in a subtune and there's no restart position, go to the first order of the subtune
+ for(ORDERINDEX iOrd = m_nCurrentPattern - 1; iOrd > 0; iOrd--)
+ {
+ if(Order[iOrd] == Order.GetInvalidPatIndex())
+ {
+ // Jump back to first order of this subtune
+ nRestartPosOverride = iOrd + 1;
+ break;
+ }
+ }
+ }
+
if(CMainFrame::GetMainFrame())
{
// If channel resetting is disabled, we will emulate a pattern break
@@ -652,7 +667,7 @@
m_dwSongFlags |= SONG_BREAKTOROW;
}
- if (!m_nRestartPos && !(m_dwSongFlags & SONG_BREAKTOROW))
+ if (!nRestartPosOverride && !(m_dwSongFlags & SONG_BREAKTOROW))
{
//rewbs.instroVSTi: stop all VSTi at end of song, if looping.
StopAllVsti();
@@ -690,7 +705,7 @@
//Handle Repeat position
if (m_nRepeatCount > 0) m_nRepeatCount--;
- m_nCurrentPattern = m_nRestartPos;
+ m_nCurrentPattern = nRestartPosOverride;
//m_nRow = 0;
m_dwSongFlags &= ~SONG_BREAKTOROW;
//If restart pos points to +++, move along
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-22 10:21:34
|
Revision: 337
http://modplug.svn.sourceforge.net/modplug/?rev=337&view=rev
Author: saga-games
Date: 2009-08-22 10:21:22 +0000 (Sat, 22 Aug 2009)
Log Message:
-----------
[Fix] A brand new PSM loader! Ditched the old and buggy loader as the new loader works way better, it can even handle modules from Extreme Pinball. Some finetuning is still mandatory, though.
[Fix] S3M Loading: Disable loop for files with very short loop at the beginning of the sample
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_s3m.cpp
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-20 20:43:52 UTC (rev 336)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-22 10:21:22 UTC (rev 337)
@@ -1,841 +1,558 @@
/*
- * This source code is public domain.
+ * Purpose: Load new PSM (ProTracker Studio) modules
+ * Authors: Johannes Schultz
*
- * Authors: Olivier Lapicque <oli...@jp...>
-*/
+ * This is partly based on http://www.shikadi.net/moddingwiki/ProTracker_Studio_Module
+ * and partly reverse-engineered.
+ *
+ * What's playing?
+ * - Epic Pinball - Seems to be working perfectly, apart from some portas? (esp. Deep Sea, Shareware Info - Linear freq slides needed!?)
+ * - Extreme Pinball - Default tempo / speed / restart position of subtunes is missing.
+ * I'm using the last default values, restart position is still completely missing
+ * - Jazz Jackrabbit - Hmm, I don't like some of the portas, but apart from that it's great. (same problem as Epic Pinball)
+ * - One Must Fall! - Perfect! (I modelled the volume slide and portamento conversion after this, as I got the original MTM files)
+ * - Silverball - Currently not supported (old PSM16 format)
+ */
-
-///////////////////////////////////////////////////
-//
-// PSM module loader
-//
-///////////////////////////////////////////////////
#include "stdafx.h"
#include "sndfile.h"
-//#define PSM_LOG
-
-#define PSM_ID_NEW 0x204d5350 // "PSM "
-#define PSM_ID_OLD 0xfe4d5350 // "PSM\xFE"
-#define IFFID_FILE 0x454c4946
-#define IFFID_TITL 0x4c544954
-#define IFFID_SDFT 0x54464453
-#define IFFID_PBOD 0x444f4250
-#define IFFID_SONG 0x474e4f53
-#define IFFID_PATT 0x54544150
-#define IFFID_DSMP 0x504d5344
-#define IFFID_OPLH 0x484c504f
-
#pragma pack(1)
-typedef struct _PSMCHUNK
+struct PSMHEADER
{
- DWORD id;
- DWORD len;
- DWORD listid;
-} PSMCHUNK;
+ DWORD formatID; // "PSM " (new format)
+ DWORD fileSize; // Filesize - 12
+ DWORD fileInfoID; // "FILE" Start of file info
+};
-typedef struct _PSMSONGHDR
+struct PSMSONGHEADER
{
- CHAR songname[8]; // "MAINSONG"
- BYTE reserved1;
- BYTE reserved2;
- BYTE channels;
-} PSMSONGHDR;
+ CHAR songType[9]; // Mostly "MAINSONG " (But not in Extreme Pinball!)
+ BYTE compression; // 1 - uncompressed
+ BYTE numChannels; // Number of channels, usually 4
-typedef struct _PSMPATTERN
+};
+
+struct PSMSAMPLEHEADERTEST // apparently, this is wrong.
{
- DWORD size;
- DWORD name;
- WORD rows;
- WORD reserved1;
- BYTE data[4];
-} PSMPATTERN;
+ CHAR sampleFormat[9];
+ DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal)
+ CHAR sampleName[33];
+ CHAR unknown1[6]; // 00 00 00 00 00 FF
+ WORD sampleNumber;
+ DWORD loopStart;
+ CHAR loop; // 1 = loop
+ CHAR unknown2[3]; // 00 00 00 00 00 FF
+ DWORD loopEnd; // FF FF FF FF = end of sample
+ WORD unknown3;
+ CHAR defaultVolume;
+ DWORD unknown4;
+ WORD C5Freq;
+ CHAR padding[21]; // 00 ... 00
+};
-typedef struct _PSMSAMPLE
+struct PSMSAMPLEHEADER // Use this instead
{
BYTE flags;
- CHAR songname[8];
- DWORD smpid;
- CHAR samplename[34];
- DWORD reserved1;
- BYTE reserved2;
- BYTE insno;
- BYTE reserved3;
- DWORD length;
- DWORD loopstart;
- DWORD loopend;
- WORD reserved4;
- BYTE defvol;
- DWORD reserved5;
- DWORD samplerate;
- BYTE reserved6[19];
-} PSMSAMPLE;
+ CHAR sampleFormat[8];
+ DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal)
+ CHAR sampleName[33];
+ CHAR unknown1[6]; // 00 00 00 00 00 FF
+ WORD sampleNumber;
+ DWORD sampleLength;
+ DWORD loopStart;
+ DWORD loopEnd; // FF FF FF FF = end of sample
+ WORD unknown3;
+ CHAR defaultVolume;
+ DWORD unknown4;
+ WORD C5Freq;
+ CHAR unknown5[21]; // 00 ... 00
+};
#pragma pack()
+BYTE convert_psm_param(BYTE param)
+{
+ // special conversion of some PSM parameters. is this done correctly?
+ return param >> 1;
+ //return (param + 1) >> 1;
+}
-bool CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
-//-----------------------------------------------------------
+bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength)
+//-----------------------------------------------------------------------
{
- PSMCHUNK *pfh = (PSMCHUNK *)lpStream;
- DWORD dwMemPos, dwSongPos;
- DWORD smpnames[MAX_SAMPLES];
- DWORD patptrs[MAX_PATTERNS];
- BYTE samplemap[MAX_SAMPLES];
- UINT nPatterns;
+ #define ASSERT_CAN_READ(x) \
+ if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false;
- // Chunk0: "PSM ",filesize,"FILE"
- if (dwMemLength < 256) return false;
- if (pfh->id == PSM_ID_OLD)
- {
- #ifdef PSM_LOG
- Log("Old PSM format not supported\n");
- #endif
- return false;
- }
- if ((pfh->id != PSM_ID_NEW) || (pfh->len+12 > dwMemLength) || (pfh->listid != IFFID_FILE)) return false;
+ DWORD dwMemPos = 0;
+
+ ASSERT_CAN_READ(12);
+ PSMHEADER shdr;
+ memcpy(&shdr, lpStream, sizeof(PSMHEADER));
+ if(LittleEndian(shdr.formatID) != 0x204d5350 // "PSM "
+ || LittleEndian(shdr.fileSize) != dwMemLength - 12
+ || LittleEndian(shdr.fileInfoID) != 0x454C4946 // "FILE"
+ ) return false;
+
+ // Yep, this seems to be a valid file.
m_nType = MOD_TYPE_PSM;
- m_nChannels = 16;
- m_nSamples = 0;
- nPatterns = 0;
- dwMemPos = 12;
- dwSongPos = 0;
- for (UINT iChPan=0; iChPan<16; iChPan++)
+ //m_dwSongFlags |= SONG_LINEARSLIDES; // TODO
+ m_nChannels = 0;
+
+ dwMemPos += 12;
+
+ memset(m_szNames, 0, sizeof(m_szNames));
+
+ m_nVSTiVolume = m_nSamplePreAmp = 48; // not supported in this format, so use a good default value
+
+ // pattern offset and identifier
+ PATTERNINDEX numPatterns = 0;
+ vector<DWORD> patternOffsets;
+ vector<DWORD> patternIDs;
+ patternOffsets.clear();
+ patternIDs.clear();
+ Order.clear();
+
+ std::string sComment; // we will store some information about the tune here
+
+ while(dwMemPos + 8 < dwMemLength)
{
- UINT pan = (((iChPan & 3) == 1) || ((iChPan&3)==2)) ? 0xC0 : 0x40;
- ChnSettings[iChPan].nPan = pan;
- }
- while (dwMemPos+8 < dwMemLength)
- {
- PSMCHUNK *pchunk = (PSMCHUNK *)(lpStream+dwMemPos);
- if ((pchunk->len >= dwMemLength - 8) || (dwMemPos + pchunk->len + 8 > dwMemLength)) break;
+ // Skip through the chunks
+ ASSERT_CAN_READ(8);
+ DWORD chunkID = LittleEndian(*(DWORD *)(lpStream + dwMemPos));
+ DWORD chunkSize = LittleEndian(*(DWORD *)(lpStream + dwMemPos + 4));
dwMemPos += 8;
- PUCHAR pdata = (PUCHAR)(lpStream+dwMemPos);
- ULONG len = pchunk->len;
- if (len) switch(pchunk->id)
+
+ ASSERT_CAN_READ(chunkSize);
+
+ switch(chunkID)
{
- // "TITL": Song title
- case IFFID_TITL:
- if (!pdata[0]) { pdata++; len--; }
- memcpy(m_szNames[0], pdata, (len>31) ? 31 : len);
+ case 0x4C544954: // "TITL" - Song Title
+ memcpy(m_szNames[0], lpStream + dwMemPos, (chunkSize < 31) ? chunkSize : 31);
m_szNames[0][31] = 0;
break;
- // "PBOD": Pattern
- case IFFID_PBOD:
- if ((len >= 12) && (nPatterns < MAX_PATTERNS))
- {
- patptrs[nPatterns++] = dwMemPos-8;
- }
+
+ case 0x54464453: // "SDFT" - Format info (song data starts here)
+ if(chunkSize != 8 || memcmp(lpStream + dwMemPos, "MAINSONG", 8)) return false;
break;
- // "SONG": Song description
- case IFFID_SONG:
- if ((len >= sizeof(PSMSONGHDR)+8) && (!dwSongPos))
- {
- dwSongPos = dwMemPos - 8;
- }
+
+ case 0x444F4250: // "PBOD" - Pattern data of a single pattern
+ if(chunkSize < 4 || chunkSize != LittleEndian(*(DWORD *)(lpStream + dwMemPos))) return false; // same value twice
+
+ // Pattern ID (something like "P0 " or "P13 ") follows
+ if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false;
+ patternOffsets.push_back(dwMemPos + 8);
+ patternIDs.push_back(*(DWORD *)(lpStream + dwMemPos + 4));
+ numPatterns++;
+
+ // Convert later as we have to know how many channels there are.
break;
- // "DSMP": Sample Data
- case IFFID_DSMP:
- if ((len >= sizeof(PSMSAMPLE)) && (m_nSamples+1 < MAX_SAMPLES))
+
+ case 0x474E4F53: // "SONG" - Information about this file (channel count etc)
+ // We will not check for the "song type", because it is not ALWAYS "MAINSONG " (Extreme Pinball seems to use other song types for the sub songs)
+ // However, the last char always seems to be a space char.
{
- m_nSamples++;
- MODSAMPLE *pSmp = &Samples[m_nSamples];
- PSMSAMPLE *psmp = (PSMSAMPLE *)pdata;
- smpnames[m_nSamples] = psmp->smpid;
- memcpy(m_szNames[m_nSamples], psmp->samplename, 31);
- m_szNames[m_nSamples][31] = 0;
- samplemap[m_nSamples-1] = (BYTE)m_nSamples;
- // Init sample
- pSmp->nGlobalVol = 0x40;
- pSmp->nC5Speed = psmp->samplerate;
- pSmp->nLength = psmp->length;
- pSmp->nLoopStart = psmp->loopstart;
- pSmp->nLoopEnd = psmp->loopend;
- pSmp->nPan = 128;
- pSmp->nVolume = (psmp->defvol+1) * 2;
- pSmp->uFlags = (psmp->flags & 0x80) ? CHN_LOOP : 0;
- if (pSmp->nLoopStart > 0) pSmp->nLoopStart--;
- // Point to sample data
- pdata += 0x60;
- len -= 0x60;
- // Load sample data
- if ((pSmp->nLength > 3) && (len > 3))
+ if(chunkSize < sizeof(PSMSONGHEADER)) return false;
+ PSMSONGHEADER *pSong = (PSMSONGHEADER *)(lpStream + dwMemPos);
+ if(pSong->compression != 0x01) return false;
+ m_nChannels = max(m_nChannels, pSong->numChannels); // subsongs *might* have different channel count
+
+ CHAR cSongName[10];
+ memcpy(cSongName, &pSong->songType, 9);
+ cSongName[9] = 0;
+ sComment += "\r\nSubsong: ";
+ sComment += cSongName;
+
+ DWORD dwChunkPos = dwMemPos + sizeof(PSMSONGHEADER);
+
+ // Sub chunks
+ while(dwChunkPos + 8 < dwMemPos + chunkSize)
{
- ReadSample(pSmp, RS_PCM8D, (LPCSTR)pdata, len);
- } else
- {
- pSmp->nLength = 0;
- }
- }
- break;
- #if 0
- default:
- {
- CHAR s[8], s2[64];
- *(DWORD *)s = pchunk->id;
- s[4] = 0;
- wsprintf(s2, "%s: %4d bytes @ %4d\n", s, pchunk->len, dwMemPos);
- OutputDebugString(s2);
- }
- #endif
- }
- dwMemPos += pchunk->len;
- }
- // Step #1: convert song structure
- PSMSONGHDR *pSong = (PSMSONGHDR *)(lpStream+dwSongPos+8);
- if ((!dwSongPos) || (pSong->channels < 2) || (pSong->channels > 32)) return true;
- m_nChannels = pSong->channels;
- // Valid song header -> convert attached chunks
- {
- DWORD dwSongEnd = dwSongPos + 8 + *(DWORD *)(lpStream+dwSongPos+4);
- dwMemPos = dwSongPos + 8 + 11; // sizeof(PSMCHUNK)+sizeof(PSMSONGHDR)
- while (dwMemPos + 8 < dwSongEnd)
- {
- PSMCHUNK *pchunk = (PSMCHUNK *)(lpStream+dwMemPos);
- dwMemPos += 8;
- if ((pchunk->len > dwSongEnd) || (dwMemPos + pchunk->len > dwSongEnd)) break;
- PUCHAR pdata = (PUCHAR)(lpStream+dwMemPos);
- ULONG len = pchunk->len;
- switch(pchunk->id)
- {
- case IFFID_OPLH:
- if (len >= 0x20)
- {
- UINT pos = len - 3;
- while (pos > 5)
+ DWORD subChunkID = LittleEndian(*(DWORD *)(lpStream + dwChunkPos));
+ DWORD subChunkSize = LittleEndian(*(DWORD *)(lpStream + dwChunkPos + 4));
+ dwChunkPos += 8;
+
+ switch(subChunkID)
{
- BOOL bFound = FALSE;
- pos -= 5;
- DWORD dwName = *(DWORD *)(pdata+pos);
- for (UINT i=0; i<nPatterns; i++)
+ case 0x45544144: // "DATE" - Song date (YYMMDD)
+ if(subChunkSize < 6) break;
+ CHAR cDate[7];
+ memcpy(cDate, lpStream + dwChunkPos, 6);
+ cDate[6] = 0;
+ sComment += "\r\nDate: ";
+ sComment += cDate;
+ // We don't care about the date.
+ break;
+
+ case 0x484C504F: // "OPLH" - Order list, channel + module settings
{
- DWORD dwPatName = ((PSMPATTERN *)(lpStream+patptrs[i]+8))->name;
- if (dwName == dwPatName)
+ if(subChunkSize < 9) return false;
+ // First byte = "Memory alloc, roughly ordlen + 10, if too small, song freezes"
+ if(LittleEndian(*(DWORD *)(lpStream + dwChunkPos + 1)) != 0xFF000C00 // "Something"
+ || LittleEndian(*(DWORD *)(lpStream + dwChunkPos + 5)) != 0x00010000) // "Something"
+ return false;
+
+ // Now, the interesting part begins!
+ DWORD dwSettingsOffset = dwChunkPos + 9;
+ while(dwSettingsOffset - dwChunkPos + 1 < subChunkSize)
{
- bFound = TRUE;
- break;
+ switch(lpStream[dwSettingsOffset])
+ {
+ case 0x01: // Order list item
+ if(dwSettingsOffset - dwChunkPos + 5 > subChunkSize) return false;
+ // Pattern name follows - find pattern (this is the orderlist)
+ for(PATTERNINDEX i = 0; i < patternIDs.size(); i++)
+ {
+ if(patternIDs[i] == *(DWORD *)(lpStream + dwSettingsOffset + 1))
+ {
+ Order.push_back(i);
+ break;
+ }
+ }
+ dwSettingsOffset += 5;
+ break;
+
+ case 0x04: // "end?" "04 03 00 00" in most cases (not Extreme Pinball - maybe restart positions are dumped here?)
+ if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) return false;
+ dwSettingsOffset += 4;
+ break;
+
+ case 0x07: // Default Speed
+ if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
+ // NOTE: This should not be global! (Extreme Pinball!!!)
+ m_nDefaultSpeed = lpStream[dwSettingsOffset + 1];
+ dwSettingsOffset += 2;
+ break;
+
+ case 0x08: // Default Tempo
+ if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
+ // Same note as above!
+ m_nDefaultTempo = lpStream[dwSettingsOffset + 1];
+ dwSettingsOffset += 2;
+ break;
+
+ case 0x0D: // This is a channel header
+ if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) break;
+ ChnSettings[min(lpStream[dwSettingsOffset + 1], pSong->numChannels)].nPan = lpStream[dwSettingsOffset + 2];
+ // Last byte: "either 0, 2 or 4 (Some sort of priority?)"
+ dwSettingsOffset += 4;
+ break;
+
+ case 0x0E: // Unknown - "0E <ChnID> FF"
+ if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break;
+ dwSettingsOffset += 3;
+ break;
+
+ case 0x00: // "end?"
+ dwSettingsOffset += 1;
+ break;
+
+ default: // How the hell should this happen? I've listened through all existing PSM files. :)
+ CString s;
+ s.Format("Please report to the OpenMPT team: Unknown chunk %d found at position %d (in the OPLH chunk of this PSM file)", lpStream[dwSettingsOffset], dwSettingsOffset);
+ MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
+ return false;
+ break;
+
+ }
}
+ Order.push_back(Order.GetInvalidPatIndex());
}
- if ((!bFound) && (pdata[pos+1] > 0) && (pdata[pos+1] <= 0x10)
- && (pdata[pos+3] > 0x40) && (pdata[pos+3] < 0xC0))
- {
- m_nDefaultSpeed = pdata[pos+1];
- m_nDefaultTempo = pdata[pos+3];
- break;
- }
+ break;
+
+ case 0x54544150: // PATT - Pattern list
+ // We don't really need this.
+ break;
+
+ case 0x4D415344: // DSAM - Sample list
+ // We don't need this either.
+ break;
+
+ default:
+ break;
+
}
- UINT iOrd = 0;
- Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex());
- while ((pos+5<len) && (iOrd < MAX_ORDERS))
- {
- DWORD dwName = *(DWORD *)(pdata+pos);
- for (UINT i=0; i<nPatterns; i++)
- {
- DWORD dwPatName = ((PSMPATTERN *)(lpStream+patptrs[i]+8))->name;
- if (dwName == dwPatName)
- {
- Order[iOrd++] = i;
- break;
- }
- }
- pos += 5;
- }
+
+ dwChunkPos += subChunkSize;
}
- break;
}
- dwMemPos += pchunk->len;
+
+ break;
+
+ case 0x504D5344: // DSMP - Samples
+
+ {
+ if(chunkSize < sizeof(PSMSAMPLEHEADER)) return false;
+ PSMSAMPLEHEADER *pSample = (PSMSAMPLEHEADER *)(lpStream + dwMemPos);
+ SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
+ m_nSamples = max(m_nSamples, smp);
+ memcpy(m_szNames[smp], pSample->sampleName, 31);
+ m_szNames[0][31] = 0;
+
+ Samples[smp].nGlobalVol = 0x40;
+ Samples[smp].nC5Speed = LittleEndianW(pSample->C5Freq);
+ Samples[smp].nLength = LittleEndian(pSample->sampleLength);
+ Samples[smp].nLoopStart = LittleEndian(pSample->loopStart);
+ Samples[smp].nLoopEnd = LittleEndian(pSample->loopEnd);
+ Samples[smp].nPan = 128;
+ Samples[smp].nVolume = (pSample->defaultVolume + 1) << 1;
+ Samples[smp].uFlags = (pSample->flags & 0x80) ? CHN_LOOP : 0;
+ if(Samples[smp].nLoopStart > 0) Samples[smp].nLoopStart--;
+ if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength;
+
+ // Delta-encoded samples
+ ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADER)), Samples[smp].nLength);
+ }
+
+ break;
+
+ default:
+ break;
+
}
+
+ dwMemPos += chunkSize;
}
- // Step #2: convert patterns
- for (UINT nPat=0; nPat<nPatterns; nPat++)
+ if(m_nChannels == 0)
+ return false;
+
+ // Now that we know the number of channels, we can go through all the patterns.
+ for(PATTERNINDEX i = 0; i < numPatterns; i++)
{
- PSMPATTERN *pPsmPat = (PSMPATTERN *)(lpStream+patptrs[nPat]+8);
- ULONG len = *(DWORD *)(lpStream+patptrs[nPat]+4) - 12;
- UINT nRows = pPsmPat->rows;
- if (len > pPsmPat->size) len = pPsmPat->size;
- if ((nRows < 64) || (nRows > 256)) nRows = 64;
- if(Patterns.Insert(nPat, nRows))
+ DWORD dwPatternOffset = patternOffsets[i];
+ if(dwPatternOffset + 2 > dwMemLength) return false;
+ WORD patternSize = LittleEndianW(*(WORD *)(lpStream + dwPatternOffset));
+ dwPatternOffset += 2;
+
+ if(Patterns.Insert(i, patternSize))
+ {
+ CString s;
+ s.Format(TEXT("Allocating patterns failed starting from pattern %u"), i);
+ MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
break;
+ }
- MODCOMMAND *m = Patterns[nPat];
- BYTE *p = pPsmPat->data;
- UINT pos = 0;
- UINT row = 0;
- UINT oldch = 0;
- BOOL bNewRow = FALSE;
- #ifdef PSM_LOG
- Log("Pattern %d at offset 0x%04X\n", nPat, (DWORD)(p - (BYTE *)lpStream));
- #endif
- while ((row < nRows) && (pos+1 < len))
+ // Read pattern.
+ MODCOMMAND *row_data;
+ row_data = Patterns[i];
+
+ for(int nRow = 0; nRow < patternSize; nRow++)
{
- UINT flags = p[pos++];
- UINT ch = p[pos++];
+ if(dwPatternOffset + 2 > dwMemLength) return false;
+ WORD rowSize = LittleEndianW(*(WORD *)(lpStream + dwPatternOffset));
- #ifdef PSM_LOG
- //Log("flags+ch: %02X.%02X\n", flags, ch);
- #endif
- if (((flags & 0xf0) == 0x10) && (ch <= oldch) /*&& (!bNewRow)*/)
+ DWORD dwRowOffset = dwPatternOffset + 2;
+
+ while(dwRowOffset < dwPatternOffset + rowSize)
{
- if ((pos+1<len) && (!(p[pos] & 0x0f)) && (p[pos+1] < m_nChannels))
+ if(dwRowOffset + 1 > dwMemLength) return false;
+ BYTE mask = lpStream[dwRowOffset];
+ // Point to the correct channel
+ MODCOMMAND *m = row_data + min(m_nChannels, lpStream[dwRowOffset + 1]);
+ dwRowOffset += 2;
+
+ if(mask & 0x80)
{
- #ifdef PSM_LOG
- //if (!nPat) Log("Continuing on new row\n");
- #endif
- row++;
- m += m_nChannels;
- oldch = ch;
- continue;
+ if(dwRowOffset + 1 > dwMemLength) return false;
+ // Note present
+ BYTE bNote = lpStream[dwRowOffset];
+ bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ m->note = bNote;
+ dwRowOffset++;
}
- }
- if ((pos >= len) || (row >= nRows)) break;
- if (!(flags & 0xf0))
- {
- #ifdef PSM_LOG
- //if (!nPat) Log("EOR(%d): %02X.%02X\n", row, p[pos], p[pos+1]);
- #endif
- row++;
- m += m_nChannels;
- bNewRow = TRUE;
- oldch = ch;
- continue;
- }
- bNewRow = FALSE;
- if (ch >= m_nChannels)
- {
- #ifdef PSM_LOG
- if (!nPat) Log("Invalid channel row=%d (0x%02X.0x%02X)\n", row, flags, ch);
- #endif
- ch = 0;
- }
- // Note + Instr
- if ((flags & 0x40) && (pos+1 < len))
- {
- UINT note = p[pos++];
- UINT nins = p[pos++];
- #ifdef PSM_LOG
- //if (!nPat) Log("note+ins: %02X.%02X\n", note, nins);
- if ((!nPat) && (nins >= m_nSamples)) Log("WARNING: invalid instrument number (%d)\n", nins);
- #endif
- if ((note) && (note < 0x80)) note = (note>>4)*12+(note&0x0f)+12+1;
- m[ch].instr = samplemap[nins];
- m[ch].note = note;
- }
- // Volume
- if ((flags & 0x20) && (pos < len))
- {
- m[ch].volcmd = VOLCMD_VOLUME;
- m[ch].vol = p[pos++] / 2;
- }
- // Effect
- if ((flags & 0x10) && (pos+1 < len))
- {
- UINT command = p[pos++];
- UINT param = p[pos++];
- // Convert effects
- switch(command)
+
+ if(mask & 0x40)
{
- // 01: fine volslide up
- case 0x01: command = CMD_VOLUMESLIDE; param |= 0x0f; break;
- // 04: fine volslide down
- case 0x04: command = CMD_VOLUMESLIDE; param>>=4; param |= 0xf0; break;
- // 0C: portamento up
- case 0x0C: command = CMD_PORTAMENTOUP; param = (param+1)/2; break;
- // 0E: portamento down
- case 0x0E: command = CMD_PORTAMENTODOWN; param = (param+1)/2; break;
- // 33: Position Jump
- case 0x33: command = CMD_POSITIONJUMP; break;
- // 34: Pattern break
- case 0x34: command = CMD_PATTERNBREAK; break;
- // 3D: speed
- case 0x3D: command = CMD_SPEED; break;
- // 3E: tempo
- case 0x3E: command = CMD_TEMPO; break;
- // Unknown
- default:
- #ifdef PSM_LOG
- Log("Unknown PSM effect pat=%d row=%d ch=%d: %02X.%02X\n", nPat, row, ch, command, param);
- #endif
- command = param = 0;
+ if(dwRowOffset + 1 > dwMemLength) return false;
+ // Instrument present
+ m->instr = lpStream[dwRowOffset] + 1;
+ dwRowOffset++;
}
- m[ch].command = (BYTE)command;
- m[ch].param = (BYTE)param;
- }
- oldch = ch;
- }
- #ifdef PSM_LOG
- if (pos < len)
- {
- Log("Pattern %d: %d/%d[%d] rows (%d bytes) -> %d bytes left\n", nPat, row, nRows, pPsmPat->rows, pPsmPat->size, len-pos);
- }
- #endif
- }
- // Done (finally!)
- return true;
-}
+ if(mask & 0x20)
+ {
+ if(dwRowOffset + 1 > dwMemLength) return false;
+ // Volume present
+ m->volcmd = VOLCMD_VOLUME;
+ m->vol = (min(lpStream[dwRowOffset], 127)) >> 1;
+ dwRowOffset++;
+ }
+ if(mask & 0x10)
+ {
+ // Effect present - convert
+ if(dwRowOffset + 2 > dwMemLength) return false;
+ BYTE command = lpStream[dwRowOffset], param = lpStream[dwRowOffset + 1];
-//////////////////////////////////////////////////////////////
-//
-// PSM Old Format
-//
+ switch(command)
+ {
+ // Volslides
+ case 0x01: // fine volslide up
+ command = CMD_VOLUMESLIDE;
+ param = (param << 3) | 0x0F;
+ break;
+ case 0x02: // volslide up
+ command = CMD_VOLUMESLIDE;
+ param = (param << 3);
+ break;
+ case 0x03: // fine volslide down
+ command = CMD_VOLUMESLIDE;
+ param = 0xF0 | (param >> 1);
+ break;
+ case 0x04: // volslide down
+ command = CMD_VOLUMESLIDE;
+ param >>= 1;
+ break;
-/*
+ // Portamento
+ case 0x0B: // fine portamento up
+ command = CMD_PORTAMENTOUP;
+ param = 0xF0 | convert_psm_param(param);
+ break;
+ case 0x0C: // portamento up
+ command = CMD_PORTAMENTOUP;
+ param = convert_psm_param(param);
+ break;
+ case 0x0D: // fine portamento down
+ command = CMD_PORTAMENTODOWN;
+ param = 0xF0 | convert_psm_param(param);
+ break;
+ case 0x0E: // portamento down
+ command = CMD_PORTAMENTODOWN;
+ param = convert_psm_param(param);
+ break;
+ case 0x0F: // tone portamento
+ command = CMD_TONEPORTAMENTO;
+ param = convert_psm_param(param);
+ break;
+ case 0x10: // glissando control
+ command = CMD_S3MCMDEX;
+ param = 0x10 | (param & 0x01);
+ break;
+ case 0x11: // tone portamento + volslide up
+ command = CMD_TONEPORTAVOL;
+ param = param & 0xF0;
+ break;
+ case 0x12: // tone portamento + volslide down
+ command = CMD_TONEPORTAVOL;
+ param = (param >> 4) & 0x0F;
+ break;
-CONST
- c_PSM_MaxOrder = $FF;
- c_PSM_MaxSample = $FF;
- c_PSM_MaxChannel = $0F;
+ // Vibrato
+ case 0x15: // vibrato
+ command = CMD_VIBRATO;
+ break;
+ case 0x16: // vibrato waveform
+ command = CMD_S3MCMDEX;
+ param = 0x30 | (param & 0x0F);
+ break;
+ case 0x17: // vibrato + volslide up
+ command = CMD_VIBRATOVOL;
+ param = 0xF0 | param;
+ break;
+ case 0x18: // vibrato + volslide down
+ command = CMD_VIBRATOVOL;
+ break;
- TYPE
- PPSM_Header = ^TPSM_Header;
- TPSM_Header = RECORD
- PSM_Sign : ARRAY[01..04] OF CHAR; { PSM + #254 }
- PSM_SongName : ARRAY[01..58] OF CHAR;
- PSM_Byte00 : BYTE;
- PSM_Byte1A : BYTE;
- PSM_Unknown00 : BYTE;
- PSM_Unknown01 : BYTE;
- PSM_Unknown02 : BYTE;
- PSM_Speed : BYTE;
- PSM_Tempo : BYTE;
- PSM_Unknown03 : BYTE;
- PSM_Unknown04 : WORD;
- PSM_OrderLength : WORD;
- PSM_PatternNumber : WORD;
- PSM_SampleNumber : WORD;
- PSM_ChannelNumber : WORD;
- PSM_ChannelUsed : WORD;
- PSM_OrderPosition : LONGINT;
- PSM_ChannelSettingPosition : LONGINT;
- PSM_PatternPosition : LONGINT;
- PSM_SamplePosition : LONGINT;
- { *** perhaps there are some more infos in a larger header,
- but i have not decoded it and so it apears here NOT }
- END;
+ // Tremolo
+ case 0x1F: // tremolo
+ command = CMD_TREMOLO;
+ break;
+ case 0x20: // tremolo waveform
+ command = CMD_S3MCMDEX;
+ param = 0x40 | (param & 0x0F);
+ break;
- PPSM_Sample = ^TPSM_Sample;
- TPSM_Sample = RECORD
- PSM_SampleFileName : ARRAY[01..12] OF CHAR;
- PSM_SampleByte00 : BYTE;
- PSM_SampleName : ARRAY[01..22] OF CHAR;
- PSM_SampleUnknown00 : ARRAY[01..02] OF BYTE;
- PSM_SamplePosition : LONGINT;
- PSM_SampleUnknown01 : ARRAY[01..04] OF BYTE;
- PSM_SampleNumber : BYTE;
- PSM_SampleFlags : WORD;
- PSM_SampleLength : LONGINT;
- PSM_SampleLoopBegin : LONGINT;
- PSM_SampleLoopEnd : LONGINT;
- PSM_Unknown03 : BYTE;
- PSM_SampleVolume : BYTE;
- PSM_SampleC5Speed : WORD;
- END;
+ // Sample commands
+ case 0x29: // 3-byte offset - we only support the middle byte.
+ if(dwRowOffset + 4 > dwMemLength) return false;
+ command = CMD_OFFSET;
+ param = lpStream[dwRowOffset + 2];
+ dwRowOffset += 2;
+ break;
+ case 0x2A: // set finetune
+ command = CMD_S3MCMDEX;
+ param = 0x40 | (param & 0x0F);
+ break;
+ case 0x2B: // note cut
+ command = CMD_S3MCMDEX;
+ param = 0xC0 | (param & 0x0F);
+ break;
+ case 0x2C: // note delay
+ command = CMD_S3MCMDEX;
+ param = 0xD0 | (param & 0x0F);
+ break;
- PPSM_SampleList = ^TPSM_SampleList;
- TPSM_SampleList = ARRAY[01..c_PSM_MaxSample] OF TPSM_Sample;
+ // Position change
+ case 0x33: // position jump
+ command = CMD_POSITIONJUMP;
+ break;
+ case 0x34: // pattern break
+ command = CMD_PATTERNBREAK;
+ break;
+ case 0x35: // loop pattern
+ command = CMD_S3MCMDEX;
+ param = 0xB0 | (param & 0x0F);
+ break;
+ case 0x36: // pattern delay
+ command = CMD_S3MCMDEX;
+ param = 0xE0 | (param & 0x0F);
+ break;
- PPSM_Order = ^TPSM_Order;
- TPSM_Order = ARRAY[00..c_PSM_MaxOrder] OF BYTE;
+ // speed change
+ case 0x3D: // set speed
+ command = CMD_SPEED;
+ break;
+ case 0x3E: // set tempo
+ command = CMD_TEMPO;
+ break;
- PPSM_ChannelSettings = ^TPSM_ChannelSettings;
- TPSM_ChannelSettings = ARRAY[00..c_PSM_MaxChannel] OF BYTE;
+ // misc commands
+ case 0x47: // arpeggio
+ command = CMD_ARPEGGIO;
+ break;
+ case 0x48: // set finetune
+ command = CMD_MODCMDEX;
+ param = 0x50 | (param & 0x0F);
+ break;
+ case 0x49: // set balance
+ command = CMD_S3MCMDEX;
+ param = 0x80 | (param & 0x0F);
+ break;
- CONST
- PSM_NotesInPattern : BYTE = $00;
- PSM_ChannelInPattern : BYTE = $00;
+ default:
+ //ASSERT(false);
+ break;
- CONST
- c_PSM_SetSpeed = 60;
+ }
- FUNCTION PSM_Size(FileName : STRING;FilePosition : LONGINT) : LONGINT;
- BEGIN
- END;
+ m->command = command;
+ m->param = param;
- PROCEDURE PSM_UnpackPattern(VAR Source,Destination;PatternLength : WORD);
- VAR
- Witz : ARRAY[00..04] OF WORD;
- I1,I2 : WORD;
- I3,I4 : WORD;
- TopicalByte : ^BYTE;
- Pattern : PUnpackedPattern;
- ChannelP : BYTE;
- NoteP : BYTE;
- InfoByte : BYTE;
- CodeByte : BYTE;
- InfoWord : WORD;
- Effect : BYTE;
- Opperand : BYTE;
- Panning : BYTE;
- Volume : BYTE;
- PrevInfo : BYTE;
- InfoIndex : BYTE;
- BEGIN
- Pattern := @Destination;
- TopicalByte := @Source;
- { *** Initialize patttern }
- FOR I2 := 0 TO c_Maximum_NoteIndex DO
- FOR I3 := 0 TO c_Maximum_ChannelIndex DO
- BEGIN
- Pattern^[I2,I3,c_Pattern_NoteIndex] := $FF;
- Pattern^[I2,I3,c_Pattern_SampleIndex] := $00;
- Pattern^[I2,I3,c_Pattern_VolumeIndex] := $FF;
- Pattern^[I2,I3,c_Pattern_PanningIndex] := $FF;
- Pattern^[I2,I3,c_Pattern_EffectIndex] := $00;
- Pattern^[I2,I3,c_Pattern_OpperandIndex] := $00;
- END;
- { *** Byte-pointer on first pattern-entry }
- ChannelP := $00;
- NoteP := $00;
- InfoByte := $00;
- PrevInfo := $00;
- InfoIndex := $02;
- { *** read notes in pattern }
- PSM_NotesInPattern := TopicalByte^; INC(TopicalByte); DEC(PatternLength); INC(InfoIndex);
- PSM_ChannelInPattern := TopicalByte^; INC(TopicalByte); DEC(PatternLength); INC(InfoIndex);
- { *** unpack pattern }
- WHILE (INTEGER(PatternLength) > 0) AND (NoteP < c_Maximum_NoteIndex) DO
- BEGIN
- { *** Read info-byte }
- InfoByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength); INC(InfoIndex);
- IF InfoByte <> $00 THEN
- BEGIN
- ChannelP := InfoByte AND $0F;
- IF InfoByte AND 128 = 128 THEN { note and sample }
- BEGIN
- { *** read note }
- CodeByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
- DEC(CodeByte);
- CodeByte := CodeByte MOD 12 * 16 + CodeByte DIV 12 + 2;
- Pattern^[NoteP,ChannelP,c_Pattern_NoteIndex] := CodeByte;
- { *** read sample }
- CodeByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
- Pattern^[NoteP,ChannelP,c_Pattern_SampleIndex] := CodeByte;
- END;
- IF InfoByte AND 64 = 64 THEN { Volume }
- BEGIN
- CodeByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
- Pattern^[NoteP,ChannelP,c_Pattern_VolumeIndex] := CodeByte;
- END;
- IF InfoByte AND 32 = 32 THEN { effect AND opperand }
- BEGIN
- Effect := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
- Opperand := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
- CASE Effect OF
- c_PSM_SetSpeed:
- BEGIN
- Effect := c_I_Set_Speed;
- END;
- ELSE
- BEGIN
- Effect := c_I_NoEffect;
- Opperand := $00;
- END;
- END;
- Pattern^[NoteP,ChannelP,c_Pattern_EffectIndex] := Effect;
- Pattern^[NoteP,ChannelP,c_Pattern_OpperandIndex] := Opperand;
- END;
- END ELSE INC(NoteP);
- END;
- END;
+ dwRowOffset += 2;
+ }
- PROCEDURE PSM_Load(FileName : STRING;FilePosition : LONGINT;VAR Module : PModule;VAR ErrorCode : WORD);
- { *** caution : Module has to be inited before!!!! }
- VAR
- Header : PPSM_Header;
- Sample : PPSM_SampleList;
- Order : PPSM_Order;
- ChannelSettings : PPSM_ChannelSettings;
- MultiPurposeBuffer : PByteArray;
- PatternBuffer : PUnpackedPattern;
- TopicalParaPointer : WORD;
+ }
- InFile : FILE;
- I1,I2 : WORD;
- I3,I4 : WORD;
- TempW : WORD;
- TempB : BYTE;
- TempP : PByteArray;
- TempI : INTEGER;
- { *** copy-vars for loop-extension }
- CopySource : LONGINT;
- CopyDestination : LONGINT;
- CopyLength : LONGINT;
- BEGIN
- { *** try to open file }
- ASSIGN(InFile,FileName);
-{$I-}
- RESET(InFile,1);
-{$I+}
- IF IORESULT <> $00 THEN
- BEGIN
- EXIT;
- END;
-{$I-}
- { *** seek start of module }
- IF FILESIZE(InFile) < FilePosition THEN
- BEGIN
- EXIT;
- END;
- SEEK(InFile,FilePosition);
- { *** look for enough memory for temporary variables }
- IF MEMAVAIL < SIZEOF(TPSM_Header) + SIZEOF(TPSM_SampleList) +
- SIZEOF(TPSM_Order) + SIZEOF(TPSM_ChannelSettings) +
- SIZEOF(TByteArray) + SIZEOF(TUnpackedPattern)
- THEN
- BEGIN
- EXIT;
- END;
- { *** init dynamic variables }
- NEW(Header);
- NEW(Sample);
- NEW(Order);
- NEW(ChannelSettings);
- NEW(MultiPurposeBuffer);
- NEW(PatternBuffer);
- { *** read header }
- BLOCKREAD(InFile,Header^,SIZEOF(TPSM_Header));
- { *** test if this is a DSM-file }
- IF NOT ((Header^.PSM_Sign[1] = 'P') AND (Header^.PSM_Sign[2] = 'S') AND
- (Header^.PSM_Sign[3] = 'M') AND (Header^.PSM_Sign[4] = #254)) THEN
- BEGIN
- ErrorCode := c_NoValidFileFormat;
- CLOSE(InFile);
- EXIT;
- END;
- { *** read order }
- SEEK(InFile,FilePosition + Header^.PSM_OrderPosition);
- BLOCKREAD(InFile,Order^,Header^.PSM_OrderLength);
- { *** read channelsettings }
- SEEK(InFile,FilePosition + Header^.PSM_ChannelSettingPosition);
- BLOCKREAD(InFile,ChannelSettings^,SIZEOF(TPSM_ChannelSettings));
- { *** read samplelist }
- SEEK(InFile,FilePosition + Header^.PSM_SamplePosition);
- BLOCKREAD(InFile,Sample^,Header^.PSM_SampleNumber * SIZEOF(TPSM_Sample));
- { *** copy header to intern NTMIK-structure }
- Module^.Module_Sign := 'MF';
- Module^.Module_FileFormatVersion := $0100;
- Module^.Module_SampleNumber := Header^.PSM_SampleNumber;
- Module^.Module_PatternNumber := Header^.PSM_PatternNumber;
- Module^.Module_OrderLength := Header^.PSM_OrderLength;
- Module^.Module_ChannelNumber := Header^.PSM_ChannelNumber+1;
- Module^.Module_Initial_GlobalVolume := 64;
- Module^.Module_Initial_MasterVolume := $C0;
- Module^.Module_Initial_Speed := Header^.PSM_Speed;
- Module^.Module_Initial_Tempo := Header^.PSM_Tempo;
-{ *** paragraph 01 start }
- Module^.Module_Flags := c_Module_Flags_ZeroVolume * BYTE(1) +
- c_Module_Flags_Stereo * BYTE(1) +
- c_Module_Flags_ForceAmigaLimits * BYTE(0) +
- c_Module_Flags_Panning * BYTE(1) +
- c_Module_Flags_Surround * BYTE(1) +
- c_Module_Flags_QualityMixing * BYTE(1) +
- c_Module_Flags_FastVolumeSlides * BYTE(0) +
- c_Module_Flags_SpecialCustomData * BYTE(0) +
- c_Module_Flags_SongName * BYTE(1);
- I1 := $01;
- WHILE (Header^.PSM_SongName[I1] > #00) AND (I1 < c_Module_SongNameLength) DO
- BEGIN
- Module^.Module_Name[I1] := Header^.PSM_SongName[I1];
- INC(I1);
- END;
- Module^.Module_Name[c_Module_SongNameLength] := #00;
- { *** Init channelsettings }
- FOR I1 := 0 TO c_Maximum_ChannelIndex DO
- BEGIN
- IF I1 < Header^.PSM_ChannelUsed THEN
- BEGIN
- { *** channel enabled }
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_GlobalVolume := 64;
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Panning := (ChannelSettings^[I1]) * $08;
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Code := I1 + $10 * BYTE(ChannelSettings^[I1] > $08) +
- c_ChannelSettings_Code_ChannelEnabled * BYTE(1) +
- c_ChannelSettings_Code_ChannelDigital * BYTE(1);
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Controls :=
- c_ChannelSettings_Controls_EnhancedMode * BYTE(1) +
- c_ChannelSettings_Controls_SurroundMode * BYTE(0);
- END
- ELSE
- BEGIN
- { *** channel disabled }
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_GlobalVolume := $00;
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Panning := $00;
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Code := $00;
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Controls := $00;
- END;
- END;
- { *** init and copy order }
- FILLCHAR(Module^.Module_OrderPointer^,c_Maximum_OrderIndex+1,$FF);
- MOVE(Order^,Module^.Module_OrderPointer^,Header^.PSM_OrderLength);
- { *** read pattern }
- SEEK(InFile,FilePosition + Header^.PSM_PatternPosition);
- NTMIK_LoaderPatternNumber := Header^.PSM_PatternNumber-1;
- FOR I1 := 0 TO Header^.PSM_PatternNumber-1 DO
- BEGIN
- NTMIK_LoadPatternProcedure;
- { *** read length }
- BLOCKREAD(InFile,TempW,2);
- { *** read pattern }
- BLOCKREAD(InFile,MultiPurposeBuffer^,TempW-2);
- { *** unpack pattern and set notes per channel to 64 }
- PSM_UnpackPattern(MultiPurposeBuffer^,PatternBuffer^,TempW);
- NTMIK_PackPattern(MultiPurposeBuffer^,PatternBuffer^,PSM_NotesInPattern);
- TempW := WORD(256) * MultiPurposeBuffer^[01] + MultiPurposeBuffer^[00];
- GETMEM(Module^.Module_PatternPointer^[I1],TempW);
- MOVE(MultiPurposeBuffer^,Module^.Module_PatternPointer^[I1]^,TempW);
- { *** next pattern }
- END;
- { *** read samples }
- NTMIK_LoaderSampleNumber := Header^.PSM_SampleNumber;
- FOR I1 := 1 TO Header^.PSM_SampleNumber DO
- BEGIN
- NTMIK_LoadSampleProcedure;
- { *** get index for sample }
- I3 := Sample^[I1].PSM_SampleNumber;
- { *** clip PSM-sample }
- IF Sample^[I1].PSM_SampleLoopEnd > Sample^[I1].PSM_SampleLength
- THEN Sample^[I1].PSM_SampleLoopEnd := Sample^[I1].PSM_SampleLength;
- { *** init intern sample }
- NEW(Module^.Module_SamplePointer^[I3]);
- FILLCHAR(Module^.Module_SamplePointer^[I3]^,SIZEOF(TSample),$00);
- FILLCHAR(Module^.Module_SamplePointer^[I3]^.Sample_SampleName,c_Sample_SampleNameLength,#32);
- FILLCHAR(Module^.Module_SamplePointer^[I3]^.Sample_FileName,c_Sample_FileNameLength,#32);
- { *** copy informations to intern sample }
- I2 := $01;
- WHILE (Sample^[I1].PSM_SampleName[I2] > #00) AND (I2 < c_Sample_SampleNameLength) DO
- BEGIN
- Module^.Module_SamplePointer^[I3]^.Sample_SampleName[I2] := Sample^[I1].PSM_SampleName[I2];
- INC(I2);
- END;
- Module^.Module_SamplePointer^[I3]^.Sample_Sign := 'DF';
- Module^.Module_SamplePointer^[I3]^.Sample_FileFormatVersion := $00100;
- Module^.Module_SamplePointer^[I3]^.Sample_Position := $00000000;
- Module^.Module_SamplePointer^[I3]^.Sample_Selector := $0000;
- Module^.Module_SamplePointer^[I3]^.Sample_Volume := Sample^[I1].PSM_SampleVolume;
- Module^.Module_SamplePointer^[I3]^.Sample_LoopCounter := $00;
- Module^.Module_SamplePointer^[I3]^.Sample_C5Speed := Sample^[I1].PSM_SampleC5Speed;
- Module^.Module_SamplePointer^[I3]^.Sample_Length := Sample^[I1].PSM_SampleLength;
- Module^.Module_SamplePointer^[I3]^.Sample_LoopBegin := Sample^[I1].PSM_SampleLoopBegin;
- Module^.Module_SamplePointer^[I3]^.Sample_LoopEnd := Sample^[I1].PSM_SampleLoopEnd;
- { *** now it's time for the flags }
- Module^.Module_SamplePointer^[I3]^.Sample_Flags :=
- c_Sample_Flags_DigitalSample * BYTE(1) +
- c_Sample_Flags_8BitSample * BYTE(1) +
- c_Sample_Flags_UnsignedSampleData * BYTE(1) +
- c_Sample_Flags_Packed * BYTE(0) +
- c_Sample_Flags_LoopCounter * BYTE(0) +
- c_Sample_Flags_SampleName * BYTE(1) +
- c_Sample_Flags_LoopActive *
- BYTE(Sample^[I1].PSM_SampleFlags AND (LONGINT(1) SHL 15) = (LONGINT(1) SHL 15));
- { *** alloc memory for sample-data }
- E_Getmem(Module^.Module_SamplePointer^[I3]^.Sample_Selector,
- Module^.Module_SamplePointer^[I3]^.Sample_Position,
- Module^.Module_SamplePointer^[I3]^.Sample_Length + c_LoopExtensionSize);
- { *** read out data }
- EPT(TempP).p_Selector := Module^.Module_SamplePointer^[I3]^.Sample_Selector;
- EPT(TempP).p_Offset := $0000;
- SEEK(InFile,Sample^[I1].PSM_SamplePosition);
- E_BLOCKREAD(InFile,TempP^,Module^.Module_SamplePointer^[I3]^.Sample_Length);
- { *** 'coz the samples are signed in a DSM-file -> PC-fy them }
- IF Module^.Module_SamplePointer^[I3]^.Sample_Length > 4 THEN
- BEGIN
- CopyLength := Module^.Module_SamplePointer^[I3]^.Sample_Length;
- { *** decode sample }
- ASM
- DB 066h; MOV CX,WORD PTR CopyLength
- { *** load sample selector }
- MOV ES,WORD PTR TempP[00002h]
- DB 066h; XOR SI,SI
- DB 066h; XOR DI,DI
- XOR AH,AH
- { *** conert all bytes }
- @@MainLoop:
- DB 026h; DB 067h; LODSB
- ADD AL,AH
- MOV AH,AL
- DB 067h; STOSB
- DB 066h; LOOP @@MainLoop
- END;
- { *** make samples unsigned }
- ASM
- DB 066h; MOV CX,WORD PTR CopyLength
- { *** load sample selector }
- MOV ES,WORD PTR TempP[00002h]
- DB 066h; XOR SI,SI
- DB 066h; XOR DI,DI
- { *** conert all bytes }
- @@MainLoop:
- DB 026h; DB 067h; LODSB
- SUB AL,080h
- DB 067h; STOSB
- DB 066h; LOOP @@MainLoop
- END;
- { *** Create Loop-Extension }
- IF Module^.Module_SamplePointer^[I3]^.Sample_Flags AND c_Sample_Flags_LoopActive = c_Sample_Flags_LoopActive THEN
- BEGIN
- CopySource := Module^.Module_SamplePointer^[I3]^.Sample_LoopBegin;
- CopyDestination := Module^.Module_SamplePointer^[I3]^.Sample_LoopEnd;
- CopyLength := CopyDestination - CopySource;
- ASM
- { *** load sample-selector }
- MOV ES,WORD PTR TempP[00002h]
- DB 066h; MOV DI,WORD PTR CopyDestination
- { *** calculate number of full sample-loops to copy }
- XOR DX,DX
- MOV AX,c_LoopExtensionSize
- MOV BX,WORD PTR CopyLength
- DIV BX
- OR AX,AX
- JE @@NoFullLoop
- { *** copy some full-loops (size=bx) }
- MOV CX,AX
- @@InnerLoop:
- PUSH CX
- DB 066h; MOV SI,WORD PTR CopySource
- MOV CX,BX
- DB 0F3h; DB 026h,067h,0A4h { REP MOVS BYTE PTR ES:[EDI],ES:[ESI] }
- POP CX
- LOOP @@InnerLoop
- @@NoFullLoop:
- { *** calculate number of rest-bytes to copy }
- DB 066h; MOV SI,WORD PTR CopySource
- MOV CX,DX
- DB 0F3h; DB 026h,067h,0A4h { REP MOVS BYTE PTR ES:[EDI],ES:[ESI] }
- END;
- END
- ELSE
- BEGIN
- CopyDestination := Module^.Module_SamplePointer^[I3]^.Sample_Length;
- ASM
- { *** load sample-selector }
- MOV ES,WORD PTR TempP[00002h]
- DB 066h; MOV DI,WORD PTR CopyDestination
- { *** clear extension }
- MOV CX,c_LoopExtensionSize
- MOV AL,080h
- DB 0F3h; DB 067h,0AAh { REP STOS BYTE PTR ES:[EDI] }
- END;
- END;
- END;
- { *** next sample }
- END;
- { *** init period-ranges }
- NTMIK_MaximumPeriod := $0000D600 SHR 1;
- NTMIK_MinimumPeriod := $0000D600 SHR 8;
- { *** close file }
- CLOSE(InFile);
- { *** dispose all dynamic variables }
- DISPOSE(Header);
- DISPOSE(Sample);
- DISPOSE(Order);
- DISPOSE(ChannelSettings);
- DISPOSE(MultiPurposeBuffer);
- DISPOSE(PatternBuffer);
- { *** set errorcode to noerror }
- ErrorCode := c_NoError;
- END;
+ row_data += m_nChannels;
+ dwPatternOffset += rowSize;
+ }
-*/
+ }
+ if(!sComment.empty())
+ {
+ m_lpszSongComments = new char[sComment.length() + 1];
+ if (m_lpszSongComments)
+ {
+ memset(m_lpszSongComments, 0, sComment.length() + 1);
+ memcpy(m_lpszSongComments, sComment.c_str(), sComment.length());
+ }
+ }
+
+ return true;
+
+ #undef ASSERT_CAN_READ
+}
Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-20 20:43:52 UTC (rev 336)
+++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-22 10:21:22 UTC (rev 337)
@@ -376,6 +376,10 @@
insfile[iSmp] = ((DWORD)LittleEndianW(*((LPWORD)(s+0x0E)))) << 4;
insfile[iSmp] += ((DWORD)(BYTE)s[0x0D]) << 20;
if (insfile[iSmp] > dwMemLength) insfile[iSmp] &= 0xFFFF;
+
+ if(Samples[iSmp].nLoopEnd <= 4)
+ Samples[iSmp].nLoopStart = Samples[iSmp].nLoopEnd = 0;
+
if ((Samples[iSmp].nLoopStart >= Samples[iSmp].nLoopEnd) || (Samples[iSmp].nLoopEnd - Samples[iSmp].nLoopStart < 1))
Samples[iSmp].nLoopStart = Samples[iSmp].nLoopEnd = 0;
Samples[iSmp].nPan = 0x80;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-20 20:44:03
|
Revision: 336
http://modplug.svn.sourceforge.net/modplug/?rev=336&view=rev
Author: saga-games
Date: 2009-08-20 20:43:52 +0000 (Thu, 20 Aug 2009)
Log Message:
-----------
[Ref] Dabbling with order limits (especially in the module loaders) so that...
[Fix] ...Inserting more than 128 orders in MOD format is not possible anymore.
[Fix] More order overflow checks
[Fix] Fixed checks when Instruments or Samples were created. Also added test checks for those numbers.
[Mod] Moved tagging.h into the appropriate "folder" of the project file.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_ins.cpp
trunk/OpenMPT/mptrack/Ctrl_pat.cpp
trunk/OpenMPT/mptrack/Ctrl_seq.cpp
trunk/OpenMPT/mptrack/Ctrl_smp.cpp
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/mptrack/Moddoc.h
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/mptrack.vcproj
trunk/OpenMPT/mptrack/mptrack_08.vcproj
trunk/OpenMPT/mptrack/test/test.cpp
trunk/OpenMPT/mptrack/typedefs.h
trunk/OpenMPT/soundlib/LOAD_AMF.CPP
trunk/OpenMPT/soundlib/LOAD_DBM.CPP
trunk/OpenMPT/soundlib/LOAD_DMF.CPP
trunk/OpenMPT/soundlib/LOAD_DSM.CPP
trunk/OpenMPT/soundlib/Load_ams.cpp
trunk/OpenMPT/soundlib/Load_far.cpp
trunk/OpenMPT/soundlib/Load_imf.cpp
trunk/OpenMPT/soundlib/Load_mdl.cpp
trunk/OpenMPT/soundlib/Load_med.cpp
trunk/OpenMPT/soundlib/Load_mid.cpp
trunk/OpenMPT/soundlib/Load_mod.cpp
trunk/OpenMPT/soundlib/Load_mt2.cpp
trunk/OpenMPT/soundlib/Load_okt.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_wav.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -1503,7 +1503,7 @@
}
BOOL bFirst = (pSndFile->m_nInstruments) ? FALSE : TRUE;
LONG ins = m_pModDoc->InsertInstrument(0);
- if (ins > 0)
+ if (ins != INSTRUMENTINDEX_INVALID)
{
SetCurrentInstrument(ins);
m_pModDoc->UpdateAllViews(NULL, (ins << HINT_SHIFT_INS) | HINT_INSTRUMENT | HINT_INSNAMES | HINT_ENVELOPE);
@@ -1525,7 +1525,7 @@
{
BOOL bFirst = (pSndFile->m_nInstruments) ? FALSE : TRUE;
LONG ins = m_pModDoc->InsertInstrument(0, m_nInstrument);
- if (ins > 0)
+ if (ins != INSTRUMENTINDEX_INVALID)
{
SetCurrentInstrument(ins);
m_pModDoc->UpdateAllViews(NULL, (ins << HINT_SHIFT_INS) | HINT_INSTRUMENT | HINT_INSNAMES | HINT_ENVELOPE);
Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -877,6 +877,8 @@
ORD_SELECTION selection = m_OrderList.GetCurSel(false);
ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo;
ORDERINDEX nInsertWhere = selection.nOrdLo + nInsertCount + 1;
+ if (nInsertWhere >= pSndFile->GetModSpecifications().ordersMax)
+ return;
bool bSuccess = false;
// has this pattern been duplicated already? (for multiselect)
vector<PATTERNINDEX> pReplaceIndex;
@@ -917,14 +919,15 @@
nNewPat = pReplaceIndex[nCurPat]; // take care of patterns that have been duplicated before
else
nNewPat= pSndFile->Order[selection.nOrdLo + i];
- pSndFile->Order[selection.nOrdLo + i + nInsertCount + 1] = nNewPat;
+ if (selection.nOrdLo + i + nInsertCount + 1 < pSndFile->Order.GetCount())
+ pSndFile->Order[selection.nOrdLo + i + nInsertCount + 1] = nNewPat;
}
}
if(bSuccess)
{
m_OrderList.InvalidateRect(NULL, FALSE);
m_OrderList.SetCurSel(nInsertWhere);
- SetCurrentPattern(pSndFile->Order[nInsertWhere]);
+ SetCurrentPattern(pSndFile->Order[min(nInsertWhere, pSndFile->Order.GetCount()-1)]);
m_pModDoc->SetModified();
m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE|HINT_PATNAMES, this);
if(selection.nOrdHi != selection.nOrdLo) m_OrderList.m_nScrollPos2nd = nInsertWhere + nInsertCount;
Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -570,15 +570,12 @@
s[0] = 0;
if ((nOrder >= 0) && (rect.left + m_cxFont - 4 <= rcClient.right))
{
- if (nOrder == pSndFile->Order.GetInvalidPatIndex()) strcpy(s, "---"); //Print the 'dots'
- else
+ if (nIndex < pSndFile->Order.GetCount())
{
- if (nOrder < pSndFile->Patterns.Size()) wsprintf(s, "%d", nOrder);
- else
- {
- if(nOrder == pSndFile->Order.GetIgnoreIndex()) strcpy(s, "+++");
- else strcpy(s, "???");
- }
+ if (nOrder == pSndFile->Order.GetInvalidPatIndex()) strcpy(s, "---");
+ else if (nOrder == pSndFile->Order.GetIgnoreIndex()) strcpy(s, "+++");
+ else if (nOrder < pSndFile->Patterns.Size()) wsprintf(s, "%d", nOrder);
+ else strcpy(s, "???");
}
}
dc.SetTextColor((bHighLight) ? colorTextSel : colorText);
@@ -912,7 +909,7 @@
ORD_SELECTION selection = GetCurSel(false);
ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo, nInsertEnd = selection.nOrdHi;
- for(int i = 0; i <= nInsertCount; i++)
+ for(ORDERINDEX i = 0; i <= nInsertCount; i++)
{
//Checking whether there is some pattern at the end of orderlist.
@@ -922,7 +919,7 @@
pSndFile->Order.push_back(pSndFile->Order.GetInvalidPatIndex());
}
- for (int i=pSndFile->Order.size() - 1; i>nInsertEnd; i--) pSndFile->Order[i] = pSndFile->Order[i - 1];
+ for(int j = pSndFile->Order.size() - 1; j > nInsertEnd; j--) pSndFile->Order[j] = pSndFile->Order[j - 1];
}
// now that there is enough space in the order list, overwrite the orders
for(ORDERINDEX i = 0; i <= nInsertCount; i++)
@@ -930,8 +927,8 @@
if(nInsertEnd + i + 1 < pSndFile->GetModSpecifications().ordersMax)
pSndFile->Order[nInsertEnd + i + 1] = pSndFile->Order[nInsertEnd - nInsertCount + i];
}
- m_nScrollPos = nInsertEnd + 1;
- m_nScrollPos2nd = m_nScrollPos + nInsertCount;
+ m_nScrollPos = min(nInsertEnd + 1, pSndFile->Order.GetCount() - 1);
+ m_nScrollPos2nd = min(m_nScrollPos + nInsertCount, pSndFile->Order.GetCount() - 1);
InvalidateRect(NULL, FALSE);
m_pModDoc->SetModified();
m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this);
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -884,7 +884,7 @@
//------------------------------
{
LONG smp = m_pModDoc->InsertSample(TRUE);
- if (smp > 0)
+ if (smp != SAMPLEINDEX_INVALID)
{
if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel();
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -1987,7 +1987,7 @@
//----------------------------
{
LONG smp = InsertSample();
- if (smp >= 0) ViewSample(smp);
+ if (smp != SAMPLEINDEX_INVALID) ViewSample(smp);
}
@@ -1995,7 +1995,7 @@
//--------------------------------
{
LONG ins = InsertInstrument();
- if (ins >= 0) ViewInstrument(ins);
+ if (ins != INSTRUMENTINDEX_INVALID) ViewInstrument(ins);
}
Modified: trunk/OpenMPT/mptrack/Moddoc.h
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.h 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Moddoc.h 2009-08-20 20:43:52 UTC (rev 336)
@@ -199,7 +199,7 @@
PATTERNINDEX InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64);
SAMPLEINDEX InsertSample(bool bLimit = false);
- INSTRUMENTINDEX InsertInstrument(LONG lSample=0, LONG lDuplicate=0);
+ INSTRUMENTINDEX InsertInstrument(LONG lSample = 0, LONG lDuplicate = 0);
void InitializeInstrument(MODINSTRUMENT *pIns, UINT nsample=0);
bool RemoveOrder(ORDERINDEX n);
bool RemovePattern(PATTERNINDEX n);
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -1661,10 +1661,10 @@
}
}
if (((bLimit) && (i >= 200) && (!m_SndFile.m_nInstruments))
- || (i >= MAX_SAMPLES))
+ || (i >= m_SndFile.GetModSpecifications().samplesMax))
{
ErrorBox(IDS_ERR_TOOMANYSMP, CMainFrame::GetMainFrame());
- return -1;
+ return SAMPLEINDEX_INVALID;
}
if (!m_SndFile.m_szNames[i][0]) strcpy(m_SndFile.m_szNames[i], "untitled");
MODSAMPLE *pSmp = &m_SndFile.Samples[i];
@@ -1690,7 +1690,8 @@
//-----------------------------------------------------------
{
MODINSTRUMENT *pDup = NULL;
- if ((m_SndFile.m_nType != MOD_TYPE_XM) && !(m_SndFile.m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT))) return -1;
+ INSTRUMENTINDEX nInstrumentMax = m_SndFile.GetModSpecifications().instrumentsMax - 1;
+ if ((m_SndFile.m_nType != MOD_TYPE_XM) && !(m_SndFile.m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT))) return INSTRUMENTINDEX_INVALID;
if ((lDuplicate > 0) && (lDuplicate <= (LONG)m_SndFile.m_nInstruments))
{
pDup = m_SndFile.Instruments[lDuplicate];
@@ -1702,7 +1703,7 @@
if (n == IDYES)
{
UINT nInstruments = m_SndFile.m_nSamples;
- if (nInstruments >= MAX_INSTRUMENTS) nInstruments = MAX_INSTRUMENTS-1;
+ if (nInstruments > nInstrumentMax) nInstruments = nInstrumentMax;
for (UINT smp=1; smp<=nInstruments; smp++)
{
m_SndFile.Samples[smp].uFlags &= ~CHN_MUTE;
@@ -1721,7 +1722,7 @@
}
m_SndFile.m_nInstruments = nInstruments;
} else
- if (n != IDNO) return -1;
+ if (n != IDNO) return INSTRUMENTINDEX_INVALID;
}
UINT newins = 0;
for (UINT i=1; i<=m_SndFile.m_nInstruments; i++)
@@ -1734,10 +1735,10 @@
}
if (!newins)
{
- if (m_SndFile.m_nInstruments >= MAX_INSTRUMENTS-1)
+ if (m_SndFile.m_nInstruments >= nInstrumentMax)
{
ErrorBox(IDS_ERR_TOOMANYINS, CMainFrame::GetMainFrame());
- return -1;
+ return INSTRUMENTINDEX_INVALID;
}
newins = ++m_SndFile.m_nInstruments;
}
@@ -1745,7 +1746,7 @@
if (pIns)
{
UINT newsmp = 0;
- if ((lSample > 0) && (lSample < MAX_SAMPLES))
+ if ((lSample > 0) && (lSample < m_SndFile.GetModSpecifications().samplesMax))
{
newsmp = lSample;
} else
@@ -1762,7 +1763,7 @@
if (!newsmp)
{
int inssmp = InsertSample();
- if (inssmp > 0) newsmp = inssmp;
+ if (inssmp != SAMPLEINDEX_INVALID) newsmp = inssmp;
}
}
BEGIN_CRITICAL();
@@ -1784,7 +1785,7 @@
} else
{
ErrorBox(IDS_ERR_OUTOFMEMORY, CMainFrame::GetMainFrame());
- return -1;
+ return INSTRUMENTINDEX_INVALID;
}
return newins;
}
Modified: trunk/OpenMPT/mptrack/mptrack.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-20 20:43:52 UTC (rev 336)
@@ -481,9 +481,6 @@
RelativePath=".\tagging.cpp">
</File>
<File
- RelativePath=".\tagging.h">
- </File>
- <File
RelativePath=".\view_com.cpp">
</File>
<File
@@ -870,6 +867,9 @@
RelativePath=".\StdAfx.h">
</File>
<File
+ RelativePath=".\tagging.h">
+ </File>
+ <File
RelativePath=".\typedefs.h">
</File>
<File
Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-20 20:43:52 UTC (rev 336)
@@ -645,10 +645,6 @@
>
</File>
<File
- RelativePath=".\tagging.h"
- >
- </File>
- <File
RelativePath=".\view_com.cpp"
>
</File>
@@ -1151,6 +1147,10 @@
>
</File>
<File
+ RelativePath=".\tagging.h"
+ >
+ </File>
+ <File
RelativePath=".\typedefs.h"
>
</File>
Modified: trunk/OpenMPT/mptrack/test/test.cpp
===================================================================
--- trunk/OpenMPT/mptrack/test/test.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/test/test.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -163,6 +163,9 @@
VERIFY_EQUAL(ROWINDEX_MAX, (std::numeric_limits<ROWINDEX>::max)());
VERIFY_EQUAL(ORDERINDEX_MAX, (std::numeric_limits<ORDERINDEX>::max)());
+ VERIFY_EQUAL(PATTERNINDEX_MAX, (std::numeric_limits<PATTERNINDEX>::max)());
+ VERIFY_EQUAL(SAMPLEINDEX_MAX, (std::numeric_limits<SAMPLEINDEX>::max)());
+ VERIFY_EQUAL(INSTRUMENTINDEX_MAX, (std::numeric_limits<INSTRUMENTINDEX>::max)());
}
Modified: trunk/OpenMPT/mptrack/typedefs.h
===================================================================
--- trunk/OpenMPT/mptrack/typedefs.h 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/typedefs.h 2009-08-20 20:43:52 UTC (rev 336)
@@ -43,7 +43,11 @@
typedef uint8 PLUGINDEX;
typedef uint16 TEMPO;
typedef uint16 SAMPLEINDEX;
+ const SAMPLEINDEX SAMPLEINDEX_MAX = uint16_max;
+ const SAMPLEINDEX SAMPLEINDEX_INVALID = SAMPLEINDEX_MAX;
typedef uint16 INSTRUMENTINDEX;
+ const SAMPLEINDEX INSTRUMENTINDEX_MAX = uint16_max;
+ const SAMPLEINDEX INSTRUMENTINDEX_INVALID = INSTRUMENTINDEX_MAX;
typedef uint32 MODTYPE;
Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-08-20 20:43:52 UTC (rev 336)
@@ -191,10 +191,7 @@
m_nSamples = 31;
m_nDefaultTempo = 125;
m_nDefaultSpeed = 6;
- for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
- {
- Order[iOrd] = (iOrd < numorders) ? lpStream[dwMemPos+iOrd] : Order.GetInvalidPatIndex();
- }
+ Order.ReadAsByte(lpStream + dwMemPos, numorders, dwMemLength - dwMemPos);
dwMemPos = 294; // ???
for (UINT iSmp=0; iSmp<numsamples; iSmp++)
{
@@ -307,21 +304,18 @@
dwMemPos += 2;
}
// Setup sequence list
- for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
+ Order.resize(pfh->numorders, Order.GetInvalidPatIndex());
+ for (UINT iOrd=0; iOrd < pfh->numorders; iOrd++)
{
- Order[iOrd] = Order.GetInvalidPatIndex();
- if (iOrd < pfh->numorders)
+ Order[iOrd] = iOrd;
+ Patterns[iOrd].Resize(64);
+ if (pfh->version >= 14)
{
- Order[iOrd] = iOrd;
- Patterns[iOrd].Resize(64);
- if (pfh->version >= 14)
- {
- Patterns[iOrd].Resize(LittleEndianW(*(USHORT *)(lpStream+dwMemPos)));
- dwMemPos += 2;
- }
- ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos);
- dwMemPos += m_nChannels * sizeof(USHORT);
+ Patterns[iOrd].Resize(LittleEndianW(*(USHORT *)(lpStream+dwMemPos)));
+ dwMemPos += 2;
}
+ ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos);
+ dwMemPos += m_nChannels * sizeof(USHORT);
}
if (dwMemPos + m_nSamples * (sizeof(AMFSAMPLE)+8) > dwMemLength) return true;
// Read Samples
Modified: trunk/OpenMPT/soundlib/LOAD_DBM.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-08-20 20:43:52 UTC (rev 336)
@@ -120,10 +120,11 @@
if (m_nChannels > 64) m_nChannels = 64;
memcpy(m_szNames[0], (pfh->songname[0]) ? pfh->songname : pfh->songname2, 32);
m_szNames[0][31] = 0;
+ Order.resize(nOrders, Order.GetInvalidPatIndex());
for (UINT iOrd=0; iOrd < nOrders; iOrd++)
{
- Order[iOrd] = lpStream[dwMemPos+iOrd*2+1];
- if (iOrd >= MAX_ORDERS-2) break;
+ if (iOrd >= MAX_ORDERS) break;
+ Order[iOrd] = (PATTERNINDEX)BigEndianW(*((WORD *)(lpStream + dwMemPos + iOrd * 2)));
}
dwMemPos += 2*nOrders;
while (dwMemPos + 10 < dwMemLength)
Modified: trunk/OpenMPT/soundlib/LOAD_DMF.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2009-08-20 20:43:52 UTC (rev 336)
@@ -145,8 +145,9 @@
{
UINT nseq = sequ->seqsize >> 1;
if (nseq >= MAX_ORDERS-1) nseq = MAX_ORDERS-1;
+ Order.resize(nseq, Order.GetInvalidPatIndex());
if (sequ->loopstart < nseq) m_nRestartPos = sequ->loopstart;
- for (UINT i=0; i<nseq; i++) Order[i] = (BYTE)sequ->sequ[i];
+ for (UINT i = 0; i < nseq; i++) Order[i] = (PATTERNINDEX)sequ->sequ[i];
}
dwMemPos += sequ->seqsize + 8;
break;
Modified: trunk/OpenMPT/soundlib/LOAD_DSM.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DSM.CPP 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/LOAD_DSM.CPP 2009-08-20 20:43:52 UTC (rev 336)
@@ -110,10 +110,8 @@
m_nDefaultGlobalVolume = psong->globalvol << 2;
if ((!m_nDefaultGlobalVolume) || (m_nDefaultGlobalVolume > 256)) m_nDefaultGlobalVolume = 256;
m_nSamplePreAmp = psong->mastervol & 0x7F;
- for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
- {
- Order[iOrd] = (BYTE)((iOrd < psong->numord) ? psong->orders[iOrd] : 0xFF);
- }
+ Order.ReadAsByte(psong->orders, psong->numord, sizeof(psong->orders));
+
for (UINT iPan=0; iPan<16; iPan++)
{
ChnSettings[iPan].nPan = 0x80;
Modified: trunk/OpenMPT/soundlib/Load_ams.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_ams.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_ams.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -103,8 +103,12 @@
for (UINT cNam=0; cNam<m_nChannels; cNam++)
{
if (dwMemPos + 32 >= dwMemLength) return true;
- tmp = lpStream[dwMemPos++];
- dwMemPos += tmp;
+ BYTE chnnamlen = lpStream[dwMemPos++];
+ if ((chnnamlen) && (chnnamlen < MAX_CHANNELNAME))
+ {
+ memcpy(ChnSettings[cNam].szName, lpStream + dwMemPos + 1, chnnamlen);
+ }
+ dwMemPos += chnnamlen;
}
// Read Pattern Names
m_lpszPatternNames = new char[pfh->patterns * 32];
@@ -132,10 +136,10 @@
dwMemPos += tmp;
}
// Read Order List
- for (UINT iOrd=0; iOrd<pfh->orders; iOrd++, dwMemPos += 2)
+ Order.resize(pfh->orders, Order.GetInvalidPatIndex());
+ for (UINT iOrd=0; iOrd < pfh->orders; iOrd++, dwMemPos += 2)
{
- UINT n = *((WORD *)(lpStream+dwMemPos));
- Order[iOrd] = n;
+ Order[iOrd] = (PATTERNINDEX)*((WORD *)(lpStream + dwMemPos));
}
// Read Patterns
for (UINT iPat=0; iPat<pfh->patterns; iPat++)
@@ -459,15 +463,12 @@
}
// Order List
{
- for (UINT i=0; i<MAX_ORDERS; i++)
+ if ((dwMemPos + 2 * psh->orders) >= dwMemLength) return TRUE;
+ Order.resize(psh->orders, Order.GetInvalidPatIndex());
+ for (UINT iOrd = 0; iOrd < psh->orders; iOrd++)
{
- Order[i] = Order.GetInvalidPatIndex();
- if (dwMemPos + 2 >= dwMemLength) return TRUE;
- if (i < psh->orders)
- {
- Order[i] = lpStream[dwMemPos];
- dwMemPos += 2;
- }
+ Order[iOrd] = (PATTERNINDEX)*((WORD *)(lpStream + dwMemPos));
+ dwMemPos += 2;
}
}
// Pattern Data
Modified: trunk/OpenMPT/soundlib/Load_far.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_far.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_far.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -114,10 +114,8 @@
pmh2 = &farHeader2;
dwMemPos += sizeof(FARHEADER2);
if (dwMemPos >= dwMemLength) return true;
- for (UINT iorder=0; iorder<MAX_ORDERS; iorder++)
- {
- Order[iorder] = (iorder <= pmh2->snglen) ? pmh2->orders[iorder] : Order.GetInvalidPatIndex();
- }
+
+ Order.ReadAsByte(pmh2->orders, pmh2->snglen, sizeof(pmh2->orders));
m_nRestartPos = pmh2->loopto;
// Reading Patterns
dwMemPos += headerlen - (869 + pmh1->stlen);
Modified: trunk/OpenMPT/soundlib/Load_imf.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -329,8 +329,9 @@
}
if(!m_nChannels) return false;
+ Order.resize(hdr.ordnum);
for (ORDERINDEX nOrd = 0; nOrd < hdr.ordnum; nOrd++)
- Order[nOrd] = ((hdr.orderlist[nOrd] == 0xff) ? Order.GetIgnoreIndex() : hdr.orderlist[nOrd]);
+ Order[nOrd] = ((hdr.orderlist[nOrd] == 0xff) ? Order.GetIgnoreIndex() : (PATTERNINDEX)hdr.orderlist[nOrd]);
// read patterns
for (PATTERNINDEX nPat = 0; nPat < hdr.patnum; nPat++)
Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -245,7 +245,7 @@
else
m_nChannels = i+1;
}
- for (j=0; j<norders; j++) Order[j] = pmib->seq[j];
+ Order.ReadAsByte(pmib->seq, norders, sizeof(pmib->seq));
break;
// ME: song message
case 0x454D:
Modified: trunk/OpenMPT/soundlib/Load_med.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_med.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -670,19 +670,20 @@
UINT n = BigEndianW(pmps->length);
if (pseq+n <= dwMemLength)
{
+ Order.resize(nOrders++);
for (UINT i=0; i<n; i++)
{
- UINT seqval = pmps->seq[i] >> 8;
+ WORD seqval = BigEndian(pmps->seq[i]);
if ((seqval < wNumBlocks) && (nOrders < MAX_ORDERS-1))
{
- Order[nOrders++] = seqval;
+ Order[nOrders++] = (ORDERINDEX)seqval;
}
}
}
}
}
playtransp = pmsh2->playtransp;
- while (nOrders < MAX_ORDERS) Order[nOrders++] = 0xFF;
+ while (nOrders < MAX_ORDERS) Order[nOrders++] = Order.GetInvalidPatIndex();
}
// Reading Expansion structure
if (pmex)
Modified: trunk/OpenMPT/soundlib/Load_mid.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mid.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_mid.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -563,7 +563,7 @@
Log("%d tracks, tempo = %dus, division = %04X TickFactor=%d\n", tracks, nTempoUsec, ((UINT)division) & 0xFFFF, nTickMultiplier);
#endif
// Initializing
- Order.assign(Order.size(), Order.GetInvalidPatIndex());
+ Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex());
memset(chnstate, 0, sizeof(chnstate));
memset(miditracks, 0, sizeof(miditracks));
memset(midichstate, 0, sizeof(midichstate));
Modified: trunk/OpenMPT/soundlib/Load_mod.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -291,7 +291,6 @@
pMagic = (PMODMAGIC)(lpStream+dwMemPos);
dwMemPos += sizeof(MODMAGIC);
if (m_nSamples == 15) dwMemPos -= 4;
- Order.assign(Order.size(), 0);
Order.ReadAsByte(pMagic->Orders, 128, 128);
UINT nbp, nbpbuggy, nbpbuggy2, norders;
@@ -315,7 +314,7 @@
}
if (i >= nbpbuggy2) nbpbuggy2 = i+1;
}
- for (UINT iend=norders; iend<MAX_ORDERS; iend++) Order[iend] = Order.GetInvalidPatIndex();
+ for (UINT iend = norders; iend < 0x80; iend++) Order[iend] = Order.GetInvalidPatIndex();
norders--;
m_nRestartPos = pMagic->nRestartPos;
if (m_nRestartPos >= 0x78) m_nRestartPos = 0;
Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -204,9 +204,10 @@
{
m_nDefaultTempo = 110250 / pfh->wSamplesPerTick;
}
- for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
+ Order.resize(pfh->nOrders, Order.GetInvalidPatIndex());
+ for (UINT iOrd=0; iOrd < pfh->nOrders; iOrd++)
{
- Order[iOrd] = (BYTE)((iOrd < pfh->nOrders) ? pfh->Orders[iOrd] : 0xFF);
+ Order[iOrd] = (PATTERNINDEX)pfh->Orders[iOrd];
}
memcpy(m_szNames[0], pfh->szSongName, 32);
m_szNames[0][31] = 0;
Modified: trunk/OpenMPT/soundlib/Load_okt.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_okt.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_okt.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -107,6 +107,7 @@
{
UINT orderlen = norders;
if (orderlen >= MAX_ORDERS) orderlen = MAX_ORDERS-1;
+ Order.resize(orderlen);
for (UINT i=0; i<orderlen; i++) Order[i] = lpStream[dwMemPos+10+i];
for (UINT j=orderlen; j>1; j--) { if (Order[j-1]) break; Order[j-1] = 0xFF; }
dwMemPos += BigEndian(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -15,8 +15,8 @@
//#define PSM_LOG
-#define PSM_ID_NEW 0x204d5350
-#define PSM_ID_OLD 0xfe4d5350
+#define PSM_ID_NEW 0x204d5350 // "PSM "
+#define PSM_ID_OLD 0xfe4d5350 // "PSM\xFE"
#define IFFID_FILE 0x454c4946
#define IFFID_TITL 0x4c544954
#define IFFID_SDFT 0x54464453
@@ -226,6 +226,7 @@
}
}
UINT iOrd = 0;
+ Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex());
while ((pos+5<len) && (iOrd < MAX_ORDERS))
{
DWORD dwName = *(DWORD *)(pdata+pos);
Modified: trunk/OpenMPT/soundlib/Load_wav.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_wav.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_wav.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -50,8 +50,8 @@
m_nDefaultSpeed = 8;
m_nDefaultTempo = 125;
m_dwSongFlags |= SONG_LINEARSLIDES; // For no resampling
+ Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex());
Order[0] = 0;
- Order[1] = 0xFF;
bool fail = Patterns.Insert(0, 64);
fail = Patterns.Insert(1, 64);
if(fail) return true;
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -508,7 +508,8 @@
memset(ChnMix, 0, sizeof(ChnMix));
memset(Chn, 0, sizeof(Chn));
memset(Instruments, 0, sizeof(Instruments));
- Order.assign(MAX_ORDERS, Order.GetInvalidPatIndex());
+ //Order.assign(MAX_ORDERS, Order.GetInvalidPatIndex());
+ Order.resize(1, Order.GetInvalidPatIndex());
Patterns.ClearPatterns();
memset(m_szNames, 0, sizeof(m_szNames));
memset(m_MixPlugins, 0, sizeof(m_MixPlugins));
@@ -706,7 +707,7 @@
if ((m_nRestartPos >= Order.size()) || (Order[m_nRestartPos] >= Patterns.Size())) m_nRestartPos = 0;
// Load plugins only when m_pModDoc != 0. (can be == 0 for example when examining module samples in treeview.
- CString sNotFound;
+ string sNotFound;
bool bSearchIDs[MAX_MIXPLUGINS] = {false};
UINT iShowNotFound = 0;
@@ -757,7 +758,7 @@
sNotFound = "The following plugins have not been found:\n\n" + sNotFound + "\nDo you want to search for them on KVRAudio?"
"\nWARNING: A browser window / tab is opened for every plugin. If you do not want that, you can visit http://www.kvraudio.com/search.php";
}
- if (::MessageBox(0, sNotFound, "OpenMPT - Plugins missing", MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) == IDYES)
+ if (::MessageBox(0, sNotFound.c_str(), "OpenMPT - Plugins missing", MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) == IDYES)
for (UINT iPlug = 0; iPlug < MAX_MIXPLUGINS; iPlug++)
if (bSearchIDs[iPlug] == true)
{
@@ -774,6 +775,7 @@
if (m_nType)
{
SetModSpecsPointer(m_pModSpecs, m_nType);
+ Order.resize(GetModSpecifications().ordersMax, Order.GetInvalidPatIndex());
return TRUE;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|