From: <sag...@us...> - 2009-10-23 23:12:16
|
Revision: 403 http://modplug.svn.sourceforge.net/modplug/?rev=403&view=rev Author: saga-games Date: 2009-10-23 23:12:00 +0000 (Fri, 23 Oct 2009) Log Message: ----------- [Fix] Pattern c&p: invalid commands are not pasted anymore [Fix] Mod conversion: "orderlist fixing" did not work as expected [Imp] Pattern c&p: convert pasted commands if necessary [Imp] Mod conversion: insert pattern break commands when resizing patterns to 64 rows that were smaller [Imp] Note Properties: Better explanation of "Invert Loop" parameter [Ref] Added "HasCommand" / "HasVolCommand" to the Mod Specifications Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/View_ins.h trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/soundlib/LOAD_AMF.CPP trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/mod_specifications.cpp trunk/OpenMPT/soundlib/mod_specifications.h trunk/OpenMPT/soundlib/modcommand.h trunk/OpenMPT/soundlib/pattern.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -2721,10 +2721,17 @@ strcat(s, " rows"); break; case 0xF0: - if(m_SndFile.m_nType & MOD_TYPE_MOD) - wsprintf(s, "Speed %d", param & 0x0F); // invert loop - else - wsprintf(s, "SF%X", param & 0x0F); // macro + if(m_SndFile.m_nType & MOD_TYPE_MOD) // invert loop + { + if((param & 0x0F) == 0) + strcpy(s, "Stop"); + else + wsprintf(s, "Speed %d", param & 0x0F); + } + else // macro + { + wsprintf(s, "SF%X", param & 0x0F); + } break; default: break; Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -68,6 +68,8 @@ newTypeIsXM_IT_MPT = (newTypeIsXM || newTypeIsIT || newTypeIsMPT), newTypeIsIT_MPT = (newTypeIsIT || newTypeIsMPT); + const CModSpecifications& specs = m_SndFile.GetModSpecifications(nNewType); + if(oldTypeIsMPT) { if(::MessageBox(NULL, str_mptm_conversion_warning, 0, MB_YESNO) != IDYES) @@ -126,7 +128,12 @@ UINT i = 0; for (i=0; i<m_SndFile.Patterns.Size(); i++) if ((m_SndFile.Patterns[i]) && (m_SndFile.PatternSize[i] != 64)) { - m_SndFile.Patterns[i].Resize(64); + if(m_SndFile.PatternSize[i] < 64) + { + // try to save short patterns by inserting a pattern break. + m_SndFile.TryWriteEffect(i, m_SndFile.PatternSize[i] - 1, CMD_PATTERNBREAK, 0, false, CHANNELINDEX_INVALID, false, true); + } + m_SndFile.Patterns[i].Resize(64, false); if (b64 < 5) { wsprintf(s, "WARNING: Pattern %d resized to 64 rows\n", i); @@ -285,6 +292,27 @@ { AddToLog("WARNING: Samples above 31 will be lost when saving as MOD!\n"); } + + // Order list too long? -> remove unnecessary order items first. + if(m_SndFile.Order.GetLengthTailTrimmed() > specs.ordersMax) + { + for(ORDERINDEX nOrd = m_SndFile.Order.GetLengthTailTrimmed() - 1; nOrd > 0; nOrd--) + { + if(m_SndFile.Patterns.IsValidPat(m_SndFile.Order[nOrd]) == false) + { + for(ORDERINDEX nMoveOrd = nOrd; nMoveOrd < m_SndFile.Order.GetLengthTailTrimmed() - 1; nMoveOrd++) + { + m_SndFile.Order[nMoveOrd] = m_SndFile.Order[nMoveOrd + 1]; + } + m_SndFile.Order[m_SndFile.Order.GetLengthTailTrimmed() - 1] = m_SndFile.Order.GetInvalidPatIndex(); + } + } + if(m_SndFile.Order.GetLengthTailTrimmed() > specs.ordersMax) + { + AddToLog("WARNING: Order list has been trimmed!\n"); + } + } + BEGIN_CRITICAL(); m_SndFile.ChangeModTypeTo(nNewType); if (!newTypeIsXM_IT_MPT && (m_SndFile.m_dwSongFlags & SONG_LINEARSLIDES)) @@ -311,7 +339,6 @@ //end rewbs.cutomKeys // Check mod specifications - const CModSpecifications& specs = m_SndFile.GetModSpecifications(); 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); @@ -325,26 +352,6 @@ if(bTrimmedEnvelopes == true) AddToLog("WARNING: Instrument envelopes have been shortened.\n"); - // Order list too long -> remove unnecessary order items first. - if(m_SndFile.Order.GetLengthTailTrimmed() > specs.ordersMax) - { - for(ORDERINDEX nOrd = m_SndFile.Order.GetLengthTailTrimmed() - 1; nOrd >= 0; nOrd--) - { - if(m_SndFile.Patterns.IsValidPat(m_SndFile.Order[nOrd]) == false) - { - for(ORDERINDEX nMoveOrd = nOrd; nMoveOrd < m_SndFile.Order.GetLengthTailTrimmed(); nMoveOrd++) - { - m_SndFile.Order[nMoveOrd] = m_SndFile.Order[nMoveOrd + 1]; - } - } - } - if(m_SndFile.Order.GetLengthTailTrimmed() > specs.ordersMax) - { - AddToLog("WARNING: Order list has been trimmed!"); - } - m_SndFile.Order.resize(specs.ordersMax); - } - SetModified(); ClearPatternUndo(); UpdateAllViews(NULL, HINT_MODTYPE | HINT_MODGENERAL); @@ -1122,13 +1129,14 @@ if ((hCpy) && ((p = (LPSTR)GlobalLock(hCpy)) != NULL)) { PreparePatternUndo(nPattern, 0, 0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]); - BYTE spdmax = (m_SndFile.m_nType & MOD_TYPE_MOD) ? 0x20 : 0x1F; + TEMPO spdmax = m_SndFile.GetModSpecifications().speedMax; DWORD dwMemSize = GlobalSize(hCpy); MODCOMMAND *m = m_SndFile.Patterns[nPattern]; UINT nrow = dwBeginSel >> 16; UINT ncol = (dwBeginSel & 0xFFFF) >> 3; UINT col; - BOOL bS3M = FALSE, bOk = FALSE; + bool bS3MCommands = false, bOk = false; + MODTYPE origFormat = MOD_TYPE_MOD; UINT len = 0; MODCOMMAND origModCmd; @@ -1147,13 +1155,15 @@ if (!c) goto PasteDone; if ((c == 0x0D) && (len > 3)) { - //if ((p[len-3] == 'I') || (p[len-4] == 'S')) bS3M = TRUE; - // IT? S3M? MPT? - if ((p[len-3] == 'I') || (p[len-4] == 'S') || (p[len-3] == 'P')) bS3M = TRUE; + if(p[len - 3] == 'I') origFormat = MOD_TYPE_IT; + if(p[len - 3] == 'P') origFormat = MOD_TYPE_MPT; + if(p[len - 4] == 'S') origFormat = MOD_TYPE_S3M; + if(p[len - 3] == 'X') origFormat = MOD_TYPE_XM; break; } } - bOk = TRUE; + bS3MCommands = (origFormat & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_S3M)) != 0 ? true : false; + bOk = true; while ((nrow < m_SndFile.PatternSize[nPattern]) && (len + 11 < dwMemSize)) { // Search for column separator @@ -1255,7 +1265,7 @@ m[col].command = 0; if (s[8] != '.') { - LPCSTR psc = (bS3M) ? gszS3mCommands : gszModCommands; + LPCSTR psc = (bS3MCommands) ? gszS3mCommands : gszModCommands; for (UINT i=1; i<MAX_EFFECTS; i++) { if ((s[8] == psc[i]) && (psc[i] != '?')) m[col].command = i; @@ -1283,7 +1293,7 @@ { case CMD_SPEED: case CMD_TEMPO: - if (!bS3M) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; + if (!bS3MCommands) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; else { if ((m[col].command == CMD_SPEED) && (m[col].param > spdmax)) m[col].param = CMD_TEMPO; else @@ -1297,12 +1307,15 @@ { case CMD_SPEED: case CMD_TEMPO: - if (!bS3M) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; + if (!bS3MCommands) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; break; } } } } + // convert some commands, if necessary. + if(origFormat != m_SndFile.m_nType) m_SndFile.ConvertCommand(&(m[col]), origFormat, m_SndFile.m_nType); + len += 12; col++; } Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/mptrack/Mptrack.h 2009-10-23 23:12:00 UTC (rev 403) @@ -406,9 +406,6 @@ /////////////////////////////////////////////////// // Tables -#define MAX_EFFECTS 37 //rewbs.smoothVST & rewbs.velocity: increased from 32. Wonder what this will break... - //+1 for eric's multiplier -#define MAX_VOLCMDS 16 //rewbs.voloff & rewbs.velocity: increased from 14 extern const BYTE gEffectColors[MAX_EFFECTS]; extern const LPCSTR szNoteNames[12]; @@ -422,8 +419,8 @@ STATIC_ASSERT(ARRAYELEMCOUNT(szSpecialNoteShortDesc) == ARRAYELEMCOUNT(szSpecialNoteNames)); const LPCSTR szHexChar = "0123456789ABCDEF"; -const LPCSTR gszModCommands = " 0123456789ABCDRFFTE???GHK?YXPLZ\\:#"; //rewbs.smoothVST: added last \ (written as \\); rewbs.velocity: added last : -const LPCSTR gszS3mCommands = " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#"; //rewbs.smoothVST: added last \ (written as \\); rewbs.velocity: added last : +const LPCSTR gszModCommands = " 0123456789ABCDRFFTE???GHK?YXPLZ\\:#??"; //rewbs.smoothVST: added last \ (written as \\); rewbs.velocity: added last : +const LPCSTR gszS3mCommands = " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#??"; //rewbs.smoothVST: added last \ (written as \\); rewbs.velocity: added last : const LPCSTR gszVolCommands = " vpcdabuhlrgfe:o"; //rewbs.velocity: added last : ; rewbs.volOff added last o // Defined in load_mid.cpp Modified: trunk/OpenMPT/mptrack/View_ins.h =================================================================== --- trunk/OpenMPT/mptrack/View_ins.h 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/mptrack/View_ins.h 2009-10-23 23:12:00 UTC (rev 403) @@ -17,7 +17,8 @@ POINT m_ptMenu; RECT m_rcClient; bool m_baPlayingNote[128]; //rewbs.instViewNNA - UINT m_nInstrument, m_nEnv, m_nDragItem, m_nBtnMouseOver, m_nPlayingChannel; + INSTRUMENTINDEX m_nInstrument; + UINT m_nEnv, m_nDragItem, m_nBtnMouseOver, m_nPlayingChannel; DWORD m_dwStatus; DWORD m_NcButtonState[ENV_LEFTBAR_BUTTONS]; DWORD m_dwNotifyPos[MAX_CHANNELS]; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -3827,8 +3827,7 @@ if ((pSndFile->m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM)) && ((p->command == CMD_SPEED) || (p->command == CMD_TEMPO))) { - UINT maxspd = (pSndFile->m_nType & MOD_TYPE_XM) ? 0x1F : 0x20; - p->command = (p->param <= maxspd) ? CMD_SPEED : CMD_TEMPO; + p->command = (p->param <= pSndFile->GetModSpecifications().speedMax) ? CMD_SPEED : CMD_TEMPO; } } @@ -3886,8 +3885,7 @@ if ((pSndFile->m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM)) && ((p->command == CMD_SPEED) || (p->command == CMD_TEMPO))) { - UINT maxspd = (pSndFile->m_nType & MOD_TYPE_XM) ? 0x1F : 0x20; - p->command = (p->param <= maxspd) ? CMD_SPEED : CMD_TEMPO; + p->command = (p->param <= pSndFile->GetModSpecifications().speedMax) ? CMD_SPEED : CMD_TEMPO; } } Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-10-23 23:12:00 UTC (rev 403) @@ -311,7 +311,7 @@ for (UINT iOrd=0; iOrd < pfh->numorders; iOrd++) { Order[iOrd] = iOrd; - Patterns[iOrd].Resize(64); + Patterns[iOrd].Resize(64, false); if (pfh->version >= 14) { Patterns[iOrd].Resize(LittleEndianW(*(USHORT *)(lpStream+dwMemPos))); Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -664,7 +664,7 @@ ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); if(id > MAX_PATTERN_ROWS) return false; - Patterns[npat].Resize(id); + Patterns[npat].Resize(id, false); streamPos += sizeof(DWORD); // Try to allocate & read only sized patterns Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -291,7 +291,7 @@ } else { pdata = (const WORD *)(lpStream + dwPos); - Patterns[i].Resize(64); + Patterns[i].Resize(64, false); if (m_nChannels < 32) m_nChannels = 32; dwPos += 2*32; ch = 32; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -3733,4 +3733,11 @@ if(!CSoundFile::GetModSpecifications(nNewType).HasNote(m->note)) m->note = NOTE_NONE; + + // ensure the commands really exist in this format + if(CSoundFile::GetModSpecifications(nNewType).HasCommand(m->command) == false) + m->command = CMD_NONE; + if(CSoundFile::GetModSpecifications(nNewType).HasVolCommand(m->volcmd) == false) + m->volcmd = CMD_NONE; + } \ No newline at end of file Modified: trunk/OpenMPT/soundlib/mod_specifications.cpp =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/mod_specifications.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -21,4 +21,20 @@ return false; } +bool CModSpecifications::HasVolCommand(MODCOMMAND::VOLCMD volcmd) const +//--------------------------------------------------------------------- +{ + if(volcmd >= MAX_VOLCMDS) return false; + if(volcommands[volcmd] == '?') return false; + return true; +} +bool CModSpecifications::HasCommand(MODCOMMAND::COMMAND cmd) const +//---------------------------------------------------------------- +{ + if(cmd >= MAX_EFFECTS) return false; + if(commands[cmd] == '?') return false; + return true; +} + + Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-10-23 23:12:00 UTC (rev 403) @@ -12,6 +12,8 @@ { // Return true if format supports given note. bool HasNote(MODCOMMAND::NOTE note) const; + bool HasVolCommand(MODCOMMAND::VOLCMD volcmd) const; + bool HasCommand(MODCOMMAND::COMMAND cmd) const; //NOTE: If changing order, update all initializations below. char fileExtension[6]; // File extension without dot. @@ -37,6 +39,8 @@ UINT speedMax; // Maximum ticks per frame bool hasComments; // True if format has a comments field UINT envelopePointsMax; // Maximum number of points of each envelope + char commands[MAX_EFFECTS + 1]; // An array holding all commands this format supports; commands that are not supported are marked with "?" + char volcommands[MAX_VOLCMDS + 1]; // dito, but for volume column }; @@ -73,6 +77,8 @@ 255, //Max Speed true, //Has song comments 240, //Envelope point count + " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#", // Supported Effects + " vpcdabuhlrgfe:o", // Supported Volume Column commands }; @@ -104,6 +110,8 @@ 31, //Max Speed false, //No song comments 0, //No instrument envelopes + " 0123456789ABCD?FF?E???????????????", // Supported Effects + " ???????????????", // Supported Volume Column commands }; // MOD with MPT extensions. @@ -133,6 +141,8 @@ 31, //Max Speed false, //No song comments 0, //No instrument envelopes + " 0123456789ABCD?FF?E???????????????", // Supported Effects + " ???????????????", // Supported Volume Column commands }; const CModSpecifications xm = @@ -161,6 +171,8 @@ 31, //Max Speed false, //No song comments 12, //Envelope point count + " 0123456789ABCDRFFTE???GHK?YXPLZ\\:#", // Supported Effects + " vpcdabuhlrg????", // Supported Volume Column commands }; // XM with MPT extensions @@ -190,6 +202,8 @@ 31, //Max Speed true, //Has song comments 12, //Envelope point count + " 0123456789ABCDRFFTE???GHK?YXPLZ\\:#", // Supported Effects + " vpcdabuhlrgfe:o", // Supported Volume Column commands }; const CModSpecifications s3m = @@ -217,6 +231,8 @@ 255, //Max Speed false, //No song comments 0, //No instrument envelopes + " JFEGHLKRXODB?CQATI?SMNVW?U????????", // Supported Effects + " vp?????????????", // Supported Volume Column commands }; // S3M with MPT extensions @@ -246,6 +262,8 @@ 255, //Max Speed false, //No song comments 0, //No instrument envelopes + " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#", // Supported Effects + " vp?????????????", // Supported Volume Column commands }; const CModSpecifications it = @@ -274,6 +292,8 @@ 255, //Max Speed true, //Has song comments 25, //Envelope point count + " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z???", // Supported Effects + " vpcdab?h??gfe??", // Supported Volume Column commands }; const CModSpecifications itEx = @@ -302,6 +322,8 @@ 255, //Max Speed true, //Has song comments 25, //Envelope point count + " JFEGHLKRXODB?CQATI?SMNVW?UY?P?Z\\:#", // Supported Effects + " vpcdab?h??gfe:o", // Supported Volume Column commands }; } //namespace ModSpecs Modified: trunk/OpenMPT/soundlib/modcommand.h =================================================================== --- trunk/OpenMPT/soundlib/modcommand.h 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/modcommand.h 2009-10-23 23:12:00 UTC (rev 403) @@ -90,6 +90,7 @@ #define VOLCMD_PORTADOWN 13 #define VOLCMD_VELOCITY 14 //rewbs.velocity #define VOLCMD_OFFSET 15 //rewbs.volOff +#define MAX_VOLCMDS 16 // Effect column commands @@ -130,6 +131,7 @@ #define CMD_XPARAM 34 // -> CODE#0010 -> DESC="add extended parameter mechanism to pattern effects" -! NEW_FEATURE#0010 #define CMD_NOTESLIDEUP 35 // IMF Gxy #define CMD_NOTESLIDEDOWN 36 // IMF Hxy +#define MAX_EFFECTS 37 #endif Modified: trunk/OpenMPT/soundlib/pattern.cpp =================================================================== --- trunk/OpenMPT/soundlib/pattern.cpp 2009-10-20 18:24:29 UTC (rev 402) +++ trunk/OpenMPT/soundlib/pattern.cpp 2009-10-23 23:12:00 UTC (rev 403) @@ -18,7 +18,7 @@ bool CPattern::Resize(const ROWINDEX newRowCount, const bool showDataLossWarning) -//------------------------------------------- +//------------------------------------------------------------------------------- { if(m_ModCommands == NULL) { @@ -69,7 +69,7 @@ { END_CRITICAL(); rModDoc.EndWaitCursor(); - if (CMainFrame::GetMainFrame()->MessageBox("Data at the end of the pattern will be lost.\nDo you want to continue", + if (CMainFrame::GetMainFrame()->MessageBox("Data at the end of the pattern will be lost.\nDo you want to continue?", "Shrink Pattern", MB_YESNO|MB_ICONQUESTION) == IDYES) bOk = TRUE; rModDoc.BeginWaitCursor(); BEGIN_CRITICAL(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |