From: <sag...@us...> - 2012-02-07 19:55:59
|
Revision: 1176 http://modplug.svn.sourceforge.net/modplug/?rev=1176&view=rev Author: saga-games Date: 2012-02-07 19:55:52 +0000 (Tue, 07 Feb 2012) Log Message: ----------- [Ref] Moved more macro stuff around. Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/soundlib/MIDIMacros.cpp trunk/OpenMPT/soundlib/MIDIMacros.h trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-07 00:31:12 UTC (rev 1175) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-07 19:55:52 UTC (rev 1176) @@ -3585,13 +3585,9 @@ } //set new macro - char *pMacroToSet = GetSoundFile()->m_MidiCfg.szMidiSFXExt[macroToSet]; - if (paramToUse < 128) + if (paramToUse < 384) { - wsprintf(pMacroToSet, "F0F0%Xz",paramToUse+128); - } else if (paramToUse < 384) - { - wsprintf(pMacroToSet, "F0F1%Xz",paramToUse-128); + GetSoundFile()->m_MidiCfg.CreateParameteredMacro(macroToSet, sfx_plug, paramToUse); } else { CString message; Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2012-02-07 00:31:12 UTC (rev 1175) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2012-02-07 19:55:52 UTC (rev 1176) @@ -213,7 +213,7 @@ // Fix old nasty broken (non-standard) MIDI configs in INI file. if(storedVersion >= "1.17" && storedVersion < "1.20") { - CSoundFile::FixMIDIConfigStrings(macros); + macros.UpgradeMacros(); } theApp.SetDefaultMidiMacro(¯os); @@ -287,8 +287,8 @@ outTime, GetPrivateProfileInt("Update", "UpdateCheckPeriod", CUpdateCheck::GetUpdateCheckPeriod(), iniFile), CMainFrame::GetPrivateProfileCString("Update", "UpdateURL", CUpdateCheck::GetUpdateURL(), iniFile), - GetPrivateProfileInt("Update", "SendGUID", CUpdateCheck::GetSendGUID() ? 1 : 0, iniFile) ? true : false, - GetPrivateProfileInt("Update", "ShowUpdateHint", CUpdateCheck::GetShowUpdateHint() ? 1 : 0, iniFile) ? true : false + GetPrivateProfileInt("Update", "SendGUID", CUpdateCheck::GetSendGUID() ? 1 : 0, iniFile) != 0, + GetPrivateProfileInt("Update", "ShowUpdateHint", CUpdateCheck::GetShowUpdateHint() ? 1 : 0, iniFile) != 0 ); } Modified: trunk/OpenMPT/soundlib/MIDIMacros.cpp =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-02-07 00:31:12 UTC (rev 1175) +++ trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-02-07 19:55:52 UTC (rev 1176) @@ -382,6 +382,41 @@ } +// Helper function for UpgradeMacros() +void MIDIMacroConfig::UpgradeMacroString(char *macro) const +//--------------------------------------------------------- +{ + for(size_t i = 0; i < MACRO_LENGTH; i++) + { + if(macro[i] >= 'a' && macro[i] <= 'f') // both A-F and a-f were treated as hex constants + { + macro[i] = macro[i] - 'a' + 'A'; + } else if(macro[i] == 'K' || macro[i] == 'k') // channel was K or k + { + macro[i] = 'c'; + } else if(macro[i] == 'X' || macro[i] == 'x' || macro[i] == 'Y' || macro[i] == 'y') // those were pointless + { + macro[i] = 'z'; + } + } +} + + +// Fix old-format (not conforming to IT's MIDI macro definitions) MIDI config strings. +void MIDIMacroConfig::UpgradeMacros() +//----------------------------------- +{ + for(size_t i = 0; i < CountOf(szMidiSFXExt); i++) + { + UpgradeMacroString(szMidiSFXExt[i]); + } + for(size_t i = 0; i < CountOf(szMidiZXXExt); i++) + { + UpgradeMacroString(szMidiZXXExt[i]); + } +} + + // Remove blanks and other unwanted characters from macro strings for internal usage. std::string MIDIMacroConfig::GetSafeMacro(const char *macro) const //---------------------------------------------------------------- Modified: trunk/OpenMPT/soundlib/MIDIMacros.h =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.h 2012-02-07 00:31:12 UTC (rev 1175) +++ trunk/OpenMPT/soundlib/MIDIMacros.h 2012-02-07 19:55:52 UTC (rev 1176) @@ -131,8 +131,14 @@ // Sanitize all macro config strings. void Sanitize(); + // Fix old-format (not conforming to IT's MIDI macro definitions) MIDI config strings. + void UpgradeMacros(); + protected: + // Helper function for FixMacroFormat() + void UpgradeMacroString(char *macro) const; + // Remove blanks and other unwanted characters from macro strings for internal usage. std::string GetSafeMacro(const char *macro) const; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-07 00:31:12 UTC (rev 1175) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-07 19:55:52 UTC (rev 1176) @@ -3069,42 +3069,8 @@ } // Fix old nasty broken (non-standard) MIDI configs in files. - FixMIDIConfigStrings(m_MidiCfg); + m_MidiCfg.UpgradeMacros(); } Patterns.ForEachModCommand(UpgradePatternData(this)); } - - -void FixMIDIConfigString(char *line) -//---------------------------------- -{ - for(size_t i = 0; i < MACRO_LENGTH; i++) - { - if(line[i] >= 'a' && line[i] <= 'f') // both A-F and a-f were treated as hex constants - { - line[i] = line[i] - 'a' + 'A'; - } else if(line[i] == 'K' || line[i] == 'k') // channel was K or k - { - line[i] = 'c'; - } else if(line[i] == 'X' || line[i] == 'x' || line[i] == 'Y' || line[i] == 'y') // those were pointless - { - line[i] = 'z'; - } - } -} - - -// Fix old-format (not conforming to IT's MIDI macro definitions) MIDI config strings. -void CSoundFile::FixMIDIConfigStrings(MIDIMacroConfig &midiCfg) -//-------------------------------------------------------- -{ - for(size_t i = 0; i < CountOf(midiCfg.szMidiSFXExt); i++) - { - FixMIDIConfigString(midiCfg.szMidiSFXExt[i]); - } - for(size_t i = 0; i < CountOf(midiCfg.szMidiZXXExt); i++) - { - FixMIDIConfigString(midiCfg.szMidiZXXExt[i]); - } -} Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-02-07 00:31:12 UTC (rev 1175) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-02-07 19:55:52 UTC (rev 1176) @@ -783,7 +783,6 @@ void UpgradeModFlags(); void UpgradeSong(); - static void FixMIDIConfigStrings(MIDIMacroConfig &midiCfg); // Save Functions #ifndef MODPLUG_NO_FILESAVE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-11 16:34:47
|
Revision: 1177 http://modplug.svn.sourceforge.net/modplug/?rev=1177&view=rev Author: saga-games Date: 2012-02-11 16:34:40 +0000 (Sat, 11 Feb 2012) Log Message: ----------- [Fix] S3M Loader: Some malicious sample and pattern parapointers could crash OpenMPT. [Mod] S3M Loader: Changed PixPlay heuristics so that they only apply to modules made with versions of ScreamTracker older than 3.20. [Mod] OpenMPT: Version is now 1.20.00.67 Modified Paths: -------------- trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Load_s3m.cpp Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-02-07 19:55:52 UTC (rev 1176) +++ trunk/OpenMPT/mptrack/version.h 2012-02-11 16:34:40 UTC (rev 1177) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 66 +#define VER_MINORMINOR 67 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp 2012-02-07 19:55:52 UTC (rev 1176) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2012-02-11 16:34:40 UTC (rev 1177) @@ -216,6 +216,21 @@ } +// Functor for fixing VBlank MODs and MODs with 7-bit panning +struct FixPixPlayPanning +//====================== +{ + void operator()(MODCOMMAND& m) + { + if(m.command == CMD_MIDI) + { + m.command = CMD_S3MCMDEX; + m.param |= 0x80; + } + } +}; + + bool CSoundFile::ReadS3M(const BYTE *lpStream, const DWORD dwMemLength) //--------------------------------------------------------------------- { @@ -224,13 +239,8 @@ UINT insnum, patnum, nins, npat; BYTE s[1024]; DWORD dwMemPos; - vector<DWORD> smpdatapos; - vector<WORD> smppos; - vector<WORD> patpos; - vector<BYTE> insflags; - vector<BYTE> inspack; S3MFILEHEADER psfh = *(S3MFILEHEADER *)lpStream; - bool bKeepMidiMacros = false, bHasAdlibPatches = false; + bool keepMidiMacros = false, hasAdlibPatches = false; psfh.reserved1 = LittleEndianW(psfh.reserved1); psfh.ordnum = LittleEndianW(psfh.ordnum); @@ -247,14 +257,14 @@ if((psfh.cwtv & 0xF000) == 0x5000) // OpenMPT Version number (Major.Minor) { m_dwLastSavedWithVersion = (psfh.cwtv & 0x0FFF) << 16; - bKeepMidiMacros = true; // simply load Zxx commands + keepMidiMacros = 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); // Simply keep default (filter) MIDI macros - bKeepMidiMacros = true; + keepMidiMacros = true; } if((psfh.cwtv & 0xF000) >= 0x2000) @@ -263,33 +273,40 @@ if((psfh.cwtv & 0xF000) != 0x3000 || psfh.cwtv >= 0x3214) { // Keep MIDI macros if this is not an old IT version (BABYLON.S3M by Necros has Zxx commands and was saved with IT 2.05) - bKeepMidiMacros = true; + keepMidiMacros = true; } } - if(!bKeepMidiMacros) // Remove macros so they don't interfere with tunes made in trackers that don't support Zxx + if(!keepMidiMacros) // Remove macros so they don't interfere with tunes made in trackers that don't support Zxx { MemsetZero(m_MidiCfg.szMidiSFXExt); MemsetZero(m_MidiCfg.szMidiZXXExt); } - dwMemPos = 0x60; + dwMemPos = sizeof(S3MFILEHEADER); m_nType = MOD_TYPE_S3M; - memset(m_szNames, 0, sizeof(m_szNames)); + MemsetZero(m_szNames); memcpy(m_szNames[0], psfh.name, 28); StringFixer::SpaceToNullStringFixed<28>(m_szNames[0]); + // Speed m_nDefaultSpeed = psfh.speed; if (!m_nDefaultSpeed || m_nDefaultSpeed == 255) m_nDefaultSpeed = 6; + // Tempo m_nDefaultTempo = psfh.tempo; //m_nDefaultTempo = CLAMP(m_nDefaultTempo, 32, 255); if(m_nDefaultTempo < 33) m_nDefaultTempo = 125; + // Global Volume m_nDefaultGlobalVolume = psfh.globalvol << 2; - if(!m_nDefaultGlobalVolume && psfh.cwtv < 0x1320) m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; // not very reliable, but it fixes a few tunes + // The following check is probably not very reliable, but it fixes a few tunes, f.e. + // DARKNESS.S3M by Purple Motion (ST 3.00) and "Image of Variance" by C.C.Catch (ST 3.01): + if(!m_nDefaultGlobalVolume && psfh.cwtv < 0x1320) m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; if(m_nDefaultGlobalVolume > MAX_GLOBAL_VOLUME) m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; + m_nSamplePreAmp = CLAMP(psfh.mastervol & 0x7F, 0x10, 0x7F); // Bit 8 = Stereo (we always use stereo) + // Channels m_nChannels = 4; for (UINT ich=0; ich<32; ich++) @@ -316,6 +333,7 @@ } if (m_nChannels < 1) m_nChannels = 1; if ((psfh.cwtv < 0x1320) || (psfh.flags & 0x40)) m_dwSongFlags |= SONG_FASTVOLSLIDES; + // Reading pattern order UINT iord = psfh.ordnum; iord = CLAMP(iord, 1, MAX_ORDERS); @@ -325,6 +343,7 @@ dwMemPos += iord; } if ((iord & 1) && (lpStream[dwMemPos] == 0xFF)) dwMemPos++; + // Reading file pointers insnum = nins = psfh.insnum; if (insnum >= MAX_SAMPLES) insnum = MAX_SAMPLES-1; @@ -333,19 +352,21 @@ if (patnum > MAX_PATTERNS) patnum = MAX_PATTERNS; // Read sample header offsets - smppos.resize(nins, 0); + vector<WORD> smppos(nins, 0); for(UINT i = 0; i < nins; i++, dwMemPos += 2) { WORD ptr = *((WORD *)(lpStream + dwMemPos)); smppos[i] = LittleEndianW(ptr); } + // Read pattern offsets - patpos.resize(npat, 0); + vector<WORD> patpos(npat, 0); for(UINT i = 0; i < npat; i++, dwMemPos += 2) { WORD ptr = *((WORD *)(lpStream + dwMemPos)); patpos[i] = LittleEndianW(ptr); } + // Read channel panning if (psfh.panning_present == 0xFC) { @@ -357,13 +378,14 @@ } // Reading instrument headers - smpdatapos.resize(insnum, 0); - inspack.resize(insnum, 0); - insflags.resize(insnum, 0); + vector<DWORD> smpdatapos(insnum, 0); + vector<BYTE> insflags(insnum, 0); + vector<BYTE> inspack(insnum, 0); + for (UINT iSmp=1; iSmp<=insnum; iSmp++) { UINT nInd = ((DWORD)smppos[iSmp - 1]) * 16; - if (nInd + 0x50 > dwMemLength) continue; + if(nInd > dwMemLength || 0x50 > dwMemLength - nInd) continue; memcpy(s, lpStream + nInd, 0x50); memcpy(Samples[iSmp].filename, s+1, 12); @@ -377,15 +399,15 @@ if ((s[0] == S3I_TYPE_PCM) && (s[0x4E] == 'R') && (s[0x4F] == 'S')) { - Samples[iSmp].nLength = CLAMP(LittleEndian(*((LPDWORD)(s + 0x10))), 4, MAX_SAMPLE_LENGTH); - Samples[iSmp].nLoopStart = CLAMP(LittleEndian(*((LPDWORD)(s + 0x14))), 0, Samples[iSmp].nLength - 1); - Samples[iSmp].nLoopEnd = CLAMP(LittleEndian(*((LPDWORD)(s+0x18))), 0, Samples[iSmp].nLength); + Samples[iSmp].nLength = CLAMP(LittleEndian(*((DWORD *)(s + 0x10))), 4, MAX_SAMPLE_LENGTH); + Samples[iSmp].nLoopStart = CLAMP(LittleEndian(*((DWORD *)(s + 0x14))), 0, Samples[iSmp].nLength - 1); + Samples[iSmp].nLoopEnd = CLAMP(LittleEndian(*((DWORD *)(s + 0x18))), 0, Samples[iSmp].nLength); Samples[iSmp].nVolume = CLAMP(s[0x1C], 0, 64) << 2; Samples[iSmp].nGlobalVol = 64; if (s[0x1F] & 1) Samples[iSmp].uFlags |= CHN_LOOP; UINT c5Speed; - c5Speed = LittleEndian(*((LPDWORD)(s+0x20))); + c5Speed = LittleEndian(*((DWORD *)(s + 0x20))); if (!c5Speed) c5Speed = 8363; if (c5Speed < 1024) c5Speed = 1024; Samples[iSmp].nC5Speed = c5Speed; @@ -401,31 +423,33 @@ } else if(s[0] >= S3I_TYPE_ADMEL) { - bHasAdlibPatches = true; + hasAdlibPatches = true; } } - if (!m_nChannels) return true; - /* Try to find out if Zxx commands are supposed to be panning commands (PixPlay). + Actually I am only aware of one module that uses this panning style, namely "Crawling Despair" by $volkraq + and I have no idea what PixPlay is, so this code is solely based on the sample text of that module. 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; + or there are only "left" or "right" pannings (we assume that stereo should be somewhat balanced), + and modules not made with an old version of ST3 were probably made in a tracker that supports panning anyway. */ + bool pixPlayPanning = (psfh.cwtv < 0x1320); + int zxxCountRight = 0, zxxCountLeft = 0; // Reading patterns for (UINT iPat = 0; iPat < patnum; iPat++) { bool fail = Patterns.Insert(iPat, 64); UINT nInd = ((DWORD)patpos[iPat]) * 16; - if (nInd == 0 || nInd + 0x40 > dwMemLength) continue; + if (nInd == 0 || nInd > dwMemLength || 0x40 > dwMemLength - nInd) continue; WORD len = LittleEndianW(*((WORD *)(lpStream + nInd))); nInd += 2; if ((!len) || (nInd + len > dwMemLength - 6) || (fail) ) continue; - LPBYTE src = (LPBYTE)(lpStream+nInd); + LPBYTE src = (LPBYTE)(lpStream + nInd); + // Unpacking pattern - MODCOMMAND *p = Patterns[iPat]; + UINT row = 0; UINT j = 0; while (row < 64) // this fixes ftp://us.aminet.net/pub/aminet/mods/8voic/s3m_hunt.lha (was: while (j < len)) @@ -440,12 +464,12 @@ UINT chn = b & 0x1F; if (chn < m_nChannels) { - MODCOMMAND *m = &p[row * m_nChannels + chn]; + MODCOMMAND *m = Patterns[iPat].GetpModCommand(row, 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; + if (m->note < 0xF0) m->note = (m->note & 0x0F) + 12 * (m->note >> 4) + 13; else if (m->note == 0xFF) m->note = NOTE_NONE; m->instr = src[j++]; } @@ -475,12 +499,12 @@ if(m->param > 0x0F) { // PixPlay has Z00 to Z0F panning, so we ignore this. - bDoNotConvertZxx = true; + pixPlayPanning = false; } else { - if(m->param < 0x08) iZxxCountLeft++; - if(m->param > 0x08) iZxxCountRight++; + if(m->param < 0x08) zxxCountLeft++; + if(m->param > 0x08) zxxCountRight++; } } } @@ -494,21 +518,10 @@ } } - if((UINT)(iZxxCountLeft + iZxxCountRight) >= m_nChannels && !bDoNotConvertZxx && (iZxxCountLeft - iZxxCountRight > -(int)m_nChannels)) + if((zxxCountLeft + zxxCountRight) >= m_nChannels && pixPlayPanning && (-zxxCountLeft + zxxCountRight < (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 = Patterns[nPat].GetNumRows() * m_nChannels; len; m++, len--) - { - if(m->command == CMD_MIDI) - { - m->command = CMD_S3MCMDEX; - m->param |= 0x80; - } - } - } + // There are enough Zxx commands, so let's assume this was made to be played with PixPlay + Patterns.ForEachModCommand(FixPixPlayPanning()); } // Reading samples @@ -532,7 +545,7 @@ if (psfh.flags & 0x10) m_dwSongFlags |= SONG_AMIGALIMITS; #ifdef MODPLUG_TRACKER - if(bHasAdlibPatches && GetpModDoc() != nullptr) + if(hasAdlibPatches && GetpModDoc() != nullptr) { GetpModDoc()->AddToLog("This track uses Adlib instruments, which are not supported by OpenMPT."); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-14 21:39:39
|
Revision: 1179 http://modplug.svn.sourceforge.net/modplug/?rev=1179&view=rev Author: saga-games Date: 2012-02-14 21:39:32 +0000 (Tue, 14 Feb 2012) Log Message: ----------- [Imp] Installer: When checking for VSTs, the default VST folder is written to OpenMPT's config file if there is no other VST folder listed yet. [Fix] After saving, XM and S3M files were still marked as modified since rev. 1168. [Ref] Smaller stuff. Modified Paths: -------------- trunk/OpenMPT/installer/vst_scan.iss trunk/OpenMPT/mptrack/Ctrl_gen.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Mptrack.h Modified: trunk/OpenMPT/installer/vst_scan.iss =================================================================== --- trunk/OpenMPT/installer/vst_scan.iss 2012-02-11 18:52:13 UTC (rev 1178) +++ trunk/OpenMPT/installer/vst_scan.iss 2012-02-14 21:39:32 UTC (rev 1179) @@ -99,6 +99,9 @@ if(VSTPluginNumber <> OldVSTPluginNumber) then begin SetIniInt('VST Plugins', 'NumPlugins', VSTPluginNumber, INIFile); + // Also write the detected VST dir to the INI file if there was no previous entry in it. + if(GetIniString('Paths', 'Plugins_Directory', '', INIFile) = '') then + SetIniString('Paths', 'Plugins_Directory', Dir, INIFile); end; end; Modified: trunk/OpenMPT/mptrack/Ctrl_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2012-02-11 18:52:13 UTC (rev 1178) +++ trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2012-02-14 21:39:32 UTC (rev 1179) @@ -467,18 +467,18 @@ m_EditGlobalVol.GetWindowText(s, sizeof(s)); if (s[0]) { - UINT n = atoi(s); - Limit(n, 0u, 256u / GetGlobalVolumeFactor()); - if (n != (m_pSndFile->m_nDefaultGlobalVolume >> 1)) + UINT n = atoi(s) * GetGlobalVolumeFactor(); + Limit(n, 0u, 256u); + if (n != m_pSndFile->m_nDefaultGlobalVolume) { - m_bEditsLocked=true; + m_bEditsLocked = true; m_EditGlobalVol.SetModify(FALSE); - m_pSndFile->m_nDefaultGlobalVolume = n * GetGlobalVolumeFactor(); - m_pSndFile->m_nGlobalVolume = n * GetGlobalVolumeFactor(); + m_pSndFile->m_nDefaultGlobalVolume = n; + m_pSndFile->m_nGlobalVolume = n; m_pModDoc->SetModified(); m_pModDoc->UpdateAllViews(NULL, HINT_MODGENERAL, this); UpdateView(HINT_MODGENERAL, NULL); - m_bEditsLocked=false; + m_bEditsLocked = false; } } } Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-11 18:52:13 UTC (rev 1178) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-14 21:39:32 UTC (rev 1179) @@ -640,7 +640,7 @@ SetModified(FALSE); m_bHasValidPath=true; m_ShowSavedialog = false; - UpdateAllViews(NULL, HINT_MODGENERAL); // Update treeview (e.g. filename might have changed). + CMainFrame::GetMainFrame()->UpdateTree(this, HINT_MODGENERAL); // Update treeview (e.g. filename might have changed). return TRUE; } else { @@ -1652,7 +1652,7 @@ // Re-mute previously processed sample if(i > 0) MuteSample((SAMPLEINDEX)i, true); - if(m_SndFile.GetSample(i + 1).pSample == nullptr || !m_SndFile.IsSampleUsed((SAMPLEINDEX)(i + 1))) + if(m_SndFile.GetSample((SAMPLEINDEX)(i + 1)).pSample == nullptr || !m_SndFile.IsSampleUsed((SAMPLEINDEX)(i + 1))) continue; // Add sample number & name (if available) to path string if(strlen(m_SndFile.m_szNames[i + 1]) > 0) @@ -2066,17 +2066,16 @@ } +// Enable menu item only module types that support MIDI Mappings void CModDoc::OnUpdateHasMIDIMappings(CCmdUI *p) //---------------------------------------------- { - if(!p) return; - if(m_SndFile.GetModSpecifications().MIDIMappingDirectivesMax > 0) - p->Enable(); - else - p->Enable(FALSE); + if(p) + p->Enable((m_SndFile.GetModSpecifications().MIDIMappingDirectivesMax > 0) ? TRUE : FALSE); } +// Enable menu item only for IT / MPTM / XM files void CModDoc::OnUpdateXMITMPTOnly(CCmdUI *p) //--------------------------------------- { @@ -2085,6 +2084,7 @@ } +// Enable menu item only for IT / MPTM files void CModDoc::OnUpdateITMPTOnly(CCmdUI *p) //--------------------------------------- { @@ -2093,6 +2093,7 @@ } +// Enable menu item if MP3 encoder is present void CModDoc::OnUpdateMP3Encode(CCmdUI *p) //---------------------------------------- { @@ -2100,6 +2101,7 @@ } +// Enable menu item if current module type supports compatibility export void CModDoc::OnUpdateCompatExportableOnly(CCmdUI *p) //--------------------------------------------------- { Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2012-02-11 18:52:13 UTC (rev 1178) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2012-02-14 21:39:32 UTC (rev 1179) @@ -102,7 +102,7 @@ } else //Case: Valid path but opening fails. { - const int nOdc = AfxGetApp()->m_pDocManager->GetOpenDocumentCount(); + const int nOdc = theApp.GetOpenDocumentCount(); CString str; str.Format(GetStrI18N(_TEXT("Opening \"%s\" failed. This can happen if " "no more documents can be opened or if the file type was not " @@ -225,9 +225,16 @@ } +int CTrackApp::GetOpenDocumentCount() const +//----------------------------------------- +{ + return AfxGetApp()->m_pDocManager->GetOpenDocumentCount(); +} + + // Retrieve a list of all open modules. -vector<CModDoc *> CTrackApp::GetOpenDocuments() -//--------------------------------------------- +vector<CModDoc *> CTrackApp::GetOpenDocuments() const +//--------------------------------------------------- { vector<CModDoc *> documents; Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2012-02-11 18:52:13 UTC (rev 1178) +++ trunk/OpenMPT/mptrack/Mptrack.h 2012-02-14 21:39:32 UTC (rev 1179) @@ -168,7 +168,8 @@ static FileDlgResult ShowOpenSaveFileDialog(const bool load, const std::string defaultExtension, const std::string defaultFilename, const std::string extFilter, const std::string workingDirectory = "", const bool allowMultiSelect = false, int *filterIndex = nullptr); - vector<CModDoc *>GetOpenDocuments(); + int GetOpenDocumentCount() const; + vector<CModDoc *>GetOpenDocuments() const; public: CDocTemplate *GetModDocTemplate() const { return m_pModTemplate; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-14 21:41:22
|
Revision: 1180 http://modplug.svn.sourceforge.net/modplug/?rev=1180&view=rev Author: saga-games Date: 2012-02-14 21:41:16 +0000 (Tue, 14 Feb 2012) Log Message: ----------- [Fix] Sample Editor: When converting between XM and IT / MPTM, sample pan limit was not updated instantly. [Fix] VST Editor: Don't try to resize editor when it is actually not visible (some plugins like Sylenth send resize messages even if their editor is hidden) [Ref] const refactoring. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/VSTEditor.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/pattern.cpp trunk/OpenMPT/soundlib/pattern.h Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2012-02-14 21:39:32 UTC (rev 1179) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2012-02-14 21:41:16 UTC (rev 1180) @@ -221,15 +221,6 @@ // Setup Controls m_SpinVolume.SetRange(0, 64); m_SpinGlobalVol.SetRange(0, 64); - //rewbs.fix36944 - if (m_pSndFile->GetType() == MOD_TYPE_XM) - { - m_SpinPanning.SetRange(0, 255); - } else - { - m_SpinPanning.SetRange(0, 64); - } - //end rewbs.fix36944 // Auto vibrato m_ComboAutoVib.AddString("Sine"); @@ -638,6 +629,7 @@ m_CheckPanning.EnableWindow(b && !(m_pSndFile->GetType() & MOD_TYPE_XM)); m_EditPanning.EnableWindow(b); m_SpinPanning.EnableWindow(b); + m_SpinPanning.SetRange(0, (m_pSndFile->GetType() == MOD_TYPE_XM) ? 255 : 64); b = (m_pSndFile->GetType() & MOD_TYPE_MOD) ? FALSE : TRUE; m_CbnBaseNote.EnableWindow(b); Modified: trunk/OpenMPT/mptrack/VSTEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/VSTEditor.cpp 2012-02-14 21:39:32 UTC (rev 1179) +++ trunk/OpenMPT/mptrack/VSTEditor.cpp 2012-02-14 21:41:16 UTC (rev 1180) @@ -127,7 +127,7 @@ bool COwnerVstEditor::SetSize(int contentWidth, int contentHeight) //---------------------------------------------------------------- { - if(contentWidth < 0 || contentHeight < 0) + if(contentWidth < 0 || contentHeight < 0 || !m_hWnd) { return false; } Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2012-02-14 21:39:32 UTC (rev 1179) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2012-02-14 21:41:16 UTC (rev 1180) @@ -472,8 +472,8 @@ } -void CopyPatternName(CPattern &pattern, char **patNames, UINT &patNamesLen) -//------------------------------------------------------------------------- +void CopyPatternName(CPattern &pattern, const char **patNames, UINT &patNamesLen) +//------------------------------------------------------------------------------- { if(*patNames != nullptr && patNamesLen > 0) { @@ -758,7 +758,7 @@ #ifdef MODPLUG_TRACKER if(GetpModDoc() != nullptr) { - GetpModDoc()->GetFileHistory().clear(); + GetpModDoc()->GetFileHistory().resize(nflt); for(size_t n = 0; n < nflt; n++) { ITHISTORYSTRUCT itHistory = *((ITHISTORYSTRUCT *)(lpStream + dwMemPos)); @@ -776,7 +776,7 @@ mptHistory.loadDate.tm_min = CLAMP((itHistory.fattime >> 5) & 0x3F, 0, 59); mptHistory.loadDate.tm_sec = CLAMP((itHistory.fattime & 0x1F) * 2, 0, 59); mptHistory.openTime = itHistory.runtime * (HISTORY_TIMER_PRECISION / 18.2f); - GetpModDoc()->GetFileHistory().push_back(mptHistory); + GetpModDoc()->GetFileHistory().at(n) = mptHistory; #ifdef DEBUG const uint32 seconds = (uint32)(((double)itHistory.runtime) / 18.2f); @@ -828,7 +828,7 @@ } // Read pattern names: "PNAM" - char *patNames = nullptr; + const char *patNames = nullptr; UINT patNamesLen = 0; if ((dwMemPos + 8 < dwMemLength) && (*((DWORD *)(lpStream+dwMemPos)) == LittleEndian(IT_PNAM))) { @@ -847,14 +847,14 @@ { UINT len = *((DWORD *)(lpStream+dwMemPos+4)); dwMemPos += 8; - if ((dwMemPos + len <= dwMemLength) && (len <= MAX_BASECHANNELS*MAX_CHANNELNAME)) + if ((dwMemPos + len <= dwMemLength) && (len <= MAX_BASECHANNELS * MAX_CHANNELNAME)) { UINT n = len / MAX_CHANNELNAME; if (n > m_nChannels) m_nChannels = n; for (UINT i=0; i<n; i++) { - memcpy(ChnSettings[i].szName, (lpStream+dwMemPos+i*MAX_CHANNELNAME), MAX_CHANNELNAME); - ChnSettings[i].szName[MAX_CHANNELNAME-1] = 0; + memcpy(ChnSettings[i].szName, (lpStream + dwMemPos + i * MAX_CHANNELNAME), MAX_CHANNELNAME); + ChnSettings[i].szName[MAX_CHANNELNAME - 1] = 0; } dwMemPos += len; } @@ -1090,7 +1090,7 @@ UINT len = *((WORD *)(lpStream+patpos[npat])); UINT rows = *((WORD *)(lpStream+patpos[npat]+2)); if ((rows < GetModSpecifications().patternRowsMin) || (rows > GetModSpecifications().patternRowsMax)) continue; - if (patpos[npat]+8+len > dwMemLength) continue; + if (patpos[npat] + 8 + len > dwMemLength) continue; if(Patterns.Insert(npat, rows)) continue; @@ -2078,7 +2078,6 @@ return (retval >> (32-i)); } -#define IT215_SUPPORT void ITUnpack8Bit(LPSTR pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215) //------------------------------------------------------------------------------------------- { @@ -2143,11 +2142,8 @@ wBits += bTemp; bTemp = (BYTE)wBits; bTemp2 += bTemp; -#ifdef IT215_SUPPORT pDst[dwPos] = (b215) ? bTemp2 : bTemp; -#else - pDst[dwPos] = bTemp; -#endif + SkipByte: dwPos++; Next: @@ -2226,11 +2222,8 @@ dwBits += wTemp; wTemp = (signed short)dwBits; wTemp2 += wTemp; -#ifdef IT215_SUPPORT pDst[dwPos] = (b215) ? wTemp2 : wTemp; -#else - pDst[dwPos] = wTemp; -#endif + SkipByte: dwPos++; Next: @@ -2315,7 +2308,7 @@ s[0] = 'P'; s[1] = 'R'; s[2] = 'O'; s[3] = 'G'; fwrite(s, 1, 4, f); //Write chunk data itself (Could include size if you want variable size. Not necessary here.) - fwrite(&(m_MixPlugins[i].defaultProgram), 1, sizeof(float), f); + fwrite(&(m_MixPlugins[i].defaultProgram), 1, sizeof(long), f); //} //end rewbs.plugDefaultProgram @@ -2577,11 +2570,11 @@ fwrite(&size, 1, sizeof(__int16), f); fwrite(&m_nChannels, 1, size, f); - if(TypeIsIT_MPT() && m_nChannels > 64) //IT header has room only for 64 channels. Save the + if(TypeIsIT_MPT() && GetNumChannels() > 64) //IT header has room only for 64 channels. Save the { //settings that do not fit to the header here as an extension. code = 'ChnS'; fwrite(&code, 1, sizeof(__int32), f); - size = (m_nChannels - 64)*2; + size = (GetNumChannels() - 64) * 2; fwrite(&size, 1, sizeof(__int16), f); for(UINT ich = 64; ich < m_nChannels; ich++) { Modified: trunk/OpenMPT/soundlib/pattern.cpp =================================================================== --- trunk/OpenMPT/soundlib/pattern.cpp 2012-02-14 21:39:32 UTC (rev 1179) +++ trunk/OpenMPT/soundlib/pattern.cpp 2012-02-14 21:41:16 UTC (rev 1180) @@ -216,8 +216,8 @@ } -bool CPattern::SetName(char *newName, size_t maxChars) -//---------------------------------------------------- +bool CPattern::SetName(const char *newName, size_t maxChars) +//---------------------------------------------------------- { if(newName == nullptr || maxChars == 0) { @@ -280,9 +280,9 @@ bool CPattern::WriteITPdata(FILE* f) const //---------------------------------------- { - for(ROWINDEX r = 0; r<GetNumRows(); r++) + for(ROWINDEX r = 0; r < GetNumRows(); r++) { - for(CHANNELINDEX c = 0; c<GetNumChannels(); c++) + for(CHANNELINDEX c = 0; c < GetNumChannels(); c++) { MODCOMMAND mc = GetModCommand(r,c); fwrite(&mc, sizeof(MODCOMMAND), 1, f); @@ -302,7 +302,7 @@ while(streamPos - startPos + sizeof(MODCOMMAND_ORIGINAL) <= datasize) { MODCOMMAND_ORIGINAL temp; - memcpy(&temp, lpStream+streamPos, sizeof(MODCOMMAND_ORIGINAL)); + memcpy(&temp, lpStream + streamPos, sizeof(MODCOMMAND_ORIGINAL)); MODCOMMAND& mc = GetModCommand(counter); mc.command = temp.command; mc.instr = temp.instr; @@ -416,7 +416,7 @@ for(CHANNELINDEX c = 0; c<chns; c++) { const MODCOMMAND m = *pat.GetpModCommand(r, c); - // Writing only commands not writting in IT-pattern writing: + // Writing only commands not written in IT-pattern writing: // For now this means only NOTE_PC and NOTE_PCS. if(!m.IsPcNote()) continue; Modified: trunk/OpenMPT/soundlib/pattern.h =================================================================== --- trunk/OpenMPT/soundlib/pattern.h 2012-02-14 21:39:32 UTC (rev 1179) +++ trunk/OpenMPT/soundlib/pattern.h 2012-02-14 21:41:16 UTC (rev 1180) @@ -73,8 +73,8 @@ void RemoveSignature() { m_RowsPerBeat = m_RowsPerMeasure = 0; } // Patter name functions (for both CString and char[] arrays) - bool functions return true on success. - bool SetName(char *newName, size_t maxChars = MAX_PATTERNNAME); - bool SetName(CString newName) { m_PatternName = newName; return true; }; + bool SetName(const char *newName, size_t maxChars = MAX_PATTERNNAME); + bool SetName(const CString newName) { m_PatternName = newName; return true; }; bool GetName(char *buffer, size_t maxChars = MAX_PATTERNNAME) const; CString GetName() const { return m_PatternName; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-14 21:48:10
|
Revision: 1181 http://modplug.svn.sourceforge.net/modplug/?rev=1181&view=rev Author: saga-games Date: 2012-02-14 21:48:02 +0000 (Tue, 14 Feb 2012) Log Message: ----------- [Mod] VST: MIDI portamento on muted channels is not processed anymore (http://bugs.openmpt.org/view.php?id=219). [Mod] OpenMPT: Version is now 1.20.00.68 Modified Paths: -------------- trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-02-14 21:41:16 UTC (rev 1180) +++ trunk/OpenMPT/mptrack/version.h 2012-02-14 21:48:02 UTC (rev 1181) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 67 +#define VER_MINORMINOR 68 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-14 21:41:16 UTC (rev 1180) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-14 21:48:02 UTC (rev 1181) @@ -2456,6 +2456,14 @@ void CSoundFile::MidiPortamento(CHANNELINDEX nChn, int param) //----------------------------------------------------------- { + if((Chn[nChn].dwFlags & CHN_MUTE) != 0) + { + // Don't process portamento on muted channels. Note that this might have a side-effect + // on other channels which trigger notes on the same MIDI channel of the same plugin, + // as those won't be pitch-bent anymore. + return; + } + //Send midi pitch bend event if there's a plugin: const MODINSTRUMENT *pIns = Chn[nChn].pModInstrument; if (pIns && pIns->HasValidMIDIChannel()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-15 23:17:27
|
Revision: 1182 http://modplug.svn.sourceforge.net/modplug/?rev=1182&view=rev Author: saga-games Date: 2012-02-15 23:17:20 +0000 (Wed, 15 Feb 2012) Log Message: ----------- [Fix] Apparently, the row duration calculation for alternative tempo mode was completely wrong (tx Bavi H). Now it seems like alternative tempo mode is just like classic tempo mode, but with different factors... [Fix] Length Calculation also respects row delay effects in modern tempo mode now. Modified Paths: -------------- trunk/OpenMPT/mptrack/PSRatioCalc.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/PSRatioCalc.cpp =================================================================== --- trunk/OpenMPT/mptrack/PSRatioCalc.cpp 2012-02-14 21:48:02 UTC (rev 1181) +++ trunk/OpenMPT/mptrack/PSRatioCalc.cpp 2012-02-15 23:17:20 UTC (rev 1182) @@ -144,7 +144,7 @@ void CPSRatioCalc::CalcRows() { - double rowTime = sndFile.GetRowDuration(sndFile.m_nMusicSpeed, sndFile.m_nMusicTempo); + double rowTime = sndFile.GetRowDuration(sndFile.m_nMusicTempo, sndFile.m_nMusicSpeed); m_dRowsOrig = (double)m_lMsOrig / rowTime; m_dRowsNew = m_dRowsOrig*(m_dRatio / 100); Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-14 21:48:02 UTC (rev 1181) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-15 23:17:20 UTC (rev 1182) @@ -444,12 +444,12 @@ { param >>= 4; param <<= 1; - if (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) param <<= 1; + if (!(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT))) param <<= 1; memory.glbVol += param * memory.musicSpeed; } else { param = (param & 0x0F) << 1; - if (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) param <<= 1; + if (!(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT))) param <<= 1; memory.glbVol -= param * memory.musicSpeed; } memory.glbVol = CLAMP(memory.glbVol, 0, 256); @@ -488,9 +488,8 @@ nNextPatStartRow = 0; } - nSpeedCount += memory.musicSpeed; - - memory.elapsedTime += GetRowDuration(nSpeedCount, memory.musicTempo); + // XXX this does not take per-pattern time signatures into consideration! + memory.elapsedTime += GetRowDuration(memory.musicTempo, memory.musicSpeed, nSpeedCount); } if(retval.targetReached || endOrder == ORDERINDEX_INVALID || endRow == ROWINDEX_INVALID) Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-14 21:48:02 UTC (rev 1181) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-15 23:17:20 UTC (rev 1182) @@ -2759,19 +2759,25 @@ // Get the duration of a row in milliseconds, based on the current rows per beat and given speed and tempo settings. -double CSoundFile::GetRowDuration(UINT speed, UINT tempo) const -//------------------------------------------------------------- +// "additionalTicks" are ticks that are derived from Row Delay effects. +double CSoundFile::GetRowDuration(UINT tempo, UINT speed, UINT additionalTicks) const +//----------------------------------------------------------------------------------- { switch(m_nTempoMode) { - case tempo_mode_alternative: - return 60000.0 / (1.65625 * static_cast<double>(speed * tempo)); - case tempo_mode_modern: - // XXX We cannot calculate any row delays with this, since speed is not considered! - return 60000.0 / static_cast<double>(tempo) / static_cast<double>(m_nCurrentRowsPerBeat); case tempo_mode_classic: default: - return (2500.0 * static_cast<double>(speed)) / static_cast<double>(tempo); + return static_cast<double>(2500 * (speed + additionalTicks)) / static_cast<double>(tempo); + + case tempo_mode_modern: + { + // If there are any row delay effects, the row length factor compensates for those. + const double rowLength = static_cast<double>(speed + additionalTicks) / static_cast<double>(speed); + return 60000.0 * rowLength / static_cast<double>(tempo) / static_cast<double>(m_nCurrentRowsPerBeat); + } + + case tempo_mode_alternative: + return static_cast<double>(1000 * (speed + additionalTicks)) / static_cast<double>(tempo); } } Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-02-14 21:48:02 UTC (rev 1181) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-02-15 23:17:20 UTC (rev 1182) @@ -733,7 +733,7 @@ DWORD GetSongTime() { return static_cast<DWORD>((m_nTempoMode == tempo_mode_alternative) ? GetLength(eNoAdjust).duration + 1.0 : GetLength(eNoAdjust).duration + 0.5); } void RecalculateSamplesPerTick(); - double GetRowDuration(UINT speed, UINT tempo) const; + double GetRowDuration(UINT tempo, UINT speed, UINT additionalTicks = 0) const; // A repeat count value of -1 means infinite loop void SetRepeatCount(int n) { m_nRepeatCount = n; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-17 21:36:16
|
Revision: 1183 http://modplug.svn.sourceforge.net/modplug/?rev=1183&view=rev Author: saga-games Date: 2012-02-17 21:36:02 +0000 (Fri, 17 Feb 2012) Log Message: ----------- [Ref] Converted NOTE_IS_VALID macro into MODCOMMAND member functions. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_pat.h trunk/OpenMPT/soundlib/LOAD_DMF.CPP trunk/OpenMPT/soundlib/Snd_flt.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/modcommand.h Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-02-17 21:36:02 UTC (rev 1183) @@ -131,7 +131,7 @@ //------------------------------------------ { if (nNote == m_nNote) return TRUE; - if (!NOTE_IS_VALID(nNote + 1)) return FALSE; + if (!MODCOMMAND::IsNote(nNote + 1)) return FALSE; m_nNote = nNote; InvalidateRect(NULL, FALSE); return TRUE; @@ -192,10 +192,10 @@ rect.left = rect.right; rect.right = m_cxFont*2-1; strcpy(s, "..."); - if ((pIns) && (nPos >= 0) && (nPos < NOTE_MAX) && (pIns->NoteMap[nPos])) + if ((pIns) && (nPos >= 0) && (nPos < NOTE_MAX) && (pIns->NoteMap[nPos] != NOTE_NONE)) { UINT n = pIns->NoteMap[nPos]; - if(NOTE_IS_VALID(n)) + if(MODCOMMAND::IsNote(n)) { string temp = pSndFile->GetNoteName(n, m_nInstrument); temp.resize(4); @@ -345,7 +345,7 @@ if(pSndFile->GetType() != MOD_TYPE_XM) { - if(NOTE_IS_VALID(pIns->NoteMap[m_nNote])) + if(MODCOMMAND::IsNote(pIns->NoteMap[m_nNote])) { wsprintf(s, "Map all ¬es to %s\t" + ih->GetKeyTextFromCommand(kcInsNoteMapCopyCurrentNote), pSndFile->GetNoteName(pIns->NoteMap[m_nNote], m_nInstrument).c_str()); AppendMenu(hMenu, MF_STRING, ID_NOTEMAP_COPY_NOTE, s); Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-17 21:36:02 UTC (rev 1183) @@ -895,7 +895,7 @@ if ((!pMainFrm) || (!note)) return FALSE; if (nVol > 256) nVol = 256; - if (NOTE_IS_VALID(note)) + if (MODCOMMAND::IsNoteOrEmpty(note)) { //kill notes if required. Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2012-02-17 21:36:02 UTC (rev 1183) @@ -271,10 +271,10 @@ { MODCOMMAND::INSTR instr = m.instr, newinstr = 0; MODCOMMAND::NOTE note = m.note, newnote = note; - if(note != NOTE_NONE && NOTE_IS_VALID(note)) - note--; + if(MODCOMMAND::IsNote(note)) + note = note - NOTE_MIN; else - note = NOTE_MIDDLEC - 1; + note = NOTE_MIDDLEC - NOTE_MIN; if((instr < MAX_INSTRUMENTS) && (pSndFile->Instruments[instr])) { @@ -284,7 +284,7 @@ if(newinstr >= MAX_SAMPLES) newinstr = 0; } m.instr = newinstr; - if(m.note != NOTE_NONE && NOTE_IS_VALID(m.note)) + if(m.IsNote()) { m.note = newnote; } Modified: trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp =================================================================== --- trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp 2012-02-17 21:36:02 UTC (rev 1183) @@ -857,7 +857,7 @@ combo->SetItemData(combo->AddString("No note"), 0); AppendNotesToControlEx(*combo, pSndFile, m_nInstr); - if (NOTE_IS_VALID(m_nNote)) + if (MODCOMMAND::IsNoteOrEmpty(m_nNote)) { // Normal note / no note const MODCOMMAND::NOTE noteStart = (pSndFile != nullptr) ? pSndFile->GetModSpecifications().noteMin : 1; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2012-02-17 21:36:02 UTC (rev 1183) @@ -4606,7 +4606,7 @@ // just play the newly inserted note using the already specified instrument... UINT nPlayIns = newcmd.instr; - if(!nPlayIns && NOTE_IS_VALID(note)) + if(!nPlayIns && MODCOMMAND::IsNoteOrEmpty(note)) { // ...or one that can be found on a previous row of this pattern. MODCOMMAND *search = pTarget; @@ -5659,7 +5659,7 @@ result = (startRowCmd == endRowCmd && startRowCmd != NOTE_NONE) // Interpolate between two identical notes or Cut / Fade / etc... || (startRowCmd != NOTE_NONE && endRowCmd == NOTE_NONE) // Fill in values from the first row || (startRowCmd == NOTE_NONE && endRowCmd != NOTE_NONE) // Fill in values from the last row - || (NOTE_IS_VALID(startRowCmd) && NOTE_IS_VALID(endRowCmd) && !(startRowCmd == NOTE_NONE && endRowCmd == NOTE_NONE)); // Interpolate between two notes of which one may be empty + || (MODCOMMAND::IsNoteOrEmpty(startRowCmd) && MODCOMMAND::IsNoteOrEmpty(endRowCmd) && !(startRowCmd == NOTE_NONE && endRowCmd == NOTE_NONE)); // Interpolate between two notes of which one may be empty break; case EFFECT_COLUMN: startRowCmd = startRowMC.command; @@ -5923,7 +5923,7 @@ // If a note or an instr is present on the row, do the change, if required. // Do not set instr if note and instr are both blank, // but set instr if note is a PC note and instr is blank. - if (((p->note != NOTE_NONE && NOTE_IS_VALID(p->note)) || p->IsPcNote() || p->instr) && (p->instr != nIns)) + if ((p->IsNote() || p->IsPcNote() || p->instr) && (p->instr != nIns)) { p->instr = nIns; bModified = true; Modified: trunk/OpenMPT/mptrack/View_pat.h =================================================================== --- trunk/OpenMPT/mptrack/View_pat.h 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/mptrack/View_pat.h 2012-02-17 21:36:02 UTC (rev 1183) @@ -214,7 +214,7 @@ void DrawDragSel(HDC hdc); void OnDrawDragSel(); // True if default volume should be drawn for a given cell. - static bool DrawDefaultVolume(const MODCOMMAND *m) { return (CMainFrame::GetSettings().m_dwPatternSetup & PATTERN_SHOWDEFAULTVOLUME) && m->volcmd == VOLCMD_NONE && m->command != CMD_VOLUME && m->instr != 0 && m->note != NOTE_NONE && NOTE_IS_VALID(m->note); } + static bool DrawDefaultVolume(const MODCOMMAND *m) { return (CMainFrame::GetSettings().m_dwPatternSetup & PATTERN_SHOWDEFAULTVOLUME) && m->volcmd == VOLCMD_NONE && m->command != CMD_VOLUME && m->instr != 0 && m->IsNote(); } //rewbs.customKeys BOOL ExecuteCommand(CommandID command); Modified: trunk/OpenMPT/soundlib/LOAD_DMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2012-02-17 21:36:02 UTC (rev 1183) @@ -414,13 +414,13 @@ } // If there's just an instrument number, but no note, retrigger sample. - if(m->note == NOTE_NONE && NOTE_IS_VALID(m->note) && m->instr > 0) + if(m->note == NOTE_NONE && m->instr > 0) { m->note = settings.lastNote[nChn]; m->instr = 0; } - if(m->note != NOTE_NONE && NOTE_IS_VALID(m->note)) + if(m->IsNote()) { settings.playDir[nChn] = false; } @@ -636,7 +636,7 @@ } // I guess this is close enough to "not retriggering the note" - if(slideNote && m->note != NOTE_NONE && NOTE_IS_VALID(m->note)) + if(slideNote && m->IsNote()) { if(effect2 == CMD_NONE) { Modified: trunk/OpenMPT/soundlib/Snd_flt.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_flt.cpp 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/soundlib/Snd_flt.cpp 2012-02-17 21:36:02 UTC (rev 1183) @@ -63,7 +63,7 @@ // Filtering is only ever done in IT if either cutoff is not full or if resonance is set. if(IsCompatibleMode(TRK_IMPULSETRACKER) && resonance == 0 && computedCutoff >= 254) { - if(pChn->rowCommand.note != NOTE_NONE && NOTE_IS_VALID(pChn->rowCommand.note) && !(pChn->dwFlags & CHN_PORTAMENTO) && !pChn->nMasterChn && (m_dwSongFlags & SONG_FIRSTTICK) != 0) + if(pChn->rowCommand.IsNote() && !(pChn->dwFlags & CHN_PORTAMENTO) && !pChn->nMasterChn && (m_dwSongFlags & SONG_FIRSTTICK) != 0) { // Z7F next to a note disables the filter, however in other cases this should not happen. // Test cases: filter-reset.it, filter-reset-carry.it, filter-nna.it Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-17 21:36:02 UTC (rev 1183) @@ -522,10 +522,10 @@ for (CHANNELINDEX n = 0; n < GetNumChannels(); n++) { Chn[n].nGlobalVol = memory.chnVols[n]; - if (memory.notes[n]) + if (memory.notes[n] != NOTE_NONE) { Chn[n].nNewNote = memory.notes[n]; - if(NOTE_IS_VALID(memory.notes[n])) + if(MODCOMMAND::IsNote(memory.notes[n])) { Chn[n].nLastNote = memory.notes[n]; } @@ -566,7 +566,7 @@ if(note == NOTE_NONE && IsCompatibleMode(TRK_IMPULSETRACKER)) return; - if (pIns != nullptr && note != NOTE_NONE && NOTE_IS_VALID(note)) + if (pIns != nullptr && MODCOMMAND::IsNote(note)) { if(bPorta && pIns == pChn->pModInstrument && (pChn->pModSample != nullptr && pChn->pModSample->pSample != nullptr) && IsCompatibleMode(TRK_IMPULSETRACKER)) { @@ -1545,7 +1545,7 @@ // Notes that exceed FT2's limit are completely ignored. // Test case: note-limit.xm - if(note != NOTE_NONE && NOTE_IS_VALID(note) && IsCompatibleMode(TRK_FASTTRACKER2)) + if(MODCOMMAND::IsNote(note) && IsCompatibleMode(TRK_FASTTRACKER2)) { const int computedNote = note + pChn->nTranspose; if((computedNote < NOTE_MIN + 11 || computedNote > NOTE_MIN + 130)) @@ -1673,7 +1673,7 @@ // Note Cut/Off/Fade => ignore instrument if (note >= NOTE_MIN_SPECIAL) instr = 0; - if (note != NOTE_NONE && NOTE_IS_VALID(note)) + if (MODCOMMAND::IsNote(note)) { pChn->nNewNote = pChn->nLastNote = note; @@ -1937,7 +1937,7 @@ } if (m && m->command == CMD_XPARAM) { - if (GetType() & MOD_TYPE_XM) + if ((GetType() & MOD_TYPE_XM)) { param -= 0x20; //with XM, 0x20 is the lowest tempo. Anything below changes ticks per row. } @@ -1967,7 +1967,7 @@ case CMD_ARPEGGIO: // IT compatibility 01. Don't ignore Arpeggio if no note is playing (also valid for ST3) if ((m_nTickCount) || (((!pChn->nPeriod) || !pChn->nNote) && !IsCompatibleMode(TRK_IMPULSETRACKER | TRK_SCREAMTRACKER))) break; - if ((!param) && (!(GetType() & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)))) break; + if ((!param) && (!(GetType() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT)))) break; pChn->nCommand = CMD_ARPEGGIO; if (param) pChn->nArpeggio = param; break; @@ -2037,18 +2037,14 @@ // break; // } - if (!(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT))) param <<= 1; - //IT compatibility 16. FT2, ST3 and IT ignore out-of-range values - if(IsCompatibleMode(TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER)) + if (!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) param *= 2; + + // IT compatibility 16. FT2, ST3 and IT ignore out-of-range values. + // Test case: globalvol-invalid.it + if (param <= 128) { - if (param <= 128) - m_nGlobalVolume = param << 1; + m_nGlobalVolume = param * 2; } - else - { - if (param > 128) param = 128; - m_nGlobalVolume = param << 1; - } break; // Global Volume Slide @@ -2065,7 +2061,7 @@ if (!(m_dwSongFlags & SONG_FIRSTTICK)) break; if ((m_dwSongFlags & SONG_PT1XMODE)) break; if (!(m_dwSongFlags & SONG_SURROUNDPAN)) pChn->dwFlags &= ~CHN_SURROUND; - if (m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_XM|MOD_TYPE_MOD|MOD_TYPE_MT2)) + if (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_XM | MOD_TYPE_MOD | MOD_TYPE_MT2)) { pChn->nPan = param; } else @@ -2491,7 +2487,7 @@ { if ((pChn->nPeriod) && (param)) { - if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)))) + if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2)))) { pChn->nPeriod = _muldivr(pChn->nPeriod, LinearSlideDownTable[param & 0x0F], 65536); } else @@ -2515,7 +2511,7 @@ { if ((pChn->nPeriod) && (param)) { - if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)))) + if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2)))) { pChn->nPeriod = _muldivr(pChn->nPeriod, LinearSlideUpTable[param & 0x0F], 65536); } else @@ -2539,7 +2535,7 @@ { if ((pChn->nPeriod) && (param)) { - if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)))) + if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2)))) { pChn->nPeriod = _muldivr(pChn->nPeriod, FineLinearSlideDownTable[param & 0x0F], 65536); } else @@ -2563,7 +2559,7 @@ { if ((pChn->nPeriod) && (param)) { - if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)))) + if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2)))) { pChn->nPeriod = _muldivr(pChn->nPeriod, FineLinearSlideUpTable[param & 0x0F], 65536); } else @@ -3136,7 +3132,7 @@ case 0xA0: if(m_dwSongFlags & SONG_FIRSTTICK) { pChn->nOldHiOffset = param; - if (!IsCompatibleMode(TRK_IMPULSETRACKER) && (pChn->rowCommand.note != NOTE_NONE) && NOTE_IS_VALID(pChn->rowCommand.note)) + if (!IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->rowCommand.IsNote()) { DWORD pos = param << 16; if (pos < pChn->nLength) pChn->nPos = pos; @@ -3272,7 +3268,7 @@ data = (unsigned char)GetBestMidiChannel(nChn); } else if(macro[pos] == 'n') // n: note value (last triggered note) { - if(pChn->nLastNote != NOTE_NONE && NOTE_IS_VALID(pChn->nLastNote)) + if(MODCOMMAND::IsNote(pChn->nLastNote)) { data = (unsigned char)(pChn->nLastNote - NOTE_MIN); } Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-17 21:36:02 UTC (rev 1183) @@ -2646,10 +2646,10 @@ string CSoundFile::GetNoteName(const CTuning::NOTEINDEXTYPE& note, const INSTRUMENTINDEX inst) const //-------------------------------------------------------------------------------------------------- { - if((inst >= MAX_INSTRUMENTS && inst != INSTRUMENTINDEX_INVALID) || note < 1 || note > NOTE_MAX) return "BUG"; + if((inst >= MAX_INSTRUMENTS && inst != INSTRUMENTINDEX_INVALID) || note < NOTE_MIN || note > NOTE_MAX) return "BUG"; // For MPTM instruments with custom tuning, find the appropriate note name. Else, use default note names. - if(inst != INSTRUMENTINDEX_INVALID && m_nType == MOD_TYPE_MPT && Instruments[inst] && Instruments[inst]->pTuning) + if(inst != INSTRUMENTINDEX_INVALID && GetType() == MOD_TYPE_MPT && Instruments[inst] && Instruments[inst]->pTuning) return Instruments[inst]->pTuning->GetNoteName(note - NOTE_MIDDLEC); else return szDefaultNoteNames[note - 1]; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-17 21:36:02 UTC (rev 1183) @@ -2461,7 +2461,7 @@ if(note != NOTE_NONE) { MODCOMMAND::NOTE realNote = note; - if(NOTE_IS_VALID(note)) + if(MODCOMMAND::IsNote(note)) realNote = pIns->NoteMap[note - 1]; pPlugin->MidiCommand(GetBestMidiChannel(nChn), pIns->nMidiProgram, pIns->wMidiBank, realNote, pChn->nVolume, nChn); } else if (volcmd == VOLCMD_VOLUME) @@ -2488,7 +2488,7 @@ } MODCOMMAND::NOTE realNote = note; - if(NOTE_IS_VALID(note)) + if(MODCOMMAND::IsNote(note)) realNote = pIns->NoteMap[note - 1]; // Experimental VST panning //ProcessMIDIMacro(nChn, false, m_MidiCfg.szMidiGlb[MIDIOUT_PAN], 0, nPlugin); Modified: trunk/OpenMPT/soundlib/modcommand.h =================================================================== --- trunk/OpenMPT/soundlib/modcommand.h 2012-02-15 23:17:20 UTC (rev 1182) +++ trunk/OpenMPT/soundlib/modcommand.h 2012-02-17 21:36:02 UTC (rev 1183) @@ -1,20 +1,20 @@ +#pragma once + #ifndef MODCOMMAND_H #define MODCOMMAND_H - // Note definitions #define NOTE_NONE 0 -#define NOTE_MIDDLEC (5*12+1) -#define NOTE_KEYOFF 0xFF //255 -#define NOTE_NOTECUT 0xFE //254 -#define NOTE_FADE 0xFD //253, IT's action for illegal notes - DO NOT SAVE AS 253 as this is IT's internal representation of "no note"! -#define NOTE_PC 0xFC //252, Param Control 'note'. Changes param value on first tick. -#define NOTE_PCS 0xFB //251, Param Control(Smooth) 'note'. Changes param value during the whole row. +#define NOTE_MIDDLEC (5 * 12 + 1) +#define NOTE_KEYOFF 0xFF // 255 +#define NOTE_NOTECUT 0xFE // 254 +#define NOTE_FADE 0xFD // 253, IT's action for illegal notes - DO NOT SAVE AS 253 as this is IT's internal representation of "no note"! +#define NOTE_PC 0xFC // 252, Param Control 'note'. Changes param value on first tick. +#define NOTE_PCS 0xFB // 251, Param Control (Smooth) 'note'. Changes param value during the whole row. #define NOTE_MIN 1 #define NOTE_MAX 120 //Defines maximum notevalue(with index starting from 1) as well as maximum number of notes. #define NOTE_MAX_SPECIAL NOTE_KEYOFF #define NOTE_MIN_SPECIAL NOTE_PCS -#define NOTE_IS_VALID(n) ((n) == NOTE_NONE || ((n) >= NOTE_MIN && (n) <= NOTE_MAX)) // Checks whether a number represents a valid note (a "normal" note or no note, but not something like note off) //============== @@ -31,26 +31,26 @@ // Defines the maximum value for column data when interpreted as 2-byte value // (for example volcmd and vol). The valid value range is [0, maxColumnValue]. - enum {maxColumnValue = 999}; + enum { maxColumnValue = 999 }; // Returns empty modcommand. - static MODCOMMAND Empty() {MODCOMMAND m = {0,0,0,0,0,0}; return m;} + static MODCOMMAND Empty() { MODCOMMAND m = {0,0,0,0,0,0}; return m; } bool operator==(const MODCOMMAND& mc) const { return (memcmp(this, &mc, sizeof(MODCOMMAND)) == 0); } bool operator!=(const MODCOMMAND& mc) const { return !(*this == mc); } - void Set(NOTE n, INSTR ins, uint16 volcol, uint16 effectcol) {note = n; instr = ins; SetValueVolCol(volcol); SetValueEffectCol(effectcol);} + void Set(NOTE n, INSTR ins, uint16 volcol, uint16 effectcol) { note = n; instr = ins; SetValueVolCol(volcol); SetValueEffectCol(effectcol); } - uint16 GetValueVolCol() const {return GetValueVolCol(volcmd, vol);} - static uint16 GetValueVolCol(BYTE volcmd, BYTE vol) {return (volcmd << 8) + vol;} - void SetValueVolCol(const uint16 val) {volcmd = static_cast<BYTE>(val >> 8); vol = static_cast<BYTE>(val & 0xFF);} + uint16 GetValueVolCol() const { return GetValueVolCol(volcmd, vol); } + static uint16 GetValueVolCol(BYTE volcmd, BYTE vol) { return (volcmd << 8) + vol; } + void SetValueVolCol(const uint16 val) { volcmd = static_cast<BYTE>(val >> 8); vol = static_cast<BYTE>(val & 0xFF); } - uint16 GetValueEffectCol() const {return GetValueEffectCol(command, param);} - static uint16 GetValueEffectCol(BYTE command, BYTE param) {return (command << 8) + param;} - void SetValueEffectCol(const uint16 val) {command = static_cast<BYTE>(val >> 8); param = static_cast<BYTE>(val & 0xFF);} + uint16 GetValueEffectCol() const { return GetValueEffectCol(command, param); } + static uint16 GetValueEffectCol(BYTE command, BYTE param) { return (command << 8) + param; } + void SetValueEffectCol(const uint16 val) { command = static_cast<BYTE>(val >> 8); param = static_cast<BYTE>(val & 0xFF); } // Clears modcommand. - void Clear() {memset(this, 0, sizeof(MODCOMMAND)); } + void Clear() { memset(this, 0, sizeof(MODCOMMAND)); } // Returns true if modcommand is empty, false otherwise. // If ignoreEffectValues is true (default), effect values are ignored are ignored if there is no effect command present. @@ -63,12 +63,19 @@ } // Returns true if instrument column represents plugin index. - bool IsInstrPlug() const {return IsPcNote();} + bool IsInstrPlug() const { return IsPcNote(); } // Returns true if and only if note is NOTE_PC or NOTE_PCS. bool IsPcNote() const { return note == NOTE_PC || note == NOTE_PCS; } static bool IsPcNote(const NOTE note_id) { return note_id == NOTE_PC || note_id == NOTE_PCS; } + // Returns true if and only if note is a valid musical note. + bool IsNote() const { return note >= NOTE_MIN && note <= NOTE_MAX; } + static bool IsNote(NOTE note) { return note >= NOTE_MIN && note <= NOTE_MAX; } + // Returns true if and only if note is a valid musical note or the note entry is empty. + bool IsNoteOrEmpty() const { return note == NOTE_NONE || IsNote(); } + static bool IsNoteOrEmpty(NOTE note) { return note == NOTE_NONE || IsNote(note); } + // Swap volume and effect column (doesn't do any conversion as it's mainly for importing formats with multiple effect columns, so beware!) void SwapEffects() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-18 12:52:02
|
Revision: 1184 http://modplug.svn.sourceforge.net/modplug/?rev=1184&view=rev Author: saga-games Date: 2012-02-18 12:51:50 +0000 (Sat, 18 Feb 2012) Log Message: ----------- [Ref] Renamed m_nCurrentPattern and m_nNextPattern to m_nCurrentOrder and m_nNextOrder to avoid confusion. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2012-02-17 21:36:02 UTC (rev 1183) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2012-02-18 12:51:50 UTC (rev 1184) @@ -307,7 +307,7 @@ m_pModDoc->SetElapsedTime(m_nScrollPos, 0); pSndFile->m_nPattern = n; - pSndFile->m_nCurrentPattern = pSndFile->m_nNextPattern = m_nScrollPos; + pSndFile->m_nCurrentOrder = pSndFile->m_nNextOrder = m_nScrollPos; pMainFrm->ResetNotificationBuffer(); //rewbs.toCheck pSndFile->m_nNextRow = 0; @@ -321,7 +321,7 @@ // update channel parameters and play time m_pModDoc->SetElapsedTime(m_nScrollPos, 0); - pSndFile->m_nCurrentPattern = m_nScrollPos; + pSndFile->m_nCurrentOrder = m_nScrollPos; pSndFile->SetCurrentOrder(m_nScrollPos); pSndFile->m_dwSongFlags |= dwPaused; if (bIsPlaying) pMainFrm->ResetNotificationBuffer(); Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2012-02-17 21:36:02 UTC (rev 1183) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2012-02-18 12:51:50 UTC (rev 1184) @@ -1048,7 +1048,7 @@ p->dwType = m_dwNotifyType; DWORD d = dwLatency / slSampleSize; p->dwLatency = gsdwTotalSamples + d; - p->nOrder = m_pSndFile->m_nCurrentPattern; + p->nOrder = m_pSndFile->m_nCurrentOrder; p->nRow = m_pSndFile->m_nRow; p->nPattern = m_pSndFile->m_nPattern; if (m_dwNotifyType & MPTNOTIFY_SAMPLE) Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-17 21:36:02 UTC (rev 1183) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-02-18 12:51:50 UTC (rev 1184) @@ -1692,7 +1692,7 @@ { m_SndFile.SetCurrentOrder(wsdlg.m_nMinOrder); m_SndFile.GetLength(eAdjust, wsdlg.m_nMinOrder, 0); // adjust playback variables / visited rows vector - m_SndFile.m_nCurrentPattern = wsdlg.m_nMinOrder; + m_SndFile.m_nCurrentOrder = wsdlg.m_nMinOrder; m_SndFile.m_nMaxOrderPosition = wsdlg.m_nMaxOrder + 1; } if(dwcdlg.DoModal() != IDOK) break; @@ -1931,9 +1931,9 @@ { CriticalSection cs; - if ((m_SndFile.m_nCurrentPattern < m_SndFile.Order.size()) && (m_SndFile.Order[m_SndFile.m_nCurrentPattern] == nPat)) + if ((m_SndFile.m_nCurrentOrder < m_SndFile.Order.size()) && (m_SndFile.Order[m_SndFile.m_nCurrentOrder] == nPat)) { - m_SndFile.m_nNextPattern = m_SndFile.m_nCurrentPattern; + m_SndFile.m_nNextOrder = m_SndFile.m_nCurrentOrder; m_SndFile.m_nNextRow = nNextRow; m_SndFile.m_nRow = nRow; } else @@ -1943,8 +1943,8 @@ if (m_SndFile.Order[nOrd] == m_SndFile.Order.GetInvalidPatIndex()) break; if (m_SndFile.Order[nOrd] == nPat) { - m_SndFile.m_nCurrentPattern = nOrd; - m_SndFile.m_nNextPattern = nOrd; + m_SndFile.m_nCurrentOrder = nOrd; + m_SndFile.m_nNextOrder = nOrd; m_SndFile.m_nNextRow = nNextRow; m_SndFile.m_nRow = nRow; break; @@ -3261,7 +3261,7 @@ pSndFile->Chn[i].nFadeOutVol = 0; pSndFile->Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF; } - if ((nOrd < m_SndFile.Order.size()) && (pSndFile->Order[nOrd] == nPat)) pSndFile->m_nCurrentPattern = pSndFile->m_nNextPattern = nOrd; + if ((nOrd < m_SndFile.Order.size()) && (pSndFile->Order[nOrd] == nPat)) pSndFile->m_nCurrentOrder = pSndFile->m_nNextOrder = nOrd; pSndFile->m_dwSongFlags &= ~(SONG_PAUSED|SONG_STEP); pSndFile->LoopPattern(nPat); pSndFile->m_nNextRow = 0; @@ -3320,7 +3320,7 @@ { pSndFile->Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF; } - if ((nOrd < m_SndFile.Order.size()) && (pSndFile->Order[nOrd] == nPat)) pSndFile->m_nCurrentPattern = pSndFile->m_nNextPattern = nOrd; + if ((nOrd < m_SndFile.Order.size()) && (pSndFile->Order[nOrd] == nPat)) pSndFile->m_nCurrentOrder = pSndFile->m_nNextOrder = nOrd; pSndFile->m_dwSongFlags &= ~(SONG_PAUSED|SONG_STEP); pSndFile->LoopPattern(nPat); pSndFile->m_nNextRow = nRow; Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-17 21:36:02 UTC (rev 1183) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-18 12:51:50 UTC (rev 1184) @@ -2246,7 +2246,7 @@ //If song is set to loop and a pattern break occurs we should stay on the same pattern. //Use nPosJump to force playback to "jump to this pattern" rather than move to next, as by default. //rewbs.to - nPosJump = (int)m_nCurrentPattern; + nPosJump = (int)m_nCurrentOrder; } break; @@ -2284,19 +2284,19 @@ // Pattern Loop if (nPatLoopRow != ROWINDEX_INVALID) { - m_nNextPattern = m_nCurrentPattern; + m_nNextOrder = m_nCurrentOrder; m_nNextRow = nPatLoopRow; if (m_nPatternDelay) m_nNextRow++; // As long as the pattern loop is running, mark the looped rows as not visited yet for(ROWINDEX nRow = nPatLoopRow; nRow <= m_nRow; nRow++) { - SetRowVisited(m_nCurrentPattern, nRow, false); + SetRowVisited(m_nCurrentOrder, nRow, false); } } else // Pattern Break / Position Jump only if no loop running if ((nBreakRow != ROWINDEX_INVALID) || (nPosJump != ORDERINDEX_INVALID)) { - if (nPosJump == ORDERINDEX_INVALID) nPosJump = m_nCurrentPattern + 1; + if (nPosJump == ORDERINDEX_INVALID) nPosJump = m_nCurrentOrder + 1; if (nBreakRow == ROWINDEX_INVALID) nBreakRow = 0; m_dwSongFlags |= SONG_BREAKTOROW; @@ -2310,14 +2310,14 @@ //if((nPosJump != (int)m_nCurrentPattern) || (nBreakRow != (int)m_nRow)) { // IT compatibility: don't reset loop count on pattern break - if (nPosJump != (int)m_nCurrentPattern && !IsCompatibleMode(TRK_IMPULSETRACKER)) + if (nPosJump != (int)m_nCurrentOrder && !IsCompatibleMode(TRK_IMPULSETRACKER)) { for (CHANNELINDEX i = 0; i < m_nChannels; i++) { Chn[i].nPatternLoopCount = 0; } } - m_nNextPattern = nPosJump; + m_nNextOrder = nPosJump; m_nNextRow = nBreakRow; m_bPatternTransitionOccurred = true; } @@ -3957,7 +3957,7 @@ // Big Hack!!! if ((!param) || (param >= 0x80) || ((GetType() & (MOD_TYPE_MOD|MOD_TYPE_XM|MOD_TYPE_MT2)) && (param >= 0x1E))) { - if ((!m_nRepeatCount) && (IsSongFinished(m_nCurrentPattern, m_nRow+1))) + if ((!m_nRepeatCount) && (IsSongFinished(m_nCurrentOrder, m_nRow+1))) { GlobalFadeSong(1000); } @@ -4375,7 +4375,7 @@ { m_nPattern = Order[m_nSeqOverride - 1]; } - m_nNextPattern = m_nSeqOverride - 1; + m_nNextOrder = m_nSeqOverride - 1; m_nSeqOverride = 0; } Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-17 21:36:02 UTC (rev 1183) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-18 12:51:50 UTC (rev 1184) @@ -533,8 +533,8 @@ m_nNextRow = 0; m_nRow = 0; m_nPattern = 0; - m_nCurrentPattern = 0; - m_nNextPattern = 0; + m_nCurrentOrder = 0; + m_nNextOrder = 0; m_nNextPatStartRow = 0; m_nSeqOverride = 0; m_nRestartPos = 0; @@ -731,8 +731,8 @@ m_nGlobalVolumeDestination = m_nGlobalVolume; m_nSamplesToGlobalVolRampDest = 0; m_nGlobalVolumeRampAmount = 0; - m_nNextPattern = 0; - m_nCurrentPattern = 0; + m_nNextOrder = 0; + m_nCurrentOrder = 0; m_nPattern = 0; m_nBufferCount = 0; m_dBufferDiff = 0; @@ -994,7 +994,7 @@ { UINT pos = 0; - for (UINT i=0; i<m_nCurrentPattern; i++) if (Order[i] < Patterns.Size()) + for (UINT i=0; i<m_nCurrentOrder; i++) if (Order[i] < Patterns.Size()) pos += Patterns[Order[i]].GetNumRows(); return pos + m_nRow; } @@ -1075,7 +1075,7 @@ } } } - m_nNextPattern = nPattern; + m_nNextOrder = nPattern; m_nNextRow = nRow; m_nTickCount = m_nMusicSpeed; m_nBufferCount = 0; @@ -1120,7 +1120,7 @@ SetCurrentPos(0); } else { - m_nNextPattern = nOrder; + m_nNextOrder = nOrder; m_nRow = m_nNextRow = 0; m_nPattern = 0; m_nTickCount = m_nMusicSpeed; Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-02-17 21:36:02 UTC (rev 1183) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-02-18 12:51:50 UTC (rev 1184) @@ -647,8 +647,7 @@ ROWINDEX m_nNextRow, m_nRow; ROWINDEX m_nNextPatStartRow; // for FT2's E60 bug PATTERNINDEX m_nPattern; - ORDERINDEX m_nCurrentPattern, m_nNextPattern, m_nRestartPos, m_nSeqOverride; - //NOTE: m_nCurrentPattern and m_nNextPattern refer to order index - not pattern index. + ORDERINDEX m_nCurrentOrder, m_nNextOrder, m_nRestartPos, m_nSeqOverride; bool m_bPatternTransitionOccurred; UINT m_nMasterVolume, m_nGlobalVolume, m_nSamplesToGlobalVolRampDest, m_nGlobalVolumeRampAmount, m_nGlobalVolumeDestination, m_nSamplePreAmp, m_nVSTiVolume; @@ -668,7 +667,7 @@ MODSAMPLE Samples[MAX_SAMPLES]; // Sample Headers public: MODINSTRUMENT *Instruments[MAX_INSTRUMENTS]; // Instrument Headers - MIDIMacroConfig m_MidiCfg; // Midi macro config table + MIDIMacroConfig m_MidiCfg; // MIDI Macro config table SNDMIXPLUGIN m_MixPlugins[MAX_MIXPLUGINS]; // Mix plugins CHAR m_szNames[MAX_SAMPLES][MAX_SAMPLENAME]; // Song and sample names CHAR CompressionTable[16]; // ADPCM compression LUT @@ -707,7 +706,7 @@ SAMPLEINDEX GetNumSamples() const { return m_nSamples; } UINT GetCurrentPos() const; PATTERNINDEX GetCurrentPattern() const { return m_nPattern; } - ORDERINDEX GetCurrentOrder() const { return static_cast<ORDERINDEX>(m_nCurrentPattern); } + ORDERINDEX GetCurrentOrder() const { return static_cast<ORDERINDEX>(m_nCurrentOrder); } CHANNELINDEX GetNumChannels() const { return m_nChannels; } IMixPlugin* GetInstrumentPlugin(INSTRUMENTINDEX instr); Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-17 21:36:02 UTC (rev 1183) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-18 12:51:50 UTC (rev 1184) @@ -324,18 +324,18 @@ if (ReadNote()) { // Save pattern cue points for WAV rendering here (if we reached a new pattern, that is.) - if(m_bIsRendering && (m_PatternCuePoints.empty() || m_nCurrentPattern != m_PatternCuePoints.back().order)) + if(m_bIsRendering && (m_PatternCuePoints.empty() || m_nCurrentOrder != m_PatternCuePoints.back().order)) { PatternCuePoint cue; cue.offset = lMax - lRead; - cue.order = m_nCurrentPattern; + cue.order = m_nCurrentOrder; cue.processed = false; // We don't know the base offset in the file here. It has to be added in the main conversion loop. m_PatternCuePoints.push_back(cue); } } else { #ifdef MODPLUG_TRACKER - if ((m_nMaxOrderPosition) && (m_nCurrentPattern >= m_nMaxOrderPosition)) + if ((m_nMaxOrderPosition) && (m_nCurrentOrder >= m_nMaxOrderPosition)) { m_dwSongFlags |= SONG_ENDREACHED; break; @@ -681,28 +681,28 @@ m_nTickCount = 0; m_nRow = m_nNextRow; // Reset Pattern Loop Effect - if (m_nCurrentPattern != m_nNextPattern) - m_nCurrentPattern = m_nNextPattern; + if (m_nCurrentOrder != m_nNextOrder) + m_nCurrentOrder = m_nNextOrder; // Check if pattern is valid if (!(m_dwSongFlags & SONG_PATTERNLOOP)) { - m_nPattern = (m_nCurrentPattern < Order.size()) ? Order[m_nCurrentPattern] : Order.GetInvalidPatIndex(); + m_nPattern = (m_nCurrentOrder < Order.size()) ? Order[m_nCurrentOrder] : Order.GetInvalidPatIndex(); if ((m_nPattern < Patterns.Size()) && (!Patterns[m_nPattern])) m_nPattern = Order.GetIgnoreIndex(); while (m_nPattern >= Patterns.Size()) { // End of song? - if ((m_nPattern == Order.GetInvalidPatIndex()) || (m_nCurrentPattern >= Order.size())) + if ((m_nPattern == Order.GetInvalidPatIndex()) || (m_nCurrentOrder >= Order.size())) { //if (!m_nRepeatCount) return FALSE; ORDERINDEX nRestartPosOverride = m_nRestartPos; - if(!m_nRestartPos && m_nCurrentPattern <= Order.size() && m_nCurrentPattern > 0) + if(!m_nRestartPos && m_nCurrentOrder <= Order.size() && m_nCurrentOrder > 0) { /* 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--) + for(ORDERINDEX iOrd = m_nCurrentOrder - 1; iOrd > 0; iOrd--) { if(Order[iOrd] == Order.GetInvalidPatIndex()) { @@ -762,17 +762,17 @@ //Handle Repeat position if (m_nRepeatCount > 0) m_nRepeatCount--; - m_nCurrentPattern = nRestartPosOverride; + m_nCurrentOrder = nRestartPosOverride; m_dwSongFlags &= ~SONG_BREAKTOROW; //If restart pos points to +++, move along - while (Order[m_nCurrentPattern] == Order.GetIgnoreIndex()) + while (Order[m_nCurrentOrder] == Order.GetIgnoreIndex()) { - m_nCurrentPattern++; + m_nCurrentOrder++; } //Check for end of song or bad pattern - if (m_nCurrentPattern >= Order.size() - || (Order[m_nCurrentPattern] >= Patterns.Size()) - || (!Patterns[Order[m_nCurrentPattern]]) ) + if (m_nCurrentOrder >= Order.size() + || (Order[m_nCurrentOrder] >= Patterns.Size()) + || (!Patterns[Order[m_nCurrentOrder]]) ) { InitializeVisitedRows(true); return FALSE; @@ -780,21 +780,21 @@ } else { - m_nCurrentPattern++; + m_nCurrentOrder++; } - if (m_nCurrentPattern < Order.size()) - m_nPattern = Order[m_nCurrentPattern]; + if (m_nCurrentOrder < Order.size()) + m_nPattern = Order[m_nCurrentOrder]; else m_nPattern = Order.GetInvalidPatIndex(); if ((m_nPattern < Patterns.Size()) && (!Patterns[m_nPattern])) m_nPattern = Order.GetIgnoreIndex(); } - m_nNextPattern = m_nCurrentPattern; + m_nNextOrder = m_nCurrentOrder; #ifdef MODPLUG_TRACKER - if ((m_nMaxOrderPosition) && (m_nCurrentPattern >= m_nMaxOrderPosition)) return FALSE; + if ((m_nMaxOrderPosition) && (m_nCurrentOrder >= m_nMaxOrderPosition)) return FALSE; #endif // MODPLUG_TRACKER } @@ -808,7 +808,7 @@ // the pattern loop (editor flag, not to be confused with the pattern loop effect) // flag is set - because in that case, the module would stop after the first pattern loop... const bool overrideLoopCheck = (m_nRepeatCount != -1) && (m_dwSongFlags & SONG_PATTERNLOOP); - if(!overrideLoopCheck && IsRowVisited(m_nCurrentPattern, m_nRow, true)) + if(!overrideLoopCheck && IsRowVisited(m_nCurrentOrder, m_nRow, true)) { if(m_nRepeatCount) { @@ -819,7 +819,7 @@ } // Forget all but the current row. InitializeVisitedRows(true); - SetRowVisited(m_nCurrentPattern, m_nRow); + SetRowVisited(m_nCurrentOrder, m_nRow); } else { #ifdef MODPLUG_TRACKER @@ -827,7 +827,7 @@ // The visited rows vector might have been screwed up while editing... // This is of course not possible during rendering to WAV, so we ignore that case. GetLengthType t = GetLength(eNoAdjust); - if((gdwSoundSetup & SNDMIX_DIRECTTODISK) || (t.lastOrder == m_nCurrentPattern && t.lastRow == m_nRow)) + if((gdwSoundSetup & SNDMIX_DIRECTTODISK) || (t.lastOrder == m_nCurrentOrder && t.lastRow == m_nRow)) #else if(1) #endif // MODPLUG_TRACKER @@ -838,7 +838,7 @@ } else { // Ok, this is really dirty, but we have to update the visited rows vector... - GetLength(eAdjustOnSuccess, m_nCurrentPattern, m_nRow); + GetLength(eAdjustOnSuccess, m_nCurrentOrder, m_nRow); } } } @@ -846,7 +846,7 @@ m_nNextRow = m_nRow + 1; if (m_nNextRow >= Patterns[m_nPattern].GetNumRows()) { - if (!(m_dwSongFlags & SONG_PATTERNLOOP)) m_nNextPattern = m_nCurrentPattern + 1; + if (!(m_dwSongFlags & SONG_PATTERNLOOP)) m_nNextOrder = m_nCurrentOrder + 1; m_bPatternTransitionOccurred = true; m_nNextRow = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-19 01:39:07
|
Revision: 1186 http://modplug.svn.sourceforge.net/modplug/?rev=1186&view=rev Author: saga-games Date: 2012-02-19 01:39:01 +0000 (Sun, 19 Feb 2012) Log Message: ----------- [Fix] XM Compatibility: Great improvements with regards to E6x handling in combination with pattern break / position jump effects. [Mod] OpenMPT: Version is now 1.20.00.69 Modified Paths: -------------- trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-02-19 01:37:43 UTC (rev 1185) +++ trunk/OpenMPT/mptrack/version.h 2012-02-19 01:39:01 UTC (rev 1186) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 68 +#define VER_MINORMINOR 69 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-19 01:37:43 UTC (rev 1185) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-19 01:39:01 UTC (rev 1186) @@ -1517,8 +1517,18 @@ { ROWINDEX nloop = PatternLoop(pChn, param & 0x0F); - if (nloop != ROWINDEX_INVALID) nPatLoopRow = nloop; + if (nloop != ROWINDEX_INVALID) + { + // FT2 compatibility: E6x overwrites jump targets of Dxx effects that are located left of the E6x effect. + // Test cases: PatLoop-Jumps.xm, PatLoop-Various.xm + if(nBreakRow != ROWINDEX_INVALID && IsCompatibleMode(TRK_FASTTRACKER2)) + { + nBreakRow = nloop; + } + nPatLoopRow = nloop; + } + if(GetType() == MOD_TYPE_S3M) { // ST3 doesn't have per-channel pattern loop memory, so spam all changes to other channels as well. @@ -2214,7 +2224,7 @@ //occurs also when pattern loop is enabled. } // see http://forum.openmpt.org/index.php?topic=2769.0 - FastTracker resets Dxx if Bxx is called _after_ Dxx - if(GetType() == MOD_TYPE_XM) + if(GetType() == MOD_TYPE_XM && nBreakRow != ROWINDEX_INVALID) { nBreakRow = 0; } @@ -2227,11 +2237,13 @@ // ST3 ignores invalid pattern breaks. break; } + m_nNextPatStartRow = 0; // FT2 E60 bug + m = NULL; - if (m_nRow < Patterns[m_nPattern].GetNumRows()-1) + if (m_nRow < Patterns[m_nPattern].GetNumRows() - 1) { - m = Patterns[m_nPattern] + (m_nRow+1) * m_nChannels + nChn; + m = Patterns[m_nPattern].GetpModCommand(m_nRow + 1, nChn); } if (m && m->command == CMD_XPARAM) { @@ -2281,8 +2293,10 @@ // Navigation Effects if(m_dwSongFlags & SONG_FIRSTTICK) { + const bool doPatternLoop = (nPatLoopRow != ROWINDEX_INVALID); + // Pattern Loop - if (nPatLoopRow != ROWINDEX_INVALID) + if (doPatternLoop) { m_nNextOrder = m_nCurrentOrder; m_nNextRow = nPatLoopRow; @@ -2292,9 +2306,12 @@ { SetRowVisited(m_nCurrentOrder, nRow, false); } - } else + } + // Pattern Break / Position Jump only if no loop running - if ((nBreakRow != ROWINDEX_INVALID) || (nPosJump != ORDERINDEX_INVALID)) + // Test case for FT2 exception: PatLoop-Jumps.xm, PatLoop-Various.xm + if ((!doPatternLoop || IsCompatibleMode(TRK_FASTTRACKER2)) + && (nBreakRow != ROWINDEX_INVALID || nPosJump != ORDERINDEX_INVALID)) { if (nPosJump == ORDERINDEX_INVALID) nPosJump = m_nCurrentOrder + 1; if (nBreakRow == ROWINDEX_INVALID) nBreakRow = 0; @@ -2307,10 +2324,10 @@ // This checks whether we're jumping to the same row we're already on. // Sounds pretty stupid and pointless to me. And noone else does this, either. - //if((nPosJump != (int)m_nCurrentPattern) || (nBreakRow != (int)m_nRow)) { - // IT compatibility: don't reset loop count on pattern break - if (nPosJump != (int)m_nCurrentOrder && !IsCompatibleMode(TRK_IMPULSETRACKER)) + // IT / FT2 compatibility: don't reset loop count on pattern break. + // Test case: PatLoop-Break.xm + if (nPosJump != m_nCurrentOrder && !IsCompatibleMode(TRK_IMPULSETRACKER | TRK_FASTTRACKER2)) { for (CHANNELINDEX i = 0; i < m_nChannels; i++) { @@ -4295,22 +4312,22 @@ PLUGINDEX __cdecl CSoundFile::GetChannelPlugin(CHANNELINDEX nChn, PluginMutePriority respectMutes) const //------------------------------------------------------------------------------------------------------ { - const MODCHANNEL *pChn = &Chn[nChn]; + const MODCHANNEL &channel = Chn[nChn]; - // If it looks like this is an NNA channel, we need to find the master channel. - // This ensures we pick up the right ChnSettings. - // NB: nMasterChn==0 means no master channel, so we need to -1 to get correct index. - if (nChn>=m_nChannels && pChn && pChn->nMasterChn > 0) - { - nChn = pChn->nMasterChn - 1; - } - - UINT nPlugin; - if ( (respectMutes == RespectMutes && (pChn->dwFlags & CHN_MUTE)) || (pChn->dwFlags&CHN_NOFX) ) + PLUGINDEX nPlugin; + if((respectMutes == RespectMutes && (channel.dwFlags & CHN_MUTE)) || (channel.dwFlags & CHN_NOFX)) { nPlugin = 0; } else { + // If it looks like this is an NNA channel, we need to find the master channel. + // This ensures we pick up the right ChnSettings. + // NB: nMasterChn == 0 means no master channel, so we need to -1 to get correct index. + if (nChn >= m_nChannels && channel.nMasterChn > 0) + { + nChn = channel.nMasterChn - 1; + } + nPlugin = ChnSettings[nChn].nMixPlugin; } return nPlugin; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-24 22:30:24
|
Revision: 1189 http://modplug.svn.sourceforge.net/modplug/?rev=1189&view=rev Author: saga-games Date: 2012-02-24 22:30:17 +0000 (Fri, 24 Feb 2012) Log Message: ----------- [Fix] IT Compatibility: Vibrato direction in normal and Old FX mode was swapped. [Imp] Instrument Editor: Duplicate Instrument also works for XM files now. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/modcommand.h Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-02-19 21:21:46 UTC (rev 1188) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-02-24 22:30:17 UTC (rev 1189) @@ -1644,9 +1644,8 @@ if (m_pModDoc) { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - if ((pSndFile->m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) - && (pSndFile->m_nInstruments > 0) - && (CMainFrame::GetInputHandler()->ShiftPressed())) //rewbs.customKeys + if (pSndFile->m_nInstruments > 0 + && CMainFrame::GetInputHandler()->ShiftPressed()) //rewbs.customKeys { OnInstrumentDuplicate(); return; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-19 21:21:46 UTC (rev 1188) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-24 22:30:17 UTC (rev 1189) @@ -1213,7 +1213,7 @@ { // Filter Envelope: controls cutoff frequency #ifndef NO_FILTER - SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? false : true, envpitch); + SetupChannelFilter(pChn, !(pChn->dwFlags & CHN_FILTER), envpitch); #endif // NO_FILTER } else { @@ -1563,8 +1563,10 @@ if(m_nTickCount + 1 == m_nMusicSpeed) pChn->m_ReCalculateFreqOnFirstTick = true; } - else //Original behavior + else { + // Original behaviour + UINT vdepth; // IT compatibility: correct vibrato depth if(IsCompatibleMode(TRK_IMPULSETRACKER)) @@ -1572,11 +1574,13 @@ // Yes, vibrato goes backwards with old effects enabled! if(m_dwSongFlags & SONG_ITOLDEFFECTS) { + // Test case: vibrato-oldfx.it vdepth = 5; - vdelta = -vdelta; } else { + // Test case: vibrato.it vdepth = 6; + vdelta = -vdelta; } } else Modified: trunk/OpenMPT/soundlib/modcommand.h =================================================================== --- trunk/OpenMPT/soundlib/modcommand.h 2012-02-19 21:21:46 UTC (rev 1188) +++ trunk/OpenMPT/soundlib/modcommand.h 2012-02-24 22:30:17 UTC (rev 1189) @@ -1,5 +1,3 @@ -#pragma once - #ifndef MODCOMMAND_H #define MODCOMMAND_H @@ -92,7 +90,6 @@ BYTE param; }; -typedef MODCOMMAND* LPMODCOMMAND; typedef MODCOMMAND MODCOMMAND_ORIGINAL; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-24 22:32:01
|
Revision: 1190 http://modplug.svn.sourceforge.net/modplug/?rev=1190&view=rev Author: saga-games Date: 2012-02-24 22:31:54 +0000 (Fri, 24 Feb 2012) Log Message: ----------- [Mod] Changed undo buffer size to 100,000. [Ref] Added non-static version of AllocatePattern for easier usage in some cases. Modified Paths: -------------- trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Undo.cpp trunk/OpenMPT/mptrack/Undo.h trunk/OpenMPT/soundlib/pattern.cpp trunk/OpenMPT/soundlib/pattern.h trunk/OpenMPT/soundlib/patternContainer.cpp Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2012-02-24 22:30:17 UTC (rev 1189) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2012-02-24 22:31:54 UTC (rev 1190) @@ -98,7 +98,7 @@ bool CModDoc::RemoveChannels(const vector<bool> &keepMask) //-------------------------------------------------------- { - UINT nRemainingChannels = 0; + CHANNELINDEX nRemainingChannels = 0; //First calculating how many channels are to be left for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++) { @@ -107,9 +107,11 @@ if(nRemainingChannels == GetNumChannels() || nRemainingChannels < m_SndFile.GetModSpecifications().channelsMin) { CString str; - if(nRemainingChannels == GetNumChannels()) str.Format("No channels chosen to be removed."); - else str.Format("No removal done - channel number is already at minimum."); - Reporting::Information(str, "Remove channel"); + if(nRemainingChannels == GetNumChannels()) + str = "No channels chosen to be removed."; + else + str = "No removal done - channel number is already at minimum."; + Reporting::Information(str, "Remove Channels"); return false; } @@ -151,7 +153,7 @@ if(nRemainingChannels > m_SndFile.GetModSpecifications().channelsMax || nRemainingChannels < m_SndFile.GetModSpecifications().channelsMin) { CString str; - str.Format(GetStrI18N(_TEXT("Can't apply change: Number of channels should be within [%u,%u]")), m_SndFile.GetModSpecifications().channelsMin, m_SndFile.GetModSpecifications().channelsMax); + str.Format(GetStrI18N(_TEXT("Can't apply change: Number of channels should be between %u and %u.")), m_SndFile.GetModSpecifications().channelsMin, m_SndFile.GetModSpecifications().channelsMax); Reporting::Error(str , "ReArrangeChannels"); return CHANNELINDEX_INVALID; } @@ -185,34 +187,34 @@ first = false; } - MODCOMMAND *p = m_SndFile.Patterns[nPat]; - MODCOMMAND *newp = CPattern::AllocatePattern(m_SndFile.Patterns[nPat].GetNumRows(), nRemainingChannels); - if(!newp) + MODCOMMAND *oldPatData = m_SndFile.Patterns[nPat]; + MODCOMMAND *newPatData = CPattern::AllocatePattern(m_SndFile.Patterns[nPat].GetNumRows(), nRemainingChannels); + if(!newPatData) { cs.Leave(); - Reporting::Error("ERROR: Pattern allocation failed in ReArrangechannels(...)"); + Reporting::Error("ERROR: Pattern allocation failed in ReArrangeChannels(...)"); return CHANNELINDEX_INVALID; } - MODCOMMAND *tmpsrc = p, *tmpdest = newp; + MODCOMMAND *tmpdest = newPatData; for(ROWINDEX nRow = 0; nRow < m_SndFile.Patterns[nPat].GetNumRows(); nRow++) //Scrolling rows { for(CHANNELINDEX nChn = 0; nChn < nRemainingChannels; nChn++, tmpdest++) //Scrolling channels. { if(newOrder[nChn] < GetNumChannels()) //Case: getting old channel to the new channel order. - *tmpdest = tmpsrc[nRow * GetNumChannels() + newOrder[nChn]]; + *tmpdest = *m_SndFile.Patterns[nPat].GetpModCommand(nRow, newOrder[nChn]); else //Case: figure newOrder[k] is not the index of any current channel, so adding a new channel. *tmpdest = MODCOMMAND::Empty(); } } - m_SndFile.Patterns[nPat] = newp; - CPattern::FreePattern(p); + m_SndFile.Patterns[nPat] = newPatData; + CPattern::FreePattern(oldPatData); } } MODCHANNEL chns[MAX_BASECHANNELS]; MODCHANNELSETTINGS settings[MAX_BASECHANNELS]; - vector<UINT> recordStates(GetNumChannels(), 0); + vector<BYTE> recordStates(GetNumChannels(), 0); vector<bool> chnMutePendings(GetNumChannels(), false); for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++) @@ -912,13 +914,15 @@ const bool doITStyleMix = (pasteMode == pm_mixpaste_it); const bool doMixPaste = ((pasteMode == pm_mixpaste) || doITStyleMix); - ORDERINDEX oCurrentOrder; //jojo.echopaste - ROWINDEX rTemp; - PATTERNINDEX pTemp; - GetEditPosition(rTemp, pTemp, oCurrentOrder); + ORDERINDEX currentOrder; //jojo.echopaste + { + ROWINDEX rTemp; + PATTERNINDEX pTemp; + GetEditPosition(rTemp, pTemp, currentOrder); + } if ((nrow >= m_SndFile.Patterns[nPattern].GetNumRows()) || (ncol >= m_SndFile.GetNumChannels())) goto PasteDone; - m += nrow * m_SndFile.m_nChannels; + m += nrow * m_SndFile.GetNumChannels(); // Search for signature for (pos = startPos; p[pos] != 0 && pos < dwMemSize; pos++) @@ -937,7 +941,7 @@ } const CModSpecifications &sourceSpecs = CSoundFile::GetModSpecifications(origFormat); - const bool bS3MCommands = (origFormat & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_S3M)) != 0; + const bool clipboardHasS3MCommands = (origFormat & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_S3M)) != 0; pos = startPos; while ((nrow < m_SndFile.Patterns[nPattern].GetNumRows())) @@ -991,7 +995,7 @@ { for(ROWINDEX nPushRow = m_SndFile.Patterns[nPattern].GetNumRows() - 1 - nrow; nPushRow > 0; nPushRow--) { - m[col + nPushRow * m_SndFile.m_nChannels] = m[col + (nPushRow - 1) * m_SndFile.m_nChannels]; + m[col + nPushRow * m_SndFile.GetNumChannels()] = m[col + (nPushRow - 1) * m_SndFile.GetNumChannels()]; } m[col].Clear(); } @@ -1106,13 +1110,13 @@ } } // Checking command - if (m_SndFile.m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM)) + if (m_SndFile.GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM)) { switch (m[col].command) { case CMD_SPEED: case CMD_TEMPO: - if (!bS3MCommands) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; + if (!clipboardHasS3MCommands) 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 @@ -1126,7 +1130,7 @@ { case CMD_SPEED: case CMD_TEMPO: - if (!bS3MCommands) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; + if (!clipboardHasS3MCommands) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; break; } } @@ -1136,7 +1140,7 @@ // if the original modcommand was empty as otherwise the unchanged parts // of the old modcommand would falsely be interpreted being of type // origFormat and ConvertCommand could change them. - if (origFormat != m_SndFile.m_nType && (doMixPaste == false || origModCmd.IsEmpty(false))) + if (origFormat != m_SndFile.m_nType && (!doMixPaste || origModCmd.IsEmpty(false))) m_SndFile.ConvertCommand(&(m[col]), origFormat, m_SndFile.m_nType); } @@ -1144,7 +1148,7 @@ col++; } // Next row - m += m_SndFile.m_nChannels; + m += m_SndFile.GetNumChannels(); nrow++; // Overflow paste. Continue pasting in next pattern if enabled. @@ -1154,12 +1158,12 @@ while(nrow >= m_SndFile.Patterns[nPattern].GetNumRows()) { nrow = 0; - ORDERINDEX oNextOrder = m_SndFile.Order.GetNextOrderIgnoringSkips(oCurrentOrder); - if((oNextOrder == 0) || (oNextOrder >= m_SndFile.Order.size())) goto PasteDone; - nPattern = m_SndFile.Order[oNextOrder]; + ORDERINDEX nextOrder = m_SndFile.Order.GetNextOrderIgnoringSkips(currentOrder); + if((nextOrder == 0) || (nextOrder >= m_SndFile.Order.size())) goto PasteDone; + nPattern = m_SndFile.Order[nextOrder]; if(m_SndFile.Patterns.IsValidPat(nPattern) == false) goto PasteDone; m = m_SndFile.Patterns[nPattern]; - oCurrentOrder = oNextOrder; + currentOrder = nextOrder; bPrepareUndo = true; } } Modified: trunk/OpenMPT/mptrack/Undo.cpp =================================================================== --- trunk/OpenMPT/mptrack/Undo.cpp 2012-02-24 22:30:17 UTC (rev 1189) +++ trunk/OpenMPT/mptrack/Undo.cpp 2012-02-24 22:31:54 UTC (rev 1190) @@ -174,19 +174,17 @@ nRows = pUndo->patternsize; if(pUndo->firstChannel + pUndo->numChannels <= pSndFile->GetNumChannels()) { - if((!pSndFile->Patterns[nPattern]) || (pSndFile->Patterns[nPattern].GetNumRows() < nRows)) + if(!pSndFile->Patterns[nPattern]) { - MODCOMMAND *newPattern = CPattern::AllocatePattern(nRows, pSndFile->GetNumChannels()); - MODCOMMAND *oldPattern = pSndFile->Patterns[nPattern]; - if (!newPattern) return PATTERNINDEX_INVALID; - const ROWINDEX nOldRowCount = pSndFile->Patterns[nPattern].GetNumRows(); - pSndFile->Patterns[nPattern].SetData(newPattern, nRows); - if(oldPattern) + if(!pSndFile->Patterns[nPattern].AllocatePattern(nRows)) { - memcpy(newPattern, oldPattern, pSndFile->GetNumChannels() * nOldRowCount * sizeof(MODCOMMAND)); - CPattern::FreePattern(oldPattern); + return PATTERNINDEX_INVALID; } + } else if(pSndFile->Patterns[nPattern].GetNumRows() != nRows) + { + pSndFile->Patterns[nPattern].Resize(nRows, false); } + linkToPrevious = pUndo->linkToPrevious; pUndoData = pUndo->pbuffer; pPattern = pSndFile->Patterns[nPattern]; Modified: trunk/OpenMPT/mptrack/Undo.h =================================================================== --- trunk/OpenMPT/mptrack/Undo.h 2012-02-24 22:30:17 UTC (rev 1189) +++ trunk/OpenMPT/mptrack/Undo.h 2012-02-24 22:31:54 UTC (rev 1190) @@ -9,7 +9,7 @@ #pragma once -#define MAX_UNDO_LEVEL 1000 // 1000 undo steps for each undo type! +#define MAX_UNDO_LEVEL 100000 // 100,000 undo steps for each undo type! ///////////////////////////////////////////////////////////////////////////////////////// // Pattern Undo Modified: trunk/OpenMPT/soundlib/pattern.cpp =================================================================== --- trunk/OpenMPT/soundlib/pattern.cpp 2012-02-24 22:30:17 UTC (rev 1189) +++ trunk/OpenMPT/soundlib/pattern.cpp 2012-02-24 22:31:54 UTC (rev 1190) @@ -57,10 +57,10 @@ if (newRowCount > m_Rows) { - MODCOMMAND *p = AllocatePattern(newRowCount, sndFile.m_nChannels); + MODCOMMAND *p = AllocatePattern(newRowCount, sndFile.GetNumChannels()); if (p) { - memcpy(p, m_ModCommands, sndFile.m_nChannels*m_Rows*sizeof(MODCOMMAND)); + memcpy(p, m_ModCommands, sndFile.GetNumChannels() * m_Rows * sizeof(MODCOMMAND)); FreePattern(m_ModCommands); m_ModCommands = p; m_Rows = newRowCount; @@ -68,20 +68,21 @@ } else { bool bOk = true; - MODCOMMAND *p = m_ModCommands; - UINT ndif = (m_Rows - newRowCount) * sndFile.m_nChannels; - UINT npos = newRowCount * sndFile.m_nChannels; + #ifdef MODPLUG_TRACKER if(showDataLossWarning) { - for (UINT i=0; i<ndif; i++) + // Check if any non-empty pattern cells would be lost when truncating rows at the bottom. + const MODCOMMAND *m = GetpModCommand(newRowCount, 0); + for(size_t numCommands = (m_Rows - newRowCount) * sndFile.GetNumChannels(); numCommands != 0; numCommands--, m++) { - if (*((DWORD *)(p+i+npos))) + if(!m->IsEmpty()) { bOk = false; break; } } + if (!bOk) { cs.Leave(); @@ -92,12 +93,13 @@ } } #endif // MODPLUG_TRACKER + if (bOk) { - MODCOMMAND *pnew = AllocatePattern(newRowCount, sndFile.m_nChannels); + MODCOMMAND *pnew = AllocatePattern(newRowCount, sndFile.GetNumChannels()); if (pnew) { - memcpy(pnew, m_ModCommands, sndFile.m_nChannels*newRowCount*sizeof(MODCOMMAND)); + memcpy(pnew, m_ModCommands, sndFile.GetNumChannels() * newRowCount * sizeof(MODCOMMAND)); FreePattern(m_ModCommands); m_ModCommands = pnew; m_Rows = newRowCount; @@ -122,10 +124,28 @@ } +bool CPattern::AllocatePattern(ROWINDEX rows) +//------------------------------------------- +{ + MODCOMMAND *m = AllocatePattern(rows, GetNumChannels()); + if(m != nullptr) + { + Deallocate(); + m_ModCommands = m; + m_Rows = rows; + m_RowsPerBeat = m_RowsPerMeasure = 0; + return true; + } else + { + return false; + } + +} + void CPattern::Deallocate() //------------------------- { - // Removed critical section as it can cause problems when destroying patterns in the CSoundFile constructor. + // Removed critical section as it can cause problems when destroying patterns in the CSoundFile destructor. //BEGIN_CRITICAL(); m_Rows = m_RowsPerBeat = m_RowsPerMeasure = 0; FreePattern(m_ModCommands); Modified: trunk/OpenMPT/soundlib/pattern.h =================================================================== --- trunk/OpenMPT/soundlib/pattern.h 2012-02-24 22:30:17 UTC (rev 1189) +++ trunk/OpenMPT/soundlib/pattern.h 2012-02-24 22:31:54 UTC (rev 1190) @@ -56,7 +56,9 @@ bool Resize(const ROWINDEX newRowCount, const bool showDataLossWarning = true); - // Deallocates pattern data. + // Allocate new pattern memory and replace old pattern data. + bool AllocatePattern(ROWINDEX rows); + // Deallocate pattern data. void Deallocate(); // Removes all modcommands from the pattern. @@ -94,7 +96,7 @@ //Returns true on error. // Static allocation / deallocation helpers - static MODCOMMAND* AllocatePattern(ROWINDEX rows, CHANNELINDEX nchns); + static MODCOMMAND *AllocatePattern(ROWINDEX rows, CHANNELINDEX nchns); static void FreePattern(MODCOMMAND *pat); //END: INTERFACE METHODS Modified: trunk/OpenMPT/soundlib/patternContainer.cpp =================================================================== --- trunk/OpenMPT/soundlib/patternContainer.cpp 2012-02-24 22:30:17 UTC (rev 1189) +++ trunk/OpenMPT/soundlib/patternContainer.cpp 2012-02-24 22:31:54 UTC (rev 1190) @@ -52,17 +52,14 @@ m_Patterns.push_back(MODPATTERN(*this)); else { +#ifdef MODPLUG_TRACKER ErrorBox(IDS_ERR_TOOMANYPAT, CMainFrame::GetMainFrame()); +#endif // MODPLUG_TRACKER return true; } } - if(m_Patterns[index].m_ModCommands != nullptr) - { - CPattern::FreePattern(m_Patterns[index].m_ModCommands); - } - m_Patterns[index].m_ModCommands = CPattern::AllocatePattern(rows, m_rSndFile.GetNumChannels()); - m_Patterns[index].m_Rows = rows; + m_Patterns[index].AllocatePattern(rows); m_Patterns[index].RemoveSignature(); m_Patterns[index].SetName(""); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-25 20:51:42
|
Revision: 1194 http://modplug.svn.sourceforge.net/modplug/?rev=1194&view=rev Author: saga-games Date: 2012-02-25 20:51:28 +0000 (Sat, 25 Feb 2012) Log Message: ----------- Mega refactoring commit! [Ref] Renamed MODSAMPLE to ModSample, MODINSTRUMENT to ModInstrument, MODCHANNEL to ModChannel, MODCHANNEL_ENVINFO to ModChannelEnvInfo, MODCHANNELSETTINGS to ModChannelSettings and moved them to seprate files. [Ref] Since quite a few files had to be updated, I decided to also update the file headers while I was at it. They should all include proper copyright information now. [Ref] Also changed all the #include guards to #pragma once while I was at it... [Ref] Changed #pragma pack(1) to #pragma pack(push, 1) etc. everywhere. [Ref] Removed some files that have never been used. Modified Paths: -------------- trunk/OpenMPT/README trunk/OpenMPT/common/Reporting.cpp trunk/OpenMPT/common/Reporting.h trunk/OpenMPT/common/StringFixer.h trunk/OpenMPT/common/misc_util.cpp trunk/OpenMPT/common/misc_util.h trunk/OpenMPT/common/typedefs.h trunk/OpenMPT/mptrack/ACMConvert.cpp trunk/OpenMPT/mptrack/ACMConvert.h trunk/OpenMPT/mptrack/AbstractVstEditor.cpp trunk/OpenMPT/mptrack/AbstractVstEditor.h trunk/OpenMPT/mptrack/ArrayUtils.cpp trunk/OpenMPT/mptrack/ArrayUtils.h trunk/OpenMPT/mptrack/AutoSaver.cpp trunk/OpenMPT/mptrack/AutoSaver.h trunk/OpenMPT/mptrack/Autotune.cpp trunk/OpenMPT/mptrack/Autotune.h trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp trunk/OpenMPT/mptrack/ChannelManagerDlg.h trunk/OpenMPT/mptrack/Childfrm.cpp trunk/OpenMPT/mptrack/Childfrm.h trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/CleanupSong.h trunk/OpenMPT/mptrack/CloseMainDialog.cpp trunk/OpenMPT/mptrack/CloseMainDialog.h trunk/OpenMPT/mptrack/ColourEdit.cpp trunk/OpenMPT/mptrack/ColourEdit.h trunk/OpenMPT/mptrack/CommandSet.cpp trunk/OpenMPT/mptrack/CommandSet.h trunk/OpenMPT/mptrack/CreditStatic.cpp trunk/OpenMPT/mptrack/CreditStatic.h trunk/OpenMPT/mptrack/Ctrl_com.cpp trunk/OpenMPT/mptrack/Ctrl_com.h trunk/OpenMPT/mptrack/Ctrl_gen.cpp trunk/OpenMPT/mptrack/Ctrl_gen.h trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_ins.h trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_pat.h trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Ctrl_smp.h trunk/OpenMPT/mptrack/DefaultVstEditor.cpp trunk/OpenMPT/mptrack/DefaultVstEditor.h trunk/OpenMPT/mptrack/Draw_pat.cpp trunk/OpenMPT/mptrack/EffectInfo.cpp trunk/OpenMPT/mptrack/EffectInfo.h trunk/OpenMPT/mptrack/EffectVis.cpp trunk/OpenMPT/mptrack/EffectVis.h trunk/OpenMPT/mptrack/ExceptionHandler.cpp trunk/OpenMPT/mptrack/ExceptionHandler.h trunk/OpenMPT/mptrack/Globals.cpp trunk/OpenMPT/mptrack/Globals.h trunk/OpenMPT/mptrack/InputHandler.cpp trunk/OpenMPT/mptrack/InputHandler.h trunk/OpenMPT/mptrack/KeyConfigDlg.cpp trunk/OpenMPT/mptrack/KeyConfigDlg.h trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp trunk/OpenMPT/mptrack/MIDIMacroDialog.h trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp trunk/OpenMPT/mptrack/MIDIMappingDialog.h trunk/OpenMPT/mptrack/MPTHacks.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainbar.cpp trunk/OpenMPT/mptrack/Mainbar.h trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Mod2wave.cpp trunk/OpenMPT/mptrack/ModConvert.cpp trunk/OpenMPT/mptrack/ModConvert.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Moptions.cpp trunk/OpenMPT/mptrack/Moptions.h trunk/OpenMPT/mptrack/MoveFXSlotDialog.cpp trunk/OpenMPT/mptrack/MoveFXSlotDialog.h trunk/OpenMPT/mptrack/Mpdlgs.cpp trunk/OpenMPT/mptrack/Mpdlgs.h trunk/OpenMPT/mptrack/Mpt_midi.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/PSRatioCalc.cpp trunk/OpenMPT/mptrack/PSRatioCalc.h trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp trunk/OpenMPT/mptrack/PatternEditorDialogs.h trunk/OpenMPT/mptrack/PatternGotoDialog.cpp trunk/OpenMPT/mptrack/PatternGotoDialog.h trunk/OpenMPT/mptrack/STDAFX.CPP trunk/OpenMPT/mptrack/SampleEditorDialogs.cpp trunk/OpenMPT/mptrack/SampleEditorDialogs.h trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.h trunk/OpenMPT/mptrack/SelectPluginDialog.cpp trunk/OpenMPT/mptrack/SelectPluginDialog.h trunk/OpenMPT/mptrack/SoundFilePlayConfig.cpp trunk/OpenMPT/mptrack/SoundFilePlayConfig.h trunk/OpenMPT/mptrack/Stdafx.h trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/TrackerSettings.h trunk/OpenMPT/mptrack/TuningDialog.cpp trunk/OpenMPT/mptrack/TuningDialog.h trunk/OpenMPT/mptrack/Undo.cpp trunk/OpenMPT/mptrack/Undo.h trunk/OpenMPT/mptrack/UpdateCheck.cpp trunk/OpenMPT/mptrack/UpdateCheck.h trunk/OpenMPT/mptrack/VSTEditor.cpp trunk/OpenMPT/mptrack/VSTEditor.h trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/mptrack/View_gen.h 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/View_smp.cpp trunk/OpenMPT/mptrack/View_smp.h trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/View_tre.h trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/dlg_misc.h trunk/OpenMPT/mptrack/mod2midi.cpp trunk/OpenMPT/mptrack/mod2midi.h trunk/OpenMPT/mptrack/mod2wave.h trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/mptrack/serialization_utils.cpp trunk/OpenMPT/mptrack/serialization_utils.h trunk/OpenMPT/mptrack/tagging.cpp trunk/OpenMPT/mptrack/tagging.h trunk/OpenMPT/mptrack/test/test.cpp trunk/OpenMPT/mptrack/test/test.h trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp trunk/OpenMPT/mptrack/tuningRatioMapWnd.h trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/mptrack/view_com.cpp trunk/OpenMPT/mptrack/view_com.h trunk/OpenMPT/soundlib/Dlsbank.cpp trunk/OpenMPT/soundlib/Dlsbank.h trunk/OpenMPT/soundlib/Endianness.h trunk/OpenMPT/soundlib/Fastmix.cpp trunk/OpenMPT/soundlib/IT_DEFS.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_669.cpp trunk/OpenMPT/soundlib/Load_ams.cpp trunk/OpenMPT/soundlib/Load_far.cpp trunk/OpenMPT/soundlib/Load_gdm.cpp trunk/OpenMPT/soundlib/Load_imf.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_itp.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Load_med.cpp trunk/OpenMPT/soundlib/Load_mid.cpp trunk/OpenMPT/soundlib/Load_mo3.cpp trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Load_mt2.cpp trunk/OpenMPT/soundlib/Load_mtm.cpp trunk/OpenMPT/soundlib/Load_okt.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Load_ptm.cpp trunk/OpenMPT/soundlib/Load_s3m.cpp trunk/OpenMPT/soundlib/Load_stm.cpp trunk/OpenMPT/soundlib/Load_ult.cpp trunk/OpenMPT/soundlib/Load_umx.cpp trunk/OpenMPT/soundlib/Load_wav.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Loaders.h trunk/OpenMPT/soundlib/MIDIMacros.cpp trunk/OpenMPT/soundlib/MIDIMacros.h trunk/OpenMPT/soundlib/Message.cpp trunk/OpenMPT/soundlib/Mmcmp.cpp trunk/OpenMPT/soundlib/Mmx_mix.cpp trunk/OpenMPT/soundlib/ModSequence.cpp trunk/OpenMPT/soundlib/ModSequence.h trunk/OpenMPT/soundlib/PlaybackEventer.cpp trunk/OpenMPT/soundlib/PlaybackEventer.h trunk/OpenMPT/soundlib/PlugInterface.h trunk/OpenMPT/soundlib/PluginMixBuffer.h trunk/OpenMPT/soundlib/SNDDEV.H trunk/OpenMPT/soundlib/SNDDEVX.H trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Snd_defs.h trunk/OpenMPT/soundlib/Snd_dsp.cpp trunk/OpenMPT/soundlib/Snd_eq.cpp trunk/OpenMPT/soundlib/Snd_flt.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Snd_rvb.cpp trunk/OpenMPT/soundlib/Snddev.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/Tables.cpp trunk/OpenMPT/soundlib/Wav.h trunk/OpenMPT/soundlib/Waveform.cpp trunk/OpenMPT/soundlib/WindowedFIR.cpp trunk/OpenMPT/soundlib/WindowedFIR.h trunk/OpenMPT/soundlib/load_j2b.cpp trunk/OpenMPT/soundlib/midi.h trunk/OpenMPT/soundlib/mod_specifications.cpp trunk/OpenMPT/soundlib/mod_specifications.h trunk/OpenMPT/soundlib/modcommand.cpp trunk/OpenMPT/soundlib/modcommand.h trunk/OpenMPT/soundlib/modsmp_ctrl.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.h trunk/OpenMPT/soundlib/pattern.cpp trunk/OpenMPT/soundlib/pattern.h trunk/OpenMPT/soundlib/patternContainer.cpp trunk/OpenMPT/soundlib/patternContainer.h trunk/OpenMPT/soundlib/tuning.cpp trunk/OpenMPT/soundlib/tuning.h trunk/OpenMPT/soundlib/tuningCollection.cpp trunk/OpenMPT/soundlib/tuningbase.cpp trunk/OpenMPT/soundlib/tuningbase.h trunk/OpenMPT/soundlib/tuningcollection.h trunk/OpenMPT/soundlib/wavConverter.h trunk/OpenMPT/ungzip/ungzip.cpp trunk/OpenMPT/ungzip/ungzip.h Added Paths: ----------- trunk/OpenMPT/LICENSE trunk/OpenMPT/soundlib/ModChannel.h trunk/OpenMPT/soundlib/ModInstrument.cpp trunk/OpenMPT/soundlib/ModInstrument.h trunk/OpenMPT/soundlib/ModSample.h Removed Paths: ------------- trunk/OpenMPT/gpl.txt trunk/OpenMPT/modplug.htm trunk/OpenMPT/mptrack/KeyboardSettings.cpp trunk/OpenMPT/mptrack/KeyboardSettings.h trunk/OpenMPT/mptrack/OpenGLControl.cpp trunk/OpenMPT/mptrack/OpenGLControl.h trunk/OpenMPT/mptrack/OpenGLDevice.cpp trunk/OpenMPT/mptrack/OpenGLDevice.h trunk/OpenMPT/mptrack/OpenGLEditor.cpp trunk/OpenMPT/mptrack/OpenGLEditor.h trunk/OpenMPT/mptrack/PerformanceCounter.cpp trunk/OpenMPT/mptrack/PerformanceCounter.h trunk/OpenMPT/readme.txt Added: trunk/OpenMPT/LICENSE =================================================================== --- trunk/OpenMPT/LICENSE (rev 0) +++ trunk/OpenMPT/LICENSE 2012-02-25 20:51:28 UTC (rev 1194) @@ -0,0 +1,27 @@ +The OpenMPT code is licensed under the BSD license. + +Copyright (c) 2004-2012, OpenMPT contributors +Copyright (c) 1997-2003, Olivier Lapicque +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the OpenMPT project nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file Modified: trunk/OpenMPT/README =================================================================== --- trunk/OpenMPT/README 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/README 2012-02-25 20:51:28 UTC (rev 1194) @@ -46,3 +46,30 @@ } } + + +A few words from the readme of the original MPT 1.16 source drop by Olivier: + +The sound library was originally written to support VOC/WAV and MOD files under +DOS, and supported such things as PC-Speaker, SoundBlaster 1/2/Pro, and the +famous Gravis UltraSound. +It was then ported to Win32 in 1995 (through the Mod95 project, mostly for use +within Render32). +What does this mean? +It means the code base is quite old and is showing its age (over 10 years now) +It means that many things are poorly named (CSoundFile), and not very clean, and +if I was to rewrite the engine today, it would look much different. + +Some tips for future development and cleanup: +- Probably the main improvement would be to separate the Song, Channel, Mixer +and Low-level mixing routines in separate interface-based classes. +- Get rid of globals (many globals creeped up over time, mostly because of the +hack to allow simultaneous playback of 2 songs in Modplug Player -> ReadMix()). +This is a major problem for writing a DShow source filter, or any other COM +object (A DShow source would allow playback of MOD files in WMP, which would be much easier than +rewriting a different player). +- The MPT UI code is MFC-based, and I would say is fairly clean (as a rough +rule, the more recent the code is, the cleaner it is), though the UI code is +tightly integrated with the implementation (this could make it somewhat more +difficult to implement such things as a skin-based UI - but hey, if it was easy, +I probably would have done it already :). \ No newline at end of file Modified: trunk/OpenMPT/common/Reporting.cpp =================================================================== --- trunk/OpenMPT/common/Reporting.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/common/Reporting.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,10 +1,10 @@ /* - * * Reporting.cpp * ------------- * Purpose: A class for showing notifications, prompts, etc... * Notes : (currently none) * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ Modified: trunk/OpenMPT/common/Reporting.h =================================================================== --- trunk/OpenMPT/common/Reporting.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/common/Reporting.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,16 +1,14 @@ /* - * * Reporting.h * ----------- - * Purpose: Header file for reporting class. + * Purpose: A class for showing notifications, prompts, etc... * Notes : (currently none) * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once -#ifndef REPORTING_H -#define REPORTING_H enum ConfirmAnswer { @@ -66,5 +64,3 @@ static RetryAnswer RetryCancel(const char *text, const char *caption, const CWnd *parent = nullptr); }; - -#endif // REPORTING_H Modified: trunk/OpenMPT/common/StringFixer.h =================================================================== --- trunk/OpenMPT/common/StringFixer.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/common/StringFixer.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -5,14 +5,12 @@ * reading from module files, or for securing char arrays in general. * Notes : (currently none) * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ -#ifndef STRINGFIXER_H -#define STRINGFIXER_H #pragma once - namespace StringFixer { @@ -23,7 +21,7 @@ //------------------------------------------ { STATIC_ASSERT(size > 0); - buffer[size-1] = 0; + buffer[size - 1] = 0; } @@ -120,5 +118,3 @@ } }; - -#endif // STRINGFIXER_H Modified: trunk/OpenMPT/common/misc_util.cpp =================================================================== --- trunk/OpenMPT/common/misc_util.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/common/misc_util.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,3 +1,13 @@ +/* + * misc_util.cpp + * ------------- + * Purpose: Various useful utility functions. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #include "stdafx.h" #include "misc_util.h" #include <ctime> Modified: trunk/OpenMPT/common/misc_util.h =================================================================== --- trunk/OpenMPT/common/misc_util.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/common/misc_util.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,5 +1,13 @@ -#ifndef MISC_UTIL_H -#define MISC_UTIL_H +/* + * misc_util.h + * ----------- + * Purpose: Various useful utility functions. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #pragma once #include <sstream> @@ -320,5 +328,3 @@ inline bool IsPathFileAvailable(LPCTSTR pszFilePath, FileMode fm) {return (_taccess(pszFilePath, fm) == 0);} } } // namespace Util::sdOs - -#endif Modified: trunk/OpenMPT/common/typedefs.h =================================================================== --- trunk/OpenMPT/common/typedefs.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/common/typedefs.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,7 +1,18 @@ -#ifndef TYPEDEFS_H -#define TYPEDEFS_H +/* + * typedefs.h + * ---------- + * Purpose: Basic data type definitions. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + +#pragma once + +#ifndef nullptr #define nullptr 0 +#endif // CountOf macro computes the number of elements in a statically-allocated array. #if _MSC_VER >= 1400 @@ -63,6 +74,3 @@ }; }; #endif - - -#endif Deleted: trunk/OpenMPT/gpl.txt =================================================================== --- trunk/OpenMPT/gpl.txt 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/gpl.txt 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,342 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - - Deleted: trunk/OpenMPT/modplug.htm =================================================================== --- trunk/OpenMPT/modplug.htm 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/modplug.htm 2012-02-25 20:51:28 UTC (rev 1194) @@ -1 +0,0 @@ -<META HTTP-EQUIV="Refresh" CONTENT="0; URL=http://www.modplug.com/index.shtml"> \ No newline at end of file Modified: trunk/OpenMPT/mptrack/ACMConvert.cpp =================================================================== --- trunk/OpenMPT/mptrack/ACMConvert.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/ACMConvert.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,12 +1,11 @@ /* - * * ACMConvert.cpp * -------------- - * Purpose: MPEG Layer-3 Functions through ACM - access to LAMEenc and BLADEenc is emulated through the ACM interface - * Notes : (currently none) + * Purpose: MPEG Layer-3 Functions through ACM. + * Notes : Access to LAMEenc and BLADEenc is emulated through the ACM interface. * Authors: Olivier Lapicque * OpenMPT Devs - * + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ Modified: trunk/OpenMPT/mptrack/ACMConvert.h =================================================================== --- trunk/OpenMPT/mptrack/ACMConvert.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/ACMConvert.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,18 +1,15 @@ /* - * * ACMConvert.h * ------------ - * Purpose: Header for ACM and MPEG Layer-3 conversion - * Notes : (currently none) + * Purpose: MPEG Layer-3 Functions through ACM. + * Notes : Access to LAMEenc and BLADEenc is emulated through the ACM interface. * Authors: Olivier Lapicque * OpenMPT Devs - * + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once -#ifndef ACMCONVERT_H -#define ACMCONVERT_H ///////////////////////////////////////////////////////////////////////////// // ACM Functions (for dynamic linking) @@ -65,5 +62,3 @@ static BOOL CALLBACK AcmFormatEnumCB(HACMDRIVERID, LPACMFORMATDETAILS, DWORD, DWORD); }; - -#endif // ACMCONVERT_H Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,5 +1,13 @@ -//rewbs.defaultPlugGUI +/* + * AbstractVstEditor.cpp + * --------------------- + * Purpose: Common plugin editor interface class. This code is shared between custom and default plugin user interfaces. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + #include "stdafx.h" #include "mptrack.h" #include "moddoc.h" @@ -761,7 +769,7 @@ return false; } - MODINSTRUMENT *pIns = pSndFile->Instruments[nIns]; + ModInstrument *pIns = pSndFile->Instruments[nIns]; m_nInstrument = nIns; _snprintf(pIns->name, CountOf(pIns->name) - 1, _T("%d: %s"), m_pVstPlugin->GetSlot() + 1, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].Info.szName); Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.h =================================================================== --- trunk/OpenMPT/mptrack/AbstractVstEditor.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/AbstractVstEditor.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,4 +1,13 @@ -//rewbs.defaultPlugGUI +/* + * AbstractVstEditor.h + * ------------------- + * Purpose: Common plugin editor interface class. This code is shared between custom and default plugin user interfaces. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #pragma once #ifndef NO_VST Modified: trunk/OpenMPT/mptrack/ArrayUtils.cpp =================================================================== --- trunk/OpenMPT/mptrack/ArrayUtils.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/ArrayUtils.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,6 +1,16 @@ +/* + * ArrayUtils.cpp + * -------------- + * Purpose: Some tools for handling CArrays. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #include "stdafx.h" #include "afxtempl.h" -#include ".\arrayutils.h" +#include "arrayutils.h" template <class Type> static void CArrayUtils<Type>::Merge(CArray<Type,Type>& Dest, CArray<Type,Type>& Src) Modified: trunk/OpenMPT/mptrack/ArrayUtils.h =================================================================== --- trunk/OpenMPT/mptrack/ArrayUtils.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/ArrayUtils.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,3 +1,13 @@ +/* + * ArrayUtils.h + * ------------ + * Purpose: Some tools for handling CArrays. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #pragma once template <class Type> Modified: trunk/OpenMPT/mptrack/AutoSaver.cpp =================================================================== --- trunk/OpenMPT/mptrack/AutoSaver.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/AutoSaver.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,5 +1,15 @@ +/* + * AutoSaver.cpp + * ------------- + * Purpose: Class for automatically saving open modules at a specified interval. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #include "stdafx.h" -#include ".\autosaver.h" +#include "autosaver.h" #include "stdafx.h" #include "mptrack.h" #include "mainfrm.h" Modified: trunk/OpenMPT/mptrack/AutoSaver.h =================================================================== --- trunk/OpenMPT/mptrack/AutoSaver.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/AutoSaver.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,3 +1,13 @@ +/* + * AutoSaver.h + * ----------- + * Purpose: Class for automatically saving open modules at a specified interval. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #pragma once #include "resource.h" Modified: trunk/OpenMPT/mptrack/Autotune.cpp =================================================================== --- trunk/OpenMPT/mptrack/Autotune.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/Autotune.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,9 +1,10 @@ /* * Autotune.cpp - * ------------- - * Purpose: Class for tuning a sample to the next C automatically. + * ------------ + * Purpose: Class for tuning a sample to a given base note automatically. * Notes : (currently none) * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ Modified: trunk/OpenMPT/mptrack/Autotune.h =================================================================== --- trunk/OpenMPT/mptrack/Autotune.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/Autotune.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,15 +1,14 @@ /* * Autotune.h * ---------- - * Purpose: Header file for sample auto tuning + * Purpose: Class for tuning a sample to a given base note automatically. * Notes : (currently none) * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #pragma once -#ifndef AUTOTUNE_H -#define AUTOTUNE_H #include "../soundlib/Snd_defs.h" #include "resource.h" @@ -19,7 +18,7 @@ //============ { protected: - MODSAMPLE &sample; + ModSample &sample; MODTYPE modType; SmpLength selectionStart, selectionEnd; @@ -28,7 +27,7 @@ SmpLength sampleLength; public: - Autotune(MODSAMPLE &smp, MODTYPE type, SmpLength selStart, SmpLength selEnd) : sample(smp), modType(type), selectionStart(selStart), selectionEnd(selEnd) + Autotune(ModSample &smp, MODTYPE type, SmpLength selStart, SmpLength selEnd) : sample(smp), modType(type), selectionStart(selStart), selectionEnd(selEnd) { sampleData = nullptr; sampleLength = 0; @@ -79,5 +78,3 @@ virtual void DoDataExchange(CDataExchange* pDX); }; - -#endif // AUTOTUNE_H Modified: trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp =================================================================== --- trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,3 +1,13 @@ +/* + * ChannelManagerDlg.cpp + * --------------------- + * Purpose: Dialog class for moving, removing, managing channels + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #include "stdafx.h" #include "mainfrm.h" #include "moddoc.h" Modified: trunk/OpenMPT/mptrack/ChannelManagerDlg.h =================================================================== --- trunk/OpenMPT/mptrack/ChannelManagerDlg.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/ChannelManagerDlg.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,3 +1,13 @@ +/* + * ChannelManagerDlg.h + * ------------------- + * Purpose: Dialog class for moving, removing, managing channels + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #pragma once #define CM_BT_LEFT 1 @@ -83,6 +93,3 @@ afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point); }; - -// -! NEW_FEATURE#0015 - Modified: trunk/OpenMPT/mptrack/Childfrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/Childfrm.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/Childfrm.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,6 +1,13 @@ -// ChildFrm.cpp : implementation of the CChildFrame class -// +/* + * ChildFrm.cpp + * ------------ + * Purpose: Implementation of tab interface class. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + #include "stdafx.h" #include <afxpriv.h> #include "mptrack.h" Modified: trunk/OpenMPT/mptrack/Childfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Childfrm.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/Childfrm.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,12 +1,15 @@ -// ChildFrm.h : interface of the CChildFrame class -// -///////////////////////////////////////////////////////////////////////////// +/* + * ChildFrm.h + * ---------- + * Purpose: Implementation of tab interface class. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + #pragma once -#ifndef CHILDFRM_H -#define CHILDFRM_H - class CModControlDlg; class CChildFrame; @@ -151,5 +154,3 @@ //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // CHILDFRM_H Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,14 +1,14 @@ /* - * * CleanupSong.cpp * --------------- - * Purpose: Interface for cleaning up modules (rearranging, removing unused items) - * + * Purpose: Dialog for cleaning up modules (rearranging, removing unused items). + * Notes : (currently none) * Authors: Olivier Lapicque * OpenMPT Devs - * + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ + #include "stdafx.h" #include "moddoc.h" #include "Mainfrm.h" @@ -345,7 +345,7 @@ bool isPatUsed; // Is pattern used in sequence? PATTERNINDEX newIndex; // map old pattern index <-> new pattern index // This stuff is needed for copying the old pattern properties to the new pattern number - MODCOMMAND *data; // original pattern data + ModCommand *data; // original pattern data ROWINDEX numRows; // original pattern sizes ROWINDEX rowsPerBeat; // original pattern highlight ROWINDEX rowsPerMeasure; // original pattern highlight @@ -574,7 +574,7 @@ for (SAMPLEINDEX nSmp = 1; nSmp <= pSndFile->GetNumSamples(); nSmp++) { - const MODSAMPLE &sample = pSndFile->GetSample(nSmp); + const ModSample &sample = pSndFile->GetSample(nSmp); // Determine how much of the sample will be played UINT loopLength = sample.nLength; @@ -598,7 +598,7 @@ { for (SAMPLEINDEX nSmp = 1; nSmp <= pSndFile->m_nSamples; nSmp++) { - MODSAMPLE &sample = pSndFile->GetSample(nSmp); + ModSample &sample = pSndFile->GetSample(nSmp); // Determine how much of the sample will be played UINT loopLength = sample.nLength; @@ -679,7 +679,7 @@ // Also update instrument mapping (if module is in instrument mode) for(INSTRUMENTINDEX nIns = 1; nIns <= pSndFile->GetNumInstruments(); nIns++) { - MODINSTRUMENT *pIns = pSndFile->Instruments[nIns]; + ModInstrument *pIns = pSndFile->Instruments[nIns]; if(pIns) { for(size_t iNote = 0; iNote < 128; iNote++) @@ -694,7 +694,7 @@ { for (PATTERNINDEX nPat = 0; nPat < pSndFile->Patterns.Size(); nPat++) if (pSndFile->Patterns[nPat]) { - MODCOMMAND *m = pSndFile->Patterns[nPat]; + ModCommand *m = pSndFile->Patterns[nPat]; for(UINT len = pSndFile->Patterns[nPat].GetNumRows() * pSndFile->GetNumChannels(); len; m++, len--) { if(!m->IsPcNote() && m->instr <= pSndFile->GetNumSamples()) m->instr = (BYTE)nSampleMap[m->instr]; @@ -796,7 +796,7 @@ { for (PATTERNINDEX iPat = 0; iPat < pSndFile->Patterns.Size(); iPat++) if (pSndFile->Patterns[iPat]) { - MODCOMMAND *p = pSndFile->Patterns[iPat]; + ModCommand *p = pSndFile->Patterns[iPat]; UINT nLen = pSndFile->m_nChannels * pSndFile->Patterns[iPat].GetNumRows(); while (nLen--) { @@ -804,7 +804,7 @@ { for (UINT k=0; k<nSwap; k++) { - if (p->instr == swapmap[k]) p->instr = (MODCOMMAND::INSTR)swapdest[k]; + if (p->instr == swapmap[k]) p->instr = (ModCommand::INSTR)swapdest[k]; } } p++; Modified: trunk/OpenMPT/mptrack/CleanupSong.h =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/CleanupSong.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,11 +1,13 @@ /* - * * CleanupSong.h * --------------- - * Purpose: Header file for CleanupSong.cpp - * + * Purpose: Dialog for cleaning up modules (rearranging, removing unused items). + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ + #pragma once enum ENUM_CLEANUP_OPTIONS Modified: trunk/OpenMPT/mptrack/CloseMainDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/CloseMainDialog.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/CloseMainDialog.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,10 +1,10 @@ /* - * * CloseMainDialog.cpp * ------------------- - * Purpose: Code for displaying a dialog with a list of unsaved documents, and the ability to choose which documents should be saved or not. + * Purpose: Class for displaying a dialog with a list of unsaved documents, and the ability to choose which documents should be saved or not. * Notes : (currently none) * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ Modified: trunk/OpenMPT/mptrack/CloseMainDialog.h =================================================================== --- trunk/OpenMPT/mptrack/CloseMainDialog.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/CloseMainDialog.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,13 +1,13 @@ /* * CloseMainDialog.h * ----------------- - * Purpose: Header file for unsaved documents dialog. + * Purpose: Class for displaying a dialog with a list of unsaved documents, and the ability to choose which documents should be saved or not. * Notes : (currently none) * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ -#ifndef CLOSEMAINDIALOG_H -#define CLOSEMAINDIALOG_H + #pragma once //=================================== @@ -38,5 +38,3 @@ DECLARE_MESSAGE_MAP() }; - -#endif // CLOSEMAINDIALOG_H \ No newline at end of file Modified: trunk/OpenMPT/mptrack/ColourEdit.cpp =================================================================== --- trunk/OpenMPT/mptrack/ColourEdit.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/ColourEdit.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,5 +1,15 @@ +/* + * ColourEdit.cpp + * -------------- + * Purpose: Implementation of a coloured edit UI item. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #include "stdafx.h" -#include ".\colouredit.h" +#include "colouredit.h" ///////////////////////////////////////////////////////////////////////////// // CColourEdit Modified: trunk/OpenMPT/mptrack/ColourEdit.h =================================================================== --- trunk/OpenMPT/mptrack/ColourEdit.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/ColourEdit.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,4 +1,15 @@ +/* + * ColourEdit.h + * ------------ + * Purpose: Implementation of a coloured edit UI item. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #pragma once + #include "afxwin.h" class CColourEdit : Modified: trunk/OpenMPT/mptrack/CommandSet.cpp =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/CommandSet.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,5 +1,13 @@ -//rewbs.customKeys +/* + * CommandSet.cpp + * -------------- + * Purpose: Implementation of custom key handling. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + #include "stdafx.h" #include "commandset.h" #include "resource.h" Modified: trunk/OpenMPT/mptrack/CommandSet.h =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/CommandSet.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,5 +1,13 @@ -//rewbs.customKeys +/* + * CommandSet.h + * ------------ + * Purpose: Header file for custom key handling: List of supported keyboard shortcuts and class for them. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + #pragma once #include "afxtempl.h" #include <string> Modified: trunk/OpenMPT/mptrack/CreditStatic.cpp =================================================================== --- trunk/OpenMPT/mptrack/CreditStatic.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/CreditStatic.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,6 +1,12 @@ -// CreditStatic.cpp : implementation file -// +/* + * CreditStatic.cpp + * ---------------- + * Purpose: Implementation of scrolling credits control. + * Notes : Ugly! :) + * Authors: Pel K. Txnder, http://www.codeguru.com/cpp/controls/staticctrl/article.php/c2903 + */ + #include "stdafx.h" #include "CreditStatic.h" Modified: trunk/OpenMPT/mptrack/CreditStatic.h =================================================================== --- trunk/OpenMPT/mptrack/CreditStatic.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/CreditStatic.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,10 +1,14 @@ +/* + * CreditStatic.h + * -------------- + * Purpose: Implementation of scrolling credits control. + * Notes : Ugly! :) + * Authors: Pel K. Txnder, http://www.codeguru.com/cpp/controls/staticctrl/article.php/c2903 + */ + + #pragma once -#ifndef CREDITSTATIC_H -#define CREDITSTATIC_H -// CreditStatic.h : header file -// - #define DISPLAY_SLOW 0 #define DISPLAY_MEDIUM 1 #define DISPLAY_FAST 2 @@ -114,5 +118,3 @@ //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. - -#endif // CREDITSTATIC_H Modified: trunk/OpenMPT/mptrack/Ctrl_com.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_com.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/Ctrl_com.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,3 +1,14 @@ +/* + * ctrl_com.cpp + * ------------ + * Purpose: Song comments tab, upper panel. + * Notes : (currently none) + * Authors: Olivier Lapicque + * OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #include "stdafx.h" #include "mptrack.h" #include "mainfrm.h" Modified: trunk/OpenMPT/mptrack/Ctrl_com.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_com.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/Ctrl_com.h 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,7 +1,16 @@ -#ifndef _CONTROL_COMMENTS_H_ -#define _CONTROL_COMMENTS_H_ +/* + * ctrl_com.h + * ---------- + * Purpose: Song comments tab, upper panel. + * Notes : (currently none) + * Authors: Olivier Lapicque + * OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ +#pragma once + //======================================== class CCtrlComments: public CModControlDlg //======================================== @@ -34,5 +43,3 @@ //}}AFX_MSG DECLARE_MESSAGE_MAP() }; - -#endif Modified: trunk/OpenMPT/mptrack/Ctrl_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2012-02-25 20:51:28 UTC (rev 1194) @@ -1,3 +1,14 @@ +/* + * ctrl_gen.cpp + * ------------ + * Purpose: General tab, upper panel. + * Notes : (currently none) + * Authors: Olivier Lapicque + * OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + #include "stdafx.h" #include "mptrack.h" #include "mainfrm.h" Modified: trunk/OpenMPT/mptrack/Ctrl_gen.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_gen.h 2012-02-24 23:19:27 UTC (rev 1193) +++ trunk/OpenMPT/mptrack/Ctrl_g... [truncated message content] |
From: <sag...@us...> - 2012-02-25 21:56:31
|
Revision: 1195 http://modplug.svn.sourceforge.net/modplug/?rev=1195&view=rev Author: saga-games Date: 2012-02-25 21:56:25 +0000 (Sat, 25 Feb 2012) Log Message: ----------- [Mod] Macro Editor: Added "Unused" as a fixed macro preset. [Imp] Macro Editor: Fixed macro preset name is now updated instantly when inputting a macro. Modified Paths: -------------- trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp trunk/OpenMPT/soundlib/MIDIMacros.cpp trunk/OpenMPT/soundlib/MIDIMacros.h Modified: trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp 2012-02-25 20:51:28 UTC (rev 1194) +++ trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp 2012-02-25 21:56:25 UTC (rev 1195) @@ -180,16 +180,12 @@ const parameteredMacroType macroType = m_MidiCfg.GetParameteredMacroType(m); switch (macroType) { - case sfx_cc: - s.Format("MIDI CC %d", m_MidiCfg.MacroToMidiCC(m)); - break; - case sfx_plug: s.Format("Control Plugin Param %d", m_MidiCfg.MacroToPlugParam(m)); break; default: - s = m_MidiCfg.GetParameteredMacroName(macroType); + s = m_MidiCfg.GetParameteredMacroName(m, 0, m_SndFile); break; } m_EditMacroType[m].SetWindowText(s); @@ -350,6 +346,7 @@ m_EditZxx.GetWindowText(s, MACRO_LENGTH); StringFixer::SetNullTerminator(s); memcpy(m_MidiCfg.szMidiZXXExt[zxx], s, MACRO_LENGTH); + m_CbnZxxPreset.SetCurSel(m_MidiCfg.GetFixedMacroType()); } } } Modified: trunk/OpenMPT/soundlib/MIDIMacros.cpp =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-02-25 20:51:28 UTC (rev 1194) +++ trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-02-25 21:56:25 UTC (rev 1195) @@ -47,22 +47,26 @@ //------------------------------------------------------- { // Compare with all possible preset patterns - for(size_t i = 1; i < zxx_max; i++) + for(size_t i = 0; i < zxx_max; i++) { - // Prepare macro pattern to compare - char macros[128][MACRO_LENGTH]; - CreateFixedMacro(macros, static_cast<fixedMacroType>(i)); + fixedMacroType zxx = static_cast<fixedMacroType>(i); + if(zxx != zxx_custom) + { + // Prepare macro pattern to compare + char macros[128][MACRO_LENGTH]; + CreateFixedMacro(macros, zxx); - bool bFound = true; - for(size_t j = 0; j < 128; j++) - { - if(strncmp(macros[j], szMidiZXXExt[j], MACRO_LENGTH)) + bool found = true; + for(size_t j = 0; j < 128; j++) { - bFound = false; - break; + if(strncmp(macros[j], szMidiZXXExt[j], MACRO_LENGTH)) + { + found = false; + break; + } } + if(found) return zxx; } - if(bFound) return static_cast<fixedMacroType>(i); } return zxx_custom; // Custom setup } @@ -112,6 +116,10 @@ { switch(macroType) { + case zxx_unused: + strcpy(fixedMacros[i], ""); + break; + case zxx_reso4Bit: // Type 1 - Z80 - Z8F controls resonance if (i < 16) sprintf(fixedMacros[i], "F0F001%02X", i * 8); @@ -242,6 +250,8 @@ { switch(macroType) { + case zxx_unused: + return _T("Unused"); case zxx_reso4Bit: return _T("Z80 - Z8F controls Resonant Filter Resonance"); case zxx_reso7Bit: Modified: trunk/OpenMPT/soundlib/MIDIMacros.h =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.h 2012-02-25 20:51:28 UTC (rev 1194) +++ trunk/OpenMPT/soundlib/MIDIMacros.h 2012-02-25 21:56:25 UTC (rev 1195) @@ -37,7 +37,7 @@ // Fixed macro presets enum fixedMacroType { - zxx_custom = 0, + zxx_unused = 0, zxx_reso4Bit, // Type 1 - Z80 - Z8F controls resonant filter resonance zxx_reso7Bit, // Type 2 - Z80 - ZFF controls resonant filter resonance zxx_cutoff, // Type 3 - Z80 - ZFF controls resonant filter cutoff @@ -45,6 +45,7 @@ zxx_resomode, // Type 5 - Z80 - Z9F controls resonance + filter mode zxx_channelAT, // Type 6 - Z80 - ZFF controls Channel Aftertouch zxx_polyAT, // Type 7 - Z80 - ZFF controls Poly Aftertouch + zxx_custom, zxx_max }; @@ -88,7 +89,9 @@ fixedMacroType GetFixedMacroType() const; // Create a new macro +protected: void CreateParameteredMacro(char (¶meteredMacro)[MACRO_LENGTH], parameteredMacroType macroType, int subType) const; +public: void CreateParameteredMacro(size_t macroIndex, parameteredMacroType macroType, int subType = 0) { CreateParameteredMacro(szMidiSFXExt[macroIndex], macroType, subType); @@ -100,7 +103,9 @@ return std::string(parameteredMacro); }; +protected: void CreateFixedMacro(char (&fixedMacros)[128][MACRO_LENGTH], fixedMacroType macroType) const; +public: void CreateFixedMacro(fixedMacroType macroType) { CreateFixedMacro(szMidiZXXExt, macroType); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-25 22:04:37
|
Revision: 1196 http://modplug.svn.sourceforge.net/modplug/?rev=1196&view=rev Author: saga-games Date: 2012-02-25 22:04:30 +0000 (Sat, 25 Feb 2012) Log Message: ----------- [Mod] IT Compatibility: Pitch envelope loop length is now identical in compatible and normal mode. To compensate for the missing tick in normal mode, pitch loops made with older versions of MPT are fixed upon loading. [Imp] Mod Conversion: Envelope loops are now fixed automatically when converting between XM and IT files. [Ref] Moved sample / instrument conversion code to ModInstrument.cpp / ModSample.cpp [Mod] OpenMPT: Version is now 1.20.00.71 Modified Paths: -------------- trunk/OpenMPT/mptrack/ModConvert.cpp trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/ModChannel.h trunk/OpenMPT/soundlib/ModInstrument.cpp trunk/OpenMPT/soundlib/ModInstrument.h trunk/OpenMPT/soundlib/ModSample.h trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Added Paths: ----------- trunk/OpenMPT/soundlib/ModSample.cpp Modified: trunk/OpenMPT/mptrack/ModConvert.cpp =================================================================== --- trunk/OpenMPT/mptrack/ModConvert.cpp 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/mptrack/ModConvert.cpp 2012-02-25 22:04:30 UTC (rev 1196) @@ -296,7 +296,7 @@ CHANGEMODTYPE_WARNING(wMODSampleFrequency); } - m_SndFile.ConvertSample(nSmp, nOldType, nNewType); + sample.Convert(nOldType, nNewType); } for(INSTRUMENTINDEX nIns = 1; nIns <= m_SndFile.GetNumInstruments(); nIns++) @@ -344,7 +344,7 @@ } } - m_SndFile.ConvertInstrument(nIns, nOldType, nNewType); + pIns->Convert(nOldType, nNewType); } if(newTypeIsMOD) Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2012-02-25 22:04:30 UTC (rev 1196) @@ -316,6 +316,9 @@ RelativePath="..\soundlib\ModInstrument.cpp"> </File> <File + RelativePath="..\soundlib\ModSample.cpp"> + </File> + <File RelativePath=".\ModConvert.cpp"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2012-02-25 22:04:30 UTC (rev 1196) @@ -425,6 +425,10 @@ > </File> <File + RelativePath="..\soundlib\ModSample.cpp" + > + </File> + <File RelativePath=".\ModConvert.cpp" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2012-02-25 22:04:30 UTC (rev 1196) @@ -171,6 +171,7 @@ <ClCompile Include="..\common\Reporting.cpp" /> <ClCompile Include="..\soundlib\MIDIMacros.cpp" /> <ClCompile Include="..\soundlib\ModInstrument.cpp" /> + <ClCompile Include="..\soundlib\ModSample.cpp" /> <ClCompile Include="AbstractVstEditor.cpp" /> <ClCompile Include="ACMConvert.cpp" /> <ClCompile Include="ArrayUtils.cpp" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2012-02-25 22:04:30 UTC (rev 1196) @@ -433,6 +433,9 @@ <ClCompile Include="PSRatioCalc.cpp"> <Filter>Source Files\Dialogs</Filter> </ClCompile> + <ClCompile Include="..\soundlib\ModSample.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="AbstractVstEditor.h"> Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/mptrack/version.h 2012-02-25 22:04:30 UTC (rev 1196) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 70 +#define VER_MINORMINOR 71 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Modified: trunk/OpenMPT/soundlib/ModChannel.h =================================================================== --- trunk/OpenMPT/soundlib/ModChannel.h 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/soundlib/ModChannel.h 2012-02-25 22:04:30 UTC (rev 1196) @@ -102,7 +102,8 @@ void ClearRowCmd() { rowCommand = ModCommand::Empty(); } - ModChannelEnvInfo &GetEnvelope(enmEnvelopeTypes envType) + // Get a reference to a specific envelope of this channel + const ModChannelEnvInfo &GetEnvelope(enmEnvelopeTypes envType) const { switch(envType) { @@ -116,6 +117,11 @@ } } + ModChannelEnvInfo &GetEnvelope(enmEnvelopeTypes envType) + { + return const_cast<ModChannelEnvInfo &>(static_cast<const ModChannel &>(*this).GetEnvelope(envType)); + } + typedef UINT VOLUME; VOLUME GetVSTVolume() {return (pModInstrument) ? pModInstrument->nGlobalVol * 4 : nVolume;} Modified: trunk/OpenMPT/soundlib/ModInstrument.cpp =================================================================== --- trunk/OpenMPT/soundlib/ModInstrument.cpp 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/soundlib/ModInstrument.cpp 2012-02-25 22:04:30 UTC (rev 1196) @@ -13,6 +13,104 @@ #include "ModInstrument.h" +// Convert envelope data between various formats. +void InstrumentEnvelope::Convert(MODTYPE fromType, MODTYPE toType) +//---------------------------------------------------------------- +{ + if(!(fromType & MOD_TYPE_XM) && (toType & MOD_TYPE_XM)) + { + // IT / MPTM -> XM: Expand loop by one tick, convert sustain loops to sustain points, remove carry flag. + nSustainStart = nSustainEnd; + dwFlags &= ~ENV_CARRY; + + if(nLoopEnd > nLoopStart && (dwFlags & ENV_LOOP)) + { + for(UINT node = nLoopEnd; node < nNodes; node++) + { + Ticks[node]++; + } + } + } else if((fromType & MOD_TYPE_XM) && !(toType & MOD_TYPE_XM)) + { + // XM -> IT / MPTM: Shorten loop by one tick by inserting bogus point + if(nLoopEnd > nLoopStart && (dwFlags & ENV_LOOP)) + { + if(Ticks[nLoopEnd] - 1 > Ticks[nLoopEnd - 1]) + { + // Insert an interpolated point just before the loop point. + BYTE interpolatedValue = Util::Round<BYTE>(GetValueFromPosition(Ticks[nLoopEnd] - 1) * 64.0f); + + + if(nNodes + 1 < MAX_ENVPOINTS) + { + // Should always be possible, since XM only allows for 12 envelope points anyway. + for(UINT node = nNodes; node >= nLoopEnd; node--) + { + Ticks[node + 1] = Ticks[node]; + Values[node + 1] = Values[node]; + } + } + + Ticks[nLoopEnd]--; + Values[nLoopEnd] = (BYTE)interpolatedValue; + + nNodes++; + } else + { + // There is already a point before the loop point: Use it as loop end. + nLoopEnd--; + } + + } + } +}; + + +// Get envelope value at a given tick. Returns value in range [0.0, 1.0]. +float InstrumentEnvelope::GetValueFromPosition(int position) const +//---------------------------------------------------------------- +{ + UINT pt = nNodes - 1; + + // Checking where current 'tick' is relative to the envelope points. + for(UINT i = 0; i < nNodes - 1u; i++) + { + if (position <= Ticks[i]) + { + pt = i; + break; + } + } + + int x2 = Ticks[pt]; + float value = 0.0f; + + if(position >= x2) + { + // Case: current 'tick' is on a envelope point. + value = static_cast<float>(Values[pt]) / 64.0f; + } else + { + // Case: current 'tick' is between two envelope points. + int x1 = 0; + + if (pt) + { + value = static_cast<float>(Values[pt - 1]) / 64.0f; + x1 = Ticks[pt - 1]; + } + + if(x2 > x1 && position > x1) + { + // Linear approximation between the points; + // f(x+d) ~ f(x) + f'(x)*d, where f'(x) = (y2-y1) / (x2-x1) + value += ((position - x1) * (static_cast<float>(Values[pt]) / 64.0f - value)) / (x2 - x1); + } + } + return value; +}; + + ModInstrument::ModInstrument(SAMPLEINDEX sample) //---------------------------------------------- { @@ -56,3 +154,59 @@ MemsetZero(name); MemsetZero(filename); } + + +// Translate instrument properties between two given formats. +void ModInstrument::Convert(MODTYPE fromType, MODTYPE toType) +//----------------------------------------------------------- +{ + UNREFERENCED_PARAMETER(fromType); + + if(toType & MOD_TYPE_XM) + { + ResetNoteMap(); + + PitchEnv.dwFlags &= ~(ENV_ENABLED|ENV_FILTER); + + dwFlags &= ~INS_SETPANNING; + SetCutoff(GetCutoff(), false); + SetResonance(GetResonance(), false); + nFilterMode = FLTMODE_UNCHANGED; + + nCutSwing = nPanSwing = nResSwing = nVolSwing = 0; + + nPPC = NOTE_MIDDLEC - 1; + nPPS = 0; + + nNNA = NNA_NOTECUT; + nDCT = DCT_NONE; + nDNA = DNA_NOTECUT; + + if(nMidiChannel == MidiMappedChannel) + { + nMidiChannel = 1; + } + + nGlobalVol = 64; + nPan = 128; + + LimitMax(nFadeOut, 32767u); + } + + VolEnv.Convert(fromType, toType); + PanEnv.Convert(fromType, toType); + PitchEnv.Convert(fromType, toType); + + // Limit fadeout length for IT / MPT + if(toType & (MOD_TYPE_IT | MOD_TYPE_MPT)) + { + LimitMax(nFadeOut, 8192u); + } + + // MPT-specific features - remove instrument tunings, Pitch/Tempo Lock for other formats + if(!(toType & MOD_TYPE_MPT)) + { + SetTuning(nullptr); + wPitchToTempoLock = 0; + } +} Modified: trunk/OpenMPT/soundlib/ModInstrument.h =================================================================== --- trunk/OpenMPT/soundlib/ModInstrument.h 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/soundlib/ModInstrument.h 2012-02-25 22:04:30 UTC (rev 1196) @@ -33,6 +33,13 @@ MemsetZero(Ticks); MemsetZero(Values); } + + // Convert envelope data between various formats. + void Convert(MODTYPE fromType, MODTYPE toType); + + // Get envelope value at a given tick. Returns value in range [0.0, 1.0]. + float GetValueFromPosition(int position) const; + }; // Instrument Struct @@ -120,7 +127,7 @@ bool HasValidMIDIChannel() const { return (nMidiChannel >= 1 && nMidiChannel <= 17); } // Get a reference to a specific envelope of this instrument - InstrumentEnvelope &GetEnvelope(enmEnvelopeTypes envType) + const InstrumentEnvelope &GetEnvelope(enmEnvelopeTypes envType) const { switch(envType) { @@ -134,6 +141,11 @@ } } + InstrumentEnvelope &GetEnvelope(enmEnvelopeTypes envType) + { + return const_cast<InstrumentEnvelope &>(static_cast<const ModInstrument &>(*this).GetEnvelope(envType)); + } + // Get a set of all samples referenced by this instrument std::set<SAMPLEINDEX> GetSamples() const { @@ -151,4 +163,7 @@ return referencedSamples; } + // Translate instrument properties between two given formats. + void Convert(MODTYPE fromType, MODTYPE toType); + }; Added: trunk/OpenMPT/soundlib/ModSample.cpp =================================================================== --- trunk/OpenMPT/soundlib/ModSample.cpp (rev 0) +++ trunk/OpenMPT/soundlib/ModSample.cpp 2012-02-25 22:04:30 UTC (rev 1196) @@ -0,0 +1,90 @@ +/* + * ModSample.h + * ----------- + * Purpose: Module Sample header class and helpers + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#include "stdafx.h" +#include "Sndfile.h" +#include "ModSample.h" + + +// Translate sample properties between two given formats. +void ModSample::Convert(MODTYPE fromType, MODTYPE toType) +//------------------------------------------------------- +{ + // Convert between frequency and transpose values if necessary. + if ((!(toType & (MOD_TYPE_MOD | MOD_TYPE_XM))) && (fromType & (MOD_TYPE_MOD | MOD_TYPE_XM))) + { + nC5Speed = CSoundFile::TransposeToFrequency(RelativeTone, nFineTune); + RelativeTone = 0; + nFineTune = 0; + } else if((toType & (MOD_TYPE_MOD | MOD_TYPE_XM)) && (!(fromType & (MOD_TYPE_MOD | MOD_TYPE_XM)))) + { + CSoundFile::FrequencyToTranspose(this); + if(toType & MOD_TYPE_MOD) + { + RelativeTone = 0; + } + } + + // No ping-pong loop, panning and auto-vibrato for MOD / S3M samples + if(toType & (MOD_TYPE_MOD | MOD_TYPE_S3M)) + { + uFlags &= ~(CHN_PINGPONGLOOP | CHN_PANNING); + + nVibDepth = 0; + nVibRate = 0; + nVibSweep = 0; + nVibType = VIB_SINE; + } + + // No sustain loops for MOD/S3M/XM + if(toType & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_S3M)) + { + // Sustain loops - convert to normal loops + if((uFlags & CHN_SUSTAINLOOP) != 0) + { + // We probably overwrite a normal loop here, but since sustain loops are evaluated before normal loops, this is just correct. + nLoopStart = nSustainStart; + nLoopEnd = nSustainEnd; + uFlags |= CHN_LOOP; + if(uFlags & CHN_PINGPONGSUSTAIN) + { + uFlags |= CHN_PINGPONGLOOP; + } else + { + uFlags &= ~CHN_PINGPONGLOOP; + } + } + nSustainStart = nSustainEnd = 0; + uFlags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); + } + + // All XM samples have default panning, and XM's autovibrato settings are rather limited. + if(toType & MOD_TYPE_XM) + { + if(!(uFlags & CHN_PANNING)) + { + uFlags |= CHN_PANNING; + nPan = 128; + } + + LimitMax(nVibDepth, BYTE(15)); + LimitMax(nVibRate, BYTE(63)); + } + + + // Autovibrato sweep setting is inverse in XM (0 = "no sweep") and IT (0 = "no vibrato") + if(((fromType & MOD_TYPE_XM) && (toType & (MOD_TYPE_IT | MOD_TYPE_MPT))) || ((toType & MOD_TYPE_XM) && (fromType & (MOD_TYPE_IT | MOD_TYPE_MPT)))) + { + if(nVibRate != 0 && nVibDepth != 0) + { + nVibSweep = 255 - nVibSweep; + } + } +} Modified: trunk/OpenMPT/soundlib/ModSample.h =================================================================== --- trunk/OpenMPT/soundlib/ModSample.h 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/soundlib/ModSample.h 2012-02-25 22:04:30 UTC (rev 1196) @@ -45,4 +45,7 @@ // Returns sample rate of the sample. The argument is needed because // the sample rate is obtained differently for different module types. uint32 GetSampleRate(const MODTYPE type) const; + + // Translate sample properties between two given formats. + void Convert(MODTYPE fromType, MODTYPE toType); }; Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2012-02-25 22:04:30 UTC (rev 1196) @@ -250,7 +250,7 @@ } } - ConvertInstrument(targetInstr, pSrcSong->GetType()); + pIns->Convert(pSrcSong->GetType(), GetType()); // Copy all referenced samples over for(size_t i = 0; i < targetSample.size(); i++) @@ -290,7 +290,7 @@ } } - ConvertSample(targetSample, pSrcSong->GetType()); + Samples[targetSample].Convert(pSrcSong->GetType(), GetType()); return true; } @@ -544,7 +544,7 @@ } } } - ConvertSample(nSample, MOD_TYPE_IT); + pSmp->Convert(MOD_TYPE_IT, GetType()); return true; } @@ -1036,7 +1036,7 @@ pSmp->RelativeTone = 0; pSmp->nFineTune = 0; - ConvertSample(nSample, MOD_TYPE_S3M); + pSmp->Convert(MOD_TYPE_S3M, GetType()); if (pss->flags & 0x01) pSmp->uFlags |= CHN_LOOP; flags = (pss->flags & 0x04) ? RS_PCM16U : RS_PCM8U; @@ -1262,7 +1262,7 @@ memcpy(pSmp->filename, psh->name, 22); pSmp->filename[21] = 0; - ConvertSample(samplemap[ismp], MOD_TYPE_XM); + pSmp->Convert(MOD_TYPE_XM, GetType()); } // Reading sample data for (UINT dsmp=0; dsmp<nsamples; dsmp++) @@ -1273,7 +1273,7 @@ dwMemPos += samplesize[dsmp]; } - ConvertInstrument(nInstr, MOD_TYPE_XM); + pIns->Convert(MOD_TYPE_XM, GetType()); // -> CODE#0027 // -> DESC="per-instrument volume ramping setup (refered as attack)" @@ -1501,7 +1501,7 @@ memcpy(pSmp->filename, psh->name, 22); pSmp->filename[21] = 0; } - ConvertSample(nSample, MOD_TYPE_XM); + pSmp->Convert(MOD_TYPE_XM, GetType()); if (dwMemPos >= dwFileLength) return true; ReadSample(pSmp, sampleflags, (LPSTR)(lpMemFile+dwMemPos), dwFileLength-dwMemPos); return true; @@ -1707,7 +1707,7 @@ if (pis->flags & 8) flags = RS_IT2148; } - ConvertSample(nSample, MOD_TYPE_IT); + pSmp->Convert(MOD_TYPE_IT, GetType()); // -> CODE#0027 // -> DESC="per-instrument volume ramping setup (refered as attack)" @@ -1792,7 +1792,7 @@ // Leave if no extra instrument settings are available (end of file reached) if(dwMemPos >= dwFileLength) return true; - ConvertInstrument(nInstr, MOD_TYPE_IT); + pIns->Convert(MOD_TYPE_IT, GetType()); ReadExtendedInstrumentProperties(pIns, lpMemFile + dwMemPos, dwFileLength - dwMemPos); @@ -2185,161 +2185,3 @@ } return (pSmp->pSample != nullptr); } - - -// Translate sample properties between two given formats. -void CSoundFile::ConvertSample(SAMPLEINDEX sample, MODTYPE fromType, MODTYPE toType) -//---------------------------------------------------------------------------------- -{ - if(toType == MOD_TYPE_NONE) - { - toType = GetType(); - } - - if(sample < 1 || sample > GetNumSamples()) - { - return; - } - - ModSample &smp = GetSample(sample); - // Convert between frequency and transpose values if necessary. - if ((!(toType & (MOD_TYPE_MOD | MOD_TYPE_XM))) && (fromType & (MOD_TYPE_MOD | MOD_TYPE_XM))) - { - smp.nC5Speed = TransposeToFrequency(smp.RelativeTone, smp.nFineTune); - smp.RelativeTone = 0; - smp.nFineTune = 0; - } else if((toType & (MOD_TYPE_MOD | MOD_TYPE_XM)) && (!(fromType & (MOD_TYPE_MOD | MOD_TYPE_XM)))) - { - FrequencyToTranspose(&smp); - if(toType & MOD_TYPE_MOD) - { - smp.RelativeTone = 0; - } - } - - // No ping-pong loop, panning and auto-vibrato for MOD / S3M samples - if(toType & (MOD_TYPE_MOD | MOD_TYPE_S3M)) - { - smp.uFlags &= ~(CHN_PINGPONGLOOP | CHN_PANNING); - - smp.nVibDepth = 0; - smp.nVibRate = 0; - smp.nVibSweep = 0; - smp.nVibType = VIB_SINE; - } - - // No sustain loops for MOD/S3M/XM - if(toType & (MOD_TYPE_MOD | MOD_TYPE_XM | MOD_TYPE_S3M)) - { - // Sustain loops - convert to normal loops - if((smp.uFlags & CHN_SUSTAINLOOP) != 0) - { - // We probably overwrite a normal loop here, but since sustain loops are evaluated before normal loops, this is just correct. - smp.nLoopStart = smp.nSustainStart; - smp.nLoopEnd = smp.nSustainEnd; - smp.uFlags |= CHN_LOOP; - if(smp.uFlags & CHN_PINGPONGSUSTAIN) - { - smp.uFlags |= CHN_PINGPONGLOOP; - } else - { - smp.uFlags &= ~CHN_PINGPONGLOOP; - } - } - smp.nSustainStart = smp.nSustainEnd = 0; - smp.uFlags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); - } - - // All XM samples have default panning, and XM's autovibrato settings are rather limited. - if(toType & MOD_TYPE_XM) - { - if(!(smp.uFlags & CHN_PANNING)) - { - smp.uFlags |= CHN_PANNING; - smp.nPan = 128; - } - - LimitMax(smp.nVibDepth, BYTE(15)); - LimitMax(smp.nVibRate, BYTE(63)); - } - - - // Autovibrato sweep setting is inverse in XM (0 = "no sweep") and IT (0 = "no vibrato") - if(((fromType & MOD_TYPE_XM) && (toType & (MOD_TYPE_IT | MOD_TYPE_MPT))) || ((toType & MOD_TYPE_XM) && (fromType & (MOD_TYPE_IT | MOD_TYPE_MPT)))) - { - if(smp.nVibRate != 0 && smp.nVibDepth != 0) - { - smp.nVibSweep = 255 - smp.nVibSweep; - } - } -} - - -// Translate instrument properties between two given formats. -void CSoundFile::ConvertInstrument(INSTRUMENTINDEX instr, MODTYPE fromType, MODTYPE toType) -//----------------------------------------------------------------------------------------- -{ - UNREFERENCED_PARAMETER(fromType); - - if(toType == MOD_TYPE_NONE) - { - toType = GetType(); - } - - if(instr < 1 || instr > GetNumInstruments() || Instruments[instr] == nullptr) - { - return; - } - - ModInstrument *pIns = Instruments[instr]; - - if(toType & MOD_TYPE_XM) - { - pIns->ResetNoteMap(); - - // Convert sustain loops to sustain "points" - pIns->VolEnv.nSustainEnd = pIns->VolEnv.nSustainStart; - pIns->PanEnv.nSustainEnd = pIns->PanEnv.nSustainStart; - - pIns->VolEnv.dwFlags &= ~ENV_CARRY; - pIns->PanEnv.dwFlags &= ~ENV_CARRY; - pIns->PitchEnv.dwFlags &= ~(ENV_CARRY|ENV_ENABLED|ENV_FILTER); - - pIns->dwFlags &= ~INS_SETPANNING; - pIns->SetCutoff(pIns->GetCutoff(), false); - pIns->SetResonance(pIns->GetResonance(), false); - pIns->nFilterMode = FLTMODE_UNCHANGED; - - pIns->nCutSwing = pIns->nPanSwing = pIns->nResSwing = pIns->nVolSwing = 0; - - pIns->nPPC = NOTE_MIDDLEC - 1; - pIns->nPPS = 0; - - pIns->nNNA = NNA_NOTECUT; - pIns->nDCT = DCT_NONE; - pIns->nDNA = DNA_NOTECUT; - - if(pIns->nMidiChannel == MidiMappedChannel) - { - pIns->nMidiChannel = 1; - } - - pIns->nGlobalVol = 64; - pIns->nPan = 128; - - LimitMax(pIns->nFadeOut, 32767u); - } - - // Limit fadeout length for IT / MPT - if(toType & (MOD_TYPE_IT | MOD_TYPE_MPT)) - { - LimitMax(pIns->nFadeOut, 8192u); - } - - // MPT-specific features - remove instrument tunings, Pitch/Tempo Lock for other formats - if(!(toType & MOD_TYPE_MPT)) - { - pIns->SetTuning(nullptr); - pIns->wPitchToTempoLock = 0; - } -} Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2012-02-25 22:04:30 UTC (rev 1196) @@ -2487,7 +2487,7 @@ { GetpModDoc()->GetSampleUndo().PrepareUndo(nSmp, sundo_replace); } -#endif // MODPLUG_TRACKER +#endif // MODPLUG_TRACKER if(DestroySample(nSmp)) { @@ -2510,7 +2510,7 @@ LPSTR pSample = pSmp->pSample; pSmp->pSample = nullptr; pSmp->nLength = 0; - pSmp->uFlags &= ~(CHN_16BIT); + pSmp->uFlags &= ~(CHN_16BIT | CHN_STEREO); for (UINT i=0; i<MAX_CHANNELS; i++) { if (Chn[i].pSample == pSample) @@ -2725,7 +2725,7 @@ { if(strcmp(m_szNames[0], titleCandidate)) { - strncpy(m_szNames[0], titleCandidate, min(MAX_SAMPLENAME - 1, strSize)); + strncpy(m_szNames[0], titleCandidate, min(CountOf(m_szNames[0]), strSize)); StringFixer::SetNullTerminator(m_szNames[0]); return true; } @@ -2748,14 +2748,16 @@ { switch(m_nTempoMode) { + case tempo_mode_classic: default: + m_nSamplesPerTick = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8); + + case tempo_mode_modern: + m_nSamplesPerTick = gdwMixingFreq * (60 / m_nMusicTempo / (m_nMusicSpeed * m_nCurrentRowsPerBeat)); + break; + case tempo_mode_alternative: m_nSamplesPerTick = gdwMixingFreq / m_nMusicTempo; break; - case tempo_mode_modern: - m_nSamplesPerTick = gdwMixingFreq * (60/m_nMusicTempo / (m_nMusicSpeed * m_nCurrentRowsPerBeat)); - break; - case tempo_mode_classic: default: - m_nSamplesPerTick = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8); } } @@ -2881,7 +2883,7 @@ //------------------------------------------------ { // Setup LRRL panning, max channel volume - if((m_nType & MOD_TYPE_MOD) == 0 && bForceSetup == false) return; + if((GetType() & MOD_TYPE_MOD) == 0 && bForceSetup == false) return; for(CHANNELINDEX nChn = 0; nChn < MAX_BASECHANNELS; nChn++) { @@ -2916,7 +2918,7 @@ // If there are any plugins, enable volume bug emulation. for(PLUGINDEX i = 0; i < MAX_MIXPLUGINS; i++) { - if(m_MixPlugins[i].Info.dwPluginId1 | m_MixPlugins[i].Info.dwPluginId2) + if((m_MixPlugins[i].Info.dwPluginId1 | m_MixPlugins[i].Info.dwPluginId2)) { SetModFlag(MSF_MIDICC_BUGEMULATION, true); break; @@ -3033,6 +3035,14 @@ // This was corrected in compatible mode in OpenMPT 1.18, and in OpenMPT 1.20 it is corrected in normal mode as well. Instruments[i]->nPPS = (Instruments[i]->nPPS + (Instruments[i]->nPPS >= 0 ? 1 : -1)) / 2; } + + if(!IsCompatibleMode(TRK_IMPULSETRACKER) || m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 03, 02)) + { + // IT compatibility 24. Short envelope loops + // Previously, the pitch / filter envelope loop handling was broken, the loop was shortened by a tick (like in XM). + // This was corrected in compatible mode in OpenMPT 1.17.03.02, and in OpenMPT 1.20 it is corrected in normal mode as well. + Instruments[i]->GetEnvelope(ENV_PITCH).Convert(MOD_TYPE_XM, GetType()); + } } if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 03, 02) || !IsCompatibleMode(TRK_IMPULSETRACKER))) Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-02-25 22:04:30 UTC (rev 1196) @@ -325,7 +325,7 @@ SAMPLEINDEX GetNumSamples() const { return m_nSamples; } UINT GetCurrentPos() const; PATTERNINDEX GetCurrentPattern() const { return m_nPattern; } - ORDERINDEX GetCurrentOrder() const { return static_cast<ORDERINDEX>(m_nCurrentOrder); } + ORDERINDEX GetCurrentOrder() const { return m_nCurrentOrder; } CHANNELINDEX GetNumChannels() const { return m_nChannels; } IMixPlugin* GetInstrumentPlugin(INSTRUMENTINDEX instr); @@ -348,7 +348,7 @@ public: //Returns song length in seconds. - DWORD GetSongTime() { return static_cast<DWORD>((m_nTempoMode == tempo_mode_alternative) ? GetLength(eNoAdjust).duration + 1.0 : GetLength(eNoAdjust).duration + 0.5); } + DWORD GetSongTime() { return static_cast<DWORD>(GetLength(eNoAdjust).duration + 0.5); } void RecalculateSamplesPerTick(); double GetRowDuration(UINT tempo, UINT speed, UINT additionalTicks = 0) const; @@ -356,7 +356,7 @@ // A repeat count value of -1 means infinite loop void SetRepeatCount(int n) { m_nRepeatCount = n; } int GetRepeatCount() const { return m_nRepeatCount; } - bool IsPaused() const { return (m_dwSongFlags & (SONG_PAUSED|SONG_STEP)) != 0; } // Added SONG_STEP as it seems to be desirable in most cases to check for this as well. + bool IsPaused() const { return (m_dwSongFlags & (SONG_PAUSED | SONG_STEP)) != 0; } // Added SONG_STEP as it seems to be desirable in most cases to check for this as well. void LoopPattern(PATTERNINDEX nPat, ROWINDEX nRow = 0); void CheckCPUUsage(UINT nCPU); @@ -434,11 +434,6 @@ static void S3MSxx2MODExx(ModCommand *m); // Convert Sxx to Exx void SetupMODPanning(bool bForceSetup = false); // Setup LRRL panning, max channel volume - // Translate sample properties between two given formats. - void ConvertSample(SAMPLEINDEX sample, MODTYPE fromType, MODTYPE toType = MOD_TYPE_NONE); - // Translate instrument properties between two given formats. - void ConvertInstrument(INSTRUMENTINDEX instr, MODTYPE fromType, MODTYPE toType = MOD_TYPE_NONE); - public: // Real-time sound functions void SuspendPlugins(); //rewbs.VSTCompliance @@ -523,6 +518,7 @@ void ProcessTremolo(ModChannel *pChn, int &vol); void ProcessTremor(ModChannel *pChn, int &vol); + bool IsEnvelopeProcessed(const ModChannel *pChn, enmEnvelopeTypes env) const; void ProcessVolumeEnvelope(ModChannel *pChn, int &vol); void ProcessPanningEnvelope(ModChannel *pChn); void ProcessPitchFilterEnvelope(ModChannel *pChn, int &period); Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-25 21:56:25 UTC (rev 1195) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-25 22:04:30 UTC (rev 1196) @@ -1063,14 +1063,28 @@ } +bool CSoundFile::IsEnvelopeProcessed(const ModChannel *pChn, enmEnvelopeTypes env) const +//-------------------------------------------------------------------------------------- +{ + if(pChn->pModInstrument == nullptr) + { + return false; + } + const InstrumentEnvelope &insEnv = pChn->pModInstrument->GetEnvelope(env); + + // IT Compatibility: S77/S79/S7B do not disable the envelope, they just pause the counter + return (((pChn->GetEnvelope(env).flags & ENV_ENABLED) || ((insEnv.dwFlags & ENV_ENABLED) && IsCompatibleMode(TRK_IMPULSETRACKER))) + && insEnv.nNodes != 0); +} + + void CSoundFile::ProcessVolumeEnvelope(ModChannel *pChn, int &vol) //---------------------------------------------------------------- { - const ModInstrument *pIns = pChn->pModInstrument; + if(IsEnvelopeProcessed(pChn, ENV_VOLUME)) + { + const ModInstrument *pIns = pChn->pModInstrument; - // IT Compatibility: S77 does not disable the volume envelope, it just pauses the counter - if (((pChn->VolEnv.flags & ENV_ENABLED) || ((pIns->VolEnv.dwFlags & ENV_ENABLED) && IsCompatibleMode(TRK_IMPULSETRACKER))) && (pIns->VolEnv.nNodes)) - { if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->VolEnv.nEnvPosition == 0) { // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. @@ -1107,11 +1121,10 @@ void CSoundFile::ProcessPanningEnvelope(ModChannel *pChn) //------------------------------------------------------- { - const ModInstrument *pIns = pChn->pModInstrument; + if(IsEnvelopeProcessed(pChn, ENV_PANNING)) + { + const ModInstrument *pIns = pChn->pModInstrument; - // IT Compatibility: S79 does not disable the panning envelope, it just pauses the counter - if (((pChn->PanEnv.flags & ENV_ENABLED) || ((pIns->PanEnv.dwFlags & ENV_ENABLED) && IsCompatibleMode(TRK_IMPULSETRACKER))) && (pIns->PanEnv.nNodes)) - { if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->PanEnv.nEnvPosition == 0) { // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. @@ -1166,11 +1179,10 @@ void CSoundFile::ProcessPitchFilterEnvelope(ModChannel *pChn, int &period) //------------------------------------------------------------------------ { - const ModInstrument *pIns = pChn->pModInstrument; + if(IsEnvelopeProcessed(pChn, ENV_PITCH)) + { + const ModInstrument *pIns = pChn->pModInstrument; - // IT Compatibility: S7B does not disable the pitch envelope, it just pauses the counter - if ((pIns) && ((pChn->PitchEnv.flags & ENV_ENABLED) || ((pIns->PitchEnv.dwFlags & ENV_ENABLED) && IsCompatibleMode(TRK_IMPULSETRACKER))) && (pChn->pModInstrument->PitchEnv.nNodes)) - { if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->PitchEnv.nEnvPosition == 0) { // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. @@ -1351,8 +1363,7 @@ if (pIns->PitchEnv.dwFlags & ENV_LOOP) { UINT pitchloopend = pIns->PitchEnv.Ticks[pIns->PitchEnv.nLoopEnd]; - //IT compatibility 24. Short envelope loops - if (IsCompatibleMode(TRK_IMPULSETRACKER)) pitchloopend++; + if (GetType() != MOD_TYPE_XM) pitchloopend++; if (position >= pitchloopend) position = pIns->PitchEnv.Ticks[pIns->PitchEnv.nLoopStart]; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-26 00:31:54
|
Revision: 1197 http://modplug.svn.sourceforge.net/modplug/?rev=1197&view=rev Author: saga-games Date: 2012-02-26 00:31:46 +0000 (Sun, 26 Feb 2012) Log Message: ----------- [Fix] IT Compatibility: Envelope loop vs sustain loop checking priorities were wrong (http://schismtracker.org/scdev/res/1513.html). [Fix] IT Compatibility: Partly fixed envelope carry if an envelope ends with a looped point at volume 0 (test case Carry0Vol.it). [Ref] Unified envelope processing code. [Ref] Smaller related and unrelated changes. Modified Paths: -------------- trunk/OpenMPT/common/misc_util.h trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/soundlib/ModInstrument.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/common/misc_util.h =================================================================== --- trunk/OpenMPT/common/misc_util.h 2012-02-25 22:04:30 UTC (rev 1196) +++ trunk/OpenMPT/common/misc_util.h 2012-02-26 00:31:46 UTC (rev 1197) @@ -297,6 +297,7 @@ /// Returns value rounded to nearest integer. inline double Round(const double& val) {return std::floor(val + 0.5);} + inline float Round(const float& val) {return std::floor(val + 0.5f);} /// Rounds given double value to nearest integer value of type T. template <class T> inline T Round(const double& val) @@ -309,6 +310,15 @@ return intval; } + template <class T> inline T Round(const float& val) + { + static_assert(std::numeric_limits<T>::is_integer == true, "Type is a not an integer"); + static_assert(sizeof(T) <= 4, "Revise the implementation for integers > 32-bits."); + const float valRounded = Round(val); + ASSERT(valRounded >= (std::numeric_limits<T>::min)() && valRounded <= (std::numeric_limits<T>::max)()); + const T intval = static_cast<T>(valRounded); + return intval; + } }; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2012-02-25 22:04:30 UTC (rev 1196) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2012-02-26 00:31:46 UTC (rev 1197) @@ -1983,7 +1983,7 @@ if ((ch < GetChanFromCursor(m_findReplace.dwBeginSel)) || (ch > GetChanFromCursor(m_findReplace.dwEndSel))) bFound = false; if ((row < GetRowFromCursor(m_findReplace.dwBeginSel)) || (row > GetRowFromCursor(m_findReplace.dwEndSel))) bFound = false; } - if (((m_findReplace.dwFindFlags & PATSEARCH_NOTE) && ((m->note != m_findReplace.cmdFind.note) && ((m_findReplace.cmdFind.note != CFindReplaceTab::findAny) || (!m->note) || (m->note & 0x80)))) + if (((m_findReplace.dwFindFlags & PATSEARCH_NOTE) && ((m->note != m_findReplace.cmdFind.note) && ((m_findReplace.cmdFind.note != CFindReplaceTab::findAny) || !m->IsNote()))) || ((m_findReplace.dwFindFlags & PATSEARCH_INSTR) && (m->instr != m_findReplace.cmdFind.instr)) || ((m_findReplace.dwFindFlags & PATSEARCH_VOLCMD) && (m->volcmd != m_findReplace.cmdFind.volcmd)) || ((m_findReplace.dwFindFlags & PATSEARCH_VOLUME) && (m->vol != m_findReplace.cmdFind.vol)) Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-02-25 22:04:30 UTC (rev 1196) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-02-26 00:31:46 UTC (rev 1197) @@ -2408,21 +2408,21 @@ // similarly, 16383 (0x7F 0x7F) is to "bend as high as possible." // The exact range of the pitch bend is specific to the synthesizer. - // pre: 0 <= value <= 16383 + ASSERT(0 <= value && value <= 16383); - BYTE byte1 = static_cast<BYTE>(value >> 7); // get last 7 bytes only - BYTE byte2 = static_cast<BYTE>(value & 0x7F); // get first 7 bytes only - short converted = byte1<<8 | byte2; // merge + BYTE byte1 = static_cast<BYTE>(value >> 7); // get last 7 bits only + BYTE byte2 = static_cast<BYTE>(value & 0x7F); // get first 7 bits only + short converted = (byte1 << 8) | byte2; // merge return converted; } -//Bend midi pitch for given midi channel using tracker param (0x00-0xFF) +// Bend midi pitch for given midi channel using tracker param (0x00-0xFF) void CVstPlugin::MidiPitchBend(UINT nMidiCh, int nParam, UINT /*trackChannel*/) //----------------------------------------------------------------------------- { - const int16 increment = static_cast<int16>(nParam * 0x2000/0xFF); + const int16 increment = static_cast<int16>(nParam * 0x2000 / 0xFF); int16 newPitchBendPos = m_nMidiPitchBendPos[nMidiCh] + increment; Limit(newPitchBendPos, int16(MIDI_PitchBend_Min), int16(MIDI_PitchBend_Max)); Modified: trunk/OpenMPT/soundlib/ModInstrument.cpp =================================================================== --- trunk/OpenMPT/soundlib/ModInstrument.cpp 2012-02-25 22:04:30 UTC (rev 1196) +++ trunk/OpenMPT/soundlib/ModInstrument.cpp 2012-02-26 00:31:46 UTC (rev 1197) @@ -96,6 +96,7 @@ if (pt) { + // Get previous node's value and tick. value = static_cast<float>(Values[pt - 1]) / 64.0f; x1 = Ticks[pt - 1]; } @@ -107,7 +108,8 @@ value += ((position - x1) * (static_cast<float>(Values[pt]) / 64.0f - value)) / (x2 - x1); } } - return value; + + return Clamp(value, 0.0f, 1.0f); }; Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-25 22:04:30 UTC (rev 1196) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-26 00:31:46 UTC (rev 1197) @@ -703,7 +703,7 @@ || (IsCompatibleMode(TRK_IMPULSETRACKER) && instrumentChanged)) { pChn->dwFlags |= CHN_FASTVOLRAMP; - if ((GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!instrumentChanged) && (pIns) && (!(pChn->dwFlags & (CHN_KEYOFF|CHN_NOTEFADE)))) + if ((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (!instrumentChanged) && (pIns) && (!(pChn->dwFlags & (CHN_KEYOFF|CHN_NOTEFADE)))) { if (!(pIns->VolEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->VolEnv); if (!(pIns->PanEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->PanEnv); @@ -960,7 +960,7 @@ } } - if ((!bPorta) || ((!pChn->nLength) && (!(GetType() & MOD_TYPE_S3M)))) + if (!bPorta || (!pChn->nLength && !(GetType() & MOD_TYPE_S3M))) { pChn->pModSample = pSmp; pChn->pSample = pSmp->pSample; @@ -1057,9 +1057,11 @@ { // IT Compatiblity: NNA is reset on every note change, not every instrument change (fixes spx-farspacedance.it). if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nNNA = pIns->nNNA; - if (!(pIns->VolEnv.dwFlags & ENV_CARRY)) pChn->VolEnv.nEnvPosition = 0; - if (!(pIns->PanEnv.dwFlags & ENV_CARRY)) pChn->PanEnv.nEnvPosition = 0; - if (!(pIns->PitchEnv.dwFlags & ENV_CARRY)) pChn->PitchEnv.nEnvPosition = 0; + + if (!(pIns->VolEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->VolEnv); + if (!(pIns->PanEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->PanEnv); + if (!(pIns->PitchEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->PitchEnv); + if (GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) { // Volume Swing @@ -1186,8 +1188,10 @@ ModChannel *pChn = &Chn[nChn]; ModInstrument* pHeader = 0; LPSTR pSample; - if (note > 0x80) note = NOTE_NONE; - if (note < 1) return; + if(!ModCommand::IsNote(note)) + { + return; + } // Always NNA cut - using if ((!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_MT2))) || (!m_nInstruments) || (bForceCut)) { @@ -3946,7 +3950,7 @@ if (pSmp->uFlags & CHN_PINGPONGLOOP) pChn->dwFlags |= CHN_PINGPONGLOOP; else - pChn->dwFlags &= ~(CHN_PINGPONGLOOP|CHN_PINGPONGFLAG); + pChn->dwFlags &= ~(CHN_PINGPONGLOOP | CHN_PINGPONGFLAG); pChn->dwFlags |= CHN_LOOP; pChn->nLength = pSmp->nLength; pChn->nLoopStart = pSmp->nLoopStart; @@ -3959,7 +3963,7 @@ } } else { - pChn->dwFlags &= ~(CHN_LOOP|CHN_PINGPONGLOOP|CHN_PINGPONGFLAG); + pChn->dwFlags &= ~(CHN_LOOP | CHN_PINGPONGLOOP | CHN_PINGPONGFLAG); pChn->nLength = pSmp->nLength; } } @@ -3967,14 +3971,14 @@ if (pChn->pModInstrument) { const ModInstrument *pIns = pChn->pModInstrument; - if (((pIns->VolEnv.dwFlags & ENV_LOOP) || (GetType() & (MOD_TYPE_XM|MOD_TYPE_MT2))) && (pIns->nFadeOut)) + if (((pIns->VolEnv.dwFlags & ENV_LOOP) || (GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))) && (pIns->nFadeOut)) { pChn->dwFlags |= CHN_NOTEFADE; } if (pIns->VolEnv.nReleaseNode != ENV_RELEASE_NODE_UNSET) { - pChn->VolEnv.nEnvValueAtReleaseJump = GetVolEnvValueFromPosition(pChn->VolEnv.nEnvPosition, pIns->VolEnv); + pChn->VolEnv.nEnvValueAtReleaseJump = Util::Round<LONG>(pIns->VolEnv.GetValueFromPosition(pChn->VolEnv.nEnvPosition) * 256.0f); pChn->VolEnv.nEnvPosition = pIns->VolEnv.Ticks[pIns->VolEnv.nReleaseNode]; } Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-02-25 22:04:30 UTC (rev 1196) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-02-26 00:31:46 UTC (rev 1197) @@ -523,9 +523,8 @@ void ProcessPanningEnvelope(ModChannel *pChn); void ProcessPitchFilterEnvelope(ModChannel *pChn, int &period); - void IncrementVolumeEnvelopePosition(ModChannel *pChn); - void IncrementPanningEnvelopePosition(ModChannel *pChn); - void IncrementPitchFilterEnvelopePosition(ModChannel *pChn); + void IncrementEnvelopePosition(ModChannel *pChn, enmEnvelopeTypes envType); + void IncrementEnvelopePositions(ModChannel *pChn); void ProcessInstrumentFade(ModChannel *pChn, int &vol); @@ -708,7 +707,6 @@ bool ReadFixedLineLengthMessage(const BYTE *data, const size_t length, const size_t lineLength, const size_t lineEndingLength, void (*pTextConverter)(char &) = nullptr); public: - int GetVolEnvValueFromPosition(int position, const InstrumentEnvelope &env) const; void ResetChannelEnvelopes(ModChannel *pChn) const; void ResetChannelEnvelope(ModChannelEnvInfo &env) const; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-25 22:04:30 UTC (rev 1196) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-26 00:31:46 UTC (rev 1197) @@ -1091,7 +1091,8 @@ return; } const int envpos = pChn->VolEnv.nEnvPosition - (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); - int envvol = GetVolEnvValueFromPosition(envpos, pIns->VolEnv); + // Get values in [0, 256] + int envval = Util::Round<int>(pIns->VolEnv.GetValueFromPosition(envpos) * 256.0f); // if we are in the release portion of the envelope, // rescale envelope factor so that it is proportional to the release point @@ -1101,18 +1102,18 @@ && pChn->VolEnv.nEnvValueAtReleaseJump != NOT_YET_RELEASED) { int envValueAtReleaseJump = pChn->VolEnv.nEnvValueAtReleaseJump; - int envValueAtReleaseNode = pIns->VolEnv.Values[pIns->VolEnv.nReleaseNode] << 2; + int envValueAtReleaseNode = pIns->VolEnv.Values[pIns->VolEnv.nReleaseNode] * 4; //If we have just hit the release node, force the current env value //to be that of the release node. This works around the case where // we have another node at the same position as the release node. if (envpos == pIns->VolEnv.Ticks[pIns->VolEnv.nReleaseNode]) - envvol = envValueAtReleaseNode; + envval = envValueAtReleaseNode; - int relativeVolumeChange = (envvol - envValueAtReleaseNode) * 2; - envvol = envValueAtReleaseJump + relativeVolumeChange; + int relativeVolumeChange = (envval - envValueAtReleaseNode) * 2; + envval = envValueAtReleaseJump + relativeVolumeChange; } - vol = (vol * Clamp(envvol, 0, 512)) >> 8; + vol = (vol * Clamp(envval, 0, 512)) >> 8; } } @@ -1130,48 +1131,21 @@ // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. return; } + const int envpos = pChn->PanEnv.nEnvPosition - (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); + // Get values in [-32, 32] + const int envval = Util::Round<int>((pIns->PanEnv.GetValueFromPosition(envpos) - 0.5f) * 64.0f); - UINT pt = pIns->PanEnv.nNodes - 1; - for (UINT i = 0; i < (UINT)(pIns->PanEnv.nNodes - 1); i++) - { - if (envpos <= pIns->PanEnv.Ticks[i]) - { - pt = i; - break; - } - } - int x2 = pIns->PanEnv.Ticks[pt], y2 = pIns->PanEnv.Values[pt]; - int x1, envpan; - if (envpos >= x2) - { - envpan = y2; - x1 = x2; - } else if (pt) - { - envpan = pIns->PanEnv.Values[pt - 1]; - x1 = pIns->PanEnv.Ticks[pt - 1]; - } else - { - envpan = 128; - x1 = 0; - } - if ((x2 > x1) && (envpos > x1)) - { - envpan += ((envpos - x1) * (y2 - envpan)) / (x2 - x1); - } - - envpan = Clamp(envpan, 0, 64); int pan = pChn->nPan; - if (pan >= 128) + if(pan >= 128) { - pan += ((envpan - 32) * (256 - pan)) / 32; + pan += (envval * (256 - pan)) / 32; } else { - pan += ((envpan - 32) * (pan)) / 32; + pan += (envval * (pan)) / 32; } - pChn->nRealPan = Clamp(pan, 0, 256); + } } @@ -1188,55 +1162,25 @@ // If the envelope is disabled at the very same moment as it is triggered, we do not process anything. return; } - int envpos = pChn->PitchEnv.nEnvPosition - (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); - UINT pt = pIns->PitchEnv.nNodes - 1; - for (UINT i=0; i<(UINT)(pIns->PitchEnv.nNodes-1); i++) - { - if (envpos <= pIns->PitchEnv.Ticks[i]) - { - pt = i; - break; - } - } - int x2 = pIns->PitchEnv.Ticks[pt]; - int x1, envpitch; - if (envpos >= x2) - { - envpitch = (((int)pIns->PitchEnv.Values[pt]) - ENVELOPE_MID) * 8; - x1 = x2; - } else if (pt) - { - envpitch = (((int)pIns->PitchEnv.Values[pt-1]) - ENVELOPE_MID) * 8; - x1 = pIns->PitchEnv.Ticks[pt-1]; - } else - { - envpitch = 0; - x1 = 0; - } - if (envpos > x2) envpos = x2; - if ((x2 > x1) && (envpos > x1)) - { - int envpitchdest = (((int)pIns->PitchEnv.Values[pt]) - 32) * 8; - envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1); - } - Limit(envpitch, -256, 256); + const int envpos = pChn->PitchEnv.nEnvPosition - (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); + // Get values in [-256, 256] + const int envval = Util::Round<int>((pIns->PitchEnv.GetValueFromPosition(envpos) - 0.5f) * 512.0f); - //if (pIns->PitchEnv.dwFlags & ENV_FILTER) - if (pChn->PitchEnv.flags & ENV_FILTER) + if(pChn->PitchEnv.flags & ENV_FILTER) { // Filter Envelope: controls cutoff frequency #ifndef NO_FILTER - SetupChannelFilter(pChn, !(pChn->dwFlags & CHN_FILTER), envpitch); + SetupChannelFilter(pChn, !(pChn->dwFlags & CHN_FILTER), envval); #endif // NO_FILTER } else { // Pitch Envelope - if(m_nType == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning) + if(GetType() == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning) { - if(pChn->nFineTune != envpitch) + if(pChn->nFineTune != envval) { - pChn->nFineTune = envpitch; + pChn->nFineTune = envval; pChn->m_CalculateFreq = true; //Preliminary tests indicated that this behavior //is very close to original(with 12TET) when finestep count @@ -1245,15 +1189,15 @@ } else //Original behavior { - int l = envpitch; - if (l < 0) + int l = envval; + if(l < 0) { l = -l; - if (l > 255) l = 255; + LimitMax(l, 255); period = _muldiv(period, LinearSlideUpTable[l], 0x10000); } else { - if (l > 255) l = 255; + LimitMax(l, 255); period = _muldiv(period, LinearSlideDownTable[l], 0x10000); } } //End: Original behavior. @@ -1262,127 +1206,125 @@ } -void CSoundFile::IncrementVolumeEnvelopePosition(ModChannel *pChn) -//---------------------------------------------------------------- +void CSoundFile::IncrementEnvelopePosition(ModChannel *pChn, enmEnvelopeTypes envType) +//------------------------------------------------------------------------------------ { - const ModInstrument *pIns = pChn->pModInstrument; + ModChannelEnvInfo &chnEnv = pChn->GetEnvelope(envType); - if (pChn->VolEnv.flags & ENV_ENABLED) + if(pChn->pModInstrument == nullptr || !(chnEnv.flags & ENV_ENABLED)) { - // Increase position - UINT position = pChn->VolEnv.nEnvPosition + (IsCompatibleMode(TRK_IMPULSETRACKER) ? 0 : 1); - // Volume Loop ? - if (pIns->VolEnv.dwFlags & ENV_LOOP) + return; + } + + // Increase position + UINT position = chnEnv.nEnvPosition + (IsCompatibleMode(TRK_IMPULSETRACKER) ? 0 : 1); + + const InstrumentEnvelope &insEnv = pChn->pModInstrument->GetEnvelope(envType); + + bool endReached = false; + + if(!IsCompatibleMode(TRK_IMPULSETRACKER)) + { + // FT2-style envelope processing. + if(insEnv.dwFlags & ENV_LOOP) { - UINT volloopend = pIns->VolEnv.Ticks[pIns->VolEnv.nLoopEnd]; - if (GetType() != MOD_TYPE_XM) volloopend++; - if (position == volloopend) + // Normal loop active + UINT end = insEnv.Ticks[insEnv.nLoopEnd]; + if(GetType() != MOD_TYPE_XM) end++; + if(position == end) { - position = pIns->VolEnv.Ticks[pIns->VolEnv.nLoopStart]; - if ((pIns->VolEnv.nLoopEnd == pIns->VolEnv.nLoopStart) && (!pIns->VolEnv.Values[pIns->VolEnv.nLoopStart]) - && ((!(GetType() & MOD_TYPE_XM)) || (pIns->VolEnv.nLoopEnd+1 == (int)pIns->VolEnv.nNodes))) + position = insEnv.Ticks[insEnv.nLoopStart]; + + if(envType == ENV_VOLUME && insEnv.nLoopStart == insEnv.nLoopEnd && insEnv.Values[insEnv.nLoopEnd] == 0 + && (!(GetType() & MOD_TYPE_XM) || (insEnv.nLoopEnd + 1u == insEnv.nNodes))) { pChn->dwFlags |= CHN_NOTEFADE; pChn->nFadeOutVol = 0; } } } - // Volume Sustain ? - if ((pIns->VolEnv.dwFlags & ENV_SUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF))) + + if((insEnv.dwFlags & ENV_SUSTAIN) && !(pChn->dwFlags & CHN_KEYOFF)) { - if (position == (UINT)pIns->VolEnv.Ticks[pIns->VolEnv.nSustainEnd] + 1) - position = pIns->VolEnv.Ticks[pIns->VolEnv.nSustainStart]; + // Envelope sustained + if(position == insEnv.Ticks[insEnv.nSustainEnd] + 1u) + { + position = insEnv.Ticks[insEnv.nSustainStart]; + } } else { - // End of Envelope ? - if (position > pIns->VolEnv.Ticks[pIns->VolEnv.nNodes - 1]) + // Limit to last envelope point + if(position > insEnv.Ticks[insEnv.nNodes - 1]) { - if ((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) || (pChn->dwFlags & CHN_KEYOFF)) pChn->dwFlags |= CHN_NOTEFADE; - position = pIns->VolEnv.Ticks[pIns->VolEnv.nNodes - 1]; - if ((!pIns->VolEnv.Values[pIns->VolEnv.nNodes - 1]) && ((pChn->nMasterChn > 0) || (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)))) - { - pChn->dwFlags |= CHN_NOTEFADE; - pChn->nFadeOutVol = 0; - pChn->nRealVolume = 0; - pChn->nCalcVolume = 0; - } + // Env of envelope + position = insEnv.Ticks[insEnv.nNodes - 1]; + endReached = true; } } - - pChn->VolEnv.nEnvPosition = position + (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); - } -} - - -void CSoundFile::IncrementPanningEnvelopePosition(ModChannel *pChn) -//----------------------------------------------------------------- -{ - const ModInstrument *pIns = pChn->pModInstrument; - - if (pChn->PanEnv.flags & ENV_ENABLED) + } else { - // Increase position - UINT position = pChn->PanEnv.nEnvPosition + (IsCompatibleMode(TRK_IMPULSETRACKER) ? 0 : 1); + // IT envelope processing. + // Test case: EnvLoops.it + UINT start, end; - if (pIns->PanEnv.dwFlags & ENV_LOOP) + if((insEnv.dwFlags & ENV_SUSTAIN) && !(pChn->dwFlags & CHN_KEYOFF)) { - UINT panloopend = pIns->PanEnv.Ticks[pIns->PanEnv.nLoopEnd]; - if (GetType() != MOD_TYPE_XM) panloopend++; - if (position == panloopend) - position = pIns->PanEnv.Ticks[pIns->PanEnv.nLoopStart]; - } - - // Panning Sustain ? - if ((pIns->PanEnv.dwFlags & ENV_SUSTAIN) && (position == (UINT)pIns->PanEnv.Ticks[pIns->PanEnv.nSustainEnd] + 1) - && (!(pChn->dwFlags & CHN_KEYOFF))) + // Envelope sustained + start = insEnv.Ticks[insEnv.nSustainStart]; + end = insEnv.Ticks[insEnv.nSustainEnd] + 1; + } else if((insEnv.dwFlags & ENV_LOOP)) { - // Panning sustained - position = pIns->PanEnv.Ticks[pIns->PanEnv.nSustainStart]; + // Normal loop active + start = insEnv.Ticks[insEnv.nLoopStart]; + end = insEnv.Ticks[insEnv.nLoopEnd] + 1; } else { - if (position > pIns->PanEnv.Ticks[pIns->PanEnv.nNodes - 1]) - position = pIns->PanEnv.Ticks[pIns->PanEnv.nNodes - 1]; + // Limit to last envelope point + start = end = insEnv.Ticks[insEnv.nNodes - 1]; + if (position > end) + { + // Env of envelope + endReached = true; + } } - pChn->PanEnv.nEnvPosition = position + (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); + if(position >= end) + { + position = start; + } } -} - -void CSoundFile::IncrementPitchFilterEnvelopePosition(ModChannel *pChn) -//--------------------------------------------------------------------- -{ - const ModInstrument *pIns = pChn->pModInstrument; - - if (pChn->PitchEnv.flags & ENV_ENABLED) + if(envType == ENV_VOLUME && endReached) { - // Increase position - UINT position = pChn->PitchEnv.nEnvPosition + (IsCompatibleMode(TRK_IMPULSETRACKER) ? 0 : 1); - - // Pitch Loop ? - if (pIns->PitchEnv.dwFlags & ENV_LOOP) + // Special handling for volume envelopes at end of envelope + if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) || (pChn->dwFlags & CHN_KEYOFF)) { - UINT pitchloopend = pIns->PitchEnv.Ticks[pIns->PitchEnv.nLoopEnd]; - if (GetType() != MOD_TYPE_XM) pitchloopend++; - if (position >= pitchloopend) - position = pIns->PitchEnv.Ticks[pIns->PitchEnv.nLoopStart]; + pChn->dwFlags |= CHN_NOTEFADE; } - // Pitch Sustain ? - if ((pIns->PitchEnv.dwFlags & ENV_SUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF))) + + if(insEnv.Values[insEnv.nNodes - 1] == 0 && (pChn->nMasterChn > 0 || (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)))) { - if (position == (UINT)pIns->PitchEnv.Ticks[pIns->PitchEnv.nSustainEnd]+1) - position = pIns->PitchEnv.Ticks[pIns->PitchEnv.nSustainStart]; - } else - { - if (position > pIns->PitchEnv.Ticks[pIns->PitchEnv.nNodes - 1]) - position = pIns->PitchEnv.Ticks[pIns->PitchEnv.nNodes - 1]; + pChn->dwFlags |= CHN_NOTEFADE; + pChn->nFadeOutVol = 0; + pChn->nRealVolume = 0; + pChn->nCalcVolume = 0; } - - pChn->PitchEnv.nEnvPosition = position + (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); } + + chnEnv.nEnvPosition = position + (IsCompatibleMode(TRK_IMPULSETRACKER) ? 1 : 0); + } +void CSoundFile::IncrementEnvelopePositions(ModChannel *pChn) +//----------------------------------------------------------- +{ + IncrementEnvelopePosition(pChn, ENV_VOLUME); + IncrementEnvelopePosition(pChn, ENV_PANNING); + IncrementEnvelopePosition(pChn, ENV_PITCH); +} + + void CSoundFile::ProcessInstrumentFade(ModChannel *pChn, int &vol) //---------------------------------------------------------------- { @@ -2035,9 +1977,7 @@ // When using MPT behaviour, we get the envelope position for the next tick while we are still calculating the current tick, // which then results in wrong position information when the envelope is paused on the next row. // Test case: s77.it - IncrementVolumeEnvelopePosition(pChn); - IncrementPanningEnvelopePosition(pChn); - IncrementPitchFilterEnvelopePosition(pChn); + IncrementEnvelopePositions(pChn); } ProcessVolumeEnvelope(pChn, vol); ProcessInstrumentFade(pChn, vol); @@ -2188,9 +2128,7 @@ { // In IT compatible mode, envelope positions are updated above. // Test case: s77.it - IncrementVolumeEnvelopePosition(pChn); - IncrementPanningEnvelopePosition(pChn); - IncrementPitchFilterEnvelopePosition(pChn); + IncrementEnvelopePositions(pChn); } #ifdef MODPLUG_PLAYER @@ -2533,53 +2471,9 @@ } } +#endif // MODPLUG_TRACKER -int CSoundFile::GetVolEnvValueFromPosition(int position, const InstrumentEnvelope &env) const -//------------------------------------------------------------------------------------------- -{ - UINT pt = env.nNodes - 1; - // Checking where current 'tick' is relative to the - // envelope points. - for (UINT i = 0; i < (UINT)(env.nNodes-1); i++) - { - if (position <= env.Ticks[i]) - { - pt = i; - break; - } - } - - int x2 = env.Ticks[pt]; - int x1, envvol; - if (position >= x2) // Case: current 'tick' is on a envelope point. - { - envvol = env.Values[pt] * 4; - } else // Case: current 'tick' is between two envelope points. - { - if (pt) - { - envvol = env.Values[pt - 1] * 4; - x1 = env.Ticks[pt - 1]; - } else - { - envvol = 0; - x1 = 0; - } - - if(x2 > x1 && position > x1) - { - // Linear approximation between the points; - // f(x+d) ~ f(x) + f'(x)*d, where f'(x) = (y2-y1)/(x2-x1) - envvol += ((position - x1) * (((int)env.Values[pt] * 4) - envvol)) / (x2 - x1); - } - } - return envvol; -} - -#endif - - void CSoundFile::ApplyGlobalVolume(int SoundBuffer[], int RearBuffer[], long lTotalSampleCount) //--------------------------------------------------------------------------------------------- { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-26 17:38:26
|
Revision: 1198 http://modplug.svn.sourceforge.net/modplug/?rev=1198&view=rev Author: saga-games Date: 2012-02-26 17:38:19 +0000 (Sun, 26 Feb 2012) Log Message: ----------- [Fix] S3M / MOD: Amiga limits are now enfored on the stored period, not only the computed period. [Ref] Moved some more stuff around to more appropriate places. [Mod] OpenMPT: Version is now 1.20.00.72 Modified Paths: -------------- trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/ModChannel.h trunk/OpenMPT/soundlib/ModInstrument.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-02-26 00:31:46 UTC (rev 1197) +++ trunk/OpenMPT/mptrack/version.h 2012-02-26 17:38:19 UTC (rev 1198) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 71 +#define VER_MINORMINOR 72 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Modified: trunk/OpenMPT/soundlib/ModChannel.h =================================================================== --- trunk/OpenMPT/soundlib/ModChannel.h 2012-02-26 00:31:46 UTC (rev 1197) +++ trunk/OpenMPT/soundlib/ModChannel.h 2012-02-26 17:38:19 UTC (rev 1198) @@ -16,6 +16,12 @@ DWORD nEnvPosition; DWORD flags; LONG nEnvValueAtReleaseJump; + + void Reset() + { + nEnvPosition = 0; + nEnvValueAtReleaseJump = NOT_YET_RELEASED; + } }; Modified: trunk/OpenMPT/soundlib/ModInstrument.cpp =================================================================== --- trunk/OpenMPT/soundlib/ModInstrument.cpp 2012-02-26 00:31:46 UTC (rev 1197) +++ trunk/OpenMPT/soundlib/ModInstrument.cpp 2012-02-26 17:38:19 UTC (rev 1198) @@ -49,18 +49,17 @@ Ticks[node + 1] = Ticks[node]; Values[node + 1] = Values[node]; } + + nNodes++; } Ticks[nLoopEnd]--; - Values[nLoopEnd] = (BYTE)interpolatedValue; - - nNodes++; + Values[nLoopEnd] = interpolatedValue; } else { - // There is already a point before the loop point: Use it as loop end. + // There is already a point before the loop point: Use it as new loop end. nLoopEnd--; } - } } }; @@ -104,7 +103,7 @@ if(x2 > x1 && position > x1) { // Linear approximation between the points; - // f(x+d) ~ f(x) + f'(x)*d, where f'(x) = (y2-y1) / (x2-x1) + // f(x + d) ~ f(x) + f'(x) * d, where f'(x) = (y2 - y1) / (x2 - x1) value += ((position - x1) * (static_cast<float>(Values[pt]) / 64.0f - value)) / (x2 - x1); } } Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-26 00:31:46 UTC (rev 1197) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-02-26 17:38:19 UTC (rev 1198) @@ -705,9 +705,9 @@ pChn->dwFlags |= CHN_FASTVOLRAMP; if ((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (!instrumentChanged) && (pIns) && (!(pChn->dwFlags & (CHN_KEYOFF|CHN_NOTEFADE)))) { - if (!(pIns->VolEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->VolEnv); - if (!(pIns->PanEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->PanEnv); - if (!(pIns->PitchEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->PitchEnv); + if (!(pIns->VolEnv.dwFlags & ENV_CARRY)) pChn->VolEnv.Reset(); + if (!(pIns->PanEnv.dwFlags & ENV_CARRY)) pChn->PanEnv.Reset(); + if (!(pIns->PitchEnv.dwFlags & ENV_CARRY)) pChn->PitchEnv.Reset(); } else { ResetChannelEnvelopes(pChn); @@ -722,7 +722,7 @@ { if(IsCompatibleMode(TRK_IMPULSETRACKER)) { - ResetChannelEnvelope(pChn->VolEnv); + pChn->VolEnv.Reset(); } else { ResetChannelEnvelopes(pChn); @@ -1058,9 +1058,9 @@ // IT Compatiblity: NNA is reset on every note change, not every instrument change (fixes spx-farspacedance.it). if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nNNA = pIns->nNNA; - if (!(pIns->VolEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->VolEnv); - if (!(pIns->PanEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->PanEnv); - if (!(pIns->PitchEnv.dwFlags & ENV_CARRY)) ResetChannelEnvelope(pChn->PitchEnv); + if (!(pIns->VolEnv.dwFlags & ENV_CARRY)) pChn->VolEnv.Reset(); + if (!(pIns->PanEnv.dwFlags & ENV_CARRY)) pChn->PanEnv.Reset(); + if (!(pIns->PitchEnv.dwFlags & ENV_CARRY)) pChn->PitchEnv.Reset(); if (GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) { @@ -2373,20 +2373,12 @@ void CSoundFile::ResetChannelEnvelopes(ModChannel *pChn) const //------------------------------------------------------------ { - ResetChannelEnvelope(pChn->VolEnv); - ResetChannelEnvelope(pChn->PanEnv); - ResetChannelEnvelope(pChn->PitchEnv); + pChn->VolEnv.Reset(); + pChn->PanEnv.Reset(); + pChn->PitchEnv.Reset(); } -void CSoundFile::ResetChannelEnvelope(ModChannelEnvInfo &env) const -//------------------------------------------------------------------ -{ - env.nEnvPosition = 0; - env.nEnvValueAtReleaseJump = NOT_YET_RELEASED; -} - - //////////////////////////////////////////////////////////// // Channels effects Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2012-02-26 00:31:46 UTC (rev 1197) +++ trunk/OpenMPT/soundlib/Sndfile.h 2012-02-26 17:38:19 UTC (rev 1198) @@ -708,7 +708,6 @@ public: void ResetChannelEnvelopes(ModChannel *pChn) const; - void ResetChannelEnvelope(ModChannelEnvInfo &env) const; private: PLUGINDEX __cdecl GetChannelPlugin(CHANNELINDEX nChn, PluginMutePriority respectMutes) const; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-26 00:31:46 UTC (rev 1197) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2012-02-26 17:38:19 UTC (rev 1198) @@ -925,6 +925,7 @@ case 1: // IT compatibility: IT has its own, more precise tables + // XXX ModRampDownTable should be negated for XM *Vibrato* (not for Tremolo, though!) return IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[position] : ModRampDownTable[position]; case 2: @@ -1238,6 +1239,7 @@ if(envType == ENV_VOLUME && insEnv.nLoopStart == insEnv.nLoopEnd && insEnv.Values[insEnv.nLoopEnd] == 0 && (!(GetType() & MOD_TYPE_XM) || (insEnv.nLoopEnd + 1u == insEnv.nNodes))) { + // Stop channel if the envelope loop only covers the last silent envelope point. pChn->dwFlags |= CHN_NOTEFADE; pChn->nFadeOutVol = 0; } @@ -1304,6 +1306,7 @@ if(insEnv.Values[insEnv.nNodes - 1] == 0 && (pChn->nMasterChn > 0 || (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)))) { + // Stop channel if the last envelope node is silent anyway. pChn->dwFlags |= CHN_NOTEFADE; pChn->nFadeOutVol = 0; pChn->nRealVolume = 0; @@ -1394,6 +1397,7 @@ #ifndef NO_VST #if 0 // EXPERIMENTAL VSTi arpeggio. Far from perfect! + // Note: We could use pChn->nLastNote here to simplify things. if(pChn->pModInstrument && pChn->pModInstrument->nMixPlug && !(m_dwSongFlags & SONG_FIRSTTICK)) { const ModInstrument *pIns = pChn->pModInstrument; @@ -1430,7 +1434,7 @@ #endif // 0 #endif // NO_VST - if((m_nType & MOD_TYPE_MPT) && pChn->pModInstrument && pChn->pModInstrument->pTuning) + if((GetType() & MOD_TYPE_MPT) && pChn->pModInstrument && pChn->pModInstrument->pTuning) { switch(m_nTickCount % 3) { @@ -1478,8 +1482,8 @@ } } - if (note > 109 && arpPos != 0) - note = 109; // FT2's note limit + if (note > 108 + NOTE_MIN && arpPos != 0) + note = 108 + NOTE_MIN; // FT2's note limit period = GetPeriodFromNote(note, pChn->nFineTune, pChn->nC5Speed); @@ -2023,7 +2027,7 @@ if (pChn->nPeriod < m_nMinPeriod) pChn->nPeriod = m_nMinPeriod; period = pChn->nPeriod; // TODO Glissando effect is reset after portamento! What would this sound like without the CHN_PORTAMENTO flag? - if ((pChn->dwFlags & (CHN_GLISSANDO|CHN_PORTAMENTO)) == (CHN_GLISSANDO|CHN_PORTAMENTO)) + if ((pChn->dwFlags & (CHN_GLISSANDO | CHN_PORTAMENTO)) == (CHN_GLISSANDO | CHN_PORTAMENTO)) { period = GetPeriodFromNote(GetNoteFromPeriod(period), pChn->nFineTune, pChn->nC5Speed); } @@ -2031,9 +2035,11 @@ ProcessArpeggio(pChn, period, arpeggioSteps); // Preserve Amiga freq limits - if (m_dwSongFlags & (SONG_AMIGALIMITS|SONG_PT1XMODE)) + // Test case: AmigaLimits.s3m + if (m_dwSongFlags & (SONG_AMIGALIMITS | SONG_PT1XMODE)) { Limit(period, 113 * 4, 856 * 4); + Limit(pChn->nPeriod, 113 * 4, 856 * 4); } ProcessPanbrello(pChn); @@ -2062,6 +2068,8 @@ // Final Period if (period <= m_nMinPeriod) { + // ST3 simply stops playback if frequency is too high. + // Test case: FreqLimits.s3m if (GetType() & MOD_TYPE_S3M) pChn->nLength = 0; period = m_nMinPeriod; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-02-27 22:28:21
|
Revision: 1199 http://modplug.svn.sourceforge.net/modplug/?rev=1199&view=rev Author: saga-games Date: 2012-02-27 22:28:11 +0000 (Mon, 27 Feb 2012) Log Message: ----------- [Imp] Instrument tab: Random variation sliders have tooltips with actual swing variation now. [Fix] Song Properties: When converting to a format which doesn't support as few channels as the current format, the channel box isn't defaulted to an empty value anymore. Modified Paths: -------------- trunk/OpenMPT/README trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/mptrack.rc Removed Paths: ------------- trunk/OpenMPT/soundtouch/3dnow_win.cpp Modified: trunk/OpenMPT/README =================================================================== --- trunk/OpenMPT/README 2012-02-26 17:38:19 UTC (rev 1198) +++ trunk/OpenMPT/README 2012-02-27 22:28:11 UTC (rev 1199) @@ -66,8 +66,8 @@ - Get rid of globals (many globals creeped up over time, mostly because of the hack to allow simultaneous playback of 2 songs in Modplug Player -> ReadMix()). This is a major problem for writing a DShow source filter, or any other COM -object (A DShow source would allow playback of MOD files in WMP, which would be much easier than -rewriting a different player). +object (A DShow source would allow playback of MOD files in WMP, which would be +much easier than rewriting a different player). - The MPT UI code is MFC-based, and I would say is fairly clean (as a rough rule, the more recent the code is, the cleaner it is), though the UI code is tightly integrated with the implementation (this could make it somewhat more Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-02-26 17:38:19 UTC (rev 1198) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-02-27 22:28:11 UTC (rev 1199) @@ -1557,6 +1557,8 @@ //Note2: If there's problems in getting tooltips showing for certain tools, // setting the tab order may have effect. const bool hasInstrument = (m_pSndFile) && (m_pSndFile->Instruments[m_nInstrument]); + ModInstrument *pIns = m_pSndFile->Instruments[m_nInstrument]; + if(!hasInstrument) return FALSE; if ((pszText) && (uId)) { @@ -1581,7 +1583,7 @@ case IDC_PLUGIN_VELOCITYSTYLE: case IDC_PLUGIN_VOLUMESTYLE: // Plugin volume handling - if(m_pSndFile->Instruments[m_nInstrument]->nMixPlug < 1) return FALSE; + if(pIns->nMixPlug < 1) return FALSE; if(m_pSndFile->GetModFlag(MSF_MIDICC_BUGEMULATION)) { m_CbnPluginVelocityHandling.EnableWindow(FALSE); @@ -1597,6 +1599,22 @@ strcpy(pszText, "Mapped: MIDI channel corresponds to pattern channel modulo 16"); return TRUE; + case IDC_SLIDER1: + wsprintf(pszText, "\xB1%d%% volume variation", pIns->nVolSwing); + return TRUE; + + case IDC_SLIDER2: + wsprintf(pszText, "\xB1%d panning variation", pIns->nPanSwing); + return TRUE; + + case IDC_SLIDER6: + wsprintf(pszText, "\xB1%d cutoff variation", pIns->nCutSwing); + return TRUE; + + case IDC_SLIDER7: + wsprintf(pszText, "\xB1%d resonance variation", pIns->nResSwing); + return TRUE; + } } return FALSE; Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2012-02-26 17:38:19 UTC (rev 1198) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2012-02-27 22:28:11 UTC (rev 1199) @@ -172,25 +172,24 @@ CHANNELINDEX currChanSel = m_ChannelsBox.GetItemData(m_ChannelsBox.GetCurSel()); const CHANNELINDEX minChans = CSoundFile::GetModSpecifications(type).channelsMin; const CHANNELINDEX maxChans = CSoundFile::GetModSpecifications(type).channelsMax; + if(m_ChannelsBox.GetCount() < 1 - || - m_ChannelsBox.GetItemData(0) != minChans - || - m_ChannelsBox.GetItemData(m_ChannelsBox.GetCount()-1) != maxChans - ) + || m_ChannelsBox.GetItemData(0) != minChans + || m_ChannelsBox.GetItemData(m_ChannelsBox.GetCount() - 1) != maxChans) { + // Update channel list if number of supported channels has changed. if(m_ChannelsBox.GetCount() < 1) currChanSel = m_nChannels; - char s[256]; m_ChannelsBox.ResetContent(); - for (CHANNELINDEX i=minChans; i<=maxChans; i++) + + CString s; + for(CHANNELINDEX i = minChans; i <= maxChans; i++) { - wsprintf(s, "%d Channel%s", i, (i != 1) ? "s" : ""); + s.Format("%d Channel%s", i, (i != 1) ? "s" : ""); m_ChannelsBox.SetItemData(m_ChannelsBox.AddString(s), i); } - if(currChanSel > maxChans) - m_ChannelsBox.SetCurSel(m_ChannelsBox.GetCount()-1); - else - m_ChannelsBox.SetCurSel(currChanSel-minChans); + + Limit(currChanSel, minChans, maxChans); + m_ChannelsBox.SetCurSel(currChanSel - minChans); } } @@ -302,7 +301,7 @@ if (sel > maxChans) { CString error; - error.Format("Error: Max number of channels for this type is %d", maxChans); + error.Format("Error: Maximum number of channels for this module type is %d.", maxChans); Reporting::Warning(error); return FALSE; } Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2012-02-26 17:38:19 UTC (rev 1198) +++ trunk/OpenMPT/mptrack/mptrack.rc 2012-02-27 22:28:11 UTC (rev 1199) @@ -768,10 +768,10 @@ CONTROL "Cutoff",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,136,52,35,10 CONTROL "Slider2",IDC_SLIDER3,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_DISABLED | WS_TABSTOP,168,53,64,10 COMBOBOX IDC_FILTERMODE,163,70,69,42,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,172,101,60,10 - CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,172,118,60,10 - CONTROL "",IDC_SLIDER6,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,172,135,60,10 - CONTROL "",IDC_SLIDER7,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,172,152,60,10 + CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | TBS_TOOLTIPS | WS_TABSTOP,172,101,60,10 + CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | TBS_TOOLTIPS | WS_TABSTOP,172,118,60,10 + CONTROL "",IDC_SLIDER6,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | TBS_TOOLTIPS | WS_TABSTOP,172,135,60,10 + CONTROL "",IDC_SLIDER7,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | TBS_TOOLTIPS | WS_TABSTOP,172,152,60,10 COMBOBOX IDC_COMBO1,308,36,50,54,CBS_DROPDOWNLIST | WS_TABSTOP COMBOBOX IDC_COMBO2,308,53,50,69,CBS_DROPDOWNLIST | WS_TABSTOP COMBOBOX IDC_COMBO3,308,70,50,54,CBS_DROPDOWNLIST | WS_TABSTOP Deleted: trunk/OpenMPT/soundtouch/3dnow_win.cpp =================================================================== --- trunk/OpenMPT/soundtouch/3dnow_win.cpp 2012-02-26 17:38:19 UTC (rev 1198) +++ trunk/OpenMPT/soundtouch/3dnow_win.cpp 2012-02-27 22:28:11 UTC (rev 1199) @@ -1,349 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -/// -/// Win32 version of the AMD 3DNow! optimized routines for AMD K6-2/Athlon -/// processors. All 3DNow! optimized functions have been gathered into this -/// single source code file, regardless to their class or original source code -/// file, in order to ease porting the library to other compiler and processor -/// platforms. -/// -/// By the way; the performance gain depends heavily on the CPU generation: On -/// K6-2 these routines provided speed-up of even 2.4 times, while on Athlon the -/// difference to the original routines stayed at unremarkable 8%! Such a small -/// improvement on Athlon is due to 3DNow can perform only two operations in -/// parallel, and obviously also the Athlon FPU is doing a very good job with -/// the standard C floating point routines! Here these routines are anyway, -/// although it might not be worth the effort to convert these to GCC platform, -/// for Athlon CPU at least. The situation is different regarding the SSE -/// optimizations though, thanks to the four parallel operations of SSE that -/// already make a difference. -/// -/// This file is to be compiled in Windows platform with Microsoft Visual C++ -/// Compiler. Please see '3dnow_gcc.cpp' for the gcc compiler version for all -/// GNU platforms (if file supplied). -/// -/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++ -/// 6.0 processor pack" update to support 3DNow! instruction set. The update is -/// available for download at Microsoft Developers Network, see here: -/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx -/// -/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and -/// perform a search with keywords "processor pack". -/// -/// Author : Copyright (c) Olli Parviainen -/// Author e-mail : oparviai 'at' iki.fi -/// SoundTouch WWW: http://www.surina.net/soundtouch -/// -//////////////////////////////////////////////////////////////////////////////// -// -// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $ -// File revision : $Revision: 4 $ -// -// $Id: 3dnow_win.cpp 63 2009-02-21 16:00:14Z oparviai $ -// -//////////////////////////////////////////////////////////////////////////////// -// -// License : -// -// SoundTouch audio processing library -// Copyright (c) Olli Parviainen -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -//////////////////////////////////////////////////////////////////////////////// - -#include "cpu_detect.h" -#include "STTypes.h" - -#ifndef WIN32 -#error "wrong platform - this source code file is exclusively for Win32 platform" -#endif - -using namespace soundtouch; - -#ifdef ALLOW_3DNOW -// 3DNow! routines available only with float sample type - -////////////////////////////////////////////////////////////////////////////// -// -// implementation of 3DNow! optimized functions of class 'TDStretch3DNow' -// -////////////////////////////////////////////////////////////////////////////// - -#include "TDStretch.h" - - -// Calculates cross correlation of two buffers -double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) const -{ - int overlapLengthLocal = overlapLength; - float corr = 0; - - // Calculates the cross-correlation value between 'pV1' and 'pV2' vectors - /* - c-pseudocode: - - corr = 0; - for (i = 0; i < overlapLength / 4; i ++) - { - corr += pV1[0] * pV2[0]; - pV1[1] * pV2[1]; - pV1[2] * pV2[2]; - pV1[3] * pV2[3]; - pV1[4] * pV2[4]; - pV1[5] * pV2[5]; - pV1[6] * pV2[6]; - pV1[7] * pV2[7]; - - pV1 += 8; - pV2 += 8; - } - */ - - _asm - { - // give prefetch hints to CPU of what data are to be needed soonish. - // give more aggressive hints on pV1 as that changes more between different calls - // while pV2 stays the same. - prefetch [pV1] - prefetch [pV2] - prefetch [pV1 + 32] - - mov eax, dword ptr pV2 - mov ebx, dword ptr pV1 - - pxor mm0, mm0 - - mov ecx, overlapLengthLocal - shr ecx, 2 // div by four - - loop1: - movq mm1, [eax] - prefetch [eax + 32] // give a prefetch hint to CPU what data are to be needed soonish - pfmul mm1, [ebx] - prefetch [ebx + 64] // give a prefetch hint to CPU what data are to be needed soonish - - movq mm2, [eax + 8] - pfadd mm0, mm1 - pfmul mm2, [ebx + 8] - - movq mm3, [eax + 16] - pfadd mm0, mm2 - pfmul mm3, [ebx + 16] - - movq mm4, [eax + 24] - pfadd mm0, mm3 - pfmul mm4, [ebx + 24] - - add eax, 32 - pfadd mm0, mm4 - add ebx, 32 - - dec ecx - jnz loop1 - - // add halfs of mm0 together and return the result. - // note: mm1 is used as a dummy parameter only, we actually don't care about it's value - pfacc mm0, mm1 - movd corr, mm0 - femms - } - - return corr; -} - - - - -////////////////////////////////////////////////////////////////////////////// -// -// implementation of 3DNow! optimized functions of class 'FIRFilter' -// -////////////////////////////////////////////////////////////////////////////// - -#include "FIRFilter.h" - -FIRFilter3DNow::FIRFilter3DNow() : FIRFilter() -{ - filterCoeffsUnalign = NULL; - filterCoeffsAlign = NULL; -} - - -FIRFilter3DNow::~FIRFilter3DNow() -{ - delete[] filterCoeffsUnalign; - filterCoeffsUnalign = NULL; - filterCoeffsAlign = NULL; -} - - -// (overloaded) Calculates filter coefficients for 3DNow! routine -void FIRFilter3DNow::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor) -{ - uint i; - float fDivider; - - FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor); - - // Scale the filter coefficients so that it won't be necessary to scale the filtering result - // also rearrange coefficients suitably for 3DNow! - // Ensure that filter coeffs array is aligned to 16-byte boundary - delete[] filterCoeffsUnalign; - filterCoeffsUnalign = new float[2 * newLength + 4]; - filterCoeffsAlign = (float *)(((uint)filterCoeffsUnalign + 15) & (uint)-16); - - fDivider = (float)resultDivider; - - // rearrange the filter coefficients for mmx routines - for (i = 0; i < newLength; i ++) - { - filterCoeffsAlign[2 * i + 0] = - filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider; - } -} - - -// 3DNow!-optimized version of the filter routine for stereo sound -uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, uint numSamples) const -{ - float *filterCoeffsLocal = filterCoeffsAlign; - uint count = (numSamples - length) & (uint)-2; - uint lengthLocal = length / 4; - - assert(length != 0); - assert(count % 2 == 0); - - /* original code: - - double suml1, suml2; - double sumr1, sumr2; - uint i, j; - - for (j = 0; j < count; j += 2) - { - const float *ptr; - - suml1 = sumr1 = 0.0; - suml2 = sumr2 = 0.0; - ptr = src; - filterCoeffsLocal = filterCoeffs; - for (i = 0; i < lengthLocal; i ++) - { - // unroll loop for efficiency. - - suml1 += ptr[0] * filterCoeffsLocal[0] + - ptr[2] * filterCoeffsLocal[2] + - ptr[4] * filterCoeffsLocal[4] + - ptr[6] * filterCoeffsLocal[6]; - - sumr1 += ptr[1] * filterCoeffsLocal[1] + - ptr[3] * filterCoeffsLocal[3] + - ptr[5] * filterCoeffsLocal[5] + - ptr[7] * filterCoeffsLocal[7]; - - suml2 += ptr[8] * filterCoeffsLocal[0] + - ptr[10] * filterCoeffsLocal[2] + - ptr[12] * filterCoeffsLocal[4] + - ptr[14] * filterCoeffsLocal[6]; - - sumr2 += ptr[9] * filterCoeffsLocal[1] + - ptr[11] * filterCoeffsLocal[3] + - ptr[13] * filterCoeffsLocal[5] + - ptr[15] * filterCoeffsLocal[7]; - - ptr += 16; - filterCoeffsLocal += 8; - } - dest[0] = (float)suml1; - dest[1] = (float)sumr1; - dest[2] = (float)suml2; - dest[3] = (float)sumr2; - - src += 4; - dest += 4; - } - - */ - _asm - { - mov eax, dword ptr dest - mov ebx, dword ptr src - mov edx, count - shr edx, 1 - - loop1: - // "outer loop" : during each round 2*2 output samples are calculated - prefetch [ebx] // give a prefetch hint to CPU what data are to be needed soonish - prefetch [filterCoeffsLocal] // give a prefetch hint to CPU what data are to be needed soonish - - mov esi, ebx - mov edi, filterCoeffsLocal - pxor mm0, mm0 - pxor mm1, mm1 - mov ecx, lengthLocal - - loop2: - // "inner loop" : during each round four FIR filter taps are evaluated for 2*2 output samples - movq mm2, [edi] - movq mm3, mm2 - prefetch [edi + 32] // give a prefetch hint to CPU what data are to be needed soonish - pfmul mm2, [esi] - prefetch [esi + 32] // give a prefetch hint to CPU what data are to be needed soonish - pfmul mm3, [esi + 8] - - movq mm4, [edi + 8] - movq mm5, mm4 - pfadd mm0, mm2 - pfmul mm4, [esi + 8] - pfadd mm1, mm3 - pfmul mm5, [esi + 16] - - movq mm2, [edi + 16] - movq mm6, mm2 - pfadd mm0, mm4 - pfmul mm2, [esi + 16] - pfadd mm1, mm5 - pfmul mm6, [esi + 24] - - movq mm3, [edi + 24] - movq mm7, mm3 - pfadd mm0, mm2 - pfmul mm3, [esi + 24] - pfadd mm1, mm6 - pfmul mm7, [esi + 32] - add esi, 32 - pfadd mm0, mm3 - add edi, 32 - pfadd mm1, mm7 - - dec ecx - jnz loop2 - - movq [eax], mm0 - add ebx, 16 - movq [eax + 8], mm1 - add eax, 16 - - dec edx - jnz loop1 - - femms - } - - return count; -} - - -#endif // ALLOW_3DNOW This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-03-03 15:00:49
|
Revision: 1200 http://modplug.svn.sourceforge.net/modplug/?rev=1200&view=rev Author: saga-games Date: 2012-03-03 15:00:41 +0000 (Sat, 03 Mar 2012) Log Message: ----------- [Mod] Updated default keybindings and DE_jojo.mkb. [New] Added finish FT2 style keymap by cce. [Ref] Smaller changes. Modified Paths: -------------- trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/res/defaultKeybindings.mkb trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb Added Paths: ----------- trunk/OpenMPT/packageTemplate/extraKeymaps/FI_FT2Style_cce.mkb Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2012-02-27 22:28:11 UTC (rev 1199) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2012-03-03 15:00:41 UTC (rev 1200) @@ -250,7 +250,7 @@ { POSITION pos = pDocTmpl->GetFirstDocPosition(); CDocument *pDoc; - while((pos != NULL) && ((pDoc = pDocTmpl->GetNextDoc(pos)) != NULL)) + while((pos != nullptr) && ((pDoc = pDocTmpl->GetNextDoc(pos)) != nullptr)) { documents.push_back(dynamic_cast<CModDoc *>(pDoc)); } @@ -485,11 +485,11 @@ SaveDefaultDLSBanks(); // This will avoid a crash the next time if we crash while loading the bank szFileName[0] = 0; - GetSystemDirectory(szFileName, sizeof(szFileName)); + GetSystemDirectory(szFileName, CountOf(szFileName)); lstrcat(szFileName, "\\GM.DLS"); if (!AddDLSBank(szFileName)) { - GetWindowsDirectory(szFileName, sizeof(szFileName)); + GetWindowsDirectory(szFileName, CountOf(szFileName)); lstrcat(szFileName, "\\SYSTEM32\\DRIVERS\\GM.DLS"); if (!AddDLSBank(szFileName)) { Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2012-02-27 22:28:11 UTC (rev 1199) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2012-03-03 15:00:41 UTC (rev 1200) @@ -1968,7 +1968,7 @@ } */ ModInstrument *pIns = pModDoc->GetSoundFile()->Instruments[m_nInstrument]; - if ((!pIns) || (!pIns->Keyboard[note-1] && !pIns->nMixPlug)) return; + if ((!pIns) || (!pIns->Keyboard[note - NOTE_MIN] && !pIns->nMixPlug)) return; m_baPlayingNote[note] = true; //rewbs.instViewNNA m_nPlayingChannel = pModDoc->PlayNote(note, m_nInstrument, 0, false); //rewbs.instViewNNA s[0] = 0; Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2012-02-27 22:28:11 UTC (rev 1199) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2012-03-03 15:00:41 UTC (rev 1200) @@ -1797,22 +1797,12 @@ CriticalSection cs; - UINT cutlen = m_dwEndSel - m_dwBeginSel; - UINT istart = m_dwBeginSel; - UINT iend = len; + UINT cutlen = (m_dwEndSel - m_dwBeginSel); + UINT istart = m_dwBeginSel * sample.GetBytesPerSample(); + UINT iend = len * sample.GetBytesPerSample(); sample.nLength -= cutlen; - if (sample.uFlags & CHN_16BIT) - { - cutlen <<= 1; - istart <<= 1; - iend <<= 1; - } - if (sample.uFlags & CHN_STEREO) - { - cutlen <<= 1; - istart <<= 1; - iend <<= 1; - } + cutlen *= sample.GetBytesPerSample(); + LPSTR p = sample.pSample; for (UINT i=istart; i<iend; i++) { Modified: trunk/OpenMPT/mptrack/res/defaultKeybindings.mkb =================================================================== --- trunk/OpenMPT/mptrack/res/defaultKeybindings.mkb 2012-02-27 22:28:11 UTC (rev 1199) +++ trunk/OpenMPT/mptrack/res/defaultKeybindings.mkb 2012-03-03 15:00:41 UTC (rev 1200) @@ -8,6 +8,7 @@ 0:1347:2:78:1 //File/New: Ctrl+N (KeyDown) 0:1346:2:79:1 //File/Open: Ctrl+O (KeyDown) 0:1348:2:87:5 //File/Close: Ctrl+W (KeyDown|KeyHold) +0:1864:3:87:1 //File/Close All: Shift+Ctrl+W (KeyDown) 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) Modified: trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb =================================================================== --- trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2012-02-27 22:28:11 UTC (rev 1199) +++ trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2012-03-03 15:00:41 UTC (rev 1200) @@ -8,18 +8,19 @@ 0:1347:2:78:1 //File/New: Ctrl+N (KeyDown) 0:1346:2:79:1 //File/Open: Ctrl+O (KeyDown) 0:1348:2:87:5 //File/Close: Ctrl+W (KeyDown|KeyHold) +0:1864:3:87:1 //File/Close All: Shift+Ctrl+W (KeyDown) 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) -0:1031:0:119:1 //Pause song: F8 (KeyDown) +0:1030:0:116:1 //Play Song / Pause song: F5 (KeyDown) +0:1031:0:119:1 //Pause Song: F8 (KeyDown) 0:1375:0:27:1 //Stop Song: ESC (KeyDown) -0:1029:0:117:1 //Play song from start: F6 (KeyDown) -0:1028:2:117:1 //Play song from cursor: Ctrl+F6 (KeyDown) +0:1029:0:117:1 //Play Song from Start: F6 (KeyDown) +0:1028:2:117:1 //Play Song from Cursor: Ctrl+F6 (KeyDown) 0:1027:0:118:5 //Play pattern from start: F7 (KeyDown|KeyHold) 0:1026:2:118:5 //Play pattern from cursor: Ctrl+F7 (KeyDown|KeyHold) -0:1376:0:120:1 //Toggle Midi Record: F9 (KeyDown) +0:1376:0:120:1 //Toggle MIDI Record: F9 (KeyDown) 0:1359:2:90:5 //Undo: Ctrl+Z (KeyDown|KeyHold) 0:1360:2:88:1 //Cut: Ctrl+X (KeyDown) 0:1361:2:67:1 //Copy: Ctrl+C (KeyDown) @@ -42,15 +43,15 @@ 0:1025:4:67:1 //View Comments: Alt+C (KeyDown) 0:1368:2:113:1 //Toggle Tree View: Ctrl+F2 (KeyDown) 0:1369:2:112:1 //View Options: Ctrl+F1 (KeyDown) -0:1781:1:112:1 //View MIDI mapping: Shift+F1 (KeyDown) -0:1032:2:111:5 //Previous instrument: Ctrl+ (ZEHNERTASTATUR) (KeyDown|KeyHold) -0:1032:2:38:5 //Previous instrument: Ctrl+NACH-OBEN (KeyDown|KeyHold) -0:1033:2:106:5 //Next instrument: Ctrl+ (ZEHNERTASTATUR) (KeyDown|KeyHold) -0:1033:2:40:5 //Next instrument: Ctrl+NACH-UNTEN (KeyDown|KeyHold) -0:1036:0:111:1 //Previous octave: (ZEHNERTASTATUR) (KeyDown) -0:1037:0:106:1 //Next octave: (ZEHNERTASTATUR) (KeyDown) -0:1034:2:37:5 //Previous order: Ctrl+NACH-LINKS (KeyDown|KeyHold) -0:1035:2:39:5 //Next order: Ctrl+NACH-RECHTS (KeyDown|KeyHold) +0:1781:1:112:1 //View MIDI Mapping: Shift+F1 (KeyDown) +0:1032:2:111:5 //Previous Instrument: Ctrl+ (ZEHNERTASTATUR) (KeyDown|KeyHold) +0:1032:2:38:5 //Previous Instrument: Ctrl+NACH-OBEN (KeyDown|KeyHold) +0:1033:2:106:5 //Next Instrument: Ctrl+ (ZEHNERTASTATUR) (KeyDown|KeyHold) +0:1033:2:40:5 //Next Instrument: Ctrl+NACH-UNTEN (KeyDown|KeyHold) +0:1036:0:111:1 //Previous Octave: (ZEHNERTASTATUR) (KeyDown) +0:1037:0:106:1 //Next Octave: (ZEHNERTASTATUR) (KeyDown) +0:1034:2:37:5 //Previous Order: Ctrl+NACH-LINKS (KeyDown|KeyHold) +0:1035:2:39:5 //Next Order: Ctrl+NACH-RECHTS (KeyDown|KeyHold) //----( General Context [bottom] (1) )------------ @@ -78,34 +79,34 @@ 2:1050:1:16:1 //Selection key: Shift+UMSCHALT (KeyDown) 2:1051:2:17:1 //Copy select key: Ctrl+STRG (KeyDown) 2:1011:2:76:1 //Select channel / Select all: Ctrl+L (KeyDown) -2:1858:2:66:1 //Select beat: Ctrl+B (KeyDown) -2:1859:3:66:1 //Select measure: Shift+Ctrl+B (KeyDown) -2:1663:0:19:1 //Toggle follow song: (KeyDown) -2:1003:0:13:1 //Quick copy: EINGABE (KeyDown) -2:1004:0:32:5 //Quick paste: LEER (KeyDown|KeyHold) -2:1001:2:32:1 //Enable recording: Ctrl+LEER (KeyDown) -2:1002:2:13:5 //Play row: Ctrl+EINGABE (KeyDown|KeyHold) +2:1858:2:66:1 //Select Beat: Ctrl+B (KeyDown) +2:1859:3:66:1 //Select Measure: Shift+Ctrl+B (KeyDown) +2:1663:2:3:1 //Toggle follow song: Ctrl+ROLLEN-FESTSTELL (KeyDown) +2:1003:0:13:1 //Quick Copy: EINGABE (KeyDown) +2:1004:0:32:5 //Quick Paste: LEER (KeyDown|KeyHold) +2:1001:2:32:1 //Enable Recording: Ctrl+LEER (KeyDown) +2:1002:2:13:5 //Play Row: Ctrl+EINGABE (KeyDown|KeyHold) 2:1317:4:18:1 //Set row spacing on note entry: Alt (KeyDown) -2:1861:4:187:5 //Increase row spacing: Alt++ (KeyDown|KeyHold) -2:1862:4:189:5 //Decrease row spacing: Alt+- (KeyDown|KeyHold) -2:1685:2:9:1 //Switch to order list: Ctrl+TABULATOR (KeyDown) +2:1861:4:187:5 //Increase Row Spacing: Alt++ (KeyDown|KeyHold) +2:1862:4:189:5 //Decrease Row Spacing: Alt+- (KeyDown|KeyHold) +2:1685:2:9:1 //Switch to Order List: Ctrl+TABULATOR (KeyDown) 2:1806:2:68:5 //Duplicate pattern: Ctrl+D (KeyDown|KeyHold) -2:1836:2:191:1 //Edit plugin assigned to PC note: Ctrl+# (KeyDown) +2:1836:2:191:1 //Edit Plugin assigned to PC Event: Ctrl+# (KeyDown) 2:1662:6:80:1 //Toggle channel's plugin editor: Ctrl+Alt+P (KeyDown) -2:1062:0:93:1 //Show note properties: ANWENDUNG (KeyDown) -2:1772:2:93:1 //Show pattern properties window: Ctrl+ANWENDUNG (KeyDown) +2:1062:0:93:1 //Show Note Properties: ANWENDUNG (KeyDown) +2:1772:2:93:1 //Show Pattern Properties: Ctrl+ANWENDUNG (KeyDown) 2:1819:2:69:1 //Split Keyboard Settings dialog: Ctrl+E (KeyDown) 2:1780:2:80:1 //Show playback time at current row: Ctrl+P (KeyDown) -2:1005:2:85:1 //Mute current channel: Ctrl+U (KeyDown) -2:1786:2:82:1 //Reset channel: Ctrl+R (KeyDown) +2:1005:2:85:1 //Mute current Channel: Ctrl+U (KeyDown) +2:1786:2:82:1 //Reset Channel: Ctrl+R (KeyDown) 2:1007:2:81:5 //Transpose +1: Ctrl+Q (KeyDown|KeyHold) 2:1008:2:65:5 //Transpose -1: Ctrl+A (KeyDown|KeyHold) 2:1009:3:81:5 //Transpose +12: Shift+Ctrl+Q (KeyDown|KeyHold) 2:1010:3:65:5 //Transpose -12: Shift+Ctrl+A (KeyDown|KeyHold) 2:1012:2:77:1 //Amplify selection: Ctrl+M (KeyDown) -2:1014:2:74:1 //Interpolate volume: Ctrl+J (KeyDown) -2:1015:2:75:1 //Interpolate effect: Ctrl+K (KeyDown) -2:1016:4:66:1 //Open effect visualizer: Alt+B (KeyDown) +2:1014:2:74:1 //Interpolate Volume: Ctrl+J (KeyDown) +2:1015:2:75:1 //Interpolate Effect: Ctrl+K (KeyDown) +2:1016:4:66:1 //Open Effect Visualizer: Alt+B (KeyDown) 2:1766:2:71:1 //Go to row/channel/...: Ctrl+G (KeyDown) 2:1013:2:73:1 //Apply current instrument: Ctrl+I (KeyDown) 2:1660:4:69:5 //Grow selection: Alt+E (KeyDown|KeyHold) @@ -176,9 +177,9 @@ 3:1221:0:57:1 //Set octave 9: 9 (KeyDown) 3:1221:0:105:1 //Set octave 9: 9 (ZEHNERTASTATUR) (KeyDown) 3:1316:1:16:1 //Chord Modifier: Shift+UMSCHALT (KeyDown) -3:1667:0:220:1 //Note Cut (don't remember instrument): ZIRKUMFLEX (KeyDown) -3:1668:0:221:1 //Note Off (don't remember instrument): AKUT (KeyDown) -3:1792:0:219:1 //Note Fade (don't remember instrument): \xDF (KeyDown) +3:1667:0:220:1 //Note Cut (without instrument number): ZIRKUMFLEX (KeyDown) +3:1668:0:221:1 //Note Off (without instrument number): AKUT (KeyDown) +3:1792:0:219:1 //Note Fade (without instrument number): \xDF (KeyDown) 3:1788:0:226:1 //Parameter control(MPTm only): < (KeyDown) 3:1789:1:226:1 //Parameter control(smooth)(MPTm only): Shift+< (KeyDown) @@ -225,70 +226,70 @@ 5:1230:0:104:1 //Set volume digit 8: 8 (ZEHNERTASTATUR) (KeyDown) 5:1231:0:57:1 //Set volume digit 9: 9 (KeyDown) 5:1231:0:105:1 //Set volume digit 9: 9 (ZEHNERTASTATUR) (KeyDown) -5:1232:0:86:1 //Vol command - volume: V (KeyDown) -5:1233:0:80:1 //Vol command - pan: P (KeyDown) -5:1234:0:67:1 //Vol command - vol slide up: C (KeyDown) -5:1235:0:68:1 //Vol command - vol slide down: D (KeyDown) -5:1236:0:65:1 //Vol command - vol fine slide up: A (KeyDown) -5:1237:0:66:1 //Vol command - vol fine slide down: B (KeyDown) -5:1238:0:85:1 //Vol command - vibrato speed: U (KeyDown) -5:1239:0:72:1 //Vol command - vibrato: H (KeyDown) -5:1240:0:76:1 //Vol command - XM pan left: L (KeyDown) -5:1241:0:82:1 //Vol command - XM pan right: R (KeyDown) -5:1242:0:71:1 //Vol command - Portamento: G (KeyDown) -5:1243:0:70:1 //Vol command - Portamento Up: F (KeyDown) -5:1244:0:69:1 //Vol command - Portamento Down: E (KeyDown) -5:1246:0:79:1 //Vol command - Offset: O (KeyDown) +5:1232:0:86:1 //Volume Command - Volume: V (KeyDown) +5:1233:0:80:1 //Volume Command - Panning: P (KeyDown) +5:1234:0:67:1 //Volume Command - Volume Slide Up: C (KeyDown) +5:1235:0:68:1 //Volume Command - Volume Slide Down: D (KeyDown) +5:1236:0:65:1 //Volume Command - Fine Volume Slide Up: A (KeyDown) +5:1237:0:66:1 //Volume Command - Fine Volume Slide Down: B (KeyDown) +5:1238:0:85:1 //Volume Command - Vibrato Speed: U (KeyDown) +5:1239:0:72:1 //Volume Command - Vibrato Depth: H (KeyDown) +5:1240:0:76:1 //Volume Command - XM Pan Slide Left: L (KeyDown) +5:1241:0:82:1 //Volume Command - XM Pan Slide Right: R (KeyDown) +5:1242:0:71:1 //Volume Command - Portamento: G (KeyDown) +5:1243:0:70:1 //Volume Command - Portamento Up: F (KeyDown) +5:1244:0:69:1 //Volume Command - Portamento Down: E (KeyDown) +5:1246:0:79:1 //Volume Command - Offset: O (KeyDown) //----( Pattern Context [bottom] - FX Col (6) )------------ -6:1294:0:220:1 //FX midi macro slide: ZIRKUMFLEX (KeyDown) -6:1295:0:190:1 //FX combined note delay and note cut: . (KeyDown) -6:1666:0:191:1 //FX parameter extension command: # (KeyDown) +6:1294:0:220:1 //Smooth MIDI Macro Slide: ZIRKUMFLEX (KeyDown) +6:1295:0:190:1 //Combined Note Delay and Note Cut: . (KeyDown) +6:1666:0:191:1 //Parameter Extension Command: # (KeyDown) //----( Pattern Context [bottom] - Param Col (7) )------------ -7:1247:0:48:1 //FX Param digit 0: 0 (KeyDown) -7:1247:0:96:1 //FX Param digit 0: 0 (ZEHNERTASTATUR) (KeyDown) -7:1248:0:49:1 //FX Param digit 1: 1 (KeyDown) -7:1248:0:97:1 //FX Param digit 1: 1 (ZEHNERTASTATUR) (KeyDown) -7:1249:0:50:1 //FX Param digit 2: 2 (KeyDown) -7:1249:0:98:1 //FX Param digit 2: 2 (ZEHNERTASTATUR) (KeyDown) -7:1250:0:51:1 //FX Param digit 3: 3 (KeyDown) -7:1250:0:99:1 //FX Param digit 3: 3 (ZEHNERTASTATUR) (KeyDown) -7:1251:0:52:1 //FX Param digit 4: 4 (KeyDown) -7:1251:0:100:1 //FX Param digit 4: 4 (ZEHNERTASTATUR) (KeyDown) -7:1252:0:53:1 //FX Param digit 5: 5 (KeyDown) -7:1252:0:101:1 //FX Param digit 5: 5 (ZEHNERTASTATUR) (KeyDown) -7:1253:0:54:1 //FX Param digit 6: 6 (KeyDown) -7:1253:0:102:1 //FX Param digit 6: 6 (ZEHNERTASTATUR) (KeyDown) -7:1254:0:55:1 //FX Param digit 7: 7 (KeyDown) -7:1254:0:103:1 //FX Param digit 7: 7 (ZEHNERTASTATUR) (KeyDown) -7:1255:0:56:1 //FX Param digit 8: 8 (KeyDown) -7:1255:0:104:1 //FX Param digit 8: 8 (ZEHNERTASTATUR) (KeyDown) -7:1256:0:57:1 //FX Param digit 9: 9 (KeyDown) -7:1256:0:105:1 //FX Param digit 9: 9 (ZEHNERTASTATUR) (KeyDown) -7:1257:0:65:1 //FX Param digit A: A (KeyDown) -7:1258:0:66:1 //FX Param digit B: B (KeyDown) -7:1259:0:67:1 //FX Param digit C: C (KeyDown) -7:1260:0:68:1 //FX Param digit D: D (KeyDown) -7:1261:0:69:1 //FX Param digit E: E (KeyDown) -7:1262:0:70:1 //FX Param digit F: F (KeyDown) +7:1247:0:48:1 //Effect Parameter Digit 0: 0 (KeyDown) +7:1247:0:96:1 //Effect Parameter Digit 0: 0 (ZEHNERTASTATUR) (KeyDown) +7:1248:0:49:1 //Effect Parameter Digit 1: 1 (KeyDown) +7:1248:0:97:1 //Effect Parameter Digit 1: 1 (ZEHNERTASTATUR) (KeyDown) +7:1249:0:50:1 //Effect Parameter Digit 2: 2 (KeyDown) +7:1249:0:98:1 //Effect Parameter Digit 2: 2 (ZEHNERTASTATUR) (KeyDown) +7:1250:0:51:1 //Effect Parameter Digit 3: 3 (KeyDown) +7:1250:0:99:1 //Effect Parameter Digit 3: 3 (ZEHNERTASTATUR) (KeyDown) +7:1251:0:52:1 //Effect Parameter Digit 4: 4 (KeyDown) +7:1251:0:100:1 //Effect Parameter Digit 4: 4 (ZEHNERTASTATUR) (KeyDown) +7:1252:0:53:1 //Effect Parameter Digit 5: 5 (KeyDown) +7:1252:0:101:1 //Effect Parameter Digit 5: 5 (ZEHNERTASTATUR) (KeyDown) +7:1253:0:54:1 //Effect Parameter Digit 6: 6 (KeyDown) +7:1253:0:102:1 //Effect Parameter Digit 6: 6 (ZEHNERTASTATUR) (KeyDown) +7:1254:0:55:1 //Effect Parameter Digit 7: 7 (KeyDown) +7:1254:0:103:1 //Effect Parameter Digit 7: 7 (ZEHNERTASTATUR) (KeyDown) +7:1255:0:56:1 //Effect Parameter Digit 8: 8 (KeyDown) +7:1255:0:104:1 //Effect Parameter Digit 8: 8 (ZEHNERTASTATUR) (KeyDown) +7:1256:0:57:1 //Effect Parameter Digit 9: 9 (KeyDown) +7:1256:0:105:1 //Effect Parameter Digit 9: 9 (ZEHNERTASTATUR) (KeyDown) +7:1257:0:65:1 //Effect Parameter Digit A: A (KeyDown) +7:1258:0:66:1 //Effect Parameter Digit B: B (KeyDown) +7:1259:0:67:1 //Effect Parameter Digit C: C (KeyDown) +7:1260:0:68:1 //Effect Parameter Digit D: D (KeyDown) +7:1261:0:69:1 //Effect Parameter Digit E: E (KeyDown) +7:1262:0:70:1 //Effect Parameter Digit F: F (KeyDown) //----( Sample Context [bottom] (8) )------------ -8:1673:0:13:1 //Load a Sample: EINGABE (KeyDown) +8:1673:0:13:1 //Load Sample: EINGABE (KeyDown) 8:1380:2:84:1 //Trim sample around loop points: Ctrl+T (KeyDown) -8:1383:0:8:1 //Silence sample selection: R\xDCCK (KeyDown) +8:1383:0:8:1 //Silence Sample Selection: R\xDCCK (KeyDown) 8:1384:1:78:1 //Normalise Sample: Shift+N (KeyDown) 8:1385:3:65:1 //Amplify Sample: Shift+Ctrl+A (KeyDown) 8:1385:2:77:1 //Amplify Sample: Ctrl+M (KeyDown) -8:1381:3:82:1 //Reverse sample: Shift+Ctrl+R (KeyDown) -8:1382:0:46:1 //Delete sample selection: ENTF (KeyDown) +8:1381:3:82:1 //Reverse Sample: Shift+Ctrl+R (KeyDown) +8:1382:0:46:1 //Delete Sample Selection: ENTF (KeyDown) 8:1386:0:107:1 //Zoom Out: + (ZEHNERTASTATUR) (KeyDown) 8:1387:0:109:1 //Zoom In: - (ZEHNERTASTATUR) (KeyDown) -8:1784:2:73:1 //Invert sample phase: Ctrl+I (KeyDown) -8:1785:2:85:1 //Signed/Unsigned conversion: Ctrl+U (KeyDown) +8:1784:2:73:1 //Invert Sample Phase: Ctrl+I (KeyDown) +8:1785:2:85:1 //Signed / Unsigned Conversion: Ctrl+U (KeyDown) 8:1790:2:69:1 //Remove DC Offset: Ctrl+E (KeyDown) -8:1856:2:68:1 //Quick fade: Ctrl+D (KeyDown) -8:1857:2:76:1 //Crossfade sample loop: Ctrl+L (KeyDown) +8:1856:2:68:1 //Quick Fade: Ctrl+D (KeyDown) +8:1857:2:76:1 //Crossfade Sample Loop: Ctrl+L (KeyDown) //----( Instrument Context [bottom] (9) )------------ 9:1837:0:107:5 //Zoom In: + (ZEHNERTASTATUR) (KeyDown|KeyHold) @@ -298,13 +299,13 @@ 9:1821:0:37:5 //Move envelope point left: NACH-LINKS (KeyDown|KeyHold) 9:1822:0:39:5 //Move envelope point right: NACH-RECHTS (KeyDown|KeyHold) 9:1823:0:38:5 //Move envelope point up: NACH-OBEN (KeyDown|KeyHold) -9:1834:0:33:5 //Move envelope point up (big step): BILD-NACH-OBEN (KeyDown|KeyHold) +9:1834:0:33:5 //Move envelope point up (Coarse): BILD-NACH-OBEN (KeyDown|KeyHold) 9:1824:0:40:5 //Move envelope point down: NACH-UNTEN (KeyDown|KeyHold) -9:1835:0:34:5 //Move envelope point down (big step): BILD-NACH-UNTEN (KeyDown|KeyHold) -9:1827:0:45:5 //Insert envelope point: EINFG (KeyDown|KeyHold) -9:1828:0:46:5 //Remove envelope point: ENTF (KeyDown|KeyHold) -9:1829:0:36:1 //Set loop start: POS1 (KeyDown) -9:1830:0:35:1 //Set loop end: ENDE (KeyDown) +9:1835:0:34:5 //Move envelope point down (Coarse): BILD-NACH-UNTEN (KeyDown|KeyHold) +9:1827:0:45:5 //Insert Envelope Point: EINFG (KeyDown|KeyHold) +9:1828:0:46:5 //Remove Envelope Point: ENTF (KeyDown|KeyHold) +9:1829:0:36:1 //Set Loop Start: POS1 (KeyDown) +9:1830:0:35:1 //Set Loop End: ENDE (KeyDown) 9:1831:2:36:1 //Set sustain loop start: Ctrl+POS1 (KeyDown) 9:1832:2:35:1 //Set sustain loop end: Ctrl+ENDE (KeyDown) 9:1833:2:82:1 //Toggle release node: Ctrl+R (KeyDown) @@ -316,11 +317,11 @@ //----( Unknown Context (12) )------------ //----( Plugin GUI Context (13) )------------ -13:1763:0:37:1 //Previous plugin preset: NACH-LINKS (KeyDown) -13:1764:0:39:1 //Next plugin preset: NACH-RECHTS (KeyDown) +13:1763:0:37:1 //Previous Plugin Preset: NACH-LINKS (KeyDown) +13:1764:0:39:1 //Next Plugin Preset: NACH-RECHTS (KeyDown) 13:1782:0:38:1 //Plugin preset backward jump: NACH-OBEN (KeyDown) 13:1783:0:40:1 //Plugin preset forward jump: NACH-UNTEN (KeyDown) -13:1765:2:80:1 //Randomize plugin parameters: Ctrl+P (KeyDown) +13:1765:2:80:1 //Randomize Plugin Parameters: Ctrl+P (KeyDown) 13:1839:2:82:1 //Toggle parameter recording: Ctrl+R (KeyDown) 13:1840:2:75:1 //Pass key presses to plugin: Ctrl+K (KeyDown) 13:1841:2:66:1 //Bypass plugin: Ctrl+B (KeyDown) @@ -332,16 +333,16 @@ //----( Sample Context [top] (16) )------------ //----( Instrument Context [top] (17) )------------ -17:1851:2:68:1 //Duplicate instrument: Ctrl+D (KeyDown) -17:1850:3:69:1 //Edit sample map: Shift+Ctrl+E (KeyDown) -17:1849:2:69:1 //Edit current sample: Ctrl+E (KeyDown) +17:1851:2:68:1 //Duplicate Instrument: Ctrl+D (KeyDown) +17:1850:3:69:1 //Edit Sample Map: Shift+Ctrl+E (KeyDown) +17:1849:2:69:1 //Edit Current Sample: Ctrl+E (KeyDown) 17:1846:3:77:1 //Map all notes to selected note: Shift+Ctrl+M (KeyDown) 17:1847:2:77:1 //Map all notes to selected sample: Ctrl+M (KeyDown) -17:1848:2:82:1 //Reset note mapping: Ctrl+R (KeyDown) -17:1843:2:81:1 //Transpose +1 (note map): Ctrl+Q (KeyDown) -17:1842:2:65:1 //Transpose -1 (note map): Ctrl+A (KeyDown) -17:1845:3:81:1 //Transpose +12 (note map): Shift+Ctrl+Q (KeyDown) -17:1844:3:65:1 //Transpose -12 (note map): Shift+Ctrl+A (KeyDown) +17:1848:2:82:1 //Reset Note nMapping: Ctrl+R (KeyDown) +17:1843:2:81:1 //Transpose +1 (Note Map): Ctrl+Q (KeyDown) +17:1842:2:65:1 //Transpose -1 (Note Map): Ctrl+A (KeyDown) +17:1845:3:81:1 //Transpose +12 (Note Map): Shift+Ctrl+Q (KeyDown) +17:1844:3:65:1 //Transpose -12 (Note Map): Shift+Ctrl+A (KeyDown) //----( Comments Context [top] (18) )------------ Added: trunk/OpenMPT/packageTemplate/extraKeymaps/FI_FT2Style_cce.mkb =================================================================== --- trunk/OpenMPT/packageTemplate/extraKeymaps/FI_FT2Style_cce.mkb (rev 0) +++ trunk/OpenMPT/packageTemplate/extraKeymaps/FI_FT2Style_cce.mkb 2012-03-03 15:00:41 UTC (rev 1200) @@ -0,0 +1,330 @@ +//-------- OpenMPT key binding definition file ------- +//-Format is: - +//- Context:Command ID:Modifiers:Key:KeypressEventType //Comments - +//---------------------------------------------------------------------- +version:1 + +//----( Global Context (0) )------------ +0:1347:2:78:1 //File/New: Ctrl+N (KeyDown) +0:1346:2:79:1 //File/Open: Ctrl+O (KeyDown) +0:1348:2:87:5 //File/Close: Ctrl+W (KeyDown|KeyHold) +0:1864:3:87:1 //File/Close All: Shift+Ctrl+W (KeyDown) +0:1349:6:83:1 //File/Save: Ctrl+Alt+S (KeyDown) +0:1030:2:119:1 //Play song/Pause song: Ctrl+F8 (KeyDown) +0:1031:0:119:1 //Pause song: F8 (KeyDown) +0:1375:0:32:1 //Stop Song: V\xC4LI (KeyDown) +0:1029:0:13:1 //Play song from start: ENTER (KeyDown) +0:1028:1:13:5 //Play song from cursor: Shift+ENTER (KeyDown|KeyHold) +0:1027:0:117:5 //Play pattern from start: F6 (KeyDown|KeyHold) +0:1026:2:117:5 //Play pattern from cursor: Ctrl+F6 (KeyDown|KeyHold) +0:1376:2:120:1 //Toggle Midi Record: Ctrl+F9 (KeyDown) +0:1359:6:90:1 //Undo: Ctrl+Alt+Z (KeyDown) +0:1360:6:88:1 //Cut: Ctrl+Alt+X (KeyDown) +0:1361:2:67:1 //Copy: Ctrl+C (KeyDown) +0:1361:4:67:1 //Copy: Alt+C (KeyDown) +0:1362:2:86:1 //Paste: Ctrl+V (KeyDown) +0:1362:4:86:1 //Paste: Alt+V (KeyDown) +0:1363:2:77:1 //Mix Paste: Ctrl+M (KeyDown) +0:1364:2:65:1 //Select All: Ctrl+A (KeyDown) +0:1365:2:70:1 //Find / Replace: Ctrl+F (KeyDown) +0:1366:2:114:1 //Find Next: Ctrl+F3 (KeyDown) +0:1021:0:122:1 //View General: F11 (KeyDown) +0:1022:0:113:1 //View Pattern: F2 (KeyDown) +0:1022:2:88:1 //View Pattern: Ctrl+X (KeyDown) +0:1023:0:114:1 //View Samples: F3 (KeyDown) +0:1023:2:83:1 //View Samples: Ctrl+S (KeyDown) +0:1024:2:73:1 //View Instruments: Ctrl+I (KeyDown) +0:1024:0:115:1 //View Instruments: F4 (KeyDown) +0:1025:1:120:1 //View Comments: Shift+F9 (KeyDown) +0:1368:2:113:1 //Toggle Tree View: Ctrl+F2 (KeyDown) +0:1369:2:112:1 //View Options: Ctrl+F1 (KeyDown) +0:1670:6:77:1 //View Channel Manager: Ctrl+Alt+M (KeyDown) +0:1669:3:77:1 //View Plugin Manager: Shift+Ctrl+M (KeyDown) +0:1032:1:38:5 //Previous instrument: Shift+YL\xC4NUOLI (KeyDown|KeyHold) +0:1032:2:38:5 //Previous instrument: Ctrl+YL\xC4NUOLI (KeyDown|KeyHold) +0:1033:1:40:5 //Next instrument: Shift+ALANUOLI (KeyDown|KeyHold) +0:1033:2:40:5 //Next instrument: Ctrl+ALANUOLI (KeyDown|KeyHold) +0:1036:0:111:5 //Previous octave: NUM JAKO (KeyDown|KeyHold) +0:1037:0:106:5 //Next octave: NUM KERTO (KeyDown|KeyHold) +0:1034:2:37:5 //Previous order: Ctrl+VASEN NUOLI (KeyDown|KeyHold) +0:1035:2:39:5 //Next order: Ctrl+OIKEA NUOLI (KeyDown|KeyHold) + +//----( General Context [bottom] (1) )------------ + +//----( Pattern Context [bottom] (2) )------------ +2:1017:0:34:5 //Jump down by measure: PG DN (KeyDown|KeyHold) +2:1018:0:33:5 //Jump up by measure: PG UP (KeyDown|KeyHold) +2:1338:4:34:5 //Jump down by beat: Alt+PG DN (KeyDown|KeyHold) +2:1339:4:33:5 //Jump up by beat: Alt+PG UP (KeyDown|KeyHold) +2:1019:2:34:5 //Snap down to measure: Ctrl+PG DN (KeyDown|KeyHold) +2:1020:2:33:5 //Snap up to measure: Ctrl+PG UP (KeyDown|KeyHold) +2:1340:6:34:5 //Snap down to beat: Ctrl+Alt+PG DN (KeyDown|KeyHold) +2:1341:6:33:5 //Snap up to beat: Ctrl+Alt+PG UP (KeyDown|KeyHold) +2:1038:0:40:5 //Navigate down by 1 row: ALANUOLI (KeyDown|KeyHold) +2:1039:0:38:5 //Navigate up by 1 row: YL\xC4NUOLI (KeyDown|KeyHold) +2:1040:0:37:5 //Navigate left: VASEN NUOLI (KeyDown|KeyHold) +2:1041:0:39:5 //Navigate right: OIKEA NUOLI (KeyDown|KeyHold) +2:1042:0:9:1 //Navigate to next channel: SARKAIN (KeyDown) +2:1043:1:9:5 //Navigate to previous channel: Shift+SARKAIN (KeyDown|KeyHold) +2:1045:0:36:1 //Go to first row: HOME (KeyDown) +2:1046:6:36:1 //Go to first row of first channel: Ctrl+Alt+HOME (KeyDown) +2:1048:0:35:1 //Go to last row: END (KeyDown) +2:1049:6:35:1 //Go to last row of last channel: Ctrl+Alt+END (KeyDown) +2:1050:4:18:1 //Selection key: Alt (KeyDown) +2:1011:4:76:1 //Select channel / Select all: Alt+L (KeyDown) +2:1663:2:118:1 //Toggle follow song: Ctrl+F7 (KeyDown) +2:1003:6:67:1 //Quick copy: Ctrl+Alt+C (KeyDown) +2:1004:6:86:1 //Quick paste: Ctrl+Alt+V (KeyDown) +2:1001:2:82:1 //Enable recording: Ctrl+R (KeyDown) +2:1002:2:13:5 //Play row: Ctrl+ENTER (KeyDown|KeyHold) +2:1317:4:18:1 //Set row jump on note entry: Alt (KeyDown) +2:1662:6:80:1 //Toggle channel's plugin editor: Ctrl+Alt+P (KeyDown) +2:1062:0:93:1 //Show note properties: Sovellus (KeyDown) +2:1063:2:93:1 //Show context (right-click) menu: Ctrl+Sovellus (KeyDown) +2:1005:0:120:1 //Mute current channel: F9 (KeyDown) +2:1006:0:121:1 //Solo current channel: F10 (KeyDown) +2:1007:4:65:5 //Transpose +1: Alt+A (KeyDown|KeyHold) +2:1008:4:81:5 //Transpose -1: Alt+Q (KeyDown|KeyHold) +2:1009:5:65:5 //Transpose +12: Shift+Alt+A (KeyDown|KeyHold) +2:1010:5:81:5 //Transpose -12: Shift+Alt+Q (KeyDown|KeyHold) +2:1012:4:74:1 //Amplify selection: Alt+J (KeyDown) +2:1014:4:73:1 //Interpolate volume: Alt+I (KeyDown) +2:1015:4:88:1 //Interpolate effect: Alt+X (KeyDown) +2:1016:4:66:1 //Open effect visualizer: Alt+B (KeyDown) +2:1013:4:83:1 //Apply current instrument: Alt+S (KeyDown) +2:1660:4:69:1 //Grow selection: Alt+E (KeyDown) +2:1661:4:68:1 //Shrink selection: Alt+D (KeyDown) +2:1058:0:110:5 //Clear field: NUM DESIMAALI (KeyDown|KeyHold) +2:1664:1:190:1 //Clear field (IT Style): Shift+. (KeyDown) +2:1059:2:46:1 //Clear row and step: Ctrl+DEL (KeyDown) +2:1060:2:110:1 //Clear field and step: Ctrl+NUM DESIMAALI (KeyDown) +2:1665:0:46:5 //Clear field and step (IT Style): DEL (KeyDown|KeyHold) +2:1061:0:8:5 //Delete rows: ASKELPALAUTIN (KeyDown|KeyHold) +2:1377:2:8:5 //Delete all rows: Ctrl+ASKELPALAUTIN (KeyDown|KeyHold) +2:1378:0:45:5 //Insert Row: INS (KeyDown|KeyHold) +2:1379:2:45:1 //Insert All Rows: Ctrl+INS (KeyDown) +2:1055:1:37:1 //Previous pattern: Shift+VASEN NUOLI (KeyDown) +2:1054:1:39:1 //Next pattern: Shift+OIKEA NUOLI (KeyDown) + +//----( Pattern Context [bottom] - Note Col (3) )------------ +3:1064:0:90:5 //Base octave C: Z (KeyDown|KeyHold) +3:1065:0:83:5 //Base octave C#: S (KeyDown|KeyHold) +3:1066:0:88:5 //Base octave D: X (KeyDown|KeyHold) +3:1067:0:68:5 //Base octave D#: D (KeyDown|KeyHold) +3:1068:0:67:5 //Base octave E: C (KeyDown|KeyHold) +3:1069:0:86:5 //Base octave F: V (KeyDown|KeyHold) +3:1070:0:71:5 //Base octave F#: G (KeyDown|KeyHold) +3:1071:0:66:5 //Base octave G: B (KeyDown|KeyHold) +3:1072:0:72:5 //Base octave G#: H (KeyDown|KeyHold) +3:1073:0:78:5 //Base octave A: N (KeyDown|KeyHold) +3:1074:0:74:5 //Base octave A#: J (KeyDown|KeyHold) +3:1075:0:77:5 //Base octave B: M (KeyDown|KeyHold) +3:1076:0:81:5 //Base octave +1 C: Q (KeyDown|KeyHold) +3:1077:0:50:5 //Base octave +1 C#: 2 (KeyDown|KeyHold) +3:1078:0:87:5 //Base octave +1 D: W (KeyDown|KeyHold) +3:1079:0:51:5 //Base octave +1 D#: 3 (KeyDown|KeyHold) +3:1080:0:69:5 //Base octave +1 E: E (KeyDown|KeyHold) +3:1081:0:82:5 //Base octave +1 F: R (KeyDown|KeyHold) +3:1082:0:53:5 //Base octave +1 F#: 5 (KeyDown|KeyHold) +3:1083:0:84:5 //Base octave +1 G: T (KeyDown|KeyHold) +3:1084:0:54:5 //Base octave +1 G#: 6 (KeyDown|KeyHold) +3:1085:0:89:1 //Base octave +1 A: Y (KeyDown) +3:1086:0:55:1 //Base octave +1 A#: 7 (KeyDown) +3:1087:0:85:5 //Base octave +1 B: U (KeyDown|KeyHold) +3:1088:0:73:5 //Base octave +2 C: I (KeyDown|KeyHold) +3:1089:0:57:5 //Base octave +2 C#: 9 (KeyDown|KeyHold) +3:1090:0:79:5 //Base octave +2 D: O (KeyDown|KeyHold) +3:1091:0:48:1 //Base octave +2 D#: 0 (KeyDown) +3:1092:0:80:5 //Base octave +2 E: P (KeyDown|KeyHold) +3:1093:0:221:5 //Base octave +2 F: \xE5 (KeyDown|KeyHold) +3:1094:0:219:5 //Base octave +2 F#: AKUUTTIAKSENTTI (KeyDown|KeyHold) +3:1095:0:186:5 //Base octave +2 G: TREEMA (KeyDown|KeyHold) +3:1212:0:96:1 //Set octave 0: NUM 0 (KeyDown) +3:1213:0:97:1 //Set octave 1: NUM 1 (KeyDown) +3:1214:0:98:1 //Set octave 2: NUM 2 (KeyDown) +3:1215:0:99:1 //Set octave 3: NUM 3 (KeyDown) +3:1216:0:52:1 //Set octave 4: 4 (KeyDown) +3:1216:0:100:1 //Set octave 4: NUM 4 (KeyDown) +3:1217:0:101:1 //Set octave 5: NUM 5 (KeyDown) +3:1218:0:102:1 //Set octave 6: NUM 6 (KeyDown) +3:1219:0:103:1 //Set octave 7: NUM 7 (KeyDown) +3:1220:0:56:1 //Set octave 8: 8 (KeyDown) +3:1220:0:104:1 //Set octave 8: NUM 8 (KeyDown) +3:1221:0:105:1 //Set octave 9: NUM 9 (KeyDown) +3:1316:1:16:1 //Chord Modifier: Shift+VAIHTO (KeyDown) +3:1667:0:222:1 //Note Cut (without instrument number): \xE4 (KeyDown) +3:1668:0:226:1 //Note Off (without instrument number): < (KeyDown) +3:1668:0:187:1 //Note Off (without instrument number): + (KeyDown) +3:1788:4:80:5 //Parameter control(MPTm only): Alt+P (KeyDown|KeyHold) +3:1789:4:221:5 //Parameter control(smooth)(MPTm only): Alt+\xE5 (KeyDown|KeyHold) + +//----( Pattern Context [bottom] - Ins Col (4) )------------ +4:1202:0:96:1 //Set instrument digit 0: NUM 0 (KeyDown) +4:1202:0:48:1 //Set instrument digit 0: 0 (KeyDown) +4:1203:0:97:1 //Set instrument digit 1: NUM 1 (KeyDown) +4:1203:0:49:1 //Set instrument digit 1: 1 (KeyDown) +4:1204:0:98:1 //Set instrument digit 2: NUM 2 (KeyDown) +4:1204:0:50:1 //Set instrument digit 2: 2 (KeyDown) +4:1205:0:99:1 //Set instrument digit 3: NUM 3 (KeyDown) +4:1205:0:51:1 //Set instrument digit 3: 3 (KeyDown) +4:1206:0:100:1 //Set instrument digit 4: NUM 4 (KeyDown) +4:1206:0:52:1 //Set instrument digit 4: 4 (KeyDown) +4:1207:0:101:1 //Set instrument digit 5: NUM 5 (KeyDown) +4:1207:0:53:1 //Set instrument digit 5: 5 (KeyDown) +4:1208:0:102:1 //Set instrument digit 6: NUM 6 (KeyDown) +4:1208:0:54:1 //Set instrument digit 6: 6 (KeyDown) +4:1209:0:103:1 //Set instrument digit 7: NUM 7 (KeyDown) +4:1209:0:55:1 //Set instrument digit 7: 7 (KeyDown) +4:1210:0:56:1 //Set instrument digit 8: 8 (KeyDown) +4:1210:0:104:1 //Set instrument digit 8: NUM 8 (KeyDown) +4:1211:0:105:1 //Set instrument digit 9: NUM 9 (KeyDown) +4:1211:0:57:1 //Set instrument digit 9: 9 (KeyDown) + +//----( Pattern Context [bottom] - Vol Col (5) )------------ +5:1222:0:48:1 //Set volume digit 0: 0 (KeyDown) +5:1222:0:96:1 //Set volume digit 0: NUM 0 (KeyDown) +5:1223:0:49:1 //Set volume digit 1: 1 (KeyDown) +5:1223:0:97:1 //Set volume digit 1: NUM 1 (KeyDown) +5:1224:0:50:1 //Set volume digit 2: 2 (KeyDown) +5:1224:0:98:1 //Set volume digit 2: NUM 2 (KeyDown) +5:1225:0:51:1 //Set volume digit 3: 3 (KeyDown) +5:1225:0:99:1 //Set volume digit 3: NUM 3 (KeyDown) +5:1226:0:52:1 //Set volume digit 4: 4 (KeyDown) +5:1226:0:100:1 //Set volume digit 4: NUM 4 (KeyDown) +5:1227:0:53:1 //Set volume digit 5: 5 (KeyDown) +5:1227:0:101:1 //Set volume digit 5: NUM 5 (KeyDown) +5:1228:0:54:1 //Set volume digit 6: 6 (KeyDown) +5:1228:0:102:1 //Set volume digit 6: NUM 6 (KeyDown) +5:1229:0:55:1 //Set volume digit 7: 7 (KeyDown) +5:1229:0:103:1 //Set volume digit 7: NUM 7 (KeyDown) +5:1230:0:56:1 //Set volume digit 8: 8 (KeyDown) +5:1230:0:104:1 //Set volume digit 8: NUM 8 (KeyDown) +5:1231:0:57:1 //Set volume digit 9: 9 (KeyDown) +5:1231:0:105:1 //Set volume digit 9: NUM 9 (KeyDown) +5:1232:0:86:1 //Vol command - volume: V (KeyDown) +5:1233:0:80:1 //Vol command - pan: P (KeyDown) +5:1234:0:67:1 //Vol command - vol slide up: C (KeyDown) +5:1235:0:68:1 //Vol command - vol slide down: D (KeyDown) +5:1236:0:65:1 //Vol command - vol fine slide up: A (KeyDown) +5:1237:0:66:1 //Vol command - vol fine slide down: B (KeyDown) +5:1238:0:85:1 //Vol command - vibrato speed: U (KeyDown) +5:1239:0:72:1 //Vol command - vibrato: H (KeyDown) +5:1240:0:76:1 //Vol command - XM pan left: L (KeyDown) +5:1241:0:82:1 //Vol command - XM pan right: R (KeyDown) +5:1242:0:71:1 //Vol command - Portamento: G (KeyDown) +5:1243:0:70:1 //Vol command - Portamento Up: F (KeyDown) +5:1244:0:69:1 //Vol command - Portamento Down: E (KeyDown) +5:1246:0:79:1 //Vol command - Offset: O (KeyDown) + +//----( Pattern Context [bottom] - FX Col (6) )------------ +6:1294:0:220:1 //FX midi macro slide: \xA7 (KeyDown) +6:1295:1:186:1 //FX combined note delay and note cut: Shift+TREEMA (KeyDown) +6:1666:0:222:1 //FX parameter extension command: \xE4 (KeyDown) + +//----( Pattern Context [bottom] - Param Col (7) )------------ +7:1247:0:48:1 //FX Param digit 0: 0 (KeyDown) +7:1247:0:96:1 //FX Param digit 0: NUM 0 (KeyDown) +7:1248:0:49:1 //FX Param digit 1: 1 (KeyDown) +7:1248:0:97:1 //FX Param digit 1: NUM 1 (KeyDown) +7:1249:0:50:1 //FX Param digit 2: 2 (KeyDown) +7:1249:0:98:1 //FX Param digit 2: NUM 2 (KeyDown) +7:1250:0:51:1 //FX Param digit 3: 3 (KeyDown) +7:1250:0:99:1 //FX Param digit 3: NUM 3 (KeyDown) +7:1251:0:52:1 //FX Param digit 4: 4 (KeyDown) +7:1251:0:100:1 //FX Param digit 4: NUM 4 (KeyDown) +7:1252:0:53:1 //FX Param digit 5: 5 (KeyDown) +7:1252:0:101:1 //FX Param digit 5: NUM 5 (KeyDown) +7:1253:0:54:1 //FX Param digit 6: 6 (KeyDown) +7:1253:0:102:1 //FX Param digit 6: NUM 6 (KeyDown) +7:1254:0:55:1 //FX Param digit 7: 7 (KeyDown) +7:1254:0:103:1 //FX Param digit 7: NUM 7 (KeyDown) +7:1255:0:56:1 //FX Param digit 8: 8 (KeyDown) +7:1255:0:104:1 //FX Param digit 8: NUM 8 (KeyDown) +7:1256:0:57:1 //FX Param digit 9: 9 (KeyDown) +7:1256:0:105:1 //FX Param digit 9: NUM 9 (KeyDown) +7:1257:0:65:1 //FX Param digit A: A (KeyDown) +7:1258:0:66:1 //FX Param digit B: B (KeyDown) +7:1259:0:67:1 //FX Param digit C: C (KeyDown) +7:1260:0:68:1 //FX Param digit D: D (KeyDown) +7:1261:0:69:1 //FX Param digit E: E (KeyDown) +7:1262:0:70:1 //FX Param digit F: F (KeyDown) + +//----( Sample Context [bottom] (8) )------------ +8:1380:2:84:1 //Trim sample around loop points: Ctrl+T (KeyDown) +8:1383:0:8:1 //Silence sample selection: ASKELPALAUTIN (KeyDown) +8:1384:3:78:1 //Normalise Sample: Shift+Ctrl+N (KeyDown) +8:1385:3:65:1 //Amplify Sample: Shift+Ctrl+A (KeyDown) +8:1381:3:82:1 //Reverse sample: Shift+Ctrl+R (KeyDown) +8:1382:0:46:1 //Delete sample selection: DEL (KeyDown) +8:1386:0:107:1 //Zoom Out: NUM PLUS (KeyDown) +8:1387:0:109:1 //Zoom In: NUM MIINUS (KeyDown) + +//----( Instrument Context [bottom] (9) )------------ +9:1837:2:90:1 //Zoom In: Ctrl+Z (KeyDown) +9:1838:2:226:1 //Zoom Out: Ctrl+< (KeyDown) +9:1829:1:83:1 //Set loop start: Shift+S (KeyDown) +9:1830:1:69:1 //Set loop end: Shift+E (KeyDown) + +//----( Comments Context [bottom] (10) )------------ + +//----( Unknown Context (11) )------------ + +//----( Unknown Context (12) )------------ + +//----( Plugin GUI Context (13) )------------ + +//----( General Context [top] (14) )------------ + +//----( Pattern Context [top] (15) )------------ + +//----( Sample Context [top] (16) )------------ + +//----( Instrument Context [top] (17) )------------ +17:1851:2:68:1 //Duplicate instrument: Ctrl+D (KeyDown) +17:1850:3:69:1 //Edit sample map: Shift+Ctrl+E (KeyDown) +17:1849:2:69:1 //Edit current sample: Ctrl+E (KeyDown) +17:1846:3:77:1 //Map all notes to selected note: Shift+Ctrl+M (KeyDown) +17:1847:2:77:1 //Map all notes to selected sample: Ctrl+M (KeyDown) +17:1848:2:82:1 //Reset note mapping: Ctrl+R (KeyDown) +17:1843:2:81:1 //Transpose +1 (note map): Ctrl+Q (KeyDown) +17:1842:2:65:1 //Transpose -1 (note map): Ctrl+A (KeyDown) +17:1845:3:81:1 //Transpose +12 (note map): Shift+Ctrl+Q (KeyDown) +17:1844:3:65:1 //Transpose -12 (note map): Shift+Ctrl+A (KeyDown) + +//----( Comments Context [top] (18) )------------ + +//----( Orderlist (19) )------------ +19:1802:0:46:5 //Delete Order: DEL (KeyDown|KeyHold) +19:1803:0:45:5 //Insert Order: INS (KeyDown|KeyHold) +19:1804:0:13:5 //Edit Pattern: ENTER (KeyDown|KeyHold) +19:1805:0:9:5 //Switch to pattern editor: SARKAIN (KeyDown|KeyHold) +19:1794:0:37:5 //Previous Order: VASEN NUOLI (KeyDown|KeyHold) +19:1794:0:38:5 //Previous Order: YL\xC4NUOLI (KeyDown|KeyHold) +19:1795:0:39:5 //Next Order: OIKEA NUOLI (KeyDown|KeyHold) +19:1795:0:40:5 //Next Order: ALANUOLI (KeyDown|KeyHold) +19:1796:0:36:5 //First Order: HOME (KeyDown|KeyHold) +19:1797:0:35:5 //Last Order: END (KeyDown|KeyHold) +19:1807:0:48:5 //Pattern index digit 0: 0 (KeyDown|KeyHold) +19:1807:0:96:5 //Pattern index digit 0: NUM 0 (KeyDown|KeyHold) +19:1808:0:49:5 //Pattern index digit 1: 1 (KeyDown|KeyHold) +19:1808:0:97:5 //Pattern index digit 1: NUM 1 (KeyDown|KeyHold) +19:1809:0:50:5 //Pattern index digit 2: 2 (KeyDown|KeyHold) +19:1809:0:98:5 //Pattern index digit 2: NUM 2 (KeyDown|KeyHold) +19:1810:0:51:5 //Pattern index digit 3: 3 (KeyDown|KeyHold) +19:1810:0:99:5 //Pattern index digit 3: NUM 3 (KeyDown|KeyHold) +19:1811:0:52:5 //Pattern index digit 4: 4 (KeyDown|KeyHold) +19:1811:0:100:5 //Pattern index digit 4: NUM 4 (KeyDown|KeyHold) +19:1812:0:53:5 //Pattern index digit 5: 5 (KeyDown|KeyHold) +19:1812:0:101:5 //Pattern index digit 5: NUM 5 (KeyDown|KeyHold) +19:1813:0:54:5 //Pattern index digit 6: 6 (KeyDown|KeyHold) +19:1813:0:102:5 //Pattern index digit 6: NUM 6 (KeyDown|KeyHold) +19:1814:0:55:5 //Pattern index digit 7: 7 (KeyDown|KeyHold) +19:1814:0:103:5 //Pattern index digit 7: NUM 7 (KeyDown|KeyHold) +19:1815:0:56:5 //Pattern index digit 8: 8 (KeyDown|KeyHold) +19:1815:0:104:5 //Pattern index digit 8: NUM 8 (KeyDown|KeyHold) +19:1816:0:57:5 //Pattern index digit 9: 9 (KeyDown|KeyHold) +19:1816:0:105:5 //Pattern index digit 9: NUM 9 (KeyDown|KeyHold) +19:1817:0:107:5 //Increase pattern index : NUM PLUS (KeyDown|KeyHold) +19:1817:0:187:5 //Increase pattern index : + (KeyDown|KeyHold) +19:1818:0:109:1 //Decrease pattern index: NUM MIINUS (KeyDown) +19:1818:0:189:1 //Decrease pattern index: - (KeyDown) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-03-03 15:14:45
|
Revision: 1201 http://modplug.svn.sourceforge.net/modplug/?rev=1201&view=rev Author: saga-games Date: 2012-03-03 15:14:35 +0000 (Sat, 03 Mar 2012) Log Message: ----------- [Ref] Encapsulated various SNDMIXPLUGININFO variables in getter / setter functions as access to them was not very intuitive most of the time. [Ref] Made exception handler use the already existing GetOpenDocuments function. [Ref] Removed NO_FILTER #ifdefs from player engine (still preset in mixing engine). Modified Paths: -------------- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Draw_pat.cpp trunk/OpenMPT/mptrack/ExceptionHandler.cpp trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp trunk/OpenMPT/mptrack/MPTHacks.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/SelectPluginDialog.cpp trunk/OpenMPT/mptrack/SelectPluginDialog.h trunk/OpenMPT/mptrack/SoundFilePlayConfig.cpp trunk/OpenMPT/mptrack/SoundFilePlayConfig.h trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/test/test.cpp trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/mptrack/view_com.cpp trunk/OpenMPT/soundlib/Fastmix.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/PlugInterface.h trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Snd_flt.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -291,13 +291,12 @@ if (m_pVstPlugin && m_pVstPlugin->m_pMixStruct) { CString Title; - Title.Format("FX %02d: ", m_pVstPlugin->m_nSlot+1); + Title.Format("FX %02d: ", m_pVstPlugin->m_nSlot + 1); - if (m_pVstPlugin->m_pMixStruct->Info.szName[0]) { - Title.Append(m_pVstPlugin->m_pMixStruct->Info.szName); - } else { - Title.Append(m_pVstPlugin->m_pMixStruct->Info.szLibraryName); - } + if (strcmp(m_pVstPlugin->m_pMixStruct->GetName(), "")) + Title.Append(m_pVstPlugin->m_pMixStruct->GetName()); + else + Title.Append(m_pVstPlugin->m_pMixStruct->GetLibraryName()); SetWindowText(Title); } @@ -495,8 +494,8 @@ m_pVstPlugin->GetInputPlugList(inputPlugs); for (int nPlug=0; nPlug<inputPlugs.GetSize(); nPlug++) { - name.Format("FX%02d: %s", inputPlugs[nPlug]->m_nSlot+1, inputPlugs[nPlug]->m_pMixStruct->Info.szName); - m_pInputMenu->AppendMenu(MF_STRING, ID_PLUGSELECT+inputPlugs[nPlug]->m_nSlot, name); + name.Format("FX%02d: %s", inputPlugs[nPlug]->m_nSlot + 1, inputPlugs[nPlug]->m_pMixStruct->GetName()); + m_pInputMenu->AppendMenu(MF_STRING, ID_PLUGSELECT + inputPlugs[nPlug]->m_nSlot, name); } CArray<UINT, UINT> inputChannels; @@ -555,12 +554,13 @@ m_pVstPlugin->GetOutputPlugList(outputPlugs); CString name; - for (int nPlug = 0; nPlug < outputPlugs.GetSize(); nPlug++ - ) { - if (outputPlugs[nPlug] != NULL) { - name.Format("FX%02d: %s", outputPlugs[nPlug]->m_nSlot+1, - outputPlugs[nPlug]->m_pMixStruct->Info.szName); - m_pOutputMenu->AppendMenu(MF_STRING, ID_PLUGSELECT+outputPlugs[nPlug]->m_nSlot, name); + for (int nPlug = 0; nPlug < outputPlugs.GetSize(); nPlug++) + { + if (outputPlugs[nPlug] != nullptr) + { + name.Format("FX%02d: %s", outputPlugs[nPlug]->m_nSlot + 1, + outputPlugs[nPlug]->m_pMixStruct->GetName()); + m_pOutputMenu->AppendMenu(MF_STRING, ID_PLUGSELECT + outputPlugs[nPlug]->m_nSlot, name); } else { name = "Master Output"; @@ -772,8 +772,8 @@ ModInstrument *pIns = pSndFile->Instruments[nIns]; m_nInstrument = nIns; - _snprintf(pIns->name, CountOf(pIns->name) - 1, _T("%d: %s"), m_pVstPlugin->GetSlot() + 1, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].Info.szName); - strncpy(pIns->filename, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].Info.szLibraryName, CountOf(pIns->filename) - 1); + _snprintf(pIns->name, CountOf(pIns->name) - 1, _T("%d: %s"), m_pVstPlugin->GetSlot() + 1, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].GetName()); + strncpy(pIns->filename, pSndFile->m_MixPlugins[m_pVstPlugin->GetSlot()].GetLibraryName(), CountOf(pIns->filename) - 1); pIns->nMixPlug = (PLUGINDEX)m_pVstPlugin->GetSlot() + 1; pIns->nMidiChannel = 1; // People will forget to change this anyway, so the following lines can lead to some bad surprises after re-opening the module. Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -833,11 +833,11 @@ vector<bool> usedmap(MAX_MIXPLUGINS, false); - for (PLUGINDEX nPlug = 0; nPlug < MAX_MIXPLUGINS; nPlug++) + for(PLUGINDEX nPlug = 0; nPlug < MAX_MIXPLUGINS; nPlug++) { // Is the plugin assigned to a channel? - for (CHANNELINDEX nChn = 0; nChn < pSndFile->GetNumChannels(); nChn++) + for(CHANNELINDEX nChn = 0; nChn < pSndFile->GetNumChannels(); nChn++) { if (pSndFile->ChnSettings[nChn].nMixPlugin == nPlug + 1) { @@ -847,7 +847,7 @@ } // Is the plugin used by an instrument? - for (INSTRUMENTINDEX nIns = 1; nIns <= pSndFile->GetNumInstruments(); nIns++) + for(INSTRUMENTINDEX nIns = 1; nIns <= pSndFile->GetNumInstruments(); nIns++) { if (pSndFile->Instruments[nIns] && (pSndFile->Instruments[nIns]->nMixPlug == nPlug + 1)) { @@ -857,16 +857,19 @@ } // Is the plugin assigned to master? - if (pSndFile->m_MixPlugins[nPlug].Info.dwInputRouting & MIXPLUG_INPUTF_MASTEREFFECT) + if(pSndFile->m_MixPlugins[nPlug].IsMasterEffect()) usedmap[nPlug] = true; // All outputs of used plugins count as used - if (usedmap[nPlug] != false) + if(usedmap[nPlug] != false) { - if (pSndFile->m_MixPlugins[nPlug].Info.dwOutputRouting & 0x80) + if(!pSndFile->m_MixPlugins[nPlug].IsOutputToMaster()) { - int output = pSndFile->m_MixPlugins[nPlug].Info.dwOutputRouting & 0x7f; - usedmap[output] = true; + PLUGINDEX output = pSndFile->m_MixPlugins[nPlug].GetOutputPlugin(); + if(output < MAX_MIXPLUGINS) + { + usedmap[output] = true; + } } } Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -1229,7 +1229,7 @@ // MIDI Channel // XM has no "mapped" MIDI channels. m_CbnMidiCh.ResetContent(); - for (UINT ich = MidiNoChannel; ich <= (bITandMPT ? MidiMappedChannel : MidiLastChannel); ich++) + for(int ich = MidiNoChannel; ich <= (bITandMPT ? MidiMappedChannel : MidiLastChannel); ich++) { CString s; if (ich == MidiNoChannel) @@ -2141,12 +2141,13 @@ m_CbnPluginVelocityHandling.SetCurSel(pIns->nPluginVelocityHandling); m_CbnPluginVolumeHandling.SetCurSel(pIns->nPluginVolumeHandling); - if (pIns->nMixPlug) //if we have not just set to no plugin + if (pIns->nMixPlug) { - PSNDMIXPLUGIN pPlug = &(m_pSndFile->m_MixPlugins[pIns->nMixPlug - 1]); - if ((pPlug == nullptr || pPlug->pMixPlugin == nullptr) && !IsLocked()) + // we have selected a plugin that's not "no plugin" + const SNDMIXPLUGIN &plugin = m_pSndFile->m_MixPlugins[pIns->nMixPlug - 1]; + if(!plugin.IsValidPlugin() && !IsLocked()) { - // No plugin in this slot: Ask user to add one. + // No plugin in this slot yet: Ask user to add one. #ifndef NO_VST CSelectPluginDlg dlg(m_pModDoc, nPlug - 1, this); if (dlg.DoModal() == IDOK) @@ -2161,13 +2162,13 @@ #endif // NO_VST } - if (pPlug && pPlug->pMixPlugin) + if(plugin.pMixPlugin) { ::EnableWindow(::GetDlgItem(m_hWnd, IDC_INSVIEWPLG), true); // if this plug can recieve MIDI events and we have no MIDI channel // selected for this instrument, automatically select MIDI channel 1. - if (pPlug->pMixPlugin->isInstrument() && pIns->nMidiChannel == 0) + if(plugin.pMixPlugin->isInstrument() && pIns->nMidiChannel == 0) { pIns->nMidiChannel = 1; UpdateView((m_nInstrument << HINT_SHIFT_INS) | HINT_INSTRUMENT, NULL); @@ -2855,16 +2856,15 @@ CHAR s[64]; for (PLUGINDEX nPlug = 0; nPlug <= MAX_MIXPLUGINS; nPlug++) { - if (!nPlug) + if(!nPlug) { strcpy(s, "No plugin"); } else { - PSNDMIXPLUGIN p = &(m_pSndFile->m_MixPlugins[nPlug - 1]); - p->Info.szLibraryName[63] = 0; - if (p->Info.szLibraryName[0]) - wsprintf(s, "FX%d: %s", nPlug, p->Info.szName); + const SNDMIXPLUGIN &plugin = m_pSndFile->m_MixPlugins[nPlug - 1]; + if(plugin.IsValidPlugin()) + wsprintf(s, "FX%d: %s", nPlug, plugin.GetName()); else wsprintf(s, "FX%d: undefined", nPlug); } Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -1232,15 +1232,16 @@ void CCtrlPatterns::TogglePluginEditor() //-------------------------------------- { - if(m_nInstrument && m_pModDoc && m_pSndFile && m_pSndFile->Instruments[m_nInstrument]) + if(m_nInstrument && m_pModDoc && m_pSndFile && m_pSndFile->Instruments[m_nInstrument] != nullptr) { - UINT nPlug = m_pSndFile->Instruments[m_nInstrument]->nMixPlug; - if (nPlug) //if not no plugin + PLUGINDEX nPlug = m_pSndFile->Instruments[m_nInstrument]->nMixPlug; + if(nPlug) { - PSNDMIXPLUGIN pPlug = &(m_pSndFile->m_MixPlugins[nPlug-1]); - if (pPlug && pPlug->pMixPlugin) //if has valid plugin + // Has a plugin assigned + if(m_pSndFile->m_MixPlugins[nPlug - 1].pMixPlugin != nullptr) { - m_pModDoc->TogglePluginEditor(nPlug-1); + // Has a valid plugin assigned + m_pModDoc->TogglePluginEditor(nPlug - 1); } } } @@ -1250,16 +1251,13 @@ bool CCtrlPatterns::HasValidPlug(UINT instr) //------------------------------------------ { - if ((instr) && (instr<MAX_INSTRUMENTS) && (m_pSndFile) && m_pSndFile->Instruments[instr]) + if ((instr) && (instr < MAX_INSTRUMENTS) && (m_pSndFile) && m_pSndFile->Instruments[instr] != nullptr) { - UINT nPlug = m_pSndFile->Instruments[instr]->nMixPlug; - if (nPlug) //if not no plugin + PLUGINDEX nPlug = m_pSndFile->Instruments[instr]->nMixPlug; + if(nPlug) { - PSNDMIXPLUGIN pPlug = &(m_pSndFile->m_MixPlugins[nPlug-1]); - if (pPlug && pPlug->pMixPlugin) //if has valid plugin - { - return true ; - } + // Has a plugin assigned + return (m_pSndFile->m_MixPlugins[nPlug - 1].pMixPlugin != nullptr); } } return false; Modified: trunk/OpenMPT/mptrack/Draw_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Draw_pat.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/Draw_pat.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -631,7 +631,7 @@ rect.bottom+=PLUGNAME_HEIGHT; mixPlug=pSndFile->ChnSettings[ncolhdr].nMixPlugin; if (mixPlug) { - wsprintf(s, "%d: %s", mixPlug, (pSndFile->m_MixPlugins[mixPlug-1]).pMixPlugin?(pSndFile->m_MixPlugins[mixPlug-1]).Info.szName:"[empty]"); + wsprintf(s, "%d: %s", mixPlug, (pSndFile->m_MixPlugins[mixPlug - 1]).pMixPlugin ? (pSndFile->m_MixPlugins[mixPlug - 1]).GetName() : "[empty]"); } else { wsprintf(s, "---"); } Modified: trunk/OpenMPT/mptrack/ExceptionHandler.cpp =================================================================== --- trunk/OpenMPT/mptrack/ExceptionHandler.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/ExceptionHandler.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -53,8 +53,13 @@ // Shut down audio device... if(pMainFrame) { - if(pMainFrame->gpSoundDevice) pMainFrame->gpSoundDevice->Reset(); - pMainFrame->audioCloseDevice(); + try + { + if(pMainFrame->gpSoundDevice) pMainFrame->gpSoundDevice->Reset(); + pMainFrame->audioCloseDevice(); + } catch(...) + { + } } CString errorMessage; @@ -106,41 +111,34 @@ } // Rescue modified files... - CDocTemplate *pDocTmpl = theApp.GetModDocTemplate(); - if(pDocTmpl) + int numFiles = 0; + vector<CModDoc *> documents = theApp.GetOpenDocuments(); + for(vector<CModDoc *>::iterator doc = documents.begin(); doc != documents.end(); doc++) { - POSITION pos = pDocTmpl->GetFirstDocPosition(); - CDocument *pDoc; - - int numFiles = 0; - - while((pos != NULL) && ((pDoc = pDocTmpl->GetNextDoc(pos)) != NULL)) + CModDoc *pModDoc = *doc; + if(pModDoc->IsModified() && pModDoc->GetSoundFile() != nullptr) { - CModDoc *pModDoc = (CModDoc *)pDoc; - if(pModDoc->IsModified() && pModDoc->GetSoundFile() != nullptr) + if(numFiles == 0) { - if(numFiles == 0) - { - // Show the rescue directory in Explorer... - CTrackApp::OpenDirectory(baseRescuePath); - } - CString filename; - filename.Format("%s%d_%s.%s", baseRescuePath, ++numFiles, pModDoc->GetTitle(), pModDoc->GetSoundFile()->GetModSpecifications().fileExtension); + // Show the rescue directory in Explorer... + CTrackApp::OpenDirectory(baseRescuePath); + } + CString filename; + filename.Format("%s%d_%s.%s", baseRescuePath, ++numFiles, pModDoc->GetTitle(), pModDoc->GetSoundFile()->GetModSpecifications().fileExtension); - try - { - pModDoc->OnSaveDocument(filename); - } catch(...) - { - continue; - } + try + { + pModDoc->OnSaveDocument(filename); + } catch(...) + { + continue; } } + } - if(numFiles > 0) - { - errorMessage.AppendFormat("\n\n%d modified file%s been rescued, but it cannot be guaranteed that %s still intact.", numFiles, (numFiles == 1 ? " has" : "s have"), (numFiles == 1 ? "it is" : "they are")); - } + if(numFiles > 0) + { + errorMessage.AppendFormat("\n\n%d modified file%s been rescued, but it cannot be guaranteed that %s still intact.", numFiles, (numFiles == 1 ? " has" : "s have"), (numFiles == 1 ? "it is" : "they are")); } Reporting::Error(errorMessage, "OpenMPT Crash", pMainFrame); Modified: trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/MIDIMacroDialog.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -126,14 +126,14 @@ } UpdateMacroList(); - for(PLUGINDEX plug = 0; plug < MAX_MIXPLUGINS; plug++) + for(PLUGINDEX i = 0; i < MAX_MIXPLUGINS; i++) { - PSNDMIXPLUGIN p = &(m_SndFile.m_MixPlugins[plug]); - StringFixer::SetNullTerminator(p->Info.szLibraryName); - if (p->Info.szLibraryName[0]) + const SNDMIXPLUGIN &plugin = m_SndFile.m_MixPlugins[i]; + + if(plugin.IsValidPlugin()) { - wsprintf(s, "FX%d: %s", plug + 1, p->Info.szName); - m_CbnMacroPlug.SetItemData(m_CbnMacroPlug.AddString(s), plug); + wsprintf(s, "FX%d: %s", i + 1, plugin.GetName()); + m_CbnMacroPlug.SetItemData(m_CbnMacroPlug.AddString(s), i); } } m_CbnMacroPlug.SetCurSel(0); @@ -369,7 +369,7 @@ for(PLUGINDEX plug = 0; plug < MAX_MIXPLUGINS; plug++) { - plugName = m_SndFile.m_MixPlugins[plug].Info.szName; + plugName = m_SndFile.m_MixPlugins[plug].GetName(); if(m_SndFile.m_MixPlugins[plug].Info.dwPluginId1 != 0) { pVstPlugin = (CVstPlugin*) m_SndFile.m_MixPlugins[plug].pMixPlugin; @@ -392,10 +392,9 @@ if (plug < 0 || plug > MAX_MIXPLUGINS) return; - PSNDMIXPLUGIN pPlugin = &m_SndFile.m_MixPlugins[plug]; - CVstPlugin *pVstPlugin = (pPlugin->pMixPlugin) ? (CVstPlugin *)pPlugin->pMixPlugin : NULL; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(m_SndFile.m_MixPlugins[plug].pMixPlugin); - if (pVstPlugin) + if (pVstPlugin != nullptr) { m_CbnMacroParam.SetRedraw(FALSE); m_CbnMacroParam.Clear(); Modified: trunk/OpenMPT/mptrack/MPTHacks.cpp =================================================================== --- trunk/OpenMPT/mptrack/MPTHacks.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/MPTHacks.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -182,7 +182,7 @@ foundHere = false; for(PLUGINDEX i = 0; i < MAX_MIXPLUGINS; i++) { - if(m_SndFile.m_MixPlugins[i].pMixPlugin != nullptr || m_SndFile.m_MixPlugins[i].Info.dwPluginId1 || m_SndFile.m_MixPlugins[i].Info.dwPluginId2) + if(m_SndFile.m_MixPlugins[i].IsValidPlugin()) { foundHere = foundHacks = true; break; Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -1895,16 +1895,16 @@ { CSoundFile *pSndFile = pModDoc->GetSoundFile(); //Find empty plugin slot - for (int nPlug=0; nPlug<MAX_MIXPLUGINS; nPlug++) + for (PLUGINDEX nPlug = 0; nPlug < MAX_MIXPLUGINS; nPlug++) { - PSNDMIXPLUGIN pCandidatePlugin = &pSndFile->m_MixPlugins[nPlug]; - if (pCandidatePlugin->pMixPlugin == NULL) + if (pSndFile->m_MixPlugins[nPlug].pMixPlugin == NULL) { - nPlugslot=nPlug; + nPlugslot = nPlug; break; } } } + CSelectPluginDlg dlg(GetActiveDoc(), nPlugslot, this); if(dlg.DoModal() == IDOK && pModDoc) { @@ -2681,12 +2681,12 @@ { for (PLUGINDEX iPlug = 0; iPlug < MAX_MIXPLUGINS; iPlug++) { - PSNDMIXPLUGIN p = &plugarray[iPlug]; + const SNDMIXPLUGIN &plugin = plugarray[iPlug]; CString str; str.Preallocate(80); str.Format(_T("FX%d: "), iPlug + 1); const int size0 = str.GetLength(); - str += (librarynames) ? p->GetLibraryName() : p->GetName(); + str += (librarynames) ? plugin.GetLibraryName() : plugin.GetName(); if(str.GetLength() <= size0) str += _T("undefined"); CBox.SetItemData(CBox.AddString(str), iPlug + 1); Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -2511,12 +2511,11 @@ void CModDoc::TogglePluginEditor(UINT m_nCurrentPlugin) //----------------------------------------------------- { - PSNDMIXPLUGIN pPlugin; + SNDMIXPLUGIN &plugin = m_SndFile.m_MixPlugins[m_nCurrentPlugin]; - pPlugin = &m_SndFile.m_MixPlugins[m_nCurrentPlugin]; - if (m_nCurrentPlugin<MAX_MIXPLUGINS && pPlugin && pPlugin->pMixPlugin) + if (m_nCurrentPlugin < MAX_MIXPLUGINS && plugin.pMixPlugin) { - CVstPlugin *pVstPlugin = (CVstPlugin *)pPlugin->pMixPlugin; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(plugin.pMixPlugin); pVstPlugin->ToggleEditor(); } Modified: trunk/OpenMPT/mptrack/SelectPluginDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/SelectPluginDialog.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/SelectPluginDialog.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -14,6 +14,7 @@ #include "Mainfrm.h" #include "Moddoc.h" #include "SelectPluginDialog.h" +#include "../common/StringFixer.h" #ifndef NO_VST @@ -139,12 +140,14 @@ { // Enable drymix by default for these known plugins case CCONST('S', 'c', 'o', 'p'): - m_pPlugin->Info.dwInputRouting |= MIXPLUG_INPUTF_WETMIX; + m_pPlugin->SetWetMix(); break; } lstrcpyn(m_pPlugin->Info.szName, pFactory->szLibraryName, 32); lstrcpyn(m_pPlugin->Info.szLibraryName, pFactory->szLibraryName, 64); + StringFixer::SetNullTerminator(m_pPlugin->Info.szName); + StringFixer::SetNullTerminator(m_pPlugin->Info.szLibraryName); cs.Leave(); Modified: trunk/OpenMPT/mptrack/SelectPluginDialog.h =================================================================== --- trunk/OpenMPT/mptrack/SelectPluginDialog.h 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/SelectPluginDialog.h 2012-03-03 15:14:35 UTC (rev 1201) @@ -21,7 +21,7 @@ { protected: int m_nPlugSlot; - PSNDMIXPLUGIN m_pPlugin; + SNDMIXPLUGIN *m_pPlugin; CModDoc *m_pModDoc; CTreeCtrl m_treePlugins; CString m_sNameFilter; Modified: trunk/OpenMPT/mptrack/SoundFilePlayConfig.cpp =================================================================== --- trunk/OpenMPT/mptrack/SoundFilePlayConfig.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/SoundFilePlayConfig.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -113,23 +113,6 @@ setExtraSampleAttenuation(1); break; - // FOR TEST PURPOSES ONLY: - /* - case mixLevels_Test: - setVSTiAttenuation(1.0f); - setIntToFloat(1.0f/static_cast<float>(MIXING_CLIPMAX)); - setFloatToInt(static_cast<float>(MIXING_CLIPMAX)); - setGlobalVolumeAppliesToMaster(true); - setUseGlobalPreAmp(false); - setForceSoftPanning(true); - setDisplayDBValues(true); - setNormalSamplePreAmp(128.0); - setNormalVSTiVol(128.0); - setNormalGlobalVol(256.0); - setExtraAttenuation(0); - break; - */ - } return; Modified: trunk/OpenMPT/mptrack/SoundFilePlayConfig.h =================================================================== --- trunk/OpenMPT/mptrack/SoundFilePlayConfig.h 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/SoundFilePlayConfig.h 2012-03-03 15:14:35 UTC (rev 1201) @@ -25,14 +25,13 @@ tempo_mode_modern = 2, }; -enum +enum mixLevels { mixLevels_original = 0, mixLevels_117RC1 = 1, mixLevels_117RC2 = 2, mixLevels_117RC3 = 3, mixLevels_compatible = 4, - mixLevels_Test = 5, }; enum forcePanningMode Modified: trunk/OpenMPT/mptrack/View_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/View_gen.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -238,7 +238,7 @@ } -VOID CViewGlobals::OnDestroy() +void CViewGlobals::OnDestroy() //---------------------------- { CChildFrame *pFrame = (CChildFrame *)GetParentFrame(); @@ -391,12 +391,11 @@ int fxsel = 0; for (UINT ifx=0; ifx<MAX_MIXPLUGINS; ifx++) { - if ((pSndFile->m_MixPlugins[ifx].Info.dwPluginId1) - || (pSndFile->m_MixPlugins[ifx].Info.dwPluginId2) - || (pSndFile->m_MixPlugins[ifx].Info.szName[0] - || (pSndFile->ChnSettings[nChn].nMixPlugin == ifx+1))) + if (pSndFile->m_MixPlugins[ifx].IsValidPlugin() + || (strcmp(pSndFile->m_MixPlugins[ifx].GetName(), "") + || (pSndFile->ChnSettings[nChn].nMixPlugin == ifx + 1))) { - wsprintf(s, "FX%d: %s", ifx+1, pSndFile->m_MixPlugins[ifx].Info.szName); + wsprintf(s, "FX%d: %s", ifx + 1, pSndFile->m_MixPlugins[ifx].GetName()); int n = m_CbnEffects[ichn].AddString(s); m_CbnEffects[ichn].SetItemData(n, ifx+1); if (pSndFile->ChnSettings[nChn].nMixPlugin == ifx+1) fxsel = n; @@ -434,16 +433,16 @@ m_CbnPlugin.SetRedraw(TRUE); m_CbnPlugin.SetCurSel(m_nCurrentPlugin); if (m_nCurrentPlugin >= MAX_MIXPLUGINS) m_nCurrentPlugin = 0; - PSNDMIXPLUGIN pPlugin = &(pSndFile->m_MixPlugins[m_nCurrentPlugin]); - SetDlgItemText(IDC_EDIT13, pPlugin->Info.szName); - CheckDlgButton(IDC_CHECK9, (pPlugin->Info.dwInputRouting & MIXPLUG_INPUTF_MASTEREFFECT) ? TRUE : FALSE); - CheckDlgButton(IDC_CHECK10, (pPlugin->IsBypassed()) ? TRUE : FALSE); - CheckDlgButton(IDC_CHECK11, (pPlugin->Info.dwInputRouting & MIXPLUG_INPUTF_WETMIX) ? TRUE : FALSE); + SNDMIXPLUGIN *pPlugin = &(pSndFile->m_MixPlugins[m_nCurrentPlugin]); + SetDlgItemText(IDC_EDIT13, pPlugin->GetName()); + CheckDlgButton(IDC_CHECK9, pPlugin->IsMasterEffect() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECK10, pPlugin->IsBypassed() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECK11, pPlugin->IsWetMix() ? BST_CHECKED : BST_UNCHECKED); CVstPlugin *pVstPlugin = (pPlugin->pMixPlugin) ? (CVstPlugin *)pPlugin->pMixPlugin : NULL; m_BtnEdit.EnableWindow(((pVstPlugin) && ((pVstPlugin->HasEditor()) || (pVstPlugin->GetNumCommands()))) ? TRUE : FALSE); - ::EnableWindow(::GetDlgItem(m_hWnd, IDC_MOVEFXSLOT), (pVstPlugin)?TRUE:FALSE); - ::EnableWindow(::GetDlgItem(m_hWnd, IDC_INSERTFXSLOT), (pVstPlugin)?TRUE:FALSE); - ::EnableWindow(::GetDlgItem(m_hWnd, IDC_CLONEPLUG), (pVstPlugin)?TRUE:FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_MOVEFXSLOT), (pVstPlugin) ? TRUE : FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_INSERTFXSLOT), (pVstPlugin) ? TRUE : FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_CLONEPLUG), (pVstPlugin) ? TRUE : FALSE); //rewbs.DryRatio int n = static_cast<int>(pPlugin->fDryRatio*100); wsprintf(s, "(%d%% wet, %d%% dry)", 100-n, n); @@ -462,14 +461,14 @@ else{ ::EnableWindow(::GetDlgItem(m_hWnd, IDC_COMBO9), TRUE); ::EnableWindow(::GetDlgItem(m_hWnd, IDC_CHECK12), TRUE); - m_CbnSpecialMixProcessing.SetCurSel( (pPlugin->Info.dwInputRouting>>8) & 0xff ); // update#02 (fix) - CheckDlgButton(IDC_CHECK12, (pPlugin->Info.dwInputRouting & MIXPLUG_INPUTF_MIXEXPAND) ? TRUE : FALSE); + m_CbnSpecialMixProcessing.SetCurSel(pPlugin->GetMixMode()); // update#02 (fix) + CheckDlgButton(IDC_CHECK12, pPlugin->IsExpandedMix() ? BST_CHECKED : BST_UNCHECKED); } // update#02 - DWORD gain = (pPlugin->Info.dwInputRouting>>16) & 0xff; + int gain = pPlugin->GetGain(); if(gain == 0) gain = 10; float value = 0.1f * (float)gain; - sprintf(s,"Gain: x %1.1f",value); + sprintf(s,"Gain: x %1.1f", value); SetDlgItemText(IDC_STATIC2, s); m_SpinMixGain.SetPos(gain); // -! BEHAVIOUR_CHANGE#0028 @@ -537,21 +536,21 @@ m_CbnOutput.SetItemData(m_CbnOutput.AddString("Default"), 0); for (PLUGINDEX iOut = m_nCurrentPlugin + 1; iOut < MAX_MIXPLUGINS; iOut++) { - PSNDMIXPLUGIN p = &pSndFile->m_MixPlugins[iOut]; - if (p->Info.dwPluginId1) + const SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[iOut]; + if(plugin.IsValidPlugin()) { - if(!strcmp(p->Info.szLibraryName, p->Info.szName) || strlen(p->Info.szName) == 0) + if(!strcmp(plugin.GetLibraryName(), plugin.GetName()) || !strcmp(plugin.GetName(), "")) { - wsprintf(s, "FX%d: %s", iOut + 1, p->Info.szLibraryName); + wsprintf(s, "FX%d: %s", iOut + 1, plugin.GetLibraryName()); } else { - wsprintf(s, "FX%d: %s (%s)", iOut + 1, p->Info.szLibraryName, p->Info.szName); + wsprintf(s, "FX%d: %s (%s)", iOut + 1, plugin.GetLibraryName(), plugin.GetName()); } int n = m_CbnOutput.AddString(s); - m_CbnOutput.SetItemData(n, 0x80|iOut); - if ((pSndFile->m_MixPlugins[m_nCurrentPlugin].Info.dwOutputRouting & 0x80) - && ((pSndFile->m_MixPlugins[m_nCurrentPlugin].Info.dwOutputRouting & 0x7f) == iOut)) + m_CbnOutput.SetItemData(n, 0x80 + iOut); + if (!pSndFile->m_MixPlugins[m_nCurrentPlugin].IsOutputToMaster() + && (pSndFile->m_MixPlugins[m_nCurrentPlugin].GetOutputPlugin() == iOut)) { outputsel = n; } @@ -708,14 +707,13 @@ if ((n >= 0) && (n <= 100) && (m_nCurrentPlugin < MAX_MIXPLUGINS)) { CSoundFile *pSndFile = pModDoc->GetSoundFile(); - PSNDMIXPLUGIN pPlugin; + SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[m_nCurrentPlugin]; - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if (pPlugin->pMixPlugin) + if (plugin.pMixPlugin) { - wsprintf(s, "(%d%% wet, %d%% dry)", 100-n, n); + wsprintf(s, "(%d%% wet, %d%% dry)", 100 - n, n); SetDlgItemText(IDC_STATIC8, s); - pPlugin->fDryRatio = static_cast<float>(n)/100.0f; + plugin.fDryRatio = static_cast<float>(n) / 100.0f; if(pSndFile->GetModSpecifications().supportsPlugins) pModDoc->SetModified(); } @@ -732,12 +730,11 @@ if ((n >= 0) && (n <= 100) && (m_nCurrentPlugin < MAX_MIXPLUGINS)) { CSoundFile *pSndFile = pModDoc->GetSoundFile(); - PSNDMIXPLUGIN pPlugin; + SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[m_nCurrentPlugin]; - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if (pPlugin->pMixPlugin) + if (plugin.pMixPlugin) { - CVstPlugin *pVstPlugin = (CVstPlugin *)pPlugin->pMixPlugin; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(plugin.pMixPlugin); const PlugParamIndex nParams = pVstPlugin->GetNumParameters(); if (m_nCurrentParam < nParams) { @@ -765,24 +762,22 @@ // -> CODE#0028 update#02 // -> DESC="effect plugin mixing mode combo" CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; - CSoundFile *pSndFile; + CSoundFile *pSndFile = pModDoc->GetSoundFile(); CHAR s[32]; if((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; - if(nSBCode != SB_ENDSCROLL && pScrollBar && pScrollBar == (CScrollBar*)&m_SpinMixGain){ + if(nSBCode != SB_ENDSCROLL && pScrollBar && pScrollBar == (CScrollBar*)&m_SpinMixGain) + { - pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; + SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if(pPlugin->pMixPlugin) + if(plugin.pMixPlugin) { DWORD gain = nPos; if(gain == 0) gain = 1; - pPlugin->Info.dwInputRouting = (pPlugin->Info.dwInputRouting & 0xff00ffff) | (gain<<16); - pPlugin->pMixPlugin->RecalculateGain(); + plugin.SetGain(gain); float fValue = 0.1f * (float)gain; sprintf(s,"Gain: x %1.1f",fValue); @@ -858,18 +853,18 @@ void CViewGlobals::OnPluginNameChanged() //-------------------------------------- { - CHAR s[64]; + CHAR s[32]; CModDoc *pModDoc = GetDocument(); if ((pModDoc) && (m_nCurrentPlugin < MAX_MIXPLUGINS)) { CSoundFile *pSndFile = pModDoc->GetSoundFile(); - memset(s, 0, 32); + GetDlgItemText(IDC_EDIT13, s, 32); - s[31] = 0; - if (strcmp(s, pSndFile->m_MixPlugins[m_nCurrentPlugin].Info.szName)) + StringFixer::SetNullTerminator(s); + if (strcmp(s, pSndFile->m_MixPlugins[m_nCurrentPlugin].GetName())) { - memcpy(pSndFile->m_MixPlugins[m_nCurrentPlugin].Info.szName, s, 32); + lstrcpyn(pSndFile->m_MixPlugins[m_nCurrentPlugin].Info.szName, s, 32); if(pSndFile->GetModSpecifications().supportsPlugins) pModDoc->SetModified(); pModDoc->UpdateAllViews(NULL, HINT_MODCHANNELS | (m_nActiveTab << HINT_SHIFT_CHNTAB)); @@ -965,15 +960,15 @@ int cursel = m_CbnParam.GetItemData(m_CbnParam.GetCurSel()); CModDoc *pModDoc = GetDocument(); CHAR s[256]; - PSNDMIXPLUGIN pPlugin; CSoundFile *pSndFile; if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if (pPlugin->pMixPlugin && cursel != CB_ERR) + SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[m_nCurrentPlugin]; + + if (plugin.pMixPlugin && cursel != CB_ERR) { - CVstPlugin *pVstPlugin = (CVstPlugin *)pPlugin->pMixPlugin; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(plugin.pMixPlugin); const PlugParamIndex nParams = pVstPlugin->GetNumParameters(); if ((cursel >= 0) && (cursel < nParams)) m_nCurrentParam = cursel; if (m_nCurrentParam < nParams) @@ -1000,15 +995,15 @@ { int cursel = m_CbnPreset.GetCurSel(); CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; CSoundFile *pSndFile; if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if (pPlugin->pMixPlugin) + SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[m_nCurrentPlugin]; + + if (plugin.pMixPlugin) { - CVstPlugin *pVstPlugin = (CVstPlugin *)pPlugin->pMixPlugin; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(plugin.pMixPlugin); UINT nParams = pVstPlugin->GetNumPrograms(); if ((cursel > 0) && (cursel <= (int)nParams)) m_nCurrentPreset = cursel; if (m_nCurrentPreset > 0 && m_nCurrentPreset <= nParams) @@ -1026,13 +1021,19 @@ //------------------------------ { CModDoc *pModDoc = GetDocument(); - CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; - PSNDMIXPLUGIN pPlugin = pSndFile ? &pSndFile->m_MixPlugins[m_nCurrentPlugin] : NULL; - CVstPlugin *pVstPlugin = pPlugin ? (CVstPlugin *)pPlugin->pMixPlugin : NULL; + CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : nullptr; + if(pSndFile == nullptr) + { + return; + } - //rewbs.fxpPresets: changed Eric's code to use fxp load/save - if(pVstPlugin == NULL) return; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(pSndFile->m_MixPlugins[m_nCurrentPlugin].pMixPlugin); + if(pVstPlugin == nullptr) + { + return; + } + FileDlgResult files = CTrackApp::ShowOpenSaveFileDialog(true, "fxp", "", "VST FX Program (*.fxp)|*.fxp||", CMainFrame::GetSettings().GetDefaultDirectory(DIR_PLUGINPRESETS)); @@ -1055,13 +1056,18 @@ //------------------------------ { CModDoc *pModDoc = GetDocument(); - CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; - PSNDMIXPLUGIN pPlugin = pSndFile ? &pSndFile->m_MixPlugins[m_nCurrentPlugin] : NULL; - CVstPlugin *pVstPlugin = pPlugin ? (CVstPlugin *)pPlugin->pMixPlugin : NULL; + CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : nullptr; + if(pSndFile == nullptr) + { + return; + } - if(pVstPlugin == NULL) return; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(pSndFile->m_MixPlugins[m_nCurrentPlugin].pMixPlugin); - //rewbs.fxpPresets: changed Eric's code to use fxp load/save + if(pVstPlugin == nullptr) + { + return; + } FileDlgResult files = CTrackApp::ShowOpenSaveFileDialog(false, "fxp", "", "VST Program (*.fxp)|*.fxp||", CMainFrame::GetSettings().GetDefaultDirectory(DIR_PLUGINPRESETS)); @@ -1076,19 +1082,19 @@ // -! NEW_FEATURE#0002 -VOID CViewGlobals::OnSetParameter() +void CViewGlobals::OnSetParameter() //--------------------------------- { CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; CSoundFile *pSndFile; if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if (pPlugin->pMixPlugin) + SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[m_nCurrentPlugin]; + + if (plugin.pMixPlugin != nullptr) { - CVstPlugin *pVstPlugin = (CVstPlugin *)pPlugin->pMixPlugin; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(plugin.pMixPlugin); const PlugParamIndex nParams = pVstPlugin->GetNumParameters(); CHAR s[32]; GetDlgItemText(IDC_EDIT14, s, sizeof(s)); @@ -1106,89 +1112,55 @@ // -> CODE#0014 // -> DESC="vst wet/dry slider" -VOID CViewGlobals::OnSetWetDry() +void CViewGlobals::OnSetWetDry() //------------------------------ { CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; CSoundFile *pSndFile; if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if (pPlugin->pMixPlugin){ + SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[m_nCurrentPlugin]; + + if (plugin.pMixPlugin != nullptr) + { //CVstPlugin *pVstPlugin = (CVstPlugin *)pPlugin->pMixPlugin; UINT value = GetDlgItemIntEx(IDC_EDIT15); - pPlugin->fDryRatio = (float)value / 100.0f; + plugin.fDryRatio = (float)value / 100.0f; if(pSndFile->GetModSpecifications().supportsPlugins) pModDoc->SetModified(); //OnWetDryChanged(); } } -/* -void CViewGlobals::OnWetDryChanged() -{ - CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; - CSoundFile *pSndFile; - CHAR s[32]; - - if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; - pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - - if (pPlugin->pMixPlugin){ - CVstPlugin *pVstPlugin = (CVstPlugin *)pPlugin->pMixPlugin; - UINT value = (UINT)(pPlugin->fDryRatio * 100.0f); - wsprintf(s, "%d", value); - SetDlgItemText(IDC_EDIT15, s); - m_sbWetDry.SetPos(value); - return; - } - - SetDlgItemText(IDC_EDIT15, ""); - m_sbWetDry.SetPos(0); -} -// -! NEW_FEATURE#0014 -*/ - -VOID CViewGlobals::OnMixModeChanged() +void CViewGlobals::OnMixModeChanged() //----------------------------------- { CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; CSoundFile *pSndFile; if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if (IsDlgButtonChecked(IDC_CHECK9)) - { - pPlugin->Info.dwInputRouting |= MIXPLUG_INPUTF_MASTEREFFECT; - } else - { - pPlugin->Info.dwInputRouting &= ~MIXPLUG_INPUTF_MASTEREFFECT; - } + + pSndFile->m_MixPlugins[m_nCurrentPlugin].SetMasterEffect(IsDlgButtonChecked(IDC_CHECK9) != BST_UNCHECKED); if(pSndFile->GetModSpecifications().supportsPlugins) pModDoc->SetModified(); } -VOID CViewGlobals::OnBypassChanged() +void CViewGlobals::OnBypassChanged() //---------------------------------- { CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; CSoundFile *pSndFile; if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - pPlugin->Bypass(IsDlgButtonChecked(IDC_CHECK10) != FALSE); + pSndFile->m_MixPlugins[m_nCurrentPlugin].SetBypass(IsDlgButtonChecked(IDC_CHECK10) != BST_UNCHECKED); + if(pSndFile->GetModSpecifications().supportsPlugins) pModDoc->SetModified(); } @@ -1200,63 +1172,51 @@ //---------------------------------------- { CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; CSoundFile *pSndFile; if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if (IsDlgButtonChecked(IDC_CHECK12)) - { - pPlugin->Info.dwInputRouting |= MIXPLUG_INPUTF_MIXEXPAND; - } else - { - pPlugin->Info.dwInputRouting &= ~MIXPLUG_INPUTF_MIXEXPAND; - } + pSndFile->m_MixPlugins[m_nCurrentPlugin].SetExpandedMix(IsDlgButtonChecked(IDC_CHECK12) != BST_UNCHECKED); + if(pSndFile->GetModSpecifications().supportsPlugins) pModDoc->SetModified(); } -VOID CViewGlobals::OnSpecialMixProcessingChanged() + +void CViewGlobals::OnSpecialMixProcessingChanged() //------------------------------------------------ { CModDoc *pModDoc = GetDocument(); - CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; - PSNDMIXPLUGIN pPlugin = m_nCurrentPlugin < MAX_MIXPLUGINS && pSndFile ? &pSndFile->m_MixPlugins[m_nCurrentPlugin] : NULL; + CSoundFile *pSndFile; - if(!pPlugin) return; - pPlugin->Info.dwInputRouting = (pPlugin->Info.dwInputRouting & 0xffff00ff) | (m_CbnSpecialMixProcessing.GetCurSel()<<8); // update#02 (fix) + if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; + pSndFile = pModDoc->GetSoundFile(); + + pSndFile->m_MixPlugins[m_nCurrentPlugin].SetMixMode(m_CbnSpecialMixProcessing.GetCurSel()); // update#02 (fix) if(pSndFile->GetModSpecifications().supportsPlugins) pModDoc->SetModified(); } // -! BEHAVIOUR_CHANGE#0028 -VOID CViewGlobals::OnDryMixChanged() +void CViewGlobals::OnDryMixChanged() //---------------------------------- { CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; CSoundFile *pSndFile; if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if (IsDlgButtonChecked(IDC_CHECK11)) - { - pPlugin->Info.dwInputRouting |= MIXPLUG_INPUTF_WETMIX; - } else - { - pPlugin->Info.dwInputRouting &= ~MIXPLUG_INPUTF_WETMIX; - } + pSndFile->m_MixPlugins[m_nCurrentPlugin].SetWetMix(IsDlgButtonChecked(IDC_CHECK11) != BST_UNCHECKED); + if(pSndFile->GetModSpecifications().supportsPlugins) pModDoc->SetModified(); } -VOID CViewGlobals::OnEditPlugin() +void CViewGlobals::OnEditPlugin() //------------------------------- { CModDoc *pModDoc = GetDocument(); @@ -1266,20 +1226,20 @@ } -VOID CViewGlobals::OnFxCommands(UINT id) +void CViewGlobals::OnFxCommands(UINT id) //-------------------------------------- { CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; CSoundFile *pSndFile; UINT nIndex = id - ID_FXCOMMANDS_BASE; if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; - if (pPlugin->pMixPlugin) + SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[m_nCurrentPlugin]; + + if (plugin.pMixPlugin != nullptr) { - CVstPlugin *pVstPlugin = (CVstPlugin *)pPlugin->pMixPlugin; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(plugin.pMixPlugin); pVstPlugin->ExecuteCommand(nIndex); if(pSndFile->GetModSpecifications().supportsPlugins) pModDoc->SetModified(); @@ -1287,19 +1247,23 @@ } -VOID CViewGlobals::OnOutputRoutingChanged() +void CViewGlobals::OnOutputRoutingChanged() //----------------------------------------- { CModDoc *pModDoc = GetDocument(); - PSNDMIXPLUGIN pPlugin; CSoundFile *pSndFile; int nroute; if ((m_nCurrentPlugin >= MAX_MIXPLUGINS) || (!pModDoc)) return; pSndFile = pModDoc->GetSoundFile(); - pPlugin = &pSndFile->m_MixPlugins[m_nCurrentPlugin]; + SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[m_nCurrentPlugin]; nroute = m_CbnOutput.GetItemData(m_CbnOutput.GetCurSel()); - pPlugin->Info.dwOutputRouting = nroute; + + if(!nroute) + plugin.SetOutputToMaster(); + else + plugin.SetOutputPlugin(static_cast<PLUGINDEX>(nroute - 0x80)); + if(pSndFile->GetModSpecifications().supportsPlugins) pModDoc->SetModified(); } @@ -1335,8 +1299,7 @@ { for(PLUGINDEX i = 0; i < m_nCurrentPlugin; i++) { - const DWORD toPlug = pSndFile->m_MixPlugins[i].Info.dwOutputRouting; - if((toPlug & 0x80) && (toPlug & 0x7F) == m_nCurrentPlugin) + if(pSndFile->m_MixPlugins[i].GetOutputPlugin() == m_nCurrentPlugin) { defaultIndex = i + 1; } @@ -1386,42 +1349,52 @@ CriticalSection cs; // Move plug data - memcpy(&(pSndFile->m_MixPlugins[dest]), &(pSndFile->m_MixPlugins[src]), sizeof(SNDMIXPLUGIN)); + MemCopy(pSndFile->m_MixPlugins[dest], pSndFile->m_MixPlugins[src]); MemsetZero(pSndFile->m_MixPlugins[src]); //Prevent plug from pointing backwards. - if (pSndFile->m_MixPlugins[dest].Info.dwOutputRouting & 0x80) { - UINT nOutput = pSndFile->m_MixPlugins[dest].Info.dwOutputRouting & 0x7f; - if (nOutput<=dest) { - pSndFile->m_MixPlugins[dest].Info.dwOutputRouting = 0; + if(!pSndFile->m_MixPlugins[dest].IsOutputToMaster()) + { + PLUGINDEX nOutput = pSndFile->m_MixPlugins[dest].GetOutputPlugin(); + if (nOutput <= dest) + { + pSndFile->m_MixPlugins[dest].SetOutputToMaster(); } } // Update current plug - if (pSndFile->m_MixPlugins[dest].pMixPlugin) { + if(pSndFile->m_MixPlugins[dest].pMixPlugin) + { ((CVstPlugin*)pSndFile->m_MixPlugins[dest].pMixPlugin)->SetSlot(dest); ((CVstPlugin*)pSndFile->m_MixPlugins[dest].pMixPlugin)->UpdateMixStructPtr(&(pSndFile->m_MixPlugins[dest])); } // Update all other plugs' outputs - for (PLUGINDEX nPlug=0; nPlug<src; nPlug++) { - if (pSndFile->m_MixPlugins[nPlug].Info.dwOutputRouting & 0x80) { - if ((pSndFile->m_MixPlugins[nPlug].Info.dwOutputRouting & 0x7f) == src) { - pSndFile->m_MixPlugins[nPlug].Info.dwOutputRouting = ((BYTE)dest)|0x80; + for (PLUGINDEX nPlug = 0; nPlug < src; nPlug++) + { + if(!pSndFile->m_MixPlugins[nPlug].IsOutputToMaster()) + { + if(pSndFile->m_MixPlugins[nPlug].GetOutputPlugin() == src) + { + pSndFile->m_MixPlugins[nPlug].SetOutputPlugin(dest); } } } // Update channels - for (CHANNELINDEX nChn=0; nChn<pSndFile->m_nChannels; nChn++) { - if (pSndFile->ChnSettings[nChn].nMixPlugin == src+1) { - pSndFile->ChnSettings[nChn].nMixPlugin = dest+1; + for (CHANNELINDEX nChn = 0; nChn < pSndFile->GetNumChannels(); nChn++) + { + if (pSndFile->ChnSettings[nChn].nMixPlugin == src + 1u) + { + pSndFile->ChnSettings[nChn].nMixPlugin = dest + 1u; } } // Update instruments - for (INSTRUMENTINDEX nIns=1; nIns<=pSndFile->m_nInstruments; nIns++) { - if (pSndFile->Instruments[nIns] && (pSndFile->Instruments[nIns]->nMixPlug == src+1)) { - pSndFile->Instruments[nIns]->nMixPlug = static_cast<BYTE>(dest+1); + for (INSTRUMENTINDEX nIns = 1; nIns <= pSndFile->GetNumInstruments(); nIns++) + { + if (pSndFile->Instruments[nIns] && (pSndFile->Instruments[nIns]->nMixPlug == src + 1)) + { + pSndFile->Instruments[nIns]->nMixPlug = dest + 1u; } } @@ -1522,8 +1495,7 @@ CSoundFile *pSndFile = GetDocument()->GetSoundFile(); if(pSndFile == nullptr) return; if (m_nCurrentPlugin >= MAX_MIXPLUGINS) m_nCurrentPlugin = 0; - PSNDMIXPLUGIN pPlugin = &(pSndFile->m_MixPlugins[m_nCurrentPlugin]); - CVstPlugin *pVstPlugin = (pPlugin->pMixPlugin) ? (CVstPlugin *)pPlugin->pMixPlugin : nullptr; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(pSndFile->m_MixPlugins[m_nCurrentPlugin].pMixPlugin); if(pVstPlugin == nullptr) return; const PlugParamIndex nParams = pVstPlugin->GetNumParameters(); @@ -1553,8 +1525,7 @@ CSoundFile *pSndFile = GetDocument()->GetSoundFile(); if(pSndFile == nullptr) return; if (m_nCurrentPlugin >= MAX_MIXPLUGINS) m_nCurrentPlugin = 0; - PSNDMIXPLUGIN pPlugin = &(pSndFile->m_MixPlugins[m_nCurrentPlugin]); - CVstPlugin *pVstPlugin = (pPlugin->pMixPlugin) ? (CVstPlugin *)pPlugin->pMixPlugin : nullptr; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(pSndFile->m_MixPlugins[m_nCurrentPlugin].pMixPlugin); if(pVstPlugin == nullptr) return; UINT nProg = pVstPlugin->GetNumPrograms(); Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -5138,23 +5138,23 @@ bool CViewPattern::BuildPluginCtxMenu(HMENU hMenu, UINT nChn, CSoundFile *pSndFile) const //--------------------------------------------------------------------------------------- { - for (UINT plug=0; plug<=MAX_MIXPLUGINS; plug++) + for(PLUGINDEX plug = 0; plug <= MAX_MIXPLUGINS; plug++) { bool itemFound = false; CHAR s[64]; - if (!plug) + if(!plug) { strcpy(s, "No plugin"); itemFound = true; } else { - PSNDMIXPLUGIN p = &(pSndFile->m_MixPlugins[plug - 1]); - if (p->Info.szLibraryName[0]) + const SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[plug - 1]; + if(plugin.IsValidPlugin()) { - wsprintf(s, "FX%d: %s", plug, p->Info.szName); + wsprintf(s, "FX%d: %s", plug, plugin.GetName()); itemFound = true; } } Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -693,16 +693,16 @@ } for (UINT iFx=0; iFx<MAX_MIXPLUGINS; iFx++) { - PSNDMIXPLUGIN pPlugin = &pSndFile->m_MixPlugins[iFx]; - if (pPlugin->Info.dwPluginId1) + const SNDMIXPLUGIN &plugin = pSndFile->m_MixPlugins[iFx]; + if (plugin.IsValidPlugin()) { if (!pInfo->hEffects) { pInfo->hEffects = InsertItem("Plugins", IMAGE_FOLDER, IMAGE_FOLDER, pInfo->hSong, TVI_LAST); } - wsprintf(s, "FX%d: %s", iFx+1, pPlugin->Info.szName); + wsprintf(s, "FX%d: %s", iFx + 1, plugin.GetName()); int nImage = IMAGE_NOPLUGIN; - if(pPlugin->pMixPlugin != nullptr) nImage = (pPlugin->pMixPlugin->isInstrument()) ? IMAGE_PLUGININSTRUMENT : IMAGE_EFFECTPLUGIN; + if(plugin.pMixPlugin != nullptr) nImage = (plugin.pMixPlugin->isInstrument()) ? IMAGE_PLUGININSTRUMENT : IMAGE_EFFECTPLUGIN; pInfo->tiEffects[iFx] = InsertItem(s, nImage, nImage, pInfo->hEffects, TVI_LAST); nFx++; } @@ -2508,12 +2508,9 @@ CModDoc *pModDoc = GetDocumentFromItem(hItem); CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; - if (pSndFile) { - PSNDMIXPLUGIN pPlugin = &pSndFile->m_MixPlugins[modItemID]; - if (pPlugin) - { - AppendMenu(hMenu, (pPlugin->IsBypassed() ? MF_CHECKED : 0) | MF_STRING, ID_MODTREE_MUTE, "&Bypass"); - } + if (pSndFile) + { + AppendMenu(hMenu, (pSndFile->m_MixPlugins[modItemID].IsBypassed() ? MF_CHECKED : 0) | MF_STRING, ID_MODTREE_MUTE, "&Bypass"); } } break; @@ -2880,10 +2877,7 @@ CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : nullptr; if (pSndFile == nullptr) return; - PSNDMIXPLUGIN pPlugin = &pSndFile->m_MixPlugins[modItemID]; - if(pPlugin == nullptr) - return; - CVstPlugin *pVstPlugin = (CVstPlugin *)pPlugin->pMixPlugin; + CVstPlugin *pVstPlugin = dynamic_cast<CVstPlugin *>(pSndFile->m_MixPlugins[modItemID].pMixPlugin); if(pVstPlugin == nullptr) return; pVstPlugin->ToggleBypass(); Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-03-03 15:00:41 UTC (rev 1200) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-03-03 15:14:35 UTC (rev 1201) @@ -76,7 +76,7 @@ } -BOOL CVstPluginManager::CreateMixPluginProc(PSNDMIXPLUGIN pMixPlugin, CSoundFile* pSndFile) +BOOL CVstPluginManager::CreateMixPluginProc(SNDMIXPLUGIN *pMixPlugin, CSoundFile* pSndFile) //----------------------------------------------------------------------------------------- { CVstPluginManager *that = theApp.GetPluginManager(); @@ -501,11 +501,11 @@ } -BOOL CVstPluginManager::CreateMixPlugin(PSNDMIXPLUGIN pMixPlugin, CSoundFile* pSndFile) +BOOL CVstPluginManager::CreateMixPlugin(SNDMIXPLUGIN *pMixPlugin, CSoundFile* pSndFile) //------------------------------------------------------------------------------------- { UINT nMatch = 0; - PVSTPLUGINLIB pFound = NULL; + PVSTPLUGINLIB pFound = nullptr; if (pMixPlugin) { @@ -521,7 +521,7 @@ { b1 = true; } - if (!_strnicmp(p->szLibraryName, pMixPlugin->Info.szLibraryName, 64)) + if (!_strnicmp(p->szLibraryName, pMixPlugin->GetLibraryName(), 64)) { b2 = true; } @@ -563,22 +563,22 @@ return bOk; } } - if ((!pFound) && (pMixPlugin->Info.szLibraryName[0])) + if ((!pFound) && strcmp(pMixPlugin->GetLibraryName(), "")) { CHAR s[_MAX_PATH], dir[_MAX_PATH]; _splitpath(theApp.GetConfigFileName(), s, dir, NULL, NULL); strcat(s, dir); int len = strlen(s); - if ((len > 0) && (s[len-1] != '\\')) strcat(s, "\\"); - strncat(s, "plugins\\", _MAX_PATH-1); - strncat(s, pMixPlugin->Info.szLibraryName, _MAX_PATH-1); + if ((len > 0) && (s[len - 1] != '\\')) strcat(s, "\\"); + strncat(s, "plugins\\", _MAX_PATH - 1); + strncat(s, pMixPlugin->GetLibraryName(), _MAX_PATH - 1); strncat(s, ".dll", _MAX_PATH-1); pFound = AddPlugin(s); if (!pFound) { CString cacheSection = "PluginCache"; CString cacheFile = theApp.GetPluginCacheFileName(); - CString IDs = CMainFrame::GetPrivateProfileCString(cacheSection, pMixPlugin->Info.szLibraryName, "", cacheFile); + CString IDs = CMainFrame::GetPrivateProfileCString(cacheSection, pMixPlugin->GetLibraryName(), "", cacheFile); if (IDs.GetLength() >= 16) { CString strFullPath = CMainFrame::GetPrivateProfileCString(cacheSection, IDs, "", cacheFile); @@ -1329,7 +1329,7 @@ // CVstPlugin // -CVstPlugin::CVstPlugin(HMODULE hLibrary, PVSTPLUGINLIB pFactory, PSNDMIXPLUGIN pMixStruct, AEffect *pEffect) +CVstPlugin::CVstPlugin(HMODULE hLibrary, VSTPLUGINLIB *pFactory, SNDMIXPLUGIN *pMixStruct, AEffect *pEffect) //---------------------------------------------------------------------------------------------------------- { m_hLibrary = hLibrary; @@ -1490,7 +1490,7 @@ //rewbs.VSTcompliance m_bIsInstrument = isInstrument(); RecalculateGain(); - m_pProcessFP = (m_pEffect->flags & effFlagsCanReplacing) ? m_pEffect->processReplacing : m_pEffect->process; + m_pProcessFP = (m_pEffect->flags & effFlagsCanReplacing) ? m_pEffect->processReplacing : m_pEffect->process; // issue samplerate again here, cos some plugs like it before the block size, other like it right at the end. Dispatch(effSetSampleRate, 0, 0, NULL, static_cast<float>(CSoundFile::gdwMixingFreq)); @@ -1664,8 +1664,8 @@ } -bool CVstPlugin::RandomizeParams(VstInt32 minParam, VstInt32 maxParam) -//-------------------------------------------------------------------- +bool CVstPlugin::RandomizeParams(PlugParamIndex minParam, PlugParamIndex maxParam) +//-------------------------------------------------------------------------------- { if (!(m_pEffect)) return false; @@ -1675,10 +1675,10 @@ maxParam = m_pEffect->numParams; } - LimitMax(maxParam, m_pEffect->numParams); + LimitMax(maxParam, PlugParamIndex(m_pEffect->numParams)); - for (VstInt32 p = minParam; p < maxParam; p++) - SetParameter(p, (rand() / float(RAND_MAX))); + for(PlugParamIndex p = minParam; p < maxParam; p++) + SetParameter(p, (float(rand()) / float(RAND_MAX))); return true; } @@ -1691,26 +1691,26 @@ return false; bool success; - //Collect required data + // Collect required data long ID = GetUID(); long plugVersion = GetVersion(); Cfxp* fxp = nullptr; - //Construct & save fxp + // Construct & save fxp // try chunk-based preset: - if(m_pEffect->flags & effFlagsProgramChunks) + if((m_pEffect->flags & effFlagsProgramChunks) != 0) { void *chunk = NULL; long chunkSize = Dispatch(effGetChunk, 1,0, &chunk, 0); - if (chunkSize && chunk) + if(chunkSize && chunk) fxp = new Cfxp(ID, plugVersion, 1, chunkSize, chunk); } // fall back on parameter based preset: - if (fxp == nullptr) + if(fxp == nullptr) { - //Collect required data + // Collect required data PlugParamIndex numParams = GetNumParameters(); float *params = new float[numParams]; GetParams(params, 0, numParams); @@ -1721,7 +1721,7 @@ } success = fxp->Save(fileName); - if (fxp) + if(fxp) delete fxp; return success; @@ -1735,20 +1735,19 @@ if (!(m_pEffect)) return false; - Cfxp fxp(fileName); //load from file + Cfxp fxp(fileName); // load from file - //Verify + // Verify if (m_pEffect->uniqueID != fxp.fxID) return false; - if (fxp.fxMagic == fMagic) //Load preset based fxp + if (fxp.fxMagic == fMagic) // Load preset based fxp { if (m_pEffect->numParams != fxp.numParams) return false; for (int p=0; p<fxp.numParams; p++) SetParameter(p, fxp.params[p]); - } - else if (fxp.fxMagic == chunkPresetMagic) + } else if (fxp.fxMagic == chunkPresetMagic) { Dispatch(effSetChunk, 1, fxp.chunkSize, (BYTE*)fxp.chunk, 0); } @@ -1792,8 +1791,8 @@ } -bool CVstPlugin::GetProgramNameIndexed(long index, long category, char *text) -//--------------------------------------------------------------------------- +bool CVstPlugin::GetProgramNameIndexed(VstInt32 index, VstIntPtr category, char *text) +//------------------------------------------------------------------------------------ { if ((m_pEffect) && (m_pEffect->numPrograms > 0)) { @@ -1806,7 +1805,7 @@ CString CVstPlugin::GetFormattedProgramName(VstInt32 index, bool allowFallback) //----------------------------------------------------------------------------- { - char rawname[256]; // kVstMaxProgNameLen is 24... + char rawname[max(kVstMaxProgNameLen, 256)]; // kVstMaxProgNameLen is 24... if(!GetProgramNameIndexed(index, -1, rawname)) { // Fallback: Try to get current program name. @@ -2040,7 +2039,7 @@ void CVstPlugin::RecalculateGain() //-------------------------------- { - float gain = 0.1f * (float)( m_pMixStruct ? (m_pMixStruct->Info.dwInputRouting>>16) & 0xff : 10 ); + float gain = 0.1f * static_cast<float>(m_pMixStruct ? m_pMixStruct->GetGain() : 10); if(gain < 0.1f) gain = 1.0f; if (m_bIsInstrument && m_pSndFile) @@ -2093,7 +2092,7 @@ { Bypass(); CString processMethod = (m_pEffect->flags & effFlagsCanReplacing) ? "processReplacing" : "process"; - CVstPluginManager::ReportPlugException("The plugin %s threw an exception in %s. It has automatically been set to \"Bypass\".", m_pMixStruct->Info.szName, processMethod); + CVstPluginManager::ReportPlugException("The plugin %s threw an exception in %s. It has automatically been set to \"Bypass\".", m_pMixStruct->GetName(), processMethod); ClearVSTEvents(); // SetEvent(processCalled); } @@ -2134,7 +2133,7 @@ // If dry mix is ticked, we add the unprocessed buffer, // except if this is an instrument since this it has already been done: - if((m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_WETMIX) && !m_bIsInstrument) + if(m_pMixStruct->IsWetMix() && !m_bIsInstrument) { for(size_t i = 0; i < nSamples; i++) { @@ -2178,19 +2177,20 @@ // MIX_R += dryRatio * (WET_L - DRY_L) + wetRatio * (DRY_R - WET_R) int mixop; - if(m_bIsInstrument) + if(m_bIsInstrument || m_pMixStruct == nullptr) { - mixop = 0; // Force normal mix mode for instruments + // Force normal mix mode for instruments + mixop = 0; } else { - mixop = m_pMixStruct ? (m_pMixStruct->Info.dwInputRouting >> 8) & 0xFF : 0; + mixop = m_pMixStruct->GetMixMode(); } float wetRatio = 1 - m_pMixStruct->fDryRatio; float dryRatio = m_bIsInstrument ? 1 : m_pMixStruct->fDryRatio; // Always mix full dry if this is an instrument // Wet / Dry range expansion [0,1] -> [-1,1] - if(m_pEffect->numInputs > 0 && m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_MIXEXPAND) + if(m_pEffect->numInputs > 0 && m_pMixStruct->IsExpandedMix()) { wetRatio = 2.0f * wetRatio - 1.0f; dryRatio = -wetRatio; @@ -2252,7 +2252,7 @@ // Left / Right balance case 5: - if(m_pMixStruct->Info.dwInputRouting & MIXPLUG_INPUTF_MIXEXPAND) + if(m_pMixStruct->IsExpandedMix()) { wetRatio /= 2.0f; dryRatio /= 2.0f; @@ -2861,13 +2861,10 @@ } -bool CVstPlugin::Bypass(bool bypass) -//----------------------------------- +void CVstPlugin::Bypass(bool bypass) +//---------------------------------- { - if (bypass) - m_pMixStruct->Info.dwInputRouting |= MIXPLUG_INPUTF_BYPASS; - else - m_pMixStruct->Info.dwInputRouting &= ~MIXPLUG_INPUTF_BYPASS; + m_pMixStruct->Info.SetBypass(bypass); Dispatch(effSetBypass, bypass ? 1 : 0, nullptr, nullptr, 0.0f); @@ -2875,8 +2872,6 @@ if (m_pModDoc) m_pModDoc->UpdateAllViews(NULL, HINT_MIXPLUGINS, NULL); #endif // MODPLUG_TRACKER - - return bypass; } @@ -2936,7 +2931,7 @@ } -void CVstPlugin::UpdateMixStructPtr(PSNDMIXPLUGIN p) +void CVstPlugin::UpdateMixStructPtr(SNDMIXPLUGIN *p) //-------------------------------------------------- { m_pMixStruct = p; @@ -2967,9 +2962,9 @@ list.RemoveAll(); CVstPlugin *pOutputPlug = NULL; - if (m_pMixStruct->Info.dwOutputRouting & 0x80) + if (!m_pMixStruct->IsOutputToMaster()) { - UINT nOutput = m_pMixStruct->Info.dwOutputRouting & 0x7f; + PLUGINDEX nOutput = m_pMixStruct->GetOutputPlugin(); if (m_pSndFile && (nOutput > m_nSlot) && (nOutput < MAX_MIXPLUGINS)) { pOutputPlug = reinterpret_cast<CVstPlugin *>(m_pSndFile->m_MixPlugins[nOutput].pMixPlugin); @@ -3667,6 +3662,7 @@ } break; + case MPT_INT: default: wsprintf(pszName, "%d", (int)md); break; @@ -3695,7 +3691,7 @@ mt.bFixedSizeSamples = TRUE; mt.bTemporalCompression = FALSE; mt.formattype = FORMAT_WaveFormatEx; - mt.pUnk = NULL; + mt.pUnk = nullptr; mt.pbFormat = (LPBYTE)&wfx; mt.cbFormat = sizeof(WAVEFORMATEX); mt.lSampleSize = 2 * sizeof(float); @@ -3706,8 +3702,8 @@ wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample >> 3); wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; wfx.cbSize = 0; - if ((FAILED(m_pMediaObject->SetInputType(0, &mt, 0))) - || (FAILED(m_pMediaObject->SetOutputType(0, &mt, 0)))) + if (FAILED(m_pMediaObject->SetInputType(0, &mt, 0)) + || FAILED(m_pMediaObject->SetOutputType(0, &mt, 0))) { #ifdef DMO_LOG Log("DMO: Failed to set I/O media type\n"); @@ -3717,8 +3713,8 @@ } else { m_pMediaObject->Flush(); - m_pMediaObject->SetInputType(0, NULL, DMO_SET_TYPEF_CLEAR); - m_pMediaObject->SetOutputType(0, NULL, DMO_SET_TYPEF_CLEAR); + m_pMediaObject->SetInputType(0, nullptr, DMO_SET_TYPEF_CLEAR); + m_pMediaObject->SetOutputType(0, nullptr, DMO_SET_TYPEF_CLEAR); m_DataTime = 0; } break; @@ -3767,8 +3763,8 @@ MemsetZero(mpi); md = 0; ... [truncated message content] |
From: <sag...@us...> - 2012-03-04 23:19:58
|
Revision: 1202 http://modplug.svn.sourceforge.net/modplug/?rev=1202&view=rev Author: saga-games Date: 2012-03-04 23:19:51 +0000 (Sun, 04 Mar 2012) Log Message: ----------- [Int] VS08 SoundTouch project was slightly broken. [Fix] Sample Editor: When cleaning up samples, the sample spin button is now updated instantly. [Imp] Pattern Editor: Slightly improved PC Event handling in the Note Properties. Modified Paths: -------------- trunk/OpenMPT/common/misc_util.h trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp trunk/OpenMPT/mptrack/PatternEditorDialogs.h trunk/OpenMPT/soundtouch/soundtouch.vcproj trunk/OpenMPT/soundtouch/soundtouch_08.vcproj Modified: trunk/OpenMPT/common/misc_util.h =================================================================== --- trunk/OpenMPT/common/misc_util.h 2012-03-03 15:14:35 UTC (rev 1201) +++ trunk/OpenMPT/common/misc_util.h 2012-03-04 23:19:51 UTC (rev 1202) @@ -63,17 +63,6 @@ // Copy given object to other location. template <class T> -inline void MemCopy(T &destination, T &source) -//-------------------------------------------- -{ -#if _HAS_TR1 - static_assert(std::tr1::is_pointer<T>::value == false, "Won't copy pointers."); - static_assert(std::tr1::is_pod<T>::value == true, "Won't copy non-pods."); -#endif - memcpy(&destination, &source, sizeof(T)); -} - -template <class T> inline void MemCopy(T &destination, const T &source) //-------------------------------------------------- { Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-03-03 15:14:35 UTC (rev 1201) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-03-04 23:19:51 UTC (rev 1202) @@ -160,7 +160,7 @@ if(m_bCheckBoxes[CU_RESET_VARIABLES]) bModified |= ResetVariables(); if(bModified) m_pModDoc->SetModified(); - m_pModDoc->UpdateAllViews(NULL, HINT_MODTYPE|HINT_MODSEQUENCE|HINT_MODGENERAL); + m_pModDoc->UpdateAllViews(NULL, HINT_MODTYPE | HINT_MODSEQUENCE | HINT_MODGENERAL | HINT_SMPNAMES | HINT_INSNAMES); m_pModDoc->ShowLog("Cleanup", this); CDialog::OnOK(); } Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2012-03-03 15:14:35 UTC (rev 1201) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2012-03-04 23:19:51 UTC (rev 1202) @@ -326,12 +326,13 @@ bool CCtrlSamples::SetCurrentSample(SAMPLEINDEX nSmp, LONG lZoom, bool bUpdNum) //----------------------------------------------------------------------------- { - CModDoc *pModDoc = GetDocument(); - CSoundFile *pSndFile; - if (!pModDoc) return false; - pSndFile = pModDoc->GetSoundFile(); - if (pSndFile->m_nSamples < 1) pSndFile->m_nSamples = 1; - if ((nSmp < 1) || (nSmp > pSndFile->m_nSamples)) return FALSE; + if (m_pSndFile == nullptr) + { + return false; + } + + if (m_pSndFile->GetNumSamples() < 1) m_pSndFile->m_nSamples = 1; + if ((nSmp < 1) || (nSmp > m_pSndFile->GetNumSamples())) return FALSE; LockControls(); if (m_nSample != nSmp) @@ -342,7 +343,7 @@ if (bUpdNum) { SetDlgItemInt(IDC_EDIT_SAMPLE, m_nSample); - m_SpinSample.SetRange(1, pSndFile->m_nSamples); + m_SpinSample.SetRange(1, m_pSndFile->GetNumSamples()); } if (lZoom < 0) lZoom = m_ComboZoom.GetCurSel(); @@ -655,6 +656,8 @@ const ModSample &sample = m_pSndFile->GetSample(m_nSample); CHAR s[128]; DWORD d; + + m_SpinSample.SetRange(1, m_pSndFile->GetNumSamples()); // Length / Type wsprintf(s, "%d-bit %s, len: %d", sample.GetElementarySampleSize() * 8, (sample.uFlags & CHN_STEREO) ? "stereo" : "mono", sample.nLength); @@ -3258,4 +3261,4 @@ } } -} +} \ No newline at end of file Modified: trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp =================================================================== --- trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp 2012-03-03 15:14:35 UTC (rev 1201) +++ trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp 2012-03-04 23:19:51 UTC (rev 1202) @@ -1069,12 +1069,12 @@ void CPageEditEffect::UpdateDialog() //---------------------------------- { - CHAR s[128]; CComboBox *combo; CSoundFile *pSndFile; if ((!m_pModDoc) || (!m_bInitialized)) return; pSndFile = m_pModDoc->GetSoundFile(); + if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO1)) != NULL) { combo->ResetContent(); @@ -1083,6 +1083,7 @@ // plugin param control note if(m_nPlugin > 0 && m_nPlugin <= MAX_MIXPLUGINS) { + combo->ModifyStyle(CBS_SORT, 0); // Y U NO WORK? AddPluginParameternamesToCombobox(*combo, pSndFile->m_MixPlugins[m_nPlugin - 1]); combo->SetCurSel(m_nPluginParam); } @@ -1091,8 +1092,11 @@ // process as effect UINT numfx = effectInfo.GetNumEffects(); UINT fxndx = effectInfo.GetIndexFromEffect(m_nCommand, m_nParam); + combo->ModifyStyle(0, CBS_SORT); combo->SetItemData(combo->AddString(" None"), (DWORD)-1); - if (!m_nCommand) combo->SetCurSel(0); + if (m_nCommand == CMD_NONE) combo->SetCurSel(0); + + CHAR s[128]; for (UINT i=0; i<numfx; i++) { if (effectInfo.GetEffectInfo(i, s, true)) @@ -1102,6 +1106,7 @@ if (i == fxndx) combo->SetCurSel(k); } } + combo->ModifyStyle(CBS_SORT, 0); } } UpdateRange(FALSE); @@ -1114,22 +1119,35 @@ CSliderCtrl *slider = (CSliderCtrl *)GetDlgItem(IDC_SLIDER1); if ((slider) && (m_pModDoc)) { - DWORD rangeMin = 0, rangeMax = 0; - LONG fxndx = effectInfo.GetIndexFromEffect(m_nCommand, m_nParam); - bool bEnable = ((fxndx >= 0) && (effectInfo.GetEffectInfo(fxndx, NULL, false, &rangeMin, &rangeMax))); - if (bEnable) + DWORD rangeMin = 0, rangeMax = 0, pos; + bool enable = true; + + if(m_bIsParamControl) { + // plugin param control note + rangeMax = ModCommand::maxColumnValue; + pos = ModCommand::GetValueEffectCol(m_nCommand, m_nParam); + } else + { + // process as effect + LONG fxndx = effectInfo.GetIndexFromEffect(m_nCommand, m_nParam); + enable = ((fxndx >= 0) && (effectInfo.GetEffectInfo(fxndx, NULL, false, &rangeMin, &rangeMax))); + + pos = effectInfo.MapValueToPos(fxndx, m_nParam); + if (pos > rangeMax) pos = rangeMin | (pos & 0x0F); + if (pos < rangeMin) pos = rangeMin; + if (pos > rangeMax) pos = rangeMax; + } + + if (enable) + { slider->EnableWindow(TRUE); slider->SetPageSize(1); slider->SetRange(rangeMin, rangeMax); - DWORD pos = effectInfo.MapValueToPos(fxndx, m_nParam); - if (pos > rangeMax) pos = rangeMin | (pos & 0x0F); - if (pos < rangeMin) pos = rangeMin; - if (pos > rangeMax) pos = rangeMax; slider->SetPos(pos); } else { - slider->SetRange(0,0); + slider->SetRange(0, 0); slider->EnableWindow(FALSE); } UpdateValue(bSet); @@ -1141,8 +1159,17 @@ //------------------------------------------ { CHAR s[128] = ""; - LONG fxndx = effectInfo.GetIndexFromEffect(m_nCommand, m_nParam); - if (fxndx >= 0) effectInfo.GetEffectNameEx(s, fxndx, m_nParam * m_nMultiplier + m_nXParam); + + if(m_bIsParamControl) + { + // plugin param control note + wsprintf(s, "Value: %u", ModCommand::GetValueEffectCol(m_nCommand, m_nParam)); + } else + { + // process as effect + LONG fxndx = effectInfo.GetIndexFromEffect(m_nCommand, m_nParam); + if (fxndx >= 0) effectInfo.GetEffectNameEx(s, fxndx, m_nParam * m_nMultiplier + m_nXParam); + } SetDlgItemText(IDC_TEXT1, s); if ((m_pParent) && (bSet)) m_pParent->UpdateEffect(m_nCommand, m_nParam); @@ -1156,16 +1183,29 @@ if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO1)) != NULL) { - BOOL bSet = FALSE; int n = combo->GetCurSel(); - if (n >= 0) + + if(m_bIsParamControl) { - int param = -1, ndx = combo->GetItemData(n); - m_nCommand = (ndx >= 0) ? effectInfo.GetEffectFromIndex(ndx, param) : 0; - if (param >= 0) m_nParam = static_cast<ModCommand::PARAM>(param); - bSet = TRUE; + // plugin param control note + if(n >= 0) + { + // TODO update in pattern + m_nPluginParam = n; + } + } else + { + // process as effect + BOOL bSet = FALSE; + if (n >= 0) + { + int param = -1, ndx = combo->GetItemData(n); + m_nCommand = (ndx >= 0) ? effectInfo.GetEffectFromIndex(ndx, param) : 0; + if (param >= 0) m_nParam = static_cast<ModCommand::PARAM>(param); + bSet = TRUE; + } + UpdateRange(bSet); } - UpdateRange(bSet); } } @@ -1177,15 +1217,28 @@ CSliderCtrl *slider = (CSliderCtrl *)GetDlgItem(IDC_SLIDER1); if (slider != nullptr) { - LONG fxndx = effectInfo.GetIndexFromEffect(m_nCommand, m_nParam); - if (fxndx >= 0) + if(m_bIsParamControl) { - int pos = slider->GetPos(); - UINT param = effectInfo.MapPosToValue(fxndx, pos); - if (param != m_nParam) + // plugin param control note + // HACK + ModCommand m; + m.SetValueEffectCol(static_cast<int16>(slider->GetPos())); + m_nCommand = m.command; + m_nParam = m.param; + UpdateValue(TRUE); + } else + { + // process as effect + LONG fxndx = effectInfo.GetIndexFromEffect(m_nCommand, m_nParam); + if (fxndx >= 0) { - m_nParam = static_cast<ModCommand::PARAM>(param); - UpdateValue(TRUE); + int pos = slider->GetPos(); + UINT param = effectInfo.MapPosToValue(fxndx, pos); + if (param != m_nParam) + { + m_nParam = static_cast<ModCommand::PARAM>(param); + UpdateValue(TRUE); + } } } } Modified: trunk/OpenMPT/mptrack/PatternEditorDialogs.h =================================================================== --- trunk/OpenMPT/mptrack/PatternEditorDialogs.h 2012-03-03 15:14:35 UTC (rev 1201) +++ trunk/OpenMPT/mptrack/PatternEditorDialogs.h 2012-03-04 23:19:51 UTC (rev 1202) @@ -214,7 +214,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; m_bIsParamControl = m.IsPcNote(); m_nPlugin = m.instr; m_nPluginParam = ModCommand::GetValueVolCol(m.volcmd, m.vol);} + void Init(ModCommand &m) { m_nCommand = m.command; m_nParam = m.param; m_pModcommand = &m; m_bIsParamControl = m.IsPcNote(); m_nPlugin = m.instr; m_nPluginParam = m.GetValueVolCol();} void XInit(UINT xparam = 0, UINT multiplier = 1) { m_nXParam = xparam; m_nMultiplier = multiplier; } // -! NEW_FEATURE#0010 void UpdateDialog(); Modified: trunk/OpenMPT/soundtouch/soundtouch.vcproj =================================================================== --- trunk/OpenMPT/soundtouch/soundtouch.vcproj 2012-03-03 15:14:35 UTC (rev 1201) +++ trunk/OpenMPT/soundtouch/soundtouch.vcproj 2012-03-04 23:19:51 UTC (rev 1202) @@ -123,9 +123,6 @@ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> <File - RelativePath=".\3dnow_win.cpp"> - </File> - <File RelativePath=".\AAFilter.cpp"> </File> <File Modified: trunk/OpenMPT/soundtouch/soundtouch_08.vcproj =================================================================== --- trunk/OpenMPT/soundtouch/soundtouch_08.vcproj 2012-03-03 15:14:35 UTC (rev 1201) +++ trunk/OpenMPT/soundtouch/soundtouch_08.vcproj 2012-03-04 23:19:51 UTC (rev 1202) @@ -187,10 +187,6 @@ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > <File - RelativePath=".\3dnow_win.cpp" - > - </File> - <File RelativePath=".\AAFilter.cpp" > </File> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-03-04 23:39:59
|
Revision: 1203 http://modplug.svn.sourceforge.net/modplug/?rev=1203&view=rev Author: saga-games Date: 2012-03-04 23:39:50 +0000 (Sun, 04 Mar 2012) Log Message: ----------- [Ref] Even more refactoring: Removed a lot of duplicate code regaring IT sample / instrument loading. A lot of IT-related code has been moved to a new file, ITTools.cpp. Also smashed a couple of related bugs while I was at it... Modified Paths: -------------- trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_itp.cpp trunk/OpenMPT/soundlib/ModInstrument.h trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/pattern.cpp Added Paths: ----------- trunk/OpenMPT/soundlib/ITTools.cpp trunk/OpenMPT/soundlib/ITTools.h Removed Paths: ------------- trunk/OpenMPT/soundlib/IT_DEFS.H Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2012-03-04 23:19:51 UTC (rev 1202) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2012-03-04 23:39:50 UTC (rev 1203) @@ -753,9 +753,6 @@ RelativePath="InputHandler.h"> </File> <File - RelativePath="..\soundlib\IT_DEFS.H"> - </File> - <File RelativePath=".\KeyConfigDlg.h"> </File> <File @@ -972,6 +969,12 @@ Name="Module Loaders" Filter=""> <File + RelativePath="..\soundlib\ITTools.h"> + </File> + <File + RelativePath="..\soundlib\ITTools.cpp"> + </File> + <File RelativePath="..\soundlib\Load_669.cpp"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2012-03-04 23:19:51 UTC (rev 1202) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2012-03-04 23:39:50 UTC (rev 1203) @@ -999,10 +999,6 @@ > </File> <File - RelativePath="..\soundlib\IT_DEFS.H" - > - </File> - <File RelativePath=".\KeyConfigDlg.h" > </File> @@ -1291,6 +1287,14 @@ Name="Module Loaders" > <File + RelativePath="..\soundlib\ITTools.h" + > + </File> + <File + RelativePath="..\soundlib\ITTools.cpp" + > + </File> + <File RelativePath="..\soundlib\Load_669.cpp" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2012-03-04 23:19:51 UTC (rev 1202) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2012-03-04 23:39:50 UTC (rev 1203) @@ -169,6 +169,7 @@ <ItemGroup> <ClCompile Include="..\common\misc_util.cpp" /> <ClCompile Include="..\common\Reporting.cpp" /> + <ClCompile Include="..\soundlib\ITTools.cpp" /> <ClCompile Include="..\soundlib\MIDIMacros.cpp" /> <ClCompile Include="..\soundlib\ModInstrument.cpp" /> <ClCompile Include="..\soundlib\ModSample.cpp" /> @@ -326,6 +327,7 @@ <ClInclude Include="..\common\Reporting.h" /> <ClInclude Include="..\common\StringFixer.h" /> <ClInclude Include="..\common\typedefs.h" /> + <ClInclude Include="..\soundlib\ITTools.h" /> <ClInclude Include="..\soundlib\MIDIMacros.h" /> <ClInclude Include="..\soundlib\ModChannel.h" /> <ClInclude Include="..\soundlib\ModInstrument.h" /> @@ -376,7 +378,6 @@ <ClInclude Include="fxp.h" /> <ClInclude Include="globals.h" /> <ClInclude Include="InputHandler.h" /> - <ClInclude Include="..\soundlib\IT_DEFS.H" /> <ClInclude Include="KeyConfigDlg.h" /> <ClInclude Include="mainbar.h" /> <ClInclude Include="MainFrm.h" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2012-03-04 23:19:51 UTC (rev 1202) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2012-03-04 23:39:50 UTC (rev 1203) @@ -436,6 +436,9 @@ <ClCompile Include="..\soundlib\ModSample.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\soundlib\ITTools.cpp"> + <Filter>Module Loaders</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="AbstractVstEditor.h"> @@ -477,9 +480,6 @@ <ClInclude Include="DefaultVstEditor.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\soundlib\IT_DEFS.H"> - <Filter>Module Loaders</Filter> - </ClInclude> <ClInclude Include="..\soundlib\Loaders.h"> <Filter>Module Loaders</Filter> </ClInclude> @@ -771,6 +771,9 @@ <ClInclude Include="PSRatioCalc.h"> <Filter>Header Files\Dialogs</Filter> </ClInclude> + <ClInclude Include="..\soundlib\ITTools.h"> + <Filter>Module Loaders</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="res\bitmap1.bmp"> Added: trunk/OpenMPT/soundlib/ITTools.cpp =================================================================== --- trunk/OpenMPT/soundlib/ITTools.cpp (rev 0) +++ trunk/OpenMPT/soundlib/ITTools.cpp 2012-03-04 23:39:50 UTC (rev 1203) @@ -0,0 +1,634 @@ +/* + * ITTools.cpp + * ----------- + * Purpose: Definition of IT file structures and helper functions + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#include "stdafx.h" +#include "Loaders.h" +#include "ITTools.h" +#include "../common/StringFixer.h" + + +// Convert all multi-byte numeric values to current platform's endianness or vice versa. +void ITFileHeader::ConvertEndianness() +//------------------------------------ +{ + id = LittleEndian(id); + ordnum = LittleEndianW(ordnum); + insnum = LittleEndianW(insnum); + smpnum = LittleEndianW(smpnum); + patnum = LittleEndianW(patnum); + cwtv = LittleEndianW(cwtv); + cmwt = LittleEndianW(cmwt); + flags = LittleEndianW(flags); + special = LittleEndianW(special); + msglength = LittleEndianW(msglength); + msgoffset = LittleEndian(msgoffset); + reserved = LittleEndian(reserved); +} + + +// Convert OpenMPT's internal envelope format into an IT/MPTM envelope. +void ITEnvelope::ConvertToIT(const InstrumentEnvelope &mptEnv, BYTE envOffset, BYTE envDefault) +//--------------------------------------------------------------------------------------------- +{ + // Envelope Flags + if(mptEnv.dwFlags & ENV_ENABLED) flags |= ITEnvelope::envEnabled; + if(mptEnv.dwFlags & ENV_LOOP) flags |= ITEnvelope::envLoop; + if(mptEnv.dwFlags & ENV_SUSTAIN) flags |= ITEnvelope::envSustain; + if(mptEnv.dwFlags & ENV_CARRY) flags |= ITEnvelope::envCarry; + + // Nodes and Loops + num = (uint8)min(mptEnv.nNodes, 25); + lpb = (uint8)mptEnv.nLoopStart; + lpe = (uint8)mptEnv.nLoopEnd; + slb = (uint8)mptEnv.nSustainStart; + sle = (uint8)mptEnv.nSustainEnd; + + // Envelope Data + if(mptEnv.nNodes > 0) + { + // Attention: Full MPTM envelope is stored in extended instrument properties + for(size_t ev = 0; ev < 25; ev++) + { + data[ev * 3] = mptEnv.Values[ev] - envOffset; + data[ev * 3 + 1] = mptEnv.Ticks[ev] & 0xFF; + data[ev * 3 + 2] = mptEnv.Ticks[ev] >> 8; + } + } else + { + // Fix non-existing envelopes so that they can still be edited in Impulse Tracker. + num = 2; + MemsetZero(data); + data[0] = data[3] = envDefault - envOffset; + data[4] = 10; + } +} + + +// Convert IT/MPTM envelope data into OpenMPT's internal envelope format - To be used by ITInstrToMPT() +void ITEnvelope::ConvertToMPT(InstrumentEnvelope &mptEnv, BYTE envOffset, int maxNodes) const +//------------------------------------------------------------------------------------------- +{ + // Envelope Flags + if(flags & ITEnvelope::envEnabled) mptEnv.dwFlags |= ENV_ENABLED; + if(flags & ITEnvelope::envLoop) mptEnv.dwFlags |= ENV_LOOP; + if(flags & ITEnvelope::envSustain) mptEnv.dwFlags |= ENV_SUSTAIN; + if(flags & ITEnvelope::envCarry) mptEnv.dwFlags |= ENV_CARRY; + + // Nodes and Loops + mptEnv.nNodes = min(num, maxNodes); + mptEnv.nLoopStart = min(lpb, static_cast<uint8>(maxNodes)); + mptEnv.nLoopEnd = Clamp(lpe, mptEnv.nLoopStart, static_cast<uint8>(maxNodes)); + mptEnv.nSustainStart = min(slb, static_cast<uint8>(maxNodes)); + mptEnv.nSustainEnd = Clamp(sle, mptEnv.nSustainStart, static_cast<uint8>(maxNodes)); + + // Envelope Data + // Attention: Full MPTM envelope is stored in extended instrument properties + for(size_t ev = 0; ev < 25; ev++) + { + mptEnv.Values[ev] = data[ev * 3] + envOffset; + mptEnv.Ticks[ev] = (data[ev * 3 + 2] << 8) | (data[ev * 3 + 1]); + if(ev > 0 && ev < num && mptEnv.Ticks[ev] < mptEnv.Ticks[ev - 1]) + { + // Fix broken envelopes... Instruments 2 and 3 in NoGap.it by Werewolf have envelope points where the high byte of envelope nodes is missing. + // NoGap.it was saved with MPT 1.07 or MPT 1.09, which *normally* doesn't do this in IT files. + // However... It turns out that MPT 1.07 omitted the high byte of envelope nodes when saving an XI instrument file, and it looks like + // Instrument 2 and 3 in NoGap.it were loaded from XI files. + mptEnv.Ticks[ev] &= 0xFF; + mptEnv.Ticks[ev] |= (mptEnv.Ticks[ev] & ~0xFF); + if(mptEnv.Ticks[ev] < mptEnv.Ticks[ev - 1]) + { + mptEnv.Ticks[ev] += 0x100; + } + } + } + + // Sanitize envelope + mptEnv.Ticks[0] = 0; +} + + +// Convert an ITOldInstrument to OpenMPT's internal instrument representation. +void ITOldInstrument::ConvertToMPT(ModInstrument &mptIns) const +//------------------------------------------------------------- +{ + // Header + if(id != LittleEndian(ITOldInstrument::magic)) + { + return; + } + + memcpy(mptIns.name, name, 26); + StringFixer::SpaceToNullStringFixed<25>(mptIns.name); + memcpy(mptIns.filename, filename, 13); + StringFixer::SpaceToNullStringFixed<12>(mptIns.filename); + + // Volume / Panning + mptIns.nFadeOut = LittleEndianW(fadeout) << 6; + mptIns.nGlobalVol = 64; + mptIns.nPan = 128; + + // NNA Stuff + mptIns.nNNA = nna; + mptIns.nDCT = dnc; + + // Sample Map + for(size_t i = 0; i < 120; i++) + { + BYTE note = keyboard[i * 2]; + SAMPLEINDEX ins = keyboard[i * 2 + 1]; + if(ins < MAX_SAMPLES) + { + mptIns.Keyboard[i] = ins; + } + if(note < 120) + { + mptIns.NoteMap[i] = note + 1u; + } + else + { + mptIns.NoteMap[i] = static_cast<BYTE>(i + 1); + } + } + + // Volume Envelope Flags + if(flags & ITOldInstrument::envEnabled) mptIns.VolEnv.dwFlags |= ENV_ENABLED; + if(flags & ITOldInstrument::envLoop) mptIns.VolEnv.dwFlags |= ENV_LOOP; + if(flags & ITOldInstrument::envSustain) mptIns.VolEnv.dwFlags |= ENV_SUSTAIN; + + // Volume Envelope Loops + mptIns.VolEnv.nLoopStart = vls; + mptIns.VolEnv.nLoopEnd = vle; + mptIns.VolEnv.nSustainStart = sls; + mptIns.VolEnv.nSustainEnd = sle; + mptIns.VolEnv.nNodes = 25; + + // Volume Envelope Data + for(size_t i = 0; i < 25; i++) + { + if((mptIns.VolEnv.Ticks[i] = nodes[i * 2]) == 0xFF) + { + mptIns.VolEnv.nNodes = i; + break; + } + mptIns.VolEnv.Values[i] = nodes[i * 2 + 1]; + } + + if(max(mptIns.VolEnv.nLoopStart, mptIns.VolEnv.nLoopEnd) >= mptIns.VolEnv.nNodes) mptIns.VolEnv.dwFlags &= ~ENV_LOOP; + if(max(mptIns.VolEnv.nSustainStart, mptIns.VolEnv.nSustainEnd) >= mptIns.VolEnv.nNodes) mptIns.VolEnv.dwFlags &= ~ENV_SUSTAIN; +} + + +// Convert OpenMPT's internal instrument representation to an ITInstrument. +size_t ITInstrument::ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile) +//--------------------------------------------------------------------------------------------------------- +{ + MemsetZero(*this); + + // Header + id = LittleEndian(ITInstrument::magic); + trkvers = LittleEndianW(0x0214); + + memcpy(filename, mptIns.filename, 13); + StringFixer::FixNullString(filename); + memcpy(name, mptIns.name, 26); + StringFixer::FixNullString(name); + + // Volume / Panning + fadeout = LittleEndianW(static_cast<uint16>(min(mptIns.nFadeOut >> 5, 256))); + gbv = static_cast<uint8>(mptIns.nGlobalVol * 2); + dfp = static_cast<uint8>(mptIns.nPan >> 2); + if(!(mptIns.dwFlags & INS_SETPANNING)) dfp |= ITInstrument::ignorePanning; + + // Random Variation + rv = min(mptIns.nVolSwing, 100); + rp = min(mptIns.nPanSwing, 64); + + // NNA Stuff + nna = mptIns.nNNA; + dct = (mptIns.nDCT < DCT_PLUGIN || !compatExport) ? mptIns.nDCT : DCT_NONE; + dca = mptIns.nDNA; + + // Pitch / Pan Separation + pps = mptIns.nPPS; + ppc = mptIns.nPPC; + + // Filter Stuff + ifc = mptIns.GetCutoff() | (mptIns.IsCutoffEnabled() ? ITInstrument::enableCutoff : 0x00); + ifr = mptIns.GetResonance() | (mptIns.IsResonanceEnabled() ? ITInstrument::enableResonance : 0x00); + + // MIDI Setup + mbank = mptIns.wMidiBank; + mpr = mptIns.nMidiProgram; + if(mptIns.nMidiChannel || mptIns.nMixPlug == 0 || compatExport) + { + // Default. Prefer MIDI channel over mixplug to keep the semantics intact. + mch = mptIns.nMidiChannel; + } else + { + // Keep compatibility with MPT 1.16's instrument format if possible, as XMPlay / BASS also uses this. + mch = mptIns.nMixPlug + 128; + } + + // Sample Map + nos = 0; + vector<bool> smpcount(sndFile.GetNumSamples(), false); + for(size_t i = 0; i < 120; i++) + { + keyboard[i * 2] = (mptIns.NoteMap[i] >= NOTE_MIN && mptIns.NoteMap[i] <= NOTE_MAX) ? (mptIns.NoteMap[i] - NOTE_MIN) : static_cast<uint8>(i); + + const SAMPLEINDEX smp = mptIns.Keyboard[i]; + if(smp < MAX_SAMPLES && smp < 256) + { + keyboard[i * 2 + 1] = static_cast<uint8>(smp); + + if(smp && smp <= sndFile.GetNumSamples() && !smpcount[smp - 1]) + { + // We haven't considered this sample yet. Update number of samples. + smpcount[smp - 1] = true; + nos++; + } + } + } + + // Writing Volume envelope + volenv.ConvertToIT(mptIns.VolEnv, 0, 64); + // Writing Panning envelope + panenv.ConvertToIT(mptIns.PanEnv, 32, 32); + // Writing Pitch Envelope + pitchenv.ConvertToIT(mptIns.PitchEnv, 32, 32); + if(mptIns.PitchEnv.dwFlags & ENV_FILTER) pitchenv.flags |= ITEnvelope::envFilter; + + return sizeof(ITInstrument); +} + + +// Convert an ITInstrument to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read. +size_t ITInstrument::ConvertToMPT(ModInstrument &mptIns, MODTYPE modFormat) const +//------------------------------------------------------------------------------- +{ + if(id != LittleEndian(ITInstrument::magic)) + { + return 0; + } + + memcpy(mptIns.name, name, 26); + StringFixer::SpaceToNullStringFixed<25>(mptIns.name); + memcpy(mptIns.filename, filename, 13); + StringFixer::SpaceToNullStringFixed<12>(mptIns.filename); + + // Volume / Panning + mptIns.nFadeOut = LittleEndianW(fadeout) << 5; + mptIns.nGlobalVol = gbv / 2; + LimitMax(mptIns.nGlobalVol, 64u); + mptIns.nPan = (dfp & 0x7F) << 2; + if(mptIns.nPan > 256) mptIns.nPan = 128; + if(!(dfp & ITInstrument::ignorePanning)) mptIns.dwFlags |= INS_SETPANNING; + + // Random Variation + mptIns.nVolSwing = min(rv, 100); + mptIns.nPanSwing = min(rp, 64); + + // NNA Stuff + mptIns.nNNA = nna; + mptIns.nDCT = dct; + mptIns.nDNA = dca; + + // Pitch / Pan Separation + mptIns.nPPS = pps; + mptIns.nPPC = ppc; + + // Filter Stuff + mptIns.SetCutoff(ifc & 0x7F, (ifc & ITInstrument::enableCutoff) != 0); + mptIns.SetResonance(ifr & 0x7F, (ifr & ITInstrument::enableResonance) != 0); + + // MIDI Setup + if(mpr <= 128) + { + mptIns.nMidiProgram = mpr; + } + mptIns.nMidiChannel = mch; + if(mptIns.nMidiChannel >= 128) + { + // Handle old format where MIDI channel and Plugin index are stored in the same variable + mptIns.nMixPlug = mptIns.nMidiChannel - 128; + mptIns.nMidiChannel = 0; + } + if(mbank <= 128) + { + mptIns.wMidiBank = LittleEndianW(mbank); + } + + // Envelope point count. Limited to 25 in IT format. + const int maxNodes = (modFormat & MOD_TYPE_MPT) ? MAX_ENVPOINTS : 25; + + // Volume Envelope + volenv.ConvertToMPT(mptIns.VolEnv, 0, maxNodes); + // Panning Envelope + panenv.ConvertToMPT(mptIns.PanEnv, 32, maxNodes); + // Pitch Envelope + pitchenv.ConvertToMPT(mptIns.PitchEnv, 32, maxNodes); + if(pitchenv.flags & ITEnvelope::envFilter) mptIns.PitchEnv.dwFlags |= ENV_FILTER; + + // Sample Map + for(size_t i = 0; i < 120; i++) + { + BYTE note = keyboard[i * 2]; + SAMPLEINDEX ins = keyboard[i * 2 + 1]; + if(ins < MAX_SAMPLES) + { + mptIns.Keyboard[i] = ins; + } + if(note < 120) + { + mptIns.NoteMap[i] = note + 1u; + } + else + { + mptIns.NoteMap[i] = static_cast<BYTE>(i + 1); + } + } + + return sizeof(ITInstrument); +} + + +// Convert OpenMPT's internal instrument representation to an ITInstrumentEx. Returns true if instrument extension is actually necessary. +size_t ITInstrumentEx::ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile) +//----------------------------------------------------------------------------------------------------------- +{ + size_t instSize = iti.ConvertToIT(mptIns, compatExport, sndFile); + + if(compatExport) + { + return instSize; + } + + // Sample Map + bool usedExtension = false; + iti.nos = 0; + vector<bool>smpcount(sndFile.GetNumSamples(), false); + for(size_t i = 0; i < 120; i++) + { + const SAMPLEINDEX smp = mptIns.Keyboard[i]; + if(smp < MAX_SAMPLES) + { + if(smp >= 256) + { + // We need to save the upper byte for this sample index. + iti.keyboard[i * 2 + 1] = static_cast<uint8>(smp & 0xFF); + keyboardhi[i] = static_cast<uint8>(smp >> 8); + usedExtension = true; + } + + if(smp && smp <= sndFile.GetNumSamples() && !smpcount[smp - 1]) + { + // We haven't considered this sample yet. Update number of samples. + smpcount[smp - 1] = true; + iti.nos++; + } + } + } + + if(usedExtension) + { + // If we actually had to extend the sample map, update the magic bytes and instrument size. + iti.dummy = LittleEndian(ITInstrumentEx::mptx); + instSize = sizeof(ITInstrumentEx); + } + + return instSize; +} + + +// Convert an ITInstrumentEx to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read. +size_t ITInstrumentEx::ConvertToMPT(ModInstrument &mptIns, MODTYPE fromType) const +//-------------------------------------------------------------------------------- +{ + size_t insSize = iti.ConvertToMPT(mptIns, fromType); + + // Is this actually an extended instrument? + if(insSize == 0 || iti.dummy != LittleEndian(ITInstrumentEx::mptx)) + { + return insSize; + } + + // Olivier's MPT Instrument Extension + for(size_t i = 0; i < 120; i++) + { + mptIns.Keyboard[i] |= ((SAMPLEINDEX)keyboardhi[i] << 8); + } + + return sizeof(ITInstrumentEx); +} + + +// Convert OpenMPT's internal sample representation to an ITSample. +void ITSample::ConvertToIT(const ModSample &mptSmp, MODTYPE fromType) +//------------------------------------------------------------------- +{ + MemsetZero(*this); + + // Header + id = LittleEndian(ITSample::magic); + + memcpy(filename, mptSmp.filename, 13); + StringFixer::FixNullString(filename); + //memcpy(name, m_szNames[nsmp], 26); + //StringFixer::FixNullString(name); + + // Volume / Panning + gvl = static_cast<BYTE>(mptSmp.nGlobalVol); + vol = static_cast<BYTE>(mptSmp.nVolume / 4); + dfp = static_cast<BYTE>(mptSmp.nPan / 4); + if(mptSmp.uFlags & CHN_PANNING) dfp |= ITSample::enablePanning; + + // Sample Format / Loop Flags + if(mptSmp.nLength && mptSmp.pSample) + { + flags = ITSample::sampleDataPresent; + if(mptSmp.uFlags & CHN_LOOP) flags |= ITSample::sampleLoop; + if(mptSmp.uFlags & CHN_SUSTAINLOOP) flags |= ITSample::sampleSustain; + if(mptSmp.uFlags & CHN_PINGPONGLOOP) flags |= ITSample::sampleBidiLoop; + if(mptSmp.uFlags & CHN_PINGPONGSUSTAIN) flags |= ITSample::sampleBidiSustain; + + if(mptSmp.uFlags & CHN_STEREO) + { + flags |= ITSample::sampleStereo; + } + if(mptSmp.uFlags & CHN_16BIT) + { + flags |= ITSample::sample16Bit; + } + cvt = ITSample::cvtSignedSample; + } + else + { + flags = 0x00; + } + + // Frequency + C5Speed = LittleEndian(mptSmp.nC5Speed ? mptSmp.nC5Speed : 8363); + + // Size and loops + length = LittleEndian(mptSmp.nLength); + loopbegin = LittleEndian(mptSmp.nLoopStart); + loopend = LittleEndian(mptSmp.nLoopEnd); + susloopbegin = LittleEndian(mptSmp.nSustainStart); + susloopend = LittleEndian(mptSmp.nSustainEnd); + + // Auto Vibrato settings + static const uint8 autovibxm2it[8] = { 0, 2, 4, 1, 3, 0, 0, 0 }; // OpenMPT VibratoType -> IT Vibrato + vit = autovibxm2it[mptSmp.nVibType & 7]; + vis = min(mptSmp.nVibRate, 64); + vid = min(mptSmp.nVibDepth, 32); + vir = min(mptSmp.nVibSweep, 255); + + if((vid | vis) != 0 && (fromType & MOD_TYPE_XM)) + { + // Sweep is upside down in XM + vir = 255 - vir; + } +} + + +// Convert an ITSample to OpenMPT's internal sample representation. +size_t ITSample::ConvertToMPT(ModSample &mptSmp) const +//---------------------------------------------------- +{ + if(id != LittleEndian(ITSample::magic)) + { + return 0; + } + + memcpy(mptSmp.filename, filename, 13); + StringFixer::SpaceToNullStringFixed<12>(mptSmp.filename); + + mptSmp.uFlags = 0; + + // Volume / Panning + mptSmp.nVolume = vol * 4; + LimitMax(mptSmp.nVolume, WORD(256)); + mptSmp.nGlobalVol = gvl; + LimitMax(mptSmp.nGlobalVol, WORD(64)); + mptSmp.nPan = (dfp & 0x7F) * 4; + LimitMax(mptSmp.nPan, WORD(256)); + if(dfp & ITSample::enablePanning) mptSmp.uFlags |= CHN_PANNING; + + // Loop Flags + if(flags & ITSample::sampleLoop) mptSmp.uFlags |= CHN_LOOP; + if(flags & ITSample::sampleSustain) mptSmp.uFlags |= CHN_SUSTAINLOOP; + if(flags & ITSample::sampleBidiLoop) mptSmp.uFlags |= CHN_PINGPONGLOOP; + if(flags & ITSample::sampleBidiSustain) mptSmp.uFlags |= CHN_PINGPONGSUSTAIN; + + // Frequency + mptSmp.nC5Speed = LittleEndian(C5Speed); + if(!mptSmp.nC5Speed) mptSmp.nC5Speed = 8363; + if(mptSmp.nC5Speed < 256) mptSmp.nC5Speed = 256; + + // Size and loops + mptSmp.nLength = min(LittleEndian(length), MAX_SAMPLE_LENGTH); + mptSmp.nLoopStart = LittleEndian(loopbegin); + mptSmp.nLoopEnd = LittleEndian(loopend); + mptSmp.nSustainStart = LittleEndian(susloopbegin); + mptSmp.nSustainEnd = LittleEndian(susloopend); + + // Auto Vibrato settings + static const uint8 autovibit2xm[8] = { VIB_SINE, VIB_RAMP_DOWN, VIB_SQUARE, VIB_RANDOM, VIB_RAMP_UP, 0, 0, 0 }; // IT Vibrato -> OpenMPT VibratoType + mptSmp.nVibType = autovibit2xm[vit & 7]; + mptSmp.nVibRate = vis; + mptSmp.nVibDepth = vid & 0x7F; + mptSmp.nVibSweep = vir; + + return mptSmp.nLength ? LittleEndian(samplepointer) : 0; +} + + +// Retrieve the internal sample format flags for this instrument. +UINT ITSample::GetSampleFormat(uint16 cwtv) const +//----------------------------------------------- +{ + UINT mptFlags = (cvt & ITSample::cvtSignedSample) ? RS_PCM8S : RS_PCM8U; + + if(flags & ITSample::sample16Bit) + { + // 16-Bit sample + mptFlags += 5; + + // Some old version of IT didn't clear the stereo flag when importing samples. Luckily, all other trackers are identifying as IT 2.14+, so let's check for old IT versions. + if((flags & ITSample::sampleStereo) && cwtv >= 0x214) + { + mptFlags |= RSF_STEREO; + } + + if(flags & ITSample::sampleCompressed) + { + // IT 2.14 16-bit packed sample + mptFlags = (cvt & ITSample::cvtIT215Compression) ? RS_IT21516 : RS_IT21416; + } + } else + { + // 8-Bit sample + // Some old version of IT didn't clear the stereo flag when importing samples. Luckily, all other trackers are identifying as IT 2.14+, so let's check for old IT versions. + if((flags & ITSample::sampleStereo) && cwtv >= 0x214) + { + mptFlags |= RSF_STEREO; + } + + if(cvt == ITSample::cvtADPCMSample) + { + mptFlags = RS_ADPCM4; + } else if(flags & ITSample::sampleCompressed) + { + // IT 2.14 8-bit packed sample? + mptFlags = (cvt & ITSample::cvtIT215Compression) ? RS_IT2158 : RS_IT2148; + } + } + + return mptFlags; +} + + +#ifdef MODPLUG_TRACKER + +// Convert an ITHistoryStruct to OpenMPT's internal edit history representation +void ITHistoryStruct::ConvertToMPT(FileHistory &mptHistory) const +//--------------------------------------------------------------- +{ + uint16 date = LittleEndianW(fatdate); + uint16 time = LittleEndianW(fattime); + uint32 run = LittleEndian(runtime); + + // Decode FAT date and time + MemsetZero(mptHistory.loadDate); + mptHistory.loadDate.tm_year = ((date >> 9) & 0x7F) + 80; + mptHistory.loadDate.tm_mon = Clamp((date >> 5) & 0x0F, 1, 12) - 1; + mptHistory.loadDate.tm_mday = Clamp(date & 0x1F, 1, 31); + mptHistory.loadDate.tm_hour = Clamp((time >> 11) & 0x1F, 0, 23); + mptHistory.loadDate.tm_min = Clamp((time >> 5) & 0x3F, 0, 59); + mptHistory.loadDate.tm_sec = Clamp((time & 0x1F) * 2, 0, 59); + mptHistory.openTime = static_cast<uint32>(run * (HISTORY_TIMER_PRECISION / 18.2f)); +} + + +// Convert OpenMPT's internal edit history representation to an ITHistoryStruct +void ITHistoryStruct::ConvertToIT(const FileHistory &mptHistory) +//-------------------------------------------------------------- +{ + // Create FAT file dates + fatdate = static_cast<uint16>(mptHistory.loadDate.tm_mday | ((mptHistory.loadDate.tm_mon + 1) << 5) | ((mptHistory.loadDate.tm_year - 80) << 9)); + fattime = static_cast<uint16>((mptHistory.loadDate.tm_sec / 2) | (mptHistory.loadDate.tm_min << 5) | (mptHistory.loadDate.tm_hour << 11)); + runtime = static_cast<uint32>(mptHistory.openTime * (18.2f / HISTORY_TIMER_PRECISION)); + + fatdate = LittleEndianW(fatdate); + fattime = LittleEndianW(fattime); + runtime = LittleEndian(runtime); +} + +#endif // MODPLUG_TRACKER Copied: trunk/OpenMPT/soundlib/ITTools.h (from rev 1194, trunk/OpenMPT/soundlib/IT_DEFS.H) =================================================================== --- trunk/OpenMPT/soundlib/ITTools.h (rev 0) +++ trunk/OpenMPT/soundlib/ITTools.h 2012-03-04 23:39:50 UTC (rev 1203) @@ -0,0 +1,326 @@ +/* + * ITTools.h + * --------- + * Purpose: Definition of IT file structures and helper functions + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#pragma once + +#ifdef MODPLUG_TRACKER +#include "../mptrack/Moddoc.h" +#endif // MODPLUG_TRACKER + +#pragma pack(push, 1) + +struct ITFileHeader +{ + // Magic Bytes + enum Magic + { + itMagic = 0x4D504D49, // "IMPM" IT Header Magic Bytes + mptmMagic = 0x2E6D7074, // "tpm." Old MPTM header magic bytes + omptMagic = 0x54504D4F, // "OMPT" Magic Bytes for non-standard OpenMPT IT files + chibiMagic = 0x49424843, // "CHBI" Magic Bytes in the IT header to identify ChibiTracker + }; + + // Header Flags + enum ITHeaderFlags + { + useStereoPlayback = 0x01, + vol0Optimisations = 0x02, + instrumentMode = 0x04, + linearSlides = 0x08, + itOldEffects = 0x10, + itCompatGxx = 0x20, + useMIDIPitchController = 0x40, + reqEmbeddedMIDIConfig = 0x80, + extendedFilterRange = 0x1000, + }; + + // Special Flags + enum ITHeaderSpecialFlags + { + embedSongMessage = 0x01, + embedEditHistory = 0x02, + embedPatternHighlights = 0x04, + embedMIDIConfiguration = 0x08, + }; + + uint32 id; // Magic Bytes (IMPM) + char songname[26]; // Song Name (duh) + uint8 highlight_minor; // Rows per Beat highlight + uint8 highlight_major; // Rows per Measure highlight + uint16 ordnum; // Number of Orders + uint16 insnum; // Number of Instruments + uint16 smpnum; // Number of Samples + uint16 patnum; // Number of Patterns + uint16 cwtv; // "Made With" Tracker + uint16 cmwt; // "Compatible With" Tracker + uint16 flags; // Header Flags + uint16 special; // Special Flags, for embedding extra information + uint8 globalvol; // Global Volume (0...128) + uint8 mv; // Master Volume (0...128), referred to as Sample Volume in OpenMPT + uint8 speed; // Initial Speed (1...255) + uint8 tempo; // Initial Tempo (31...255) + uint8 sep; // Pan Separation (0...128) + uint8 pwd; // Pitch Wheel Depth + uint16 msglength; // Length of Song Message + uint32 msgoffset; // Offset of Song Message in File + uint32 reserved; // ChibiTracker writes "CHBI" here. OpenMPT writes "OMPT" here in some cases, see Load_it.cpp + uint8 chnpan[64]; // Initial Channel Panning + uint8 chnvol[64]; // Initial Channel Volume + + // Convert all multi-byte numeric values to current platform's endianness or vice versa. + void ConvertEndianness(); +}; + +STATIC_ASSERT(sizeof(ITFileHeader) == 192); + + +struct ITEnvelope +{ + // Envelope Flags + enum ITEnvelopeFlags + { + envEnabled = 0x01, + envLoop = 0x02, + envSustain = 0x04, + envCarry = 0x08, + envFilter = 0x80, + }; + + uint8 flags; // Envelope Flags + uint8 num; // Number of Envelope Nodes + uint8 lpb; // Loop Start + uint8 lpe; // Loop End + uint8 slb; // Sustain Start + uint8 sle; // Sustain End + uint8 data[25 * 3]; // Envelope Node Positions / Values + uint8 reserved; // Reserved + + // Convert OpenMPT's internal envelope format to an IT/MPTM envelope. + void ConvertToIT(const InstrumentEnvelope &mptEnv, BYTE envOffset, BYTE envDefault); + // Convert IT/MPTM envelope data into OpenMPT's internal envelope format - To be used by ITInstrToMPT() + void ConvertToMPT(InstrumentEnvelope &mptEnv, BYTE envOffset, int maxNodes) const; +}; + +STATIC_ASSERT(sizeof(ITEnvelope) == 82); + + +// Old Impulse Instrument Format (cmwt < 0x200) +struct ITOldInstrument +{ + // Magic Bytes + enum Magic + { + magic = 0x49504D49, // "IMPI" IT Instrument Header Magic Bytes + }; + + enum ITOldInstrFlags + { + envEnabled = 0x01, + envLoop = 0x02, + envSustain = 0x04, + }; + + uint32 id; // Magic Bytes (IMPI) + char filename[13]; // DOS Filename + uint8 flags; // Volume Envelope Flags + uint8 vls; // Envelope Loop Start + uint8 vle; // Envelope Loop End + uint8 sls; // Envelope Sustain Start + uint8 sle; // Envelope Sustain End + char reserved1[2]; // Reserved + uint16 fadeout; // Instrument Fadeout (0...128) + uint8 nna; // New Note Action + uint8 dnc; // Duplicate Note Check Type + uint16 trkvers; // Tracker ID + uint8 nos; // Number of embedded samples + char reserved2; // Reserved + char name[26]; // Instrument Name + char reserved3[6]; // Even more reserved bytes + uint8 keyboard[240]; // Sample / Transpose map + uint8 volenv[200]; // This appears to be a pre-computed (interpolated) version of the volume envelope data found below. + uint8 nodes[25 * 2]; // Volume Envelope Node Positions / Values + + // Convert an ITOldInstrument to OpenMPT's internal instrument representation. + void ConvertToMPT(ModInstrument &mptIns) const; +}; + +STATIC_ASSERT(sizeof(ITOldInstrument) == 554); + + +// Impulse Instrument Format +struct ITInstrument +{ + // Magic Bytes + enum Magic + { + magic = 0x49504D49, // "IMPI" IT Instrument Header Magic Bytes + }; + + enum ITInstrumentFlags + { + ignorePanning = 0x80, + enableCutoff = 0x80, + enableResonance = 0x80, + }; + + uint32 id; // Magic Bytes (IMPI) + char filename[13]; // DOS Filename + uint8 nna; // New Note Action + uint8 dct; // Duplicate Note Check Type + uint8 dca; // Duplicate Note Check Action + uint16 fadeout; // Instrument Fadeout (0...128) + int8 pps; // Pitch/Pan Separatation + uint8 ppc; // Pitch/Pan Centre + uint8 gbv; // Global Volume + uint8 dfp; // Panning + uint8 rv; // Vol Swing + uint8 rp; // Pan Swing + uint16 trkvers; // Tracker ID + uint8 nos; // Number of embedded samples + char reserved1; // Reserved + char name[26]; // Instrument Name + uint8 ifc; // Filter Cutoff + uint8 ifr; // Filter Resonance + uint8 mch; // MIDI Channel + uint8 mpr; // MIDI Program + uint16 mbank; // MIDI Bank + uint8 keyboard[240]; // Sample / Transpose map + ITEnvelope volenv; // Volume Envelope + ITEnvelope panenv; // Pan Envelope + ITEnvelope pitchenv; // Pitch / Filter Envelope + uint32 dummy; // IT saves some additional padding bytes to match the size of the old instrument format for simplified loading. We use them for some hacks. + + // Convert OpenMPT's internal instrument representation to an ITInstrument. Returns amount of bytes that need to be written. + size_t ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile); + // Convert an ITInstrument to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read. + size_t ConvertToMPT(ModInstrument &mptIns, MODTYPE fromType) const; +}; + +STATIC_ASSERT(sizeof(ITInstrument) == 554); + + +// MPT IT Instrument Extension +struct ITInstrumentEx +{ + enum Magic + { + mptx = 0x5854504D, // "MPTX" Extended Instrument Header Magic Bytes + }; + + ITInstrument iti; // Normal IT Instrument + uint8 keyboardhi[120]; // High Byte of Sample map + + // Convert OpenMPT's internal instrument representation to an ITInstrumentEx. Returns amount of bytes that need to be written. + size_t ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile); + // Convert an ITInstrumentEx to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read. + size_t ConvertToMPT(ModInstrument &mptIns, MODTYPE fromType) const; +}; + +STATIC_ASSERT(sizeof(ITInstrumentEx) == sizeof(ITInstrument) + 120); + + +// IT Sample Format +struct ITSample +{ + // Magic Bytes + enum Magic + { + magic = 0x53504D49, // "IMPS" IT Sample Header Magic Bytes + }; + + enum ITSampleFlags + { + sampleDataPresent = 0x01, + sample16Bit = 0x02, + sampleStereo = 0x04, + sampleCompressed = 0x08, + sampleLoop = 0x10, + sampleSustain = 0x20, + sampleBidiLoop = 0x40, + sampleBidiSustain = 0x80, + + enablePanning = 0x80, + + cvtSignedSample = 0x01, + cvtIT215Compression = 0x04, + cvtADPCMSample = 0xFF + }; + + uint32 id; // Magic Bytes (IMPS) + char filename[13]; // DOS Filename + uint8 gvl; // Global Volume + uint8 flags; // Sample Flags + uint8 vol; // Default Volume + char name[26]; // Sample Name + uint8 cvt; // Sample Import Format + uint8 dfp; // Sample Panning + uint32 length; // Sample Length (in samples) + uint32 loopbegin; // Sample Loop Begin (in samples) + uint32 loopend; // Sample Loop End (in samples) + uint32 C5Speed; // C-5 frequency + uint32 susloopbegin; // Sample Sustain Begin (in samples) + uint32 susloopend; // Sample Sustain End (in samples) + uint32 samplepointer; // Pointer to sample data + uint8 vis; // Auto-Vibrato Rate (called Sweep in IT) + uint8 vid; // Auto-Vibrato Depth + uint8 vir; // Auto-Vibrato Sweep (called Rate in IT) + uint8 vit; // Auto-Vibrato Type + + // Convert OpenMPT's internal sample representation to an ITSample. + void ConvertToIT(const ModSample &mptSmp, MODTYPE fromType); + // Convert an ITSample to OpenMPT's internal sample representation. + size_t ConvertToMPT(ModSample &mptSmp) const; + // Retrieve the internal sample format flags for this instrument. + UINT GetSampleFormat(uint16 cwtv = 0x214) const; +}; + +STATIC_ASSERT(sizeof(ITSample) == 80); + + +// IT Header extension: Save history +struct ITHistoryStruct +{ + uint16 fatdate; // DOS / FAT date when the file was opened / created in the editor. For details, read http://msdn.microsoft.com/en-us/library/ms724247(VS.85).aspx + uint16 fattime; // DOS / FAT time when the file was opened / created in the editor. + uint32 runtime; // The time how long the file was open in the editor, in 1/18.2th seconds. (= ticks of the DOS timer) + +#ifdef MODPLUG_TRACKER + + // Convert an ITHistoryStruct to OpenMPT's internal edit history representation + void ConvertToMPT(FileHistory &mptHistory) const; + // Convert OpenMPT's internal edit history representation to an ITHistoryStruct + void ConvertToIT(const FileHistory &mptHistory); + +#endif // MODPLUG_TRACKER + +}; + +STATIC_ASSERT(sizeof(ITHistoryStruct) == 8); + +#pragma pack(pop) + +// MPT stuff +enum MPTHackMagic +{ + magicPatternNames = 0x4D414E50, // "PNAM" pattern names + magicChannelNames = 0x4D414E43, // "CNAM" channel names +}; + +enum IT_ReaderBitMasks +{ + // pattern row parsing, the channel data is read to obtain + // number of channels active in the pattern. These bit masks are + // to blank out sections of the byte of data being read. + + IT_bitmask_patternChanField_c = 0x7f, + IT_bitmask_patternChanMask_c = 0x3f, + IT_bitmask_patternChanEnabled_c = 0x80, + IT_bitmask_patternChanUsed_c = 0x0f +}; Deleted: trunk/OpenMPT/soundlib/IT_DEFS.H =================================================================== --- trunk/OpenMPT/soundlib/IT_DEFS.H 2012-03-04 23:19:51 UTC (rev 1202) +++ trunk/OpenMPT/soundlib/IT_DEFS.H 2012-03-04 23:39:50 UTC (rev 1203) @@ -1,186 +0,0 @@ -/* - * IT_DEFS.H - * --------- - * Purpose: IT file structures - * Notes : (currently none) - * Authors: OpenMPT Devs - * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. - */ - - -#pragma once - -#pragma pack(push, 1) - -struct ITFILEHEADER -{ - DWORD id; // 0x4D504D49 - CHAR songname[26]; - BYTE highlight_minor; - BYTE highlight_major; - WORD ordnum; - WORD insnum; - WORD smpnum; - WORD patnum; - WORD cwtv; // "made with" tracker - WORD cmwt; // "compatible with" tracker - WORD flags; - WORD special; - BYTE globalvol; - BYTE mv; // master volume - BYTE speed; - BYTE tempo; - BYTE sep; // panning separation (0...128) - BYTE pwd; // pitch wheel depth - WORD msglength; - DWORD msgoffset; - DWORD reserved; // ChibiTracker writes "CHBI" here. OpenMPT writes "OMPT" here in some cases, see Load_it.cpp - BYTE chnpan[64]; - BYTE chnvol[64]; -}; - - -struct ITENVELOPE -{ - BYTE flags; - BYTE num; - BYTE lpb; - BYTE lpe; - BYTE slb; - BYTE sle; - BYTE data[25*3]; - BYTE reserved; -}; - -// Old Impulse Instrument Format (cmwt < 0x200) -struct ITOLDINSTRUMENT -{ - DWORD id; // IMPI = 0x49504D49 - CHAR filename[12]; // DOS file name - BYTE zero; - BYTE flags; - BYTE vls; - BYTE vle; - BYTE sls; - BYTE sle; - WORD reserved1; - WORD fadeout; - BYTE nna; - BYTE dnc; - WORD trkvers; - BYTE nos; - BYTE reserved2; - CHAR name[26]; - WORD reserved3[3]; - BYTE keyboard[240]; - BYTE volenv[200]; - BYTE nodes[50]; -}; - - -// Impulse Instrument Format -struct ITINSTRUMENT -{ - DWORD id; - CHAR filename[12]; - BYTE zero; - BYTE nna; - BYTE dct; - BYTE dca; - WORD fadeout; - signed char pps; - BYTE ppc; - BYTE gbv; - BYTE dfp; - BYTE rv; - BYTE rp; - WORD trkvers; - BYTE nos; - BYTE reserved1; - CHAR name[26]; - BYTE ifc; - BYTE ifr; - BYTE mch; - BYTE mpr; - WORD mbank; - BYTE keyboard[240]; - ITENVELOPE volenv; - ITENVELOPE panenv; - ITENVELOPE pitchenv; - BYTE dummy[4]; // was 7, but IT v2.17 saves 554 bytes -}; - - -// MPT IT Instrument Extension -struct ITINSTRUMENTEX -{ - ITINSTRUMENT iti; - BYTE keyboardhi[120]; -}; - - -// IT Sample Format -struct ITSAMPLESTRUCT -{ - DWORD id; // 0x53504D49 - CHAR filename[12]; - BYTE zero; - BYTE gvl; - BYTE flags; - BYTE vol; - CHAR name[26]; - BYTE cvt; - BYTE dfp; - DWORD length; - DWORD loopbegin; - DWORD loopend; - DWORD C5Speed; - DWORD susloopbegin; - DWORD susloopend; - DWORD samplepointer; - BYTE vis; - BYTE vid; - BYTE vir; - BYTE vit; -}; - - -// IT Header extension: Save history -struct ITHISTORYSTRUCT -{ - uint16 fatdate; // DOS / FAT date when the file was opened / created in the editor. For details, read http://msdn.microsoft.com/en-us/library/ms724247(VS.85).aspx - uint16 fattime; // DOS / FAT time when the file was opened / created in the editor. - uint32 runtime; // The time how long the file was open in the editor, in 1/18.2th seconds. (= ticks of the DOS timer) -}; - -#pragma pack(pop) - -extern BYTE autovibit2xm[8]; -extern BYTE autovibxm2it[8]; - -// Impulse Tracker identifcators -#define IT_IMPM 0x4D504D49 // "IMPM" IT header magic bytes -#define IT_IMPS 0x53504D49 // "IMPS" IT sample header magic bytes -#define IT_IMPI 0x49504D49 // "IMPI" IT instrument header magic bytes - -// Identificators by other trackers -#define IT_MPTM 0x2E6D7074 // "tpm." old MPTM header magic bytes -#define IT_OMPT 0x54504D4F // "OMPT" magic bytes for non-standard OpenMPT IT files -#define IT_CHBI 0x49424843 // "CHBI" magic bytes in the IT header to identify ChibiTracker - -// MPT stuff -#define IT_PNAM 0x4D414E50 // "PNAM" pattern names -#define IT_CNAM 0x4D414E43 // "CNAM" channel names - -enum IT_ReaderBitMasks -{ - // pattern row parsing, the channel data is read to obtain - // number of channels active in the pattern. These bit masks are - // to blank out sections of the byte of data being read. - - IT_bitmask_patternChanField_c = 0x7f, - IT_bitmask_patternChanMask_c = 0x3f, - IT_bitmask_patternChanEnabled_c = 0x80, - IT_bitmask_patternChanUsed_c = 0x0f - -}; Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2012-03-04 23:19:51 UTC (rev 1202) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2012-03-04 23:39:50 UTC (rev 1203) @@ -11,7 +11,6 @@ #include "stdafx.h" #include "Loaders.h" -#include "IT_DEFS.H" #include "tuningcollection.h" #include "../mptrack/moddoc.h" #include "../mptrack/serialization_utils.h" @@ -19,6 +18,7 @@ #include <strstream> #include <list> #include "../mptrack/version.h" +#include "ITTools.h" #define str_tooMuchPatternData (GetStrI18N((_TEXT("Warning: File format limit was reached. Some pattern data may not get written to file.")))) #define str_pattern (GetStrI18N((_TEXT("pattern")))) @@ -223,14 +223,6 @@ #pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data -// IT Vibrato -> VibratoType -BYTE autovibit2xm[8] = -{ VIB_SINE, VIB_RAMP_DOWN, VIB_SQUARE, VIB_RANDOM, VIB_RAMP_UP, 0, 0, 0 }; - -// VibratoType -> Vibrato -BYTE autovibxm2it[8] = -{ 0, 2, 4, 1, 3, 0, 0, 0 }; - ////////////////////////////////////////////////////////// // Impulse Tracker IT file support @@ -242,235 +234,35 @@ } -// Convert MPT's internal envelope format into an IT/MPTM envelope. -void MPTEnvToIT(const InstrumentEnvelope *mptEnv, ITENVELOPE *itEnv, const BYTE envOffset, const BYTE envDefault) -//--------------------------------------------------------------------------------------------------------------- +size_t CSoundFile::ITInstrToMPT(const void *p, ModInstrument *pIns, UINT trkvers, size_t memLength) +//------------------------------------------------------------------------------------------------- { - if(mptEnv->dwFlags & ENV_ENABLED) itEnv->flags |= 1; - if(mptEnv->dwFlags & ENV_LOOP) itEnv->flags |= 2; - if(mptEnv->dwFlags & ENV_SUSTAIN) itEnv->flags |= 4; - if(mptEnv->dwFlags & ENV_CARRY) itEnv->flags |= 8; - itEnv->num = (BYTE)min(mptEnv->nNodes, 25); - itEnv->lpb = (BYTE)mptEnv->nLoopStart; - itEnv->lpe = (BYTE)mptEnv->nLoopEnd; - itEnv->slb = (BYTE)mptEnv->nSustainStart; - itEnv->sle = (BYTE)mptEnv->nSustainEnd; - - if(mptEnv->nNodes > 0) + if(trkvers < 0x0200) { - // Attention: Full MPTM envelope is stored in extended instrument properties - for(size_t ev = 0; ev < 25; ev++) - { - itEnv->data[ev * 3] = mptEnv->Values[ev] - envOffset; - itEnv->data[ev * 3 + 1] = mptEnv->Ticks[ev] & 0xFF; - itEnv->data[ev * 3 + 2] = mptEnv->Ticks[ev] >> 8; - } + // Load old format (IT 1.xx) instrument + const ITOldInstrument *itIns = reinterpret_cast<const ITOldInstrument *>(p); + itIns->ConvertToMPT(*pIns); + return sizeof(ITOldInstrument); } else { - // Fix non-existing envelopes so that they can still be edited in Impulse Tracker. - itEnv->num = 2; - MemsetZero(itEnv->data); - itEnv->data[0] = itEnv->data[3] = envDefault - envOffset; - itEnv->data[4] = 10; - } -} - - -// 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) -//----------------------------------------------------------------------------------------------------------- -{ - if(itEnv->flags & 1) mptEnv->dwFlags |= ENV_ENABLED; - if(itEnv->flags & 2) mptEnv->dwFlags |= ENV_LOOP; - if(itEnv->flags & 4) mptEnv->dwFlags |= ENV_SUSTAIN; - if(itEnv->flags & 8) mptEnv->dwFlags |= ENV_CARRY; - 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]); - if(ev > 0 && ev < itEnv->num && mptEnv->Ticks[ev] < mptEnv->Ticks[ev - 1]) + size_t instSize = 0; + if(memLength >= sizeof(ITInstrumentEx)) { - // Fix broken envelopes... Instruments 2 and 3 in NoGap.it by Werewolf have envelope points where the high byte of envelope nodes is missing. - // NoGap.it was saved with MPT 1.07 or MPT 1.09, which *normally* doesn't do this in IT files. - // However... It turns out that MPT 1.07 omitted the high byte of envelope nodes when saving an XI instrument file, and it looks like - // Instrument 2 and 3 in NoGap.it were loaded from XI files. - mptEnv->Ticks[ev] &= 0xFF; - mptEnv->Ticks[ev] |= (mptEnv->Ticks[ev] & ~0xFF); - if(mptEnv->Ticks[ev] < mptEnv->Ticks[ev - 1]) - { - mptEnv->Ticks[ev] += 0x100; - } - } - } - // Sanitize envelope - mptEnv->Ticks[0] = 0; -} - - -//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; - if (trkvers < 0x0200) - { - const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p; - memcpy(pIns->name, pis->name, 26); - memcpy(pIns->filename, pis->filename, 12); - StringFixer::SpaceToNullStringFixed<26>(pIns->name); - StringFixer::SpaceToNullStringFixed<12>(pIns->filename); - pIns->nFadeOut = pis->fadeout << 6; - pIns->nGlobalVol = 64; - for (UINT j = 0; j < 120; j++) + // Try loading extended instrument + const ITInstrumentEx *itIns = reinterpret_cast<const ITInstrumentEx *>(p); + instSize = itIns->ConvertToMPT(*pIns, GetType()); + } else { - UINT note = pis->keyboard[j*2]; - UINT ins = pis->keyboard[j*2+1]; - if (ins < MAX_SAMPLES) pIns->Keyboard[j] = ins; - if (note < 120) pIns->NoteMap[j] = note + 1; - else pIns->NoteMap[j] = j + 1; + // Load normal instrument + const ITInstrument *itIns = reinterpret_cast<const ITInstrument *>(p); + instSize = itIns->ConvertToMPT(*pIns, GetType()); } - if (pis->flags & 0x01) pIns->VolEnv.dwFlags |= ENV_ENABLED; - if (pis->flags & 0x02) pIns->VolEnv.dwFlags |= ENV_LOOP; - if (pis->flags & 0x04) pIns->VolEnv.dwFlags |= ENV_SUSTAIN; - pIns->VolEnv.nLoopStart = pis->vls; - pIns->VolEnv.nLoopEnd = pis->vle; - pIns->VolEnv.nSustainStart = pis->sls; - pIns->VolEnv.nSustainEnd = pis->sle; - pIns->VolEnv.nNodes = 25; - for (UINT ev=0; ev<25; ev++) - { - if ((pIns->VolEnv.Ticks[ev] = pis->nodes[ev*2]) == 0xFF) - { - pIns->VolEnv.nNodes = ev; - break; - } - pIns->VolEnv.Values[ev] = pis->nodes[ev*2+1]; - } - pIns->nNNA = pis->nna; - pIns->nDCT = pis->dnc; - pIns->nPan = 0x80; - } else - { - const ITINSTRUMENT *pis = (const ITINSTRUMENT *)p; - memcpy(pIns->name, pis->name, 26); - memcpy(pIns->filename, pis->filename, 12); - StringFixer::SpaceToNullStringFixed<26>(pIns->name); - StringFixer::SpaceToNullStringFixed<12>(pIns->filename); - if (pis->mpr<=128) - pIns->nMidiProgram = pis->mpr; - pIns->nMidiChannel = pis->mch; - if (pIns->nMidiChannel >= 128) //rewbs.instroVSTi - { //(handle old format where midichan - // and mixplug are 1 value) - pIns->nMixPlug = pIns->nMidiChannel - 128; - pIns->nMidiChannel = 0; - } - if (pis->mbank<=128) - pIns->wMidiBank = pis->mbank; - pIns->nFadeOut = pis->fadeout << 5; - pIns->nGlobalVol = pis->gbv >> 1; - if (pIns->nGlobalVol > 64) pIns->nGlobalVol = 64; - for (UINT j = 0; j < 120; j++) - { - UINT note = pis->keyboard[j*2]; - UINT ins = pis->keyboard[j*2+1]; - if (ins < MAX_SAMPLES) pIns->Keyboard[j] = ins; - if (note < 120) pIns->NoteMap[j] = note + 1; - else pIns->NoteMap[j] = j + 1; - } - // Olivier's MPT Instrument Extension - if (*((int *)pis->dummy) == 'MPTX') - { - const ITINSTRUMENTEX *pisex = (const ITINSTRUMENTEX *)pis; - for (UINT k = 0; k < 120; k++) - { - pIns->Keyboard[k] |= ((UINT)pisex->keyboardhi[k] << 8); - } - } - //rewbs.modularInstData - //find end of standard header - BYTE* pEndInstHeader; - if (*((int *)pis->dummy) == 'MPTX') - pEndInstHeader=(BYTE*)pis+sizeof(ITINSTRUMENTEX); - else - pEndInstHeader=(BYTE*)pis+sizeof(ITINSTRUMENT); + // Try reading modular instrument data + instSize += LoadModularInstrumentData(LPCBYTE(p) + instSize, memLength - instSize, pIns); - //If the next piece of data is 'INSM' we have modular extensions to our instrument... - if ( *( (UINT*)pEndInstHeader ) == 'INSM' ) - { - //...the next piece of data must be the total size of the modular data - long modularInstSize = *((long *)(pEndInstHeader+4)); - - //handle chunks - BYTE* pModularInst = (BYTE*)(pEndInstHeader+4+sizeof(modularInstSize)); //4 is for 'INSM' - pEndInstHeader+=4+sizeof(modularInstSize)+modularInstSize; - while (pModularInst<pEndInstHeader) //4 is for 'INSM' - { - UINT chunkID = *((int *)pModularInst); - pModularInst+=4; - switch (chunkID) - { - /*case 'DMMY': - MessageBox(NULL, "Dummy chunk identified", NULL, MB_OK|MB_ICONEXCLAMATION); - pModularInst+=1024; - break;*/ - case 'PLUG': - pIns->nMixPlug = *(pModularInst); - pModularInst+=sizeof(pIns->nMixPlug); - break; - /*How to load more chunks? -- see also how to save chunks - case: 'MYID': - // handle chunk data, as pointed to by pModularInst - // move pModularInst as appropriate - break; - */ - - default: pModularInst++; //move forward one byte and try to recognize again. - - } - } - returnVal = 4+sizeof(modularInstSize)+modularInstSize; - } - //end rewbs.modularInstData - - - // Volume Envelope - ITEnvToMPT(&pis->volenv, &pIns->VolEnv, 0, iEnvMax); - // Panning Envelope - ITEnvToMPT(&pis->panenv, &pIns->PanEnv, 32, iEnvMax); - // Pitch Envelope - ITEnvToMPT(&pis->pitchenv, &pIns->PitchEnv, 32, iEnvMax); - if (pis->pitchenv.flags & 0x80) pIns->PitchEnv.dwFlags |= ENV_FILTER; - - pIns->nNNA = pis->nna; - pIns->nDCT = pis->dct; - pIns->nDNA = pis->dca; - pIns->nPPS = pis->pps; - pIns->nPPC = pis->ppc; - pIns->SetCutoff(pis->ifc & 0x7F, (pis->ifc & 0x80) != 0); - pIns->SetResonance(pis->ifr & 0x7F, (pis->ifr & 0x80) != 0); - pIns->nVolSwing = min(pis->rv, 100); - pIns->nPanSwing = min(pis->rp, 64); - pIns->nPan = (pis->dfp & 0x7F) << 2; - if (pIns->nPan > 256) pIns->nPan = 128; - if (pis->dfp < 0x80) pIns->dwFlags |= INS_SETPANNING; + return instSize; } - - if ((pIns->VolEnv.nLoopStart >= iEnvMax) || (pIns->VolEnv.nLoopEnd >= iEnvMax)) pIns->VolEnv.dwFlags &= ~ENV_LOOP; - if ((pIns->VolEnv.nSustainStart >= iEnvMax) || (pIns->VolEnv.nSustainEnd >= iEnvMax)) pIns->VolEnv.dwFlags &= ~ENV_SUSTAIN; - - return returnVal; //return offset } @@ -489,9 +281,12 @@ bool CSoundFile::ReadIT(const LPCBYTE lpStream, const DWORD dwMemLength) //---------------------------------------------------------------------- { - ITFILEHEADER *pifh = (ITFILEHEADER *)lpStream; + if(!lpStream || dwMemLength < sizeof(ITFileHeader)) return false; - DWORD dwMemPos = sizeof(ITFILEHEADER); + ITFileHeader itHeader = *reinterpret_cast<const ITFileHeader *>(lpStream); + itHeader.ConvertEndianness(); + + DWORD dwMemPos = sizeof(ITFileHeader); vector<DWORD> inspos; vector<DWORD> smppos; vector<DWORD> patpos; @@ -499,25 +294,24 @@ bool interpretModPlugMade = false; bool hasModPlugExtensions = false; - if ((!lpStream) || (dwMemLength < 0xC0)) return false; - if ((pifh->id != LittleEndian(IT_IMPM) && pifh->id != LittleEndian(IT_MPTM)) || (pifh->insnum > 0xFF) - || (pifh->smpnum >= MAX_SAMPLES)) return false; - if (dwMemPos + pifh->ordnum + pifh->insnum*4 - + pifh->smpnum*4 + pifh->patnum*4 > dwMemLength) return false; + if((itHeader.id != ITFileHeader::itMagic && itHeader.id != ITFileHeader::mptmMagic) || itHeader.insnum > 0xFF + || itHeader.smpnum >= MAX_SAMPLES) return false; + // Check if we can actually read all parapointers + if(dwMemPos + itHeader.ordnum + itHeader.insnum * 4 + + itHeader.smpnum * 4 + itHeader.patnum * 4 > dwMemLength) return false; - DWORD mptStartPos = dwMemLength; memcpy(&mptStartPos, lpStream + (dwMemLength - sizeof(DWORD)), sizeof(DWORD)); if(mptStartPos >= dwMemLength || mptStartPos < 0x100) mptStartPos = dwMemLength; - if(pifh->id == LittleEndian(IT_MPTM)) + if(itHeader.id == ITFileHeader::mptmMagic) { ChangeModTypeTo(MOD_TYPE_MPT); } else { - if(mptStartPos <= dwMemLength - 3 && pifh->cwtv > 0x888) + if(mptStartPos <= dwMemLength - 3 && itHeader.cwtv > 0x888) { char temp[3]; const char ID[3] = {'2','2','8'}; @@ -530,22 +324,22 @@ if(GetType() == MOD_TYPE_IT) { // Which tracker was used to made this? - if((pifh->cwtv & 0xF000) == 0x5000) + if((itHeader.cwtv & 0xF000) == 0x5000) { // OpenMPT Version number (Major.Minor) // This will only be interpreted as "made with ModPlug" (i.e. disable compatible playback etc) if the "reserved" field is set to "OMPT" - else, compatibility was used. - m_dwLastSavedWithVersion = (pifh->cwtv & 0x0FFF) << 16; - if(pifh->reserved == LittleEndian(IT_OMPT)) + m_dwLastSavedWithVersion = (itHeader.cwtv & 0x0FFF) << 16; + if(itHeader.reserved == ITFileHeader::omptMagic) interpretModPlugMade = true; - } else if(pifh->cmwt == 0x888 || pifh->cwtv == 0x888) + } else if(itHeader.cmwt == 0x888 || itHeader.cwtv == 0x888) { // OpenMPT 1.17 and 1.18 (raped IT format) // Exact version number will be determined later. interpretModPlugMade = true; m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 17, 00, 00); - } else if(pifh->cwtv == 0x0217 && pifh->cmwt == 0x0200 && pifh->reserved == 0) + } else if(itHeader.cwtv == 0x0217 && itHeader.cmwt == 0x0200 && itHeader.reserved == 0) { - if(memchr(pifh->chnpan, 0xFF, sizeof(pifh->chnpan)) != NULL) + if(memchr(itHeader.chnpan, 0xFF, sizeof(itHeader.chnpan)) != NULL) { // ModPlug Tracker 1.16 (semi-raped IT format) m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00); @@ -556,13 +350,13 @@ m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 17, 00, 00); } interpretModPlugMade = true; - } else if(pifh->cwtv == 0x0214 && pifh->cmwt == 0x0202 && pifh->reserved == 0) + } else if(itHeader.cwtv == 0x0214 && itHeader.cmwt == 0x0202 && itHeader.reserved == 0) { // ModPlug Tracker b3.3 - 1.09, instruments 557 bytes apart m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 09, 00, 00); interpretModPlugMade = true; } - else if(pifh->cwtv == 0x0214 && pifh->cmwt == 0x0200 && pifh->reserved == 0) + else if(itHeader.cwtv == 0x0214 && itHeader.cmwt == 0x0200 && itHeader.reserved == 0) { // ModPlug Tracker 1.00a5, instruments 560 bytes apart m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, A5); @@ -571,13 +365,13 @@ } else // case: type == MOD_TYPE_MPT { - if (pifh->cwtv >= verMptFileVerLoadLimit) + if (itHeader.cwtv >= verMptFileVerLoadLimit) { if (GetpModDoc()) GetpModDoc()->AddToLog(str_LoadingIncompatibleVersion); return false; } - else if (pifh->cwtv > verMptFileVer) + else if (itHeader.cwtv > verMptFileVer) { if (GetpModDoc()) GetpModDoc()->AddToLog(str_LoadingMoreRecentVersion); @@ -588,67 +382,59 @@ if(GetType() == MOD_TYPE_IT) mptStartPos = dwMemLength; // Read row highlights - if((pifh->special & 0x04)) + if((itHeader.special & ITFileHeader::embedPatternHighlights)) { // MPT 1.09, 1.07 and most likely other old MPT versions leave this blank (0/0), but have the "special" flag set. // Newer versions of MPT and OpenMPT 1.17 *always* write 4/16 here. // Thus, we will just ignore those old versions. if(m_dwLastSavedWithVersion == 0 || m_dwLastSavedWithVersion >= MAKE_VERSION_NUMERIC(1, 17, 03, 02)) { - m_nDefaultRowsPerBeat = pifh->highlight_minor; - m_nDefaultRowsPerMeasure = pifh->highlight_major; + m_nDefaultRowsPerBeat = itHeader.highlight_minor; + m_nDefaultRowsPerMeasure = itHeader.highlight_major; } #ifdef DEBUG - if((pifh->highlight_minor | pifh->highlight_major) == 0) + if((itHeader.highlight_minor | itHeader.highlight_major) == 0) { Log("IT Header: Row highlight is 0"); } #endif } - if (pifh->flags & 0x08) m_dwSongFlags |= SONG_LINEARSLIDES; - if (pifh->flags & 0x10) m_dwSongFlags |= SONG_ITOLDEFFECTS; - if (pifh->flags & 0x20) m_dwSongFlags |= SONG_ITCOMPATGXX; - if ((pifh->flags & 0x80) || (pifh->special & 0x08)) m_dwSongFlags |= SONG_EMBEDMIDICFG; - if (pifh->flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE; + if (itHeader.flags & ITFileHeader::linearSlides) m_dwSongFlags |= SONG_LINEARSLIDES; + if (itHeader.flags & ITFileHeader::itOldEffects) m_dwSongFlags |= SONG_ITOLDEFFECTS; + if (itHeader.flags & ITFileHeader::itCompatGxx) m_dwSongFlags |= SONG_ITCOMPATGXX; + if ((itHeader.flags & ITFileHeader::reqEmbeddedMIDIConfig) || (itHeader.special & ITFileHeader::embedMIDIConfiguration)) m_dwSongFlags |= SONG_EMBEDMIDICFG; + if (itHeader.flags & ITFileHeader::extendedFilterRange) m_dwSongFlags |= SONG_EXFILTERRANGE; - memcpy(m_szNames[0], pifh->songname, 26); + memcpy(m_szNames[0], itHeader.songname, 26); StringFixer::SpaceToNullStringFixed<26>(m_szNames[0]); // Global Volume - m_nDefaultGlobalVolume = pifh->globalvol << 1; + m_nDefaultGlobalVolume = itHeader.globalvol << 1; if (m_nDefaultGlobalVolume > MAX_GLOBAL_VOLUME) m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; - if (pifh->speed) m_nDefaultSpeed = pifh->speed; - m_nDefaultTempo = max(32, pifh->tempo); // tempo 31 is possible. due to conflicts with the rest of the engine, let's just clamp it to 32. - m_nSamplePreAmp = min(pifh->mv, 128); + if (itHeader.speed) m_nDefaultSpeed = itHeader.speed; + m_nDefaultTempo = max(32, itHeader.tempo); // tempo 31 is possible. due to conflicts with the rest of the engine, let's just clamp it to 32. + m_nSamplePreAmp = min(itHeader.mv, 128); // Reading Channels Pan Positions - for (int ipan=0; ipan< 64; ipan++) if (pifh->chnpan[ipan] != 0xFF) + for (int ipan=0; ipan< 64; ipan++) if (itHeader.chnpan[ipan] != 0xFF) { - ChnSettings[ipan].nVolume = pifh->chnvol[ipan]; + ChnSettings[ipan].nVolume = itHeader.chnvol[ipan]; ChnSettings[ipan].nPan = 128; - if (pifh->chnpan[ipan] & 0x80) ChnSettings[ipan].dwFlags |= CHN_MUTE; - UINT n = pifh->chnpan[ipan] & 0x7F; + if (itHeader.chnpan[ipan] & 0x80) ChnSettings[ipan].dwFlags |= CHN_MUTE; + UINT n = itHeader.chnpan[ipan] & 0x7F; if (n <= 64) ChnSettings[ipan].nPan = n << 2; if (n == 100) ChnSettings[ipan].dwFlags |= CHN_SURROUND; } if (m_nChannels < GetModSpecifications().channelsMin) m_nChannels = GetModSpecifications().channelsMin; - // Reading Song Message - if ((pifh->special & 0x01) && (pifh->msglength) && (pifh->msglength <= dwMemLength) && (pifh->msgoffset < dwMemLength - pifh->msglength)) - { - // Generally, IT files should use CR for line endings. However, ChibiTracker uses LF. One could do... - // if(pifh->cwtv == 0x0214 && pifh->cmwt == 0x0214 && pifh->reserved == LittleEndian(IT_CHBI)) --> Chibi detected. - // But we'll just use autodetection here: - ReadMessage(lpStream + pifh->msgoffset, pifh->msglength, leAutodetect); - } // Reading orders - UINT nordsize = pifh->ordnum; + UINT nordsize = itHeader.ordnum; if(GetType() == MOD_TYPE_IT) { if(nordsize > MAX_ORDERS) nordsize = MAX_ORDERS; Order.ReadAsByte(lpStream + dwMemPos, nordsize, dwMemLength-dwMemPos); - dwMemPos += pifh->ordnum; + dwMemPos += itHeader.ordnum; } else { @@ -662,12 +448,12 @@ nordsize = GetModSpecifications().ordersMax; } - if(pifh->cwtv > 0x88A && pifh->cwtv <= 0x88D) + if(itHeader.cwtv... [truncated message content] |
From: <sag...@us...> - 2012-03-07 00:07:30
|
Revision: 1204 http://modplug.svn.sourceforge.net/modplug/?rev=1204&view=rev Author: saga-games Date: 2012-03-07 00:07:20 +0000 (Wed, 07 Mar 2012) Log Message: ----------- [Ref] Unhealthy amount of refactoring: Pattern cursor / selection handling has been refacored so that implementation details using bitmaks are properly hidden now. [Ref] Much more refactoring in the pattern editor, which also lead to fixing some smaller bugs. [Ref] Moved clipboard code to a separate file. The implementation is ready for multiple internal clipboards, all it needs is a proper dialog now. [Mod] OpenMPT: Version is now 1.20.00.74 Modified Paths: -------------- trunk/OpenMPT/mptrack/Childfrm.cpp trunk/OpenMPT/mptrack/Childfrm.h trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_pat.h trunk/OpenMPT/mptrack/Draw_pat.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/PatternEditorDialogs.cpp trunk/OpenMPT/mptrack/PatternEditorDialogs.h trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_pat.h trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/ITTools.h Added Paths: ----------- trunk/OpenMPT/mptrack/PatternClipboard.cpp trunk/OpenMPT/mptrack/PatternClipboard.h trunk/OpenMPT/mptrack/PatternCursor.h Modified: trunk/OpenMPT/mptrack/Childfrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/Childfrm.cpp 2012-03-04 23:39:50 UTC (rev 1203) +++ trunk/OpenMPT/mptrack/Childfrm.cpp 2012-03-07 00:07:20 UTC (rev 1204) @@ -158,7 +158,7 @@ { m_ViewPatterns.nPattern=pModDoc->GetSoundFile()->Order[0]; m_ViewPatterns.nOrder=0; //just in case (should already be 0) - m_ViewPatterns.nRow=0; //just in case + m_ViewPatterns.cursor.SetRow(0); //just in case m_bInitialActivation=false; } } Modified: trunk/OpenMPT/mptrack/Childfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Childfrm.h 2012-03-04 23:39:50 UTC (rev 1203) +++ trunk/OpenMPT/mptrack/Childfrm.h 2012-03-07 00:07:20 UTC (rev 1204) @@ -13,6 +13,7 @@ class CModControlDlg; class CChildFrame; +#include "PatternCursor.h" typedef struct _GENERALVIEWSTATE { @@ -27,11 +28,9 @@ { DWORD cbStruct; PATTERNINDEX nPattern; - ROWINDEX nRow; - UINT nCursor; - DWORD dwBeginSel; - DWORD dwEndSel; - UINT nDetailLevel; + PatternCursor cursor; + PatternRect selection; + PatternCursor::Columns nDetailLevel; ORDERINDEX nOrder; //rewbs.playSongFromCursor } PATTERNVIEWSTATE; Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2012-03-04 23:39:50 UTC (rev 1203) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2012-03-07 00:07:20 UTC (rev 1204) @@ -108,7 +108,7 @@ m_bVUMeters = CMainFrame::GetSettings().gbPatternVUMeters; m_bPluginNames = CMainFrame::GetSettings().gbPatternPluginNames; //rewbs.patPlugNames m_bRecord = CMainFrame::GetSettings().gbPatternRecord; - m_nDetailLevel = 4; + m_nDetailLevel = PatternCursor::lastColumn; } @@ -1180,9 +1180,9 @@ //------------------------------ { m_ToolBar.SetState(ID_PATTERNDETAIL_LO, TBSTATE_CHECKED|TBSTATE_ENABLED); - if (m_nDetailLevel != 1) + if (m_nDetailLevel != PatternCursor::instrColumn) { - m_nDetailLevel = 1; + m_nDetailLevel = PatternCursor::instrColumn; m_ToolBar.SetState(ID_PATTERNDETAIL_MED, TBSTATE_ENABLED); m_ToolBar.SetState(ID_PATTERNDETAIL_HI, TBSTATE_ENABLED); SendViewMessage(VIEWMSG_SETDETAIL, m_nDetailLevel); @@ -1195,9 +1195,9 @@ //------------------------------- { m_ToolBar.SetState(ID_PATTERNDETAIL_MED, TBSTATE_CHECKED|TBSTATE_ENABLED); - if (m_nDetailLevel != 2) + if (m_nDetailLevel != PatternCursor::volumeColumn) { - m_nDetailLevel = 2; + m_nDetailLevel = PatternCursor::volumeColumn; m_ToolBar.SetState(ID_PATTERNDETAIL_LO, TBSTATE_ENABLED); m_ToolBar.SetState(ID_PATTERNDETAIL_HI, TBSTATE_ENABLED); SendViewMessage(VIEWMSG_SETDETAIL, m_nDetailLevel); @@ -1210,9 +1210,9 @@ //------------------------------ { m_ToolBar.SetState(ID_PATTERNDETAIL_HI, TBSTATE_CHECKED|TBSTATE_ENABLED); - if (m_nDetailLevel != 4) + if (m_nDetailLevel != PatternCursor::lastColumn) { - m_nDetailLevel = 4; + m_nDetailLevel = PatternCursor::lastColumn; m_ToolBar.SetState(ID_PATTERNDETAIL_LO, TBSTATE_ENABLED); m_ToolBar.SetState(ID_PATTERNDETAIL_MED, TBSTATE_ENABLED); SendViewMessage(VIEWMSG_SETDETAIL, m_nDetailLevel); Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.h 2012-03-04 23:39:50 UTC (rev 1203) +++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2012-03-07 00:07:20 UTC (rev 1204) @@ -181,7 +181,7 @@ CSpinButtonCtrl m_SpinInstrument, m_SpinSpacing, m_SpinOrderListMargins, m_SpinSequence; CModControlBar m_ToolBar; INSTRUMENTINDEX m_nInstrument; - UINT m_nDetailLevel; + PatternCursor::Columns m_nDetailLevel; // Visible Columns BOOL m_bRecord, m_bVUMeters, m_bPluginNames; public: Modified: trunk/OpenMPT/mptrack/Draw_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Draw_pat.cpp 2012-03-04 23:39:50 UTC (rev 1203) +++ trunk/OpenMPT/mptrack/Draw_pat.cpp 2012-03-07 00:07:20 UTC (rev 1204) @@ -193,33 +193,32 @@ } -BOOL CViewPattern::UpdateSizes() +bool CViewPattern::UpdateSizes() //------------------------------ { PCPATTERNFONT pfnt = GetCurrentPatternFont(); int oldx = m_szCell.cx; m_szHeader.cx = ROWHDR_WIDTH; m_szHeader.cy = COLHDR_HEIGHT; - if (m_dwStatus & PATSTATUS_VUMETERS) m_szHeader.cy += VUMETERS_HEIGHT; - if (m_dwStatus & PATSTATUS_PLUGNAMESINHEADERS) m_szHeader.cy += PLUGNAME_HEIGHT; + if (m_dwStatus & psShowVUMeters) m_szHeader.cy += VUMETERS_HEIGHT; + if (m_dwStatus & psShowPluginNames) m_szHeader.cy += PLUGNAME_HEIGHT; m_szCell.cx = 4 + pfnt->nEltWidths[0]; - if (m_nDetailLevel > 0) m_szCell.cx += pfnt->nEltWidths[1]; - if (m_nDetailLevel > 1) m_szCell.cx += pfnt->nEltWidths[2]; - if (m_nDetailLevel > 2) m_szCell.cx += pfnt->nEltWidths[3] + pfnt->nEltWidths[4]; + if (m_nDetailLevel >= PatternCursor::instrColumn) m_szCell.cx += pfnt->nEltWidths[1]; + if (m_nDetailLevel >= PatternCursor::volumeColumn) m_szCell.cx += pfnt->nEltWidths[2]; + if (m_nDetailLevel >= PatternCursor::effectColumn) m_szCell.cx += pfnt->nEltWidths[3] + pfnt->nEltWidths[4]; m_szCell.cy = pfnt->nHeight; return (oldx != m_szCell.cx); } -UINT CViewPattern::GetColumnOffset(DWORD dwPos) const -//--------------------------------------------------- +UINT CViewPattern::GetColumnOffset(PatternCursor::Columns column) const +//--------------------------------------------------------------------- { PCPATTERNFONT pfnt = GetCurrentPatternFont(); - UINT n = 0; - dwPos &= 7; - if (dwPos > 4) dwPos = 4; - for (UINT i=0; i<dwPos; i++) n += pfnt->nEltWidths[i]; - return n; + LimitMax(column, PatternCursor::lastColumn); + UINT offset = 0; + for(int i = PatternCursor::firstColumn; i < column; i++) offset += pfnt->nEltWidths[i]; + return offset; } @@ -231,7 +230,7 @@ UpdateColors(); UpdateSizes(); UpdateScrollSize(); - InvalidatePattern(TRUE); + InvalidatePattern(true); return; } if(dwHintMask & HINT_MODCHANNELS) @@ -244,7 +243,7 @@ if(dwHintMask & (HINT_MODTYPE|HINT_PATTERNDATA)) { - InvalidatePattern(FALSE); + InvalidatePattern(false); } else if(dwHintMask & HINT_PATTERNROW) { @@ -254,32 +253,37 @@ } -POINT CViewPattern::GetPointFromPosition(DWORD dwPos) -//--------------------------------------------------- +POINT CViewPattern::GetPointFromPosition(PatternCursor cursor) +//------------------------------------------------------------ { PCPATTERNFONT pfnt = GetCurrentPatternFont(); POINT pt; int xofs = GetXScrollPos(); int yofs = GetYScrollPos(); - pt.x = (GetChanFromCursor(dwPos) - xofs) * GetColumnWidth(); - UINT imax = GetColTypeFromCursor(dwPos); - if (imax > LAST_COLUMN + 1) imax = LAST_COLUMN + 1; - if (imax > m_nDetailLevel + 1) imax = m_nDetailLevel + 1; - for (UINT i=0; i<imax; i++) + pt.x = (cursor.GetChannel() - xofs) * GetColumnWidth(); + + PatternCursor::Columns imax = cursor.GetColumnType(); + LimitMax(imax, PatternCursor::lastColumn); + LimitMax(imax, static_cast<PatternCursor::Columns>(m_nDetailLevel)); + + for(int i = 0; i < imax; i++) { pt.x += pfnt->nEltWidths[i]; } + if (pt.x < 0) pt.x = 0; pt.x += ROWHDR_WIDTH; - pt.y = ((dwPos >> 16) - yofs + m_nMidRow) * m_szCell.cy; + pt.y = (cursor.GetRow() - yofs + m_nMidRow) * m_szCell.cy; + if (pt.y < 0) pt.y = 0; pt.y += m_szHeader.cy; + return pt; } -DWORD CViewPattern::GetPositionFromPoint(POINT pt) -//------------------------------------------------ +PatternCursor CViewPattern::GetPositionFromPoint(POINT pt) +//-------------------------------------------------------- { PCPATTERNFONT pfnt = GetCurrentPatternFont(); int xofs = GetXScrollPos(); @@ -290,14 +294,14 @@ if (y < 0) y = 0; int xx = (pt.x - m_szHeader.cx) % GetColumnWidth(), dx = 0; int imax = 4; - if (imax > (int)m_nDetailLevel+1) imax = m_nDetailLevel+1; + if (imax > (int)m_nDetailLevel + 1) imax = m_nDetailLevel + 1; int i = 0; for (i=0; i<imax; i++) { dx += pfnt->nEltWidths[i]; if (xx < dx) break; } - return (y << 16) | (x << 3) | i; + return PatternCursor(static_cast<ROWINDEX>(y), static_cast<CHANNELINDEX>(x), static_cast<PatternCursor::Columns>(i)); } @@ -559,11 +563,11 @@ const char *pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr]? "[Channel %d]" : "Channel %d"; // const char *pszfmt = pModDoc->IsChannelRecord(ncolhdr) ? "Channel %d " : "Channel %d"; // -! NEW_FEATURE#0012 - if ((pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)) && ((BYTE)pSndFile->ChnSettings[ncolhdr].szName[0] >= ' ')) - pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr]?"%d: [%s]":"%d: %s"; - else if (m_nDetailLevel < 2) pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr]?"[Ch%d]":"Ch%d"; - else if (m_nDetailLevel < 3) pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr]?"[Chn %d]":"Chn %d"; - wsprintf(s, pszfmt, ncolhdr+1, pSndFile->ChnSettings[ncolhdr].szName); + if ((pSndFile->GetType() & (MOD_TYPE_XM | MOD_TYPE_IT | MOD_TYPE_MPT)) && ((BYTE)pSndFile->ChnSettings[ncolhdr].szName[0] >= ' ')) + pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr] ? "%d: [%s]" : "%d: %s"; + else if (m_nDetailLevel < PatternCursor::volumeColumn) pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr] ? "[Ch%d]" : "Ch%d"; + else if (m_nDetailLevel < PatternCursor::effectColumn) pszfmt = pSndFile->m_bChannelMuteTogglePending[ncolhdr] ? "[Chn %d]" : "Chn %d"; + wsprintf(s, pszfmt, ncolhdr + 1, pSndFile->ChnSettings[ncolhdr].szName); // -> CODE#0012 // -> DESC="midi keyboard split" // DrawButtonRect(hdc, &rect, s, @@ -618,14 +622,14 @@ } // -! NEW_FEATURE#0012 - if (m_dwStatus & PATSTATUS_VUMETERS) + if (m_dwStatus & psShowVUMeters) { OldVUMeters[ncolhdr] = 0; DrawChannelVUMeter(hdc, rect.left + 1, rect.bottom, ncolhdr); rect.top+=VUMETERS_HEIGHT; rect.bottom+=VUMETERS_HEIGHT; } - if (m_dwStatus & PATSTATUS_PLUGNAMESINHEADERS) + if (m_dwStatus & psShowPluginNames) { rect.top+=PLUGNAME_HEIGHT; rect.bottom+=PLUGNAME_HEIGHT; @@ -662,8 +666,7 @@ const ORDERINDEX startOrder = static_cast<ORDERINDEX>(SendCtrlMessage(CTRLMSG_GETCURRENTORDER)); if(startOrder > 0) { - ORDERINDEX prevOrder; - prevOrder = pSndFile->Order.GetPreviousOrderIgnoringSkips(startOrder); + ORDERINDEX prevOrder = pSndFile->Order.GetPreviousOrderIgnoringSkips(startOrder); //Skip +++ items if(startOrder < pSndFile->Order.size() && pSndFile->Order[startOrder] == m_nPattern) @@ -675,7 +678,7 @@ } if ((bPrevPatFound) && (nPrevPat < pSndFile->Patterns.Size()) && (pSndFile->Patterns[nPrevPat])) { - UINT nPrevRows = pSndFile->Patterns[nPrevPat].GetNumRows(); + ROWINDEX nPrevRows = pSndFile->Patterns[nPrevPat].GetNumRows(); UINT n = min(nSkip, nPrevRows); ypaint += (nSkip-n)*m_szCell.cy; @@ -707,11 +710,11 @@ int nVisRows = (rcClient.bottom - ypaint + m_szCell.cy - 1) / m_szCell.cy; if ((nVisRows > 0) && (m_nMidRow)) { - UINT nNextPat = m_nPattern; + PATTERNINDEX nNextPat = m_nPattern; bool bNextPatFound = false; const ORDERINDEX startOrder= static_cast<ORDERINDEX>(SendCtrlMessage(CTRLMSG_GETCURRENTORDER)); - ORDERINDEX nNextOrder; - nNextOrder = pSndFile->Order.GetNextOrderIgnoringSkips(startOrder); + + ORDERINDEX nNextOrder = pSndFile->Order.GetNextOrderIgnoringSkips(startOrder); if(nNextOrder == startOrder) nNextOrder = ORDERINDEX_INVALID; //Ignore skip items(+++) from sequence. const ORDERINDEX ordCount = pSndFile->Order.GetLength(); @@ -723,7 +726,7 @@ } if ((bNextPatFound) && (nNextPat < pSndFile->Patterns.Size()) && (pSndFile->Patterns[nNextPat])) { - UINT nNextRows = pSndFile->Patterns[nNextPat].GetNumRows(); + ROWINDEX nNextRows = pSndFile->Patterns[nNextPat].GetNumRows(); UINT n = min((UINT)nVisRows, nNextRows); m_Dib.SetBlendMode(0x80); @@ -746,7 +749,7 @@ DrawButtonRect(hdc, &rc, ""); } // Drawing pattern selection - if (m_dwStatus & PATSTATUS_DRAGNDROPPING) + if (m_dwStatus & psDragnDropping) { DrawDragSel(hdc); } @@ -775,6 +778,8 @@ //----------------------------------------------------------------------------------------------------- { BYTE bColSel[MAX_BASECHANNELS]; + static_assert(PatternCursor::lastColumn <= 7, "Columns are used as bitmasks here."); + PCPATTERNFONT pfnt = GetCurrentPatternFont(); const ModCommand m0 = ModCommand::Empty(); const ModCommand *pPattern = pSndFile->Patterns[nPattern]; @@ -782,20 +787,22 @@ CRect rect; int xpaint, ypaint = *pypaint; int row_col, row_bkcol; - UINT bRowSel, bSpeedUp, nColumnWidth, ncols, maxcol; + UINT bSpeedUp, nColumnWidth, ncols, maxcol; ncols = pSndFile->GetNumChannels(); nColumnWidth = m_szCell.cx; rect.SetRect(m_szHeader.cx, rcClient.top, m_szHeader.cx+nColumnWidth, rcClient.bottom); - for (UINT cmk=xofs; cmk<ncols; cmk++) + for(UINT cmk=xofs; cmk<ncols; cmk++) { - UINT c = cmk << 3; bColSel[cmk] = 0; if (bSelEnable) { - for (UINT n=0; n<5; n++) + for(int n = PatternCursor::firstColumn; n <= PatternCursor::lastColumn; n++) { - if ((c+n >= (m_dwBeginSel & 0xFFFF)) && (c+n <= (m_dwEndSel & 0xFFFF))) bColSel[cmk] |= 1 << n; + if(m_Selection.ContainsHorizontal(PatternCursor(0, static_cast<CHANNELINDEX>(cmk), static_cast<PatternCursor::Columns>(n)))) + { + bColSel[cmk] |= 1 << n; + } } } if (!::RectVisible(hdc, &rect)) bColSel[cmk] |= 0x80; @@ -816,7 +823,8 @@ m_Dib.TextBlt(ibmp-4, 0, 4, m_szCell.cy, pfnt->nClrX+pfnt->nWidth-4, pfnt->nClrY); } while (ibmp + nColumnWidth <= maxndx); } - bRowSel = FALSE; + + bool bRowSel = false; row_col = row_bkcol = -1; for (UINT row=yofs; row<nrows; row++) { @@ -835,8 +843,8 @@ } rect.right = rect.left + m_szHeader.cx; DrawButtonRect(hdc, &rect, s, !bSelEnable); - oldrowcolor = (row_bkcol << 16) | (row_col << 8) | (bRowSel); - bRowSel = ((row >= (m_dwBeginSel >> 16)) && (row <= (m_dwEndSel >> 16))) ? TRUE : FALSE; + oldrowcolor = (row_bkcol << 16) | (row_col << 8) | (bRowSel ? 1 : 0); + bRowSel = (m_Selection.ContainsVertical(PatternCursor(row))); row_col = MODCOLOR_TEXTNORMAL; row_bkcol = MODCOLOR_BACKNORMAL; @@ -872,14 +880,14 @@ row_col = MODCOLOR_TEXTPLAYCURSOR; row_bkcol = MODCOLOR_BACKPLAYCURSOR; } - if (row == m_nRow) + if (row == GetCurrentRow()) { - if (m_dwStatus & PATSTATUS_FOCUS) + if (m_dwStatus & psFocussed) { row_col = MODCOLOR_TEXTCURROW; row_bkcol = MODCOLOR_BACKCURROW; } else - if ((m_dwStatus & PATSTATUS_FOLLOWSONG) && (bPlaying)) + if ((m_dwStatus & psFollowSong) && (bPlaying)) { row_col = MODCOLOR_TEXTPLAYCURSOR; row_bkcol = MODCOLOR_BACKPLAYCURSOR; @@ -896,7 +904,7 @@ xpaint += nColumnWidth; } // Optimization: same row color ? - bSpeedUp = (oldrowcolor == (UINT)((row_bkcol << 16) | (row_col << 8) | bRowSel)) ? TRUE : FALSE; + bSpeedUp = (oldrowcolor == (UINT)((row_bkcol << 16) | (row_col << 8) | (bRowSel ? 1 : 0))) ? TRUE : FALSE; xbmp = nbmp = 0; do { @@ -914,19 +922,19 @@ const bool drawOldDefaultVolume = DrawDefaultVolume(mold); if (m->note == mold->note) dwSpeedUpMask |= 0x01; - if ((m->instr == mold->instr) || (m_nDetailLevel < 1)) dwSpeedUpMask |= 0x02; + if ((m->instr == mold->instr) || (m_nDetailLevel < PatternCursor::instrColumn)) dwSpeedUpMask |= 0x02; if ( m->IsPcNote() || mold->IsPcNote() ) { // Handle speedup mask for PC notes. if(m->note == mold->note) { - if(m->GetValueVolCol() == mold->GetValueVolCol() || (m_nDetailLevel < 2)) dwSpeedUpMask |= 0x04; - if(m->GetValueEffectCol() == mold->GetValueEffectCol() || (m_nDetailLevel < 3)) dwSpeedUpMask |= 0x18; + if(m->GetValueVolCol() == mold->GetValueVolCol() || (m_nDetailLevel < PatternCursor::volumeColumn)) dwSpeedUpMask |= 0x04; + if(m->GetValueEffectCol() == mold->GetValueEffectCol() || (m_nDetailLevel < PatternCursor::effectColumn)) dwSpeedUpMask |= 0x18; } } else { - if ((m->volcmd == mold->volcmd && (m->volcmd == VOLCMD_NONE || m->vol == mold->vol) && !drawDefaultVolume && !drawOldDefaultVolume) || (m_nDetailLevel < 2)) dwSpeedUpMask |= 0x04; - if ((m->command == mold->command) || (m_nDetailLevel < 3)) dwSpeedUpMask |= (m->command != CMD_NONE) ? 0x08 : 0x18; + if ((m->volcmd == mold->volcmd && (m->volcmd == VOLCMD_NONE || m->vol == mold->vol) && !drawDefaultVolume && !drawOldDefaultVolume) || (m_nDetailLevel < PatternCursor::volumeColumn)) dwSpeedUpMask |= 0x04; + if ((m->command == mold->command) || (m_nDetailLevel < PatternCursor::effectColumn)) dwSpeedUpMask |= (m->command != CMD_NONE) ? 0x08 : 0x18; } if (dwSpeedUpMask == 0x1F) goto DoBlit; } @@ -975,7 +983,7 @@ } x += pfnt->nEltWidths[0]; // Instrument - if (m_nDetailLevel > 0) + if (m_nDetailLevel >= PatternCursor::instrColumn) { if (!(dwSpeedUpMask & 0x02)) { @@ -997,7 +1005,7 @@ x += pfnt->nEltWidths[1]; } // Volume - if (m_nDetailLevel > 1) + if (m_nDetailLevel >= PatternCursor::volumeColumn) { if (!(dwSpeedUpMask & 0x04)) { @@ -1024,7 +1032,7 @@ x += pfnt->nEltWidths[2]; } // Command & param - if (m_nDetailLevel > 2) + if (m_nDetailLevel >= PatternCursor::effectColumn) { const bool isPCnote = m->IsPcNote(); uint16 val = m->GetValueEffectCol(); @@ -1128,14 +1136,14 @@ if (vul > 8) vul = 8; if (vur > 8) vur = 8; x += (m_szCell.cx / 2); - if (m_nDetailLevel <= 1) + if (m_nDetailLevel <= PatternCursor::instrColumn) { DibBlt(hdc, x-VUMETERS_LOWIDTH-1, y, VUMETERS_LOWIDTH, VUMETERS_BMPHEIGHT, VUMETERS_BMPWIDTH*2+VUMETERS_MEDWIDTH*2, vul * VUMETERS_BMPHEIGHT, CMainFrame::bmpVUMeters); DibBlt(hdc, x-1, y, VUMETERS_LOWIDTH, VUMETERS_BMPHEIGHT, VUMETERS_BMPWIDTH*2+VUMETERS_MEDWIDTH*2+VUMETERS_LOWIDTH, vur * VUMETERS_BMPHEIGHT, CMainFrame::bmpVUMeters); } else - if (m_nDetailLevel <= 2) + if (m_nDetailLevel <= PatternCursor::volumeColumn) { DibBlt(hdc, x - VUMETERS_MEDWIDTH-1, y, VUMETERS_MEDWIDTH, VUMETERS_BMPHEIGHT, VUMETERS_BMPWIDTH*2, vul * VUMETERS_BMPHEIGHT, CMainFrame::bmpVUMeters); @@ -1153,81 +1161,111 @@ } +// Draw an inverted border around the dragged selection. void CViewPattern::DrawDragSel(HDC hdc) //------------------------------------- { + // Ugly! + // XXX broken! CModDoc *pModDoc; CSoundFile *pSndFile; CRect rect; - POINT ptTopLeft, ptBottomRight; - DWORD dwTopLeft, dwBottomRight; - bool bLeft, bTop, bRight, bBottom; - int x1, y1, x2, y2, dx, dy, c1, c2; + int x1, y1, x2, y2; int nChannels, nRows; if ((pModDoc = GetDocument()) == nullptr) return; pSndFile = pModDoc->GetSoundFile(); - bLeft = bTop = bRight = bBottom = true; - x1 = (m_dwBeginSel & 0xFFF8) >> 3; - y1 = (m_dwBeginSel) >> 16; - x2 = (m_dwEndSel & 0xFFF8) >> 3; - y2 = (m_dwEndSel) >> 16; - c1 = (m_dwBeginSel&7); - c2 = (m_dwEndSel&7); - dx = (int)((m_dwDragPos & 0xFFF8) >> 3) - (int)((m_dwStartSel & 0xFFF8) >> 3); - dy = (int)(m_dwDragPos >> 16) - (int)(m_dwStartSel >> 16); + + // Compute relative movement + int dx = (int)m_DragPos.GetChannel() - (int)m_StartSel.GetChannel(); + int dy = (int)m_DragPos.GetRow() - (int)m_StartSel.GetRow(); + + // Compute destination rect + PatternCursor begin(m_Selection.GetUpperLeft()), end(m_Selection.GetLowerRight()); + + // Check which selection lines need to be drawn. + bool drawLeft = ((int)begin.GetChannel() + dx >= GetXScrollPos()); + bool drawRight = ((int)end.GetChannel() + dx < (int)pSndFile->GetNumChannels()); + bool drawTop = ((int)begin.GetRow() + dy >= GetYScrollPos() - (int)m_nMidRow); + bool drawBottom = ((int)end.GetRow() + dy < (int)pSndFile->Patterns[m_nPattern].GetNumRows()); + + begin.Move(dy, dx, 0); + if(begin.GetChannel() >= pSndFile->GetNumChannels()) + { + // Moved outside pattern range. + return; + } + end.Move(dy, dx, 0); + begin.Sanitize(pSndFile->Patterns[m_nPattern].GetNumRows(), pSndFile->GetNumChannels()); + end.Sanitize(pSndFile->Patterns[m_nPattern].GetNumRows(), pSndFile->GetNumChannels()); + // We need to know the first pixel that's not part of our rect anymore, so we extend the selection. + end.Move(1, 0, 1); + PatternRect destination(begin, end); + + x1 = m_Selection.GetStartChannel(); + y1 = m_Selection.GetStartRow(); + x2 = m_Selection.GetEndChannel(); + y2 = m_Selection.GetEndRow(); + PatternCursor::Columns c1 = m_Selection.GetStartColumn(); + PatternCursor::Columns c2 = m_Selection.GetEndColumn(); x1 += dx; x2 += dx; y1 += dy; y2 += dy; nChannels = pSndFile->m_nChannels; nRows = pSndFile->Patterns[m_nPattern].GetNumRows(); - if (x1 < GetXScrollPos()) bLeft = false; + if (x1 < GetXScrollPos()) drawLeft = false; if (x1 >= nChannels) x1 = nChannels - 1; - if (x1 < 0) { x1 = 0; c1 = 0; bLeft = false; } - if (x2 >= nChannels) { x2 = nChannels-1; c2 = 4; bRight = false; } + if (x1 < 0) { x1 = 0; c1 = PatternCursor::firstColumn; drawLeft = false; } + if (x2 >= nChannels) { x2 = nChannels - 1; c2 = PatternCursor::lastColumn; drawRight = false; } if (x2 < 0) x2 = 0; - if (y1 < GetYScrollPos() - (int)m_nMidRow) bTop = false; + if (y1 < GetYScrollPos() - (int)m_nMidRow) drawTop = false; if (y1 >= nRows) y1 = nRows-1; - if (y1 < 0) { y1 = 0; bTop = false; } - if (y2 >= nRows) { y2 = nRows-1; bBottom = false; } + if (y1 < 0) { y1 = 0; drawTop = false; } + if (y2 >= nRows) { y2 = nRows-1; drawBottom = false; } if (y2 < 0) y2 = 0; - dwTopLeft = (y1<<16)|(x1<<3)|c1; - dwBottomRight = ((y2+1)<<16)|(x2<<3)|(c2+1); - ptTopLeft = GetPointFromPosition(dwTopLeft); - ptBottomRight = GetPointFromPosition(dwBottomRight); + + POINT ptTopLeft = GetPointFromPosition(begin); + POINT ptBottomRight = GetPointFromPosition(end); if ((ptTopLeft.x >= ptBottomRight.x) || (ptTopLeft.y >= ptBottomRight.y)) return; + + if(end.GetColumnType() == PatternCursor::firstColumn) + { + // Special case: If selection ends on the last column of a channel, subtract the channel separator width. + ptBottomRight.x -= 4; + } + // invert the brush pattern (looks just like frame window sizing) CBrush* pBrush = CDC::GetHalftoneBrush(); if (pBrush != NULL) { HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, pBrush->m_hObject); // Top - if (bTop) + if (drawTop) { - rect.SetRect(ptTopLeft.x+4, ptTopLeft.y, ptBottomRight.x, ptTopLeft.y+4); - if (!bLeft) rect.left -= 4; + rect.SetRect(ptTopLeft.x + 4, ptTopLeft.y, ptBottomRight.x, ptTopLeft.y + 4); + if (!drawLeft) rect.left -= 4; PatBlt(hdc, rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT); } // Bottom - if (bBottom) + if (drawBottom) { - rect.SetRect(ptTopLeft.x, ptBottomRight.y-4, ptBottomRight.x-4, ptBottomRight.y); - if (!bRight) rect.right += 4; + rect.SetRect(ptTopLeft.x, ptBottomRight.y - 4, ptBottomRight.x - 4, ptBottomRight.y); + if (!drawRight) rect.right += 4; PatBlt(hdc, rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT); } // Left - if (bLeft) + if (drawLeft) { - rect.SetRect(ptTopLeft.x, ptTopLeft.y, ptTopLeft.x+4, ptBottomRight.y-4); - if (!bBottom) rect.bottom += 4; + rect.SetRect(ptTopLeft.x, ptTopLeft.y, ptTopLeft.x + 4, ptBottomRight.y - 4); + if (!drawBottom) rect.bottom += 4; PatBlt(hdc, rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT); } // Right - if (bRight) + if (drawRight) { - rect.SetRect(ptBottomRight.x-4, ptTopLeft.y+4, ptBottomRight.x, ptBottomRight.y); - if (!bTop) rect.top -= 4; + rect.SetRect(ptBottomRight.x - 4, ptTopLeft.y + 4, ptBottomRight.x, ptBottomRight.y); + if (!drawTop) rect.top -= 4; PatBlt(hdc, rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT); } if (hOldBrush != NULL) SelectObject(hdc, hOldBrush); @@ -1388,76 +1426,61 @@ void CViewPattern::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) //--------------------------------------------------------------------------- { - if (nSBCode == (SB_THUMBTRACK|SB_THUMBPOSITION)) m_dwStatus |= PATSTATUS_DRAGVSCROLL; + if (nSBCode == (SB_THUMBTRACK|SB_THUMBPOSITION)) m_dwStatus |= psDragVScroll; CModScrollView::OnVScroll(nSBCode, nPos, pScrollBar); - if (nSBCode == SB_ENDSCROLL) m_dwStatus &= ~PATSTATUS_DRAGVSCROLL; + if (nSBCode == SB_ENDSCROLL) m_dwStatus &= ~psDragVScroll; } -void CViewPattern::SetCurSel(DWORD dwBegin, DWORD dwEnd) -//------------------------------------------------------ +void CViewPattern::SetCurSel(const PatternCursor &beginSel, const PatternCursor &endSel) +//-------------------------------------------------------------------------------------- { RECT rect1, rect2, rect, rcInt, rcUni; POINT pt; - int x1, y1, x2, y2; - - x1 = dwBegin & 0xFFFF; - y1 = dwBegin >> 16; - x2 = dwEnd & 0xFFFF; - y2 = dwEnd >> 16; - if (x1 > x2) + + PatternRect oldSel = m_Selection; + m_Selection = PatternRect(beginSel, endSel); + const CModDoc *pModDoc = GetDocument(); + if(pModDoc != nullptr) { - int x = x2; - x2 = x1; - x1 = x; - } - if (y1 > y2) - { - int y = y2; - y2 = y1; - y1 = y; - } - // rewbs.fix3417: adding error checking - CModDoc *pModDoc = GetDocument(); - if (pModDoc) - { - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - if (pSndFile) + const CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if(pSndFile != nullptr) { - y1 = max(y1, 0); - y2 = min(y2, (int)pSndFile->Patterns[m_nPattern].GetNumRows() - 1); - x1 = max(x1, 0); - x2 = min(x2, pSndFile->GetNumChannels() * 8 - (8 - LAST_COLUMN)); + m_Selection.Sanitize(pSndFile->Patterns[m_nPattern].GetNumRows(), pSndFile->GetNumChannels()); } } - // end rewbs.fix3417 + // Get current selection area + PatternCursor endSel2(oldSel.GetLowerRight()); + endSel2.Move(1, 0, 1); - // Get current selection area - pt = GetPointFromPosition(m_dwBeginSel); + pt = GetPointFromPosition(oldSel.GetUpperLeft()); rect1.left = pt.x; rect1.top = pt.y; - pt = GetPointFromPosition(m_dwEndSel + 0x10001); + pt = GetPointFromPosition(endSel2); rect1.right = pt.x; rect1.bottom = pt.y; - if (rect1.left < m_szHeader.cx) rect1.left = m_szHeader.cx; - if (rect1.top < m_szHeader.cy) rect1.top = m_szHeader.cy; + if(rect1.left < m_szHeader.cx) rect1.left = m_szHeader.cx; + if(rect1.top < m_szHeader.cy) rect1.top = m_szHeader.cy; + // Get new selection area - m_dwBeginSel = (y1 << 16) | (x1); - m_dwEndSel = (y2 << 16) | (x2); - pt = GetPointFromPosition(m_dwBeginSel); + pt = GetPointFromPosition(m_Selection.GetUpperLeft()); rect2.left = pt.x; rect2.top = pt.y; - pt = GetPointFromPosition(m_dwEndSel + 0x10001); + endSel2.Set(m_Selection.GetLowerRight()); + endSel2.Move(1, 0, 1); + pt = GetPointFromPosition(endSel2); rect2.right = pt.x; rect2.bottom = pt.y; if (rect2.left < m_szHeader.cx) rect2.left = m_szHeader.cx; if (rect2.top < m_szHeader.cy) rect2.top = m_szHeader.cy; + + // Compute area for invalidation IntersectRect(&rcInt, &rect1, &rect2); UnionRect(&rcUni, &rect1, &rect2); SubtractRect(&rect, &rcUni, &rcInt); if ((rect.left == rcUni.left) && (rect.top == rcUni.top) - && (rect.right == rcUni.right) && (rect.bottom == rcUni.bottom)) + && (rect.right == rcUni.right) && (rect.bottom == rcUni.bottom)) { InvalidateRect(&rect1, FALSE); InvalidateRect(&rect2, FALSE); @@ -1468,12 +1491,12 @@ } -void CViewPattern::InvalidatePattern(BOOL bHdr) -//--------------------------------------------- +void CViewPattern::InvalidatePattern(bool invalidateHeader) +//--------------------------------------------------------- { CRect rect; GetClientRect(&rect); - if (!bHdr) + if(!invalidateHeader) { rect.left += m_szHeader.cx; rect.top += m_szHeader.cy; @@ -1490,7 +1513,7 @@ { CSoundFile *pSndFile = pModDoc->GetSoundFile(); int yofs = GetYScrollPos() - m_nMidRow; - if (n == ROWINDEX_INVALID) n = m_nRow; + if (n == ROWINDEX_INVALID) n = GetCurrentRow(); if (((int)n < yofs) || (n >= pSndFile->Patterns[m_nPattern].GetNumRows())) return; CRect rect; GetClientRect(&rect); @@ -1504,21 +1527,30 @@ } -void CViewPattern::InvalidateArea(DWORD dwBegin, DWORD dwEnd) -//----------------------------------------------------------- +void CViewPattern::InvalidateArea(PatternCursor begin, PatternCursor end) +//----------------------------------------------------------------------- { RECT rect; POINT pt; - pt = GetPointFromPosition(dwBegin); + pt = GetPointFromPosition(begin); rect.left = pt.x; rect.top = pt.y; - pt = GetPointFromPosition(dwEnd + 0x10001); + end.Move(1, 0, 1); + pt = GetPointFromPosition(end); rect.right = pt.x; rect.bottom = pt.y; InvalidateRect(&rect, FALSE); } +void CViewPattern::InvalidateCell(PatternCursor cursor) +//----------------------------------------------------- +{ + cursor.RemoveColType(); + InvalidateArea(cursor, PatternCursor(cursor.GetRow(), cursor.GetChannel(), PatternCursor::lastColumn)); +} + + void CViewPattern::InvalidateChannelsHeaders() //-------------------------------------------- { @@ -1545,23 +1577,23 @@ pMainFrm->SetUserText(s); if (::GetFocus() == m_hWnd) { - nChn = GetChanFromCursor(m_dwCursor); + nChn = m_Cursor.GetChannel(); s[0] = 0; - if ((!(m_dwStatus & (PATSTATUS_KEYDRAGSEL/*|PATSTATUS_MOUSEDRAGSEL*/))) //rewbs.xinfo: update indicator even when dragging - && (m_dwBeginSel == m_dwEndSel) && (pSndFile->Patterns[m_nPattern]) - && (m_nRow < pSndFile->Patterns[m_nPattern].GetNumRows()) && (nChn < pSndFile->m_nChannels)) + if ((!(m_dwStatus & (psKeyboardDragSelect/*|PATSTATUS_MOUSEDRAGSEL*/))) //rewbs.xinfo: update indicator even when dragging + && (m_Selection.GetUpperLeft() == m_Selection.GetLowerRight()) && (pSndFile->Patterns[m_nPattern]) + && (GetCurrentRow() < pSndFile->Patterns[m_nPattern].GetNumRows()) && (nChn < pSndFile->m_nChannels)) { - ModCommand *m = pSndFile->Patterns[m_nPattern].GetpModCommand(m_nRow, nChn); + ModCommand *m = pSndFile->Patterns[m_nPattern].GetpModCommand(GetCurrentRow(), nChn); - switch (GetColTypeFromCursor(m_dwCursor)) + switch(m_Cursor.GetColumnType()) { - case NOTE_COLUMN: + case PatternCursor::noteColumn: // display note if(m->note >= NOTE_MIN_SPECIAL) strcpy(s, szSpecialNoteShortDesc[m->note - NOTE_MIN_SPECIAL]); break; - case INST_COLUMN: + case PatternCursor::instrColumn: // display instrument if (m->instr) { @@ -1610,7 +1642,7 @@ } break; - case VOL_COLUMN: + case PatternCursor::volumeColumn: // display volume command if(m->IsPcNote()) { @@ -1629,8 +1661,8 @@ } break; - case EFFECT_COLUMN: - case PARAM_COLUMN: + case PatternCursor::effectColumn: + case PatternCursor::paramColumn: // display effect command if(!m->IsPcNote()) { Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-03-04 23:39:50 UTC (rev 1203) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-03-07 00:07:20 UTC (rev 1204) @@ -118,8 +118,8 @@ ///////////////////////////////////////////////////////////////////////////// // CModDoc construction/destruction -CModDoc::CModDoc() -//---------------- +CModDoc::CModDoc() : patternClipboard(m_SndFile) +//---------------------------------------------- { m_bHasValidPath = false; m_bPaused = TRUE; @@ -806,7 +806,9 @@ SendMessageToActiveViews(WM_MOD_ACTIVATEVIEW, IDD_CONTROL_INSTRUMENTS, nIns); } + void CModDoc::AddLogEvent(LogEventType eventType, LPCTSTR pszFuncName, LPCTSTR pszFormat, ...) +//-------------------------------------------------------------------------------------------- { CString strMsg; va_list args; @@ -820,6 +822,7 @@ << _T("Message: ") << strMsg << std::endl << std::endl; } + BOOL CModDoc::AddToLog(LPCSTR lpszLog) //------------------------------------ { @@ -2216,7 +2219,7 @@ pChildFrm->SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)(&patternViewState)); pat = patternViewState.nPattern; - row = patternViewState.nRow; + row = patternViewState.cursor.GetRow(); ord = patternViewState.nOrder; } else //patern editor object does not exist (i.e. is not active) - use saved state. @@ -2225,7 +2228,7 @@ patternViewState = pChildFrm->GetPatternViewState(); pat = patternViewState->nPattern; - row = patternViewState->nRow; + row = patternViewState->cursor.GetRow(); ord = patternViewState->nOrder; } //rewbs.fix3185: if position is invalid, go to start of song. Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2012-03-04 23:39:50 UTC (rev 1203) +++ trunk/OpenMPT/mptrack/Moddoc.h 2012-03-07 00:07:20 UTC (rev 1204) @@ -17,6 +17,7 @@ #include "sndfile.h" #include "../common/misc_util.h" #include "Undo.h" +#include "PatternClipboard.h" #include <time.h> @@ -126,6 +127,8 @@ #define SPLIT_OCTAVE_RANGE 9 +class PatternClipboard; + //========================== struct SplitKeyboardSettings //========================== @@ -183,6 +186,8 @@ vector<FileHistory> m_FileHistory; // File edit history time_t m_creationTime; + PatternClipboard patternClipboard; + public: std::bitset<MAX_INSTRUMENTS> m_bsInstrumentModified; // which instruments have been modified? (for ITP functionality) @@ -231,6 +236,8 @@ vector<FileHistory> &GetFileHistory() { return m_FileHistory; } const vector<FileHistory> &GetFileHistory() const { return m_FileHistory; } time_t GetCreationTime() const { return m_creationTime; } + + PatternClipboard &GetPatternClipboard() { return patternClipboard; } // operations public: @@ -295,10 +302,6 @@ BOOL ExpandPattern(PATTERNINDEX nPattern); BOOL ShrinkPattern(PATTERNINDEX nPattern); - // Copy&Paste - bool CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel); - bool PastePattern(PATTERNINDEX nPattern, DWORD dwBeginSel, enmPatternPasteModes pasteMode); - bool CopyEnvelope(UINT nIns, enmEnvelopeTypes nEnv); bool PasteEnvelope(UINT nIns, enmEnvelopeTypes nEnv); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2012-03-04 23:39:50 UTC (rev 1203) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2012-03-07 00:07:20 UTC (rev 1204) @@ -26,19 +26,7 @@ static char THIS_FILE[] = __FILE__; #endif -const size_t Pow10Table[10] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; -// Return D'th digit(character) of given value. -// GetDigit<0>(123) == '3' -// GetDigit<1>(123) == '2' -// GetDigit<2>(123) == '1' -template<BYTE D> -inline TCHAR GetDigit(const size_t val) -{ - return (D > 9) ? '0' : 48 + ((val / Pow10Table[D]) % 10); -} - - // Change the number of channels. // Return true on success. bool CModDoc::ChangeNumChannels(CHANNELINDEX nNewChannels, const bool showCancelInRemoveDlg) @@ -739,458 +727,6 @@ } -// Clipboard format: -// Hdr: "ModPlug Tracker S3M\r\n" -// Full: '|C#401v64A06' -// Reset: '|...........' -// Empty: '| ' -// End of row: '\n' - -static LPCSTR lpszClipboardPatternHdr = "ModPlug Tracker %3s\r\n"; - -bool CModDoc::CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel) -//-------------------------------------------------------------------------------- -{ - CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); - DWORD dwMemSize; - HGLOBAL hCpy; - UINT nrows = (dwEndSel >> 16) - (dwBeginSel >> 16) + 1; - UINT ncols = ((dwEndSel & 0xFFFF) >> 3) - ((dwBeginSel & 0xFFFF) >> 3) + 1; - - if ((!pMainFrm) || (nPattern >= m_SndFile.Patterns.Size()) || (!m_SndFile.Patterns[nPattern])) return false; - BeginWaitCursor(); - dwMemSize = strlen(lpszClipboardPatternHdr) + 1; - dwMemSize += nrows * (ncols * 12 + 2); - if ((pMainFrm->OpenClipboard()) && ((hCpy = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, dwMemSize))!=NULL)) - { - LPCSTR pszFormatName; - EmptyClipboard(); - switch(m_SndFile.GetType()) - { - case MOD_TYPE_S3M: pszFormatName = "S3M"; break; - case MOD_TYPE_XM: pszFormatName = "XM"; break; - case MOD_TYPE_IT: pszFormatName = "IT"; break; - case MOD_TYPE_MPT: pszFormatName = "MPT"; break; - default: pszFormatName = "MOD"; break; - } - LPSTR p = (LPSTR)GlobalLock(hCpy); - if (p) - { - UINT colmin = dwBeginSel & 0xFFFF; - UINT colmax = dwEndSel & 0xFFFF; - wsprintf(p, lpszClipboardPatternHdr, pszFormatName); - p += strlen(p); - for (UINT row=0; row<nrows; row++) - { - ModCommand *m = m_SndFile.Patterns[nPattern]; - if ((row + (dwBeginSel >> 16)) >= m_SndFile.Patterns[nPattern].GetNumRows()) break; - m += (row+(dwBeginSel >> 16))*m_SndFile.m_nChannels; - m += (colmin >> 3); - for (UINT col=0; col<ncols; col++, m++, p+=12) - { - UINT ncursor = ((colmin>>3)+col) << 3; - p[0] = '|'; - // Note - if ((ncursor >= colmin) && (ncursor <= colmax)) - { - UINT note = m->note; - switch(note) - { - case NOTE_NONE: p[1] = p[2] = p[3] = '.'; break; - case NOTE_KEYOFF: p[1] = p[2] = p[3] = '='; break; - case NOTE_NOTECUT: p[1] = p[2] = p[3] = '^'; break; - case NOTE_FADE: p[1] = p[2] = p[3] = '~'; break; - case NOTE_PC: p[1] = 'P'; p[2] = 'C'; p[3] = ' '; break; - case NOTE_PCS: p[1] = 'P'; p[2] = 'C'; p[3] = 'S'; break; - default: - p[1] = szNoteNames[(note-1) % 12][0]; - p[2] = szNoteNames[(note-1) % 12][1]; - p[3] = '0' + (note-1) / 12; - } - } else - { - // No note - p[1] = p[2] = p[3] = ' '; - } - // Instrument - ncursor++; - if ((ncursor >= colmin) && (ncursor <= colmax)) - { - if (m->instr) - { - p[4] = '0' + (m->instr / 10); - p[5] = '0' + (m->instr % 10); - } else p[4] = p[5] = '.'; - } else - { - p[4] = p[5] = ' '; - } - // Volume - ncursor++; - if ((ncursor >= colmin) && (ncursor <= colmax)) - { - if(m->IsPcNote()) - { - const uint16 val = m->GetValueVolCol(); - p[6] = GetDigit<2>(val); - p[7] = GetDigit<1>(val); - p[8] = GetDigit<0>(val); - } - else - { - if ((m->volcmd) && (m->volcmd <= MAX_VOLCMDS)) - { - p[6] = m_SndFile.GetModSpecifications().GetVolEffectLetter(m->volcmd); - p[7] = '0' + (m->vol / 10); - p[8] = '0' + (m->vol % 10); - } else p[6] = p[7] = p[8] = '.'; - } - } else - { - p[6] = p[7] = p[8] = ' '; - } - // Effect - ncursor++; - if (((ncursor >= colmin) && (ncursor <= colmax)) - || ((ncursor+1 >= colmin) && (ncursor+1 <= colmax))) - { - if(m->IsPcNote()) - { - const uint16 val = m->GetValueEffectCol(); - p[9] = GetDigit<2>(val); - p[10] = GetDigit<1>(val); - p[11] = GetDigit<0>(val); - } - else - { - if (m->command) - { - p[9] = m_SndFile.GetModSpecifications().GetEffectLetter(m->command); - } else p[9] = '.'; - if (m->param) - { - p[10] = szHexChar[m->param >> 4]; - p[11] = szHexChar[m->param & 0x0F]; - } else p[10] = p[11] = '.'; - } - } else - { - p[9] = p[10] = p[11] = ' '; - } - } - *p++ = '\r'; - *p++ = '\n'; - } - *p = 0; - } - GlobalUnlock(hCpy); - SetClipboardData (CF_TEXT, (HANDLE) hCpy); - CloseClipboard(); - } - EndWaitCursor(); - return true; -} - - -bool CModDoc::PastePattern(PATTERNINDEX nPattern, DWORD dwBeginSel, enmPatternPasteModes pasteMode) -//------------------------------------------------------------------------------------------------- -{ - CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); - if ((!pMainFrm) || (nPattern >= m_SndFile.Patterns.Size()) || (!m_SndFile.Patterns[nPattern])) return false; - BeginWaitCursor(); - if (pMainFrm->OpenClipboard()) - { - HGLOBAL hCpy = ::GetClipboardData(CF_TEXT); - LPSTR p; - - if ((hCpy) && ((p = (LPSTR)GlobalLock(hCpy)) != NULL)) - { - const TEMPO spdmax = m_SndFile.GetModSpecifications().speedMax; - const DWORD dwMemSize = GlobalSize(hCpy); - CHANNELINDEX ncol = (dwBeginSel & 0xFFFF) >> 3, col; - const ROWINDEX startRow = (ROWINDEX)(dwBeginSel >> 16); - ROWINDEX nrow = startRow; - bool bOk = false; - bool bPrepareUndo = true; // prepare pattern for undo next time - bool bFirstUndo = true; // for chaining undos (see overflow paste) - MODTYPE origFormat = MOD_TYPE_IT; // paste format - size_t pos, startPos = 0; - ModCommand *m = m_SndFile.Patterns[nPattern]; - - const bool doOverflowPaste = (CMainFrame::GetSettings().m_dwPatternSetup & PATTERN_OVERFLOWPASTE) && (pasteMode != pm_pasteflood) && (pasteMode != pm_pushforwardpaste); - const bool doITStyleMix = (pasteMode == pm_mixpaste_it); - const bool doMixPaste = ((pasteMode == pm_mixpaste) || doITStyleMix); - - ORDERINDEX currentOrder; //jojo.echopaste - { - ROWINDEX rTemp; - PATTERNINDEX pTemp; - GetEditPosition(rTemp, pTemp, currentOrder); - } - - if ((nrow >= m_SndFile.Patterns[nPattern].GetNumRows()) || (ncol >= m_SndFile.GetNumChannels())) goto PasteDone; - m += nrow * m_SndFile.GetNumChannels(); - - // Search for signature - for (pos = startPos; p[pos] != 0 && pos < dwMemSize; pos++) - { - CHAR szFormat[4]; // adjust this if the "%3s" part in the format string changes. - if(sscanf(p + pos, lpszClipboardPatternHdr, szFormat) > 0) - { - if(!strcmp(szFormat, "S3M")) origFormat = MOD_TYPE_S3M; - if(!strcmp(szFormat, "XM")) origFormat = MOD_TYPE_XM; - if(!strcmp(szFormat, "IT")) origFormat = MOD_TYPE_IT; - if(!strcmp(szFormat, "MPT")) origFormat = MOD_TYPE_MPT; - if(!strcmp(szFormat, "MOD")) origFormat = MOD_TYPE_MOD; - startPos = pos; // start reading patterns from here - break; - } - } - - const CModSpecifications &sourceSpecs = CSoundFile::GetModSpecifications(origFormat); - const bool clipboardHasS3MCommands = (origFormat & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_S3M)) != 0; - pos = startPos; - - while ((nrow < m_SndFile.Patterns[nPattern].GetNumRows())) - { - // Search for column separator or end of paste data - while ((pos + 11 >= dwMemSize) || p[pos] != '|') - { - if (pos + 11 >= dwMemSize || !p[pos]) - { - if((pasteMode == pm_pasteflood) && (nrow != startRow)) // prevent infinite loop with malformed clipboard data - pos = startPos; // paste from beginning - else - goto PasteDone; - } else - { - pos++; - } - } - bOk = true; - col = ncol; - // Paste columns - while ((p[pos] == '|') && (pos + 11 < dwMemSize)) - { - LPSTR s = p+pos+1; - - // Check valid paste condition. Paste will be skipped if - // -col is not a valid channelindex or - // -doing mix paste and paste destination modcommand is a PCnote or - // -doing mix paste and trying to paste PCnote on non-empty modcommand. - const bool bSkipPaste = - (col >= m_SndFile.GetNumChannels()) || - (doMixPaste && m[col].IsPcNote()) || - (doMixPaste && s[0] == 'P' && !m[col].IsEmpty()); - - if (bSkipPaste == false) - { - // Before changing anything in this pattern, we have to create an undo point. - if(bPrepareUndo) - { - GetPatternUndo().PrepareUndo(nPattern, 0, 0, m_SndFile.m_nChannels, m_SndFile.Patterns[nPattern].GetNumRows(), !bFirstUndo); - bPrepareUndo = false; - bFirstUndo = false; - } - - // ITSyle mixpaste requires that we keep a copy of the thing we are about to paste on - // so that we can refer back to check if there was anything in e.g. the note column before we pasted. - const ModCommand origModCmd = m[col]; - - // push channel data below paste point first. - if(pasteMode == pm_pushforwardpaste) - { - for(ROWINDEX nPushRow = m_SndFile.Patterns[nPattern].GetNumRows() - 1 - nrow; nPushRow > 0; nPushRow--) - { - m[col + nPushRow * m_SndFile.GetNumChannels()] = m[col + (nPushRow - 1) * m_SndFile.GetNumChannels()]; - } - m[col].Clear(); - } - - // Note - if (s[0] > ' ' && (!doMixPaste || ((!doITStyleMix && origModCmd.note == NOTE_NONE) || - (doITStyleMix && origModCmd.note == NOTE_NONE && origModCmd.instr == 0 && origModCmd.volcmd == VOLCMD_NONE)))) - { - m[col].note = NOTE_NONE; - if (s[0] == '=') m[col].note = NOTE_KEYOFF; else - if (s[0] == '^') m[col].note = NOTE_NOTECUT; else - if (s[0] == '~') m[col].note = NOTE_FADE; else - if (s[0] == 'P') - { - if(s[2] == 'S') - m[col].note = NOTE_PCS; - else - m[col].note = NOTE_PC; - } else - if (s[0] != '.') - { - for (UINT i=0; i<12; i++) - { - if ((s[0] == szNoteNames[i][0]) - && (s[1] == szNoteNames[i][1])) m[col].note = i+1; - } - if (m[col].note) m[col].note += (s[2] - '0') * 12; - } - } - // Instrument - if (s[3] > ' ' && (!doMixPaste || ( (!doITStyleMix && origModCmd.instr==0) || - (doITStyleMix && origModCmd.note == NOTE_NONE && origModCmd.instr == 0 && origModCmd.volcmd == VOLCMD_NONE) ) )) - - { - if ((s[3] >= '0') && (s[3] <= ('0'+(MAX_SAMPLES/10)))) - { - m[col].instr = (s[3]-'0') * 10 + (s[4]-'0'); - } else m[col].instr = 0; - } - // Volume - if (s[5] > ' ' && (!doMixPaste || ((!doITStyleMix && origModCmd.volcmd==0) || - (doITStyleMix && origModCmd.note == NOTE_NONE && origModCmd.instr == 0 && origModCmd.volcmd == VOLCMD_NONE)))) - - { - if (s[5] != '.') - { - if(m[col].IsPcNote()) - { - char val[4]; - memcpy(val, s+5, 3); - val[3] = 0; - m[col].SetValueVolCol(ConvertStrTo<uint16>(val)); - } - else - { - m[col].volcmd = 0; - for (UINT i=1; i<MAX_VOLCMDS; i++) - { - const char cmd = sourceSpecs.GetVolEffectLetter(i); - if (s[5] == cmd && cmd != '?') - { - m[col].volcmd = i; - break; - } - } - m[col].vol = (s[6]-'0')*10 + (s[7]-'0'); - } - } else m[col].volcmd = m[col].vol = 0; - } - - if (m[col].IsPcNote()) - { - if (s[8] != '.' && s[8] > ' ') - { - char val[4]; - memcpy(val, s+8, 3); - val[3] = 0; - m[col].SetValueEffectCol(ConvertStrTo<uint16>(val)); - } - } - else - { - if (s[8] > ' ' && (!doMixPaste || ((!doITStyleMix && origModCmd.command==0) || - (doITStyleMix && origModCmd.command==0 && origModCmd.param==0)))) - { - m[col].command = 0; - if (s[8] != '.') - { - for (UINT i=1; i<MAX_EFFECTS; i++) - { - const char cmd = sourceSpecs.GetEffectLetter(i); - if (s[8] == cmd && cmd != '?') - { - m[col].command = i; - break; - } - } - } - } - // Effect value - if (s[9] > ' ' && (!doMixPaste || ((!doITStyleMix && (origModCmd.command == CMD_NONE || origModCmd.param == 0)) || - (doITStyleMix && origModCmd.command == CMD_NONE && origModCmd.param == 0)))) - { - m[col].param = 0; - if (s[9] != '.') - { - for (UINT i=0; i<16; i++) - { - if (s[9] == szHexChar[i]) m[col].param |= (i<<4); - if (s[10] == szHexChar[i]) m[col].param |= i; - } - } - } - // Checking command - if (m_SndFile.GetType() & (MOD_TYPE_MOD | MOD_TYPE_XM)) - { - switch (m[col].command) - { - case CMD_SPEED: - case CMD_TEMPO: - if (!clipboardHasS3MCommands) 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 - if ((m[col].command == CMD_TEMPO) && (m[col].param <= spdmax)) m[col].param = CMD_SPEED; - } - break; - } - } else - { - switch (m[col].command) - { - case CMD_SPEED: - case CMD_TEMPO: - if (!clipboardHasS3MCommands) m[col].command = (m[col].param <= spdmax) ? CMD_SPEED : CMD_TEMPO; - break; - } - } - } - - // convert some commands, if necessary. With mix paste convert only - // if the original modcommand was empty as otherwise the unchanged parts - // of the old modcommand would falsely be interpreted being of type - // origFormat and ConvertCommand could change them. - if (origFormat != m_SndFile.m_nType && (!doMixPaste || origModCmd.IsEmpty(false))) - m_SndFile.ConvertCommand(&(m[col]), origFormat, m_SndFile.m_nType); - } - - pos += 12; - col++; - } - // Next row - m += m_SndFile.GetNumChannels(); - nrow++; - - // Overflow paste. Continue pasting in next pattern if enabled. - // If Paste Flood is enabled, this won't be called due to obvious reasons. - if(doOverflowPaste) - { - while(nrow >= m_SndFile.Patterns[nPattern].GetNumRows()) - { - nrow = 0; - ORDERINDEX nextOrder = m_SndFile.Order.GetNextOrderIgnoringSkips(currentOrder); - if((nextOrder == 0) || (nextOrder >= m_SndFile.Order.size())) goto PasteDone; - nPattern = m_SndFile.Order[nextOrder]; - if(m_SndFile.Patterns.IsValidPat(nPattern) == false) goto PasteDone; - m = m_SndFile.Patterns[nPattern]; - currentOrder = nextOrder; - bPrepareUndo = true; - } - } - - } - PasteDone: - GlobalUnlock(hCpy); - if (bOk) - { - SetModified(); - UpdateAllViews(NULL, HINT_PATTERNDATA | (nPattern << HINT_SHIFT_PAT), NULL); - } - } - CloseClipboard(); - } - EndWaitCursor(); - return true; -} - - ///////////////////////////////////////////////////////////////////////////////////////// // Copy/Paste envelope Added: trunk/OpenMPT/mptrack/PatternClipboard.cpp =================================================================== --- trunk/OpenMPT/mptrack/PatternClipboard.cpp (rev 0) +++ trunk/OpenMPT/mptrack/PatternClipboard.cpp 2012-03-07 00:07:20 UTC (rev 1204) @@ -0,0 +1,675 @@ +/* + * PatternClipboard.cpp + * -------------------- + * Purpose: Implementation of the pattern clipboard mechanism + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#include "stdafx.h" +#include "PatternClipboard.h" +#include "Mainfrm.h" +#include "Moddoc.h" + +size_t PatternClipboard::clipboardSize = 0; + + +// Clipboard format: +// Hdr: "ModPlug Tracker S3M\r\n" +// Full: '|C#401v64A06' +// Reset: '|...........' +// Empty: '| ' +// End of row: '\n' + +static LPCSTR lpszClipboardPatternHdr = "ModPlug Tracker %3s\r\n"; + +CString PatternClipboard::GetFileExtension(const char *ext) const +//--------------------------------------------------------------- +{ + CString format(ext); + if(format.GetLength() > 3) + { + format.Truncate(3); + } + format.MakeUpper(); + while(format.GetLength() < 3) + { + format = " " + format; + } + return format; +} + + +// Copy a pattern selection to both the system clipboard and the internal clipboard. +bool PatternClipboard::Copy(PATTERNINDEX pattern, PatternRect selection) +//---------------------------------------------------------------------- +{ + if(!sndFile.Patterns.IsValidPat(pattern)) + { + return false; + } + + if(selection.GetStartColumn() == PatternCursor::paramColumn) + { + // Special case: If selection starts with a parameter column, extend it to include the effect letter as well. + PatternCursor upper(selection.GetUpperLeft()); + upper.Move(0, 0, -1); + selection = PatternRect(upper, selection.GetLowerRight()); + } + + const ROWINDEX startRow = selection.GetStartRow(), numRows = selection.GetNumRows(); + const CHANNELINDEX startChan = selection.GetStartChannel(), numChans = selection.GetNumChannels(); + + // XXX + size_t memSize = 21 + numRows * (numChans * 12 + 2) + 1; + + CString data; + data.Preallocate(memSize); + + // Set up clipboard header. + // XXX + data = "ModPlug Tracker " + GetFileExtension(sndFile.GetModSpecifications().fileExtension) + "\r\n"; + + for(ROWINDEX row = 0; row < numRows; row++) + { + if(row + startRow >= sndFile.Patterns[pattern].GetNumRows()) + { + break; + } + + const ModCommand *m = sndFile.Patterns[pattern].GetpModCommand(row + startRow, startChan); + + for(CHANNELINDEX chan = 0; chan < numChans; chan++, m++) + { + PatternCursor cursor(0, startChan + chan); + data.AppendChar('|'); + + // Note + if(selection.ContainsHorizontal(cursor)) + { + switch(m->note) + { + case NOTE_NONE: data.Append("..."); break; + case NOTE_KEYOFF: data.Append("==="); break; + case NOTE_NOTECUT: data.Append("^^^"); break; + case NOTE_FADE: data.Append("~~~"); break; + case NOTE_PC: data.Append("PC "); break; + case NOTE_PCS: data.Append("PCS"); break; + default: if(m->IsNote()) data.Append(szDefaultNoteNames[m->note - NOTE_MIN]); + else data.Append("..."); + } + } else + { + // No note + data.Append(" "); + } + + // Instrument + cursor.Move(0, 0, 1); + if(selection.ContainsHorizontal(cursor)) + { + if(m->instr) + { + data.AppendChar('0' + (m->instr / 10)); + data.AppendChar('0' + (m->instr % 10)); + } else + { + data.Append(".."); + } + } else + { + data.Append(" "); + } + + // Volume + cursor.Move(0, 0, 1); + if(selection.ContainsHorizontal(cursor)) + { + if(m->IsPcNote()) + { + data.AppendFormat("%03u", m->GetValueVolCol()); + } + else + { + if(m->volcmd != VOLCMD_NONE && m->vol <= 99) + { + data.AppendChar(sndFile.GetModSpecifications().GetVolEffectLetter(m->volcmd)); + data.AppendFormat("%02u", m->vol); + } else + { + data.Append("..."); + } + } + } else + { + data.Append(" "); + } + + // Effect + cursor.Move(0, 0, 1); + if(selection.ContainsHorizontal(cursor)) + { + if(m->IsPcNote()) + { + data.AppendFormat("%03u", m->GetValueEffectCol()); + } + else + { + if(m->command != CMD_NONE) + { + data.AppendChar(sndFile.GetModSpecifications().GetEffectLetter(m->command)); + } else + { + data.AppendChar('.'); + } + + if(m->param != 0 && m->param <= 0xFF) + { + data.AppendFormat("%02X", m->param); + } else + { + data.Append(".."); + } + } + } else + { + data.Append(" "); + } + } + + // Next Row + data.Append("\r\n"); + } + + activeClipboard = 0; + + if(clipboardSize > 0) + { + // Copy to internal clipboard + if(clipboards.size() == clipboardSize) + { + clipboards.pop_back(); + } + + clipboards.push_front(PatternClipboardElement(data)); + } + + return ToSystemClipboard(data); + +} + + +// Try pasting a pattern selection from the system clipboard. +bool PatternClipboard::Paste(PATTERNINDEX pattern, const PatternCursor &pastePos, PasteModes mode) +//------------------------------------------------------------------------------------------------ +{ + CString data; + if(!FromSystemClipboard(data)) + { + return false; + } + + return HandlePaste(pattern, pastePos, mode, data); +} + + +// Try pasting a pattern selection from an internal clipboard. +bool PatternClipboard::Paste(PATTERNINDEX pattern, const PatternCursor &pastePos, PasteModes mode, size_t internalClipboard) +//-------------------------------------------------------------------------------------------------------------------------- +{ + if(internalClipboard >= clipboards.size()) + { + return false; + } + return HandlePaste(pattern, pastePos, mode, clipboards[internalClipboard].content); +} + + +// Perform the pasting operation. +bool PatternClipboard::HandlePaste(PATTERNINDEX pattern, const PatternCursor &pastePos, PasteModes mode, const CString &data) +//--------------------------------------------------------------------------------------------------------------------------- +{ + if(!sndFile.Patterns.IsValidPat(pattern) || sndFile.GetpModDoc() == nullptr) + { + return false; + } + + CModDoc &modDoc = *(sndFile.GetpModDoc()); + + const TEMPO tempoMin = sndFile.GetModSpecifications().tempoMin; + + CHANNELINDEX startChan = pastePos.GetChannel(), col; + ROWINDEX startRow = pastePos.GetRow(); + ROWINDEX curRow = startRow; + bool success = false; + bool prepareUndo = true; // prepare pattern for undo next time + bool firstUndo = true; // for chaining undos (see overflow paste) + + const bool overflowPaste = (CMainFrame::GetSettings().m_dwPatternSetup & PATTERN_OVERFLOWPASTE) && (mode != pmPasteFlood) && (mode != pmPushForward); + const bool doITStyleMix = (mode == pmMixPasteIT); + const bool doMixPaste = (mode == pmMixPaste) || doITStyleMix; + + // We need to know the current order for overflow paste + ORDERINDEX currentOrder = 0; + if(overflowPaste) + { + ROWINDEX rTemp; + PATTERNINDEX pTemp; + modDoc.GetEditPosition(rTemp, pTemp, currentOrder); + } + + // Can we actually paste at this position? + if(startRow >= sndFile.Patterns[pattern].GetNumRows() || startChan >= sndFile.GetNumChannels()) + { + return false; + } + + // Search for signature + int pos, startPos = 0; + MODTYPE pasteFormat = MOD_TYPE_NONE; + while(pasteFormat == MOD_TYPE_NONE && (startPos = data.Find("ModPlug Tracker ", startPos)) != -1) + { + startPos += 16; + // Check paste format + const CString format = data.Mid(startPos, 3); + + for(size_t i = 0; i < CountOf(ModSpecs::Collection); i++) + { + const CString ext = GetFileExtension(ModSpecs::Collection[i]->fileExtension); + if(format == ext) + { + pasteFormat = ModSpecs::Collection[i]->internalType; + startPos += 3; + break; + } + } + } + + if(startPos == -1) + { + // What is this I don't even + return false; + } + + const CModSpecifications &sourceSpecs = CSoundFile::GetModSpecifications(pasteFormat); + const bool clipboardHasS3MCommands = (pasteFormat & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_S3M)) != 0; + + ModCommand *m = sndFile.Patterns[pattern].GetpModCommand(startRow, 0); + + pos = startPos; + while(curRow < sndFile.Patterns[pattern].GetNumRows()) + { + // Search for column separator or end of paste data. + if((pos = data.Find('|', pos)) == -1) + { + // End of paste + if(mode == pmPasteFlood && curRow != startRow) + { + // Restarting pasting from beginning. + pos = startPos; + continue; + } + else + { + // Prevent infinite loop with malformed clipboard data. + break; + } + } + + success = true; + col = startChan; + // Paste columns + while((data[pos] == '|') && (pos + 11 < data.GetLength())) + ... [truncated message content] |
From: <sag...@us...> - 2012-03-07 18:56:09
|
Revision: 1206 http://modplug.svn.sourceforge.net/modplug/?rev=1206&view=rev Author: saga-games Date: 2012-03-07 18:55:58 +0000 (Wed, 07 Mar 2012) Log Message: ----------- [New] Plugins can now send MIDI events to follow-up plugins. [Mod] OpenMPT: Version is now 1.20.00.75 Modified Paths: -------------- trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Fastmix.cpp trunk/OpenMPT/soundlib/PlugInterface.h trunk/OpenMPT/soundlib/Snd_defs.h Added Paths: ----------- trunk/OpenMPT/soundlib/PluginEventQueue.h Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-03-07 18:55:58 UTC (rev 1206) @@ -866,7 +866,7 @@ if(!pSndFile->m_MixPlugins[nPlug].IsOutputToMaster()) { PLUGINDEX output = pSndFile->m_MixPlugins[nPlug].GetOutputPlugin(); - if(output < MAX_MIXPLUGINS) + if(output != PLUGINDEX_INVALID) { usedmap[output] = true; } Modified: trunk/OpenMPT/mptrack/View_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/mptrack/View_gen.cpp 2012-03-07 18:55:58 UTC (rev 1206) @@ -550,7 +550,7 @@ int n = m_CbnOutput.AddString(s); m_CbnOutput.SetItemData(n, 0x80 + iOut); if (!pSndFile->m_MixPlugins[m_nCurrentPlugin].IsOutputToMaster() - && (pSndFile->m_MixPlugins[m_nCurrentPlugin].GetOutputPlugin() == iOut)) + && (pSndFile->m_MixPlugins[m_nCurrentPlugin].GetOutputPlugin() == iOut)) { outputsel = n; } @@ -1356,7 +1356,7 @@ if(!pSndFile->m_MixPlugins[dest].IsOutputToMaster()) { PLUGINDEX nOutput = pSndFile->m_MixPlugins[dest].GetOutputPlugin(); - if (nOutput <= dest) + if (nOutput <= dest && nOutput != PLUGINDEX_INVALID) { pSndFile->m_MixPlugins[dest].SetOutputToMaster(); } Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-03-07 18:55:58 UTC (rev 1206) @@ -836,10 +836,13 @@ return ToVstPtr(&timeInfo); } - // VstEvents* in <ptr> - // We don't support plugs that send VSTEvents to the host + // Receive MIDI events from plugin case audioMasterProcessEvents: - Log("VST plugin to host: Process Events\n"); + if(pVstPlugin != nullptr && ptr != nullptr) + { + pVstPlugin->ReceiveVSTEvents(reinterpret_cast<VstEvents *>(ptr)); + return 1; + } break; // DEPRECATED in VST 2.4 @@ -1011,8 +1014,6 @@ // string in ptr, see below case audioMasterCanDo: //Other possible Can Do strings are: - //"receiveVstEvents", - //"receiveVstMidiEvent", //"receiveVstTimeInfo", //"asyncProcessing", //"offline", @@ -1025,6 +1026,8 @@ if ((strcmp((char*)ptr,"sendVstEvents") == 0 || strcmp((char*)ptr,"sendVstMidiEvent") == 0 || strcmp((char*)ptr,"sendVstTimeInfo") == 0 || + strcmp((char*)ptr,"receiveVstEvents") == 0 || + strcmp((char*)ptr,"receiveVstMidiEvent") == 0 || strcmp((char*)ptr,"supplyIdle") == 0 || strcmp((char*)ptr,"sizeWindow") == 0 || strcmp((char*)ptr,"openFileSelector") == 0 || @@ -1342,7 +1345,6 @@ m_pEditor = nullptr; m_nInputs = m_nOutputs = 0; m_nEditorX = m_nEditorY = -1; - m_pEvList = nullptr; m_pModDoc = nullptr; //rewbs.plugDocAware m_nPreviousMidiChan = nInvalidMidiChan; //rewbs.VSTCompliance m_pProcessFP = nullptr; @@ -1383,15 +1385,6 @@ void CVstPlugin::Initialize(CSoundFile* pSndFile) //----------------------------------------------- { - if (!m_pEvList) - { - m_pEvList = (VstEvents *)new char[sizeof(VstEvents)+sizeof(VstEvent*)*VSTEVENT_QUEUE_LEN]; - } - if (m_pEvList) - { - m_pEvList->numEvents = 0; - m_pEvList->reserved = 0; - } m_bNeedIdle=false; m_bRecordAutomation=false; m_bPassKeypressesToPlug=false; @@ -1553,9 +1546,6 @@ m_hLibrary = NULL; } - delete[] (char *)m_pEvList; - m_pEvList = nullptr; - CloseHandle(processCalled); } @@ -2004,38 +1994,57 @@ } +// Send events to plugin void CVstPlugin::ProcessVSTEvents() //--------------------------------- { // Process VST events - if ((m_pEffect) && (m_pEffect->dispatcher) && (m_pEvList) && (m_pEvList->numEvents > 0)) + if(m_pEffect != nullptr && m_pEffect->dispatcher != nullptr && vstEvents.Finalise() > 0) { try { - m_pEffect->dispatcher(m_pEffect, effProcessEvents, 0, 0, m_pEvList, 0); + m_pEffect->dispatcher(m_pEffect, effProcessEvents, 0, 0, &vstEvents, 0); } catch (...) { - CVstPluginManager::ReportPlugException("Exception in ProcessVSTEvents() (Plugin=%s, pEventList:%p, numEvents:%d, MidicodeCh:%d, MidicodeEv:%d, MidicodeNote:%d, MidiCodeVel:%d)\n", - m_pFactory->szLibraryName, m_pEvList, m_pEvList->numEvents, - (((VstMidiEvent *)(m_pEvList->events[0]))->midiData[0])&0x0f, - (((VstMidiEvent *)(m_pEvList->events[0]))->midiData[0])&0xf0, - (((VstMidiEvent *)(m_pEvList->events[0]))->midiData[1])&0xff, - (((VstMidiEvent *)(m_pEvList->events[0]))->midiData[2])&0xff); + CVstPluginManager::ReportPlugException("Exception in ProcessVSTEvents() (Plugin=%s, numEvents:%d, MidicodeCh:%d, MidicodeEv:%d, MidicodeNote:%d, MidiCodeVel:%d)\n", + m_pFactory->szLibraryName, vstEvents.numEvents, + (((VstMidiEvent *)(vstEvents.events[0]))->midiData[0]) & 0x0f, + (((VstMidiEvent *)(vstEvents.events[0]))->midiData[0]) & 0xf0, + (((VstMidiEvent *)(vstEvents.events[0]))->midiData[1]) & 0xff, + (((VstMidiEvent *)(vstEvents.events[0]))->midiData[2]) & 0xff); } } - } -void CVstPlugin::ClearVSTEvents() -//------------------------------- + +// Receive events from plugin and send them to the next plugin in the chain. +void CVstPlugin::ReceiveVSTEvents(const VstEvents *events) const +//-------------------------------------------------------------- { - // Clear VST events - if ((m_pEvList) && (m_pEvList->numEvents > 0)) + if(m_pSndFile == nullptr || m_pMixStruct == nullptr) { - m_pEvList->numEvents = 0; + return; } + + // I think we should only route events to plugins that are explicitely specified as output plugins of the current plugin. + PLUGINDEX receiver = m_pMixStruct->GetOutputPlugin(); + + if(receiver != PLUGINDEX_INVALID) + { + SNDMIXPLUGIN &mixPlug = m_pSndFile->m_MixPlugins[receiver]; + CVstPlugin *vstPlugin = dynamic_cast<CVstPlugin *>(mixPlug.pMixPlugin); + if(vstPlugin != nullptr) + { + // Add all events to the plugin's queue. + for(VstInt32 i = 0; i < events->numEvents; i++) + { + vstPlugin->vstEvents.Enqueue(*events->events[i]); + } + } + } } + void CVstPlugin::RecalculateGain() //-------------------------------- { @@ -2093,7 +2102,7 @@ Bypass(); CString processMethod = (m_pEffect->flags & effFlagsCanReplacing) ? "processReplacing" : "process"; CVstPluginManager::ReportPlugException("The plugin %s threw an exception in %s. It has automatically been set to \"Bypass\".", m_pMixStruct->GetName(), processMethod); - ClearVSTEvents(); + vstEvents.Clear(); // SetEvent(processCalled); } @@ -2143,7 +2152,7 @@ } } - ClearVSTEvents(); + vstEvents.Clear(); //SetEvent(processCalled); } @@ -2271,52 +2280,28 @@ bool CVstPlugin::MidiSend(DWORD dwMidiCode) //----------------------------------------- { - if ((m_pEvList) && (m_pEvList->numEvents < VSTEVENT_QUEUE_LEN-1)) - { - int insertPos; - if ((dwMidiCode & 0xF0) == 0x80) - { - // noteoffs go at the start of the queue. - if (m_pEvList->numEvents) - { - for (int i=m_pEvList->numEvents; i>=1; i--) - { - m_pEvList->events[i] = m_pEvList->events[i-1]; - } - } - insertPos=0; - } else - { - insertPos=m_pEvList->numEvents; - } + // Note-Offs go at the start of the queue. + bool insertAtFront = ((dwMidiCode & 0xF0) == 0x80); - VstMidiEvent *pev = &m_ev_queue[m_pEvList->numEvents]; - m_pEvList->events[insertPos] = (VstEvent *)pev; - pev->type = kVstMidiType; - pev->byteSize = 24; - pev->deltaFrames = 0; - pev->flags = 0; - pev->noteLength = 0; - pev->noteOffset = 0; - pev->detune = 0; - pev->noteOffVelocity = 0; - pev->reserved1 = 0; - pev->reserved2 = 0; - *(DWORD *)pev->midiData = dwMidiCode; - m_pEvList->numEvents++; + VstMidiEvent event; + MemsetZero(event); + event.type = kVstMidiType; + event.byteSize = 24; + event.deltaFrames = 0; + event.flags = 0; + event.noteLength = 0; + event.noteOffset = 0; + event.detune = 0; + event.noteOffVelocity = 0; + event.reserved1 = 0; + event.reserved2 = 0; + *(DWORD *)event.midiData = dwMidiCode; + #ifdef VST_LOG - Log("Sending Midi %02X.%02X.%02X\n", pev->midiData[0]&0xff, pev->midiData[1]&0xff, pev->midiData[2]&0xff); + Log("Sending Midi %02X.%02X.%02X\n", event.midiData[0]&0xff, event.midiData[1]&0xff, event.midiData[2]&0xff); #endif - return true; //rewbs.instroVST - } - else - { - Log("VST Event queue overflow!\n"); - m_pEvList->numEvents = VSTEVENT_QUEUE_LEN-1; - - return false; //rewbs.instroVST - } + return vstEvents.Enqueue(event, insertAtFront); } //rewbs.VSTiNoteHoldonStopFix @@ -2523,7 +2508,7 @@ } else { // VST event queue overflow, no point in submitting more note offs. - break; //todo: secondary buffer? + break; //todo: secondary buffer? } } } @@ -2962,10 +2947,10 @@ list.RemoveAll(); CVstPlugin *pOutputPlug = NULL; - if (!m_pMixStruct->IsOutputToMaster()) + if(!m_pMixStruct->IsOutputToMaster()) { PLUGINDEX nOutput = m_pMixStruct->GetOutputPlugin(); - if (m_pSndFile && (nOutput > m_nSlot) && (nOutput < MAX_MIXPLUGINS)) + if(m_pSndFile && nOutput > m_nSlot && nOutput != PLUGINDEX_INVALID) { pOutputPlug = reinterpret_cast<CVstPlugin *>(m_pSndFile->m_MixPlugins[nOutput].pMixPlugin); } Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/mptrack/Vstplug.h 2012-03-07 18:55:58 UTC (rev 1206) @@ -64,6 +64,11 @@ } VSTINSTCH, *PVSTINSTCH; +#ifndef NO_VST +#include "../soundlib/PluginEventQueue.h" +#endif // NO_VST + + //================================= class CVstPlugin: public IMixPlugin //================================= @@ -72,8 +77,12 @@ friend class CVstPluginManager; #ifndef NO_VST protected: - enum {VSTEVENT_QUEUE_LEN=256}; + enum + { + VstEventQueueLength = 256, + }; + ULONG m_nRefCount; CVstPlugin *m_pNext, *m_pPrev; HINSTANCE m_hLibrary; @@ -87,14 +96,9 @@ bool m_bIsVst2; SNDMIXPLUGINSTATE m_MixState; UINT m_nInputs, m_nOutputs; - VstEvents *m_pEvList; VSTINSTCH m_MidiCh[16]; short m_nMidiPitchBendPos[16]; - int m_MixBuffer[MIXBUFFERSIZE * 2 + 2]; // Stereo interleaved - PluginMixBuffer<float, MIXBUFFERSIZE> mixBuffer; // Float buffers (input and output) for plugins - - VstMidiEvent m_ev_queue[VSTEVENT_QUEUE_LEN]; CModDoc* m_pModDoc; //rewbs.plugDocAware CSoundFile* m_pSndFile; //rewbs.plugDocAware // PSNDMIXPLUGIN m_pSndMixPlugin; //rewbs.plugDocAware @@ -111,6 +115,10 @@ int m_nEditorX, m_nEditorY; + PluginMixBuffer<float, MIXBUFFERSIZE> mixBuffer; // Float buffers (input and output) for plugins + int m_MixBuffer[MIXBUFFERSIZE * 2 + 2]; // Stereo interleaved + VSTEventBlock<VstEventQueueLength> vstEvents; // MIDI events that should be sent to the plugin + public: CVstPlugin(HINSTANCE hLibrary, VSTPLUGINLIB *pFactory, SNDMIXPLUGIN *pMixPlugin, AEffect *pEffect); virtual ~CVstPlugin(); @@ -177,8 +185,6 @@ int Release(); void SaveAllParameters(); void RestoreAllParameters(long nProg=-1); //rewbs.plugDefaultProgram - added param - void ProcessVSTEvents(); //rewbs.VSTiNoteHoldonStopFix - void ClearVSTEvents(); //rewbs.VSTiNoteHoldonStopFix void RecalculateGain(); void Process(float *pOutL, float *pOutR, size_t nSamples); void Init(unsigned long nFreq, int bReset); @@ -218,6 +224,10 @@ // Set up input / output buffers. bool InitializeIOBuffers(); + // Process incoming and outgoing VST events. + void ProcessVSTEvents(); + void ReceiveVSTEvents(const VstEvents *events) const; + void ProcessMixOps(float *pOutL, float *pOutR, size_t nSamples); #else // case: NO_VST Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2012-03-07 18:55:58 UTC (rev 1206) @@ -849,6 +849,9 @@ RelativePath=".\PSRatioCalc.h"> </File> <File + RelativePath=".\soundlib\PluginEventQueue.h"> + </File> + <File RelativePath=".\soundlib\PluginMixBuffer.h"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2012-03-07 18:55:58 UTC (rev 1206) @@ -1127,6 +1127,10 @@ > </File> <File + RelativePath=".\soundlib\PluginEventQueue.h" + > + </File> + <File RelativePath=".\soundlib\PluginMixBuffer.h" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2012-03-07 18:55:58 UTC (rev 1206) @@ -333,6 +333,7 @@ <ClInclude Include="..\soundlib\ModChannel.h" /> <ClInclude Include="..\soundlib\ModInstrument.h" /> <ClInclude Include="..\soundlib\ModSample.h" /> + <ClInclude Include="..\soundlib\PluginEventQueue.h" /> <ClInclude Include="..\soundlib\PluginMixBuffer.h" /> <ClInclude Include="..\soundlib\PlugInterface.h" /> <ClInclude Include="ACMConvert.h" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2012-03-07 18:55:58 UTC (rev 1206) @@ -783,6 +783,9 @@ <ClInclude Include="PatternCursor.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\soundlib\PluginEventQueue.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="res\bitmap1.bmp"> Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/mptrack/version.h 2012-03-07 18:55:58 UTC (rev 1206) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 74 +#define VER_MINORMINOR 75 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Modified: trunk/OpenMPT/soundlib/Fastmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Fastmix.cpp 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/soundlib/Fastmix.cpp 2012-03-07 18:55:58 UTC (rev 1206) @@ -1772,8 +1772,8 @@ if (!plugin.IsOutputToMaster()) { PLUGINDEX nOutput = plugin.GetOutputPlugin(); - if ((nOutput > iDoPlug) && (nOutput < MAX_MIXPLUGINS) - && (m_MixPlugins[nOutput].pMixState)) + if(nOutput > iDoPlug && nOutput != PLUGINDEX_INVALID + && m_MixPlugins[nOutput].pMixState != nullptr) { SNDMIXPLUGINSTATE *pOutState = m_MixPlugins[nOutput].pMixState; Modified: trunk/OpenMPT/soundlib/PlugInterface.h =================================================================== --- trunk/OpenMPT/soundlib/PlugInterface.h 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/soundlib/PlugInterface.h 2012-03-07 18:55:58 UTC (rev 1206) @@ -171,7 +171,7 @@ bool IsOutputToMaster() const { return Info.dwOutputRouting == 0; }; PLUGINDEX GetOutputPlugin() const - { return Info.dwOutputRouting >= 0x80 ? static_cast<PLUGINDEX>(Info.dwOutputRouting - 0x80) : MAX_MIXPLUGINS; }; + { return Info.dwOutputRouting >= 0x80 ? static_cast<PLUGINDEX>(Info.dwOutputRouting - 0x80) : PLUGINDEX_INVALID; }; // Output routing setters void SetOutputToMaster() Added: trunk/OpenMPT/soundlib/PluginEventQueue.h =================================================================== --- trunk/OpenMPT/soundlib/PluginEventQueue.h (rev 0) +++ trunk/OpenMPT/soundlib/PluginEventQueue.h 2012-03-07 18:55:58 UTC (rev 1206) @@ -0,0 +1,108 @@ +/* + * PluginEventQueue.h + * ------------------ + * Purpose: Alternative, easy to use implementation of the VST event queue mechanism. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#pragma once + +// Copied packing options from affectx.h +#if TARGET_API_MAC_CARBON + #ifdef __LP64__ + #pragma options align=power + #else + #pragma options align=mac68k + #endif +#elif defined __BORLANDC__ + #pragma -a8 +#elif defined(__GNUC__) + #pragma pack(push,8) +#elif defined(WIN32) || defined(__FLAT__) + #pragma pack(push) + #pragma pack(8) +#endif + +#include <deque> + +// Alternative, easy to use implementation of VstEvents struct. +template <size_t N> +struct VSTEventBlock +{ + typedef VstMidiEvent BiggestVstEvent; + static_assert(sizeof(BiggestVstEvent) >= sizeof(VstEvent) + && sizeof(BiggestVstEvent) >= sizeof(VstMidiEvent) + && sizeof(BiggestVstEvent) >= sizeof(VstMidiSysexEvent), + "Check typedef above, BiggestVstEvent must be the biggest VstEvent struct."); + + VstInt32 numEvents; ///< number of Events in array + VstIntPtr reserved; ///< zero (Reserved for future use) + VstEvent* events[N]; ///< event pointer array + std::deque<BiggestVstEvent> eventQueue; // Here we store our events. + + VSTEventBlock() + { + numEvents = 0; + reserved = nullptr; + MemsetZero(events); + } + + // Add a VST event to the queue. Returns true on success. + bool Enqueue(const VstEvent &event, bool insertFront = false) + { + VstMidiEvent midiEvent; + memcpy(&midiEvent, &event, sizeof(event)); + return Enqueue(midiEvent, insertFront); + } + bool Enqueue(const VstMidiEvent &event, bool insertFront = false) + { + static_assert(sizeof(BiggestVstEvent) <= sizeof(VstMidiEvent), "Also check implementation here."); + if(insertFront) + { + eventQueue.push_front(event); + } else + { + eventQueue.push_back(event); + } + return true; + } + bool Enqueue(const VstMidiSysexEvent &event, bool insertFront = false) + { + VstMidiEvent midiEvent; + memcpy(&midiEvent, &event, sizeof(event)); + return Enqueue(midiEvent, insertFront); + } + + // Set up the queue for transmitting to the plugin. Returns number of elements that are going to be transmitted. + VstInt32 Finalise() + { + numEvents = min(eventQueue.size(), N); + for(VstInt32 i = 0; i < numEvents; i++) + { + events[i] = reinterpret_cast<VstEvent *>(&eventQueue[i]); + } + return numEvents; + } + + // Remove transmitted events from the queue + void Clear() + { + if(numEvents) + { + eventQueue.erase(eventQueue.begin(), eventQueue.begin() + numEvents); + numEvents = 0; + } + } + +}; + +#if TARGET_API_MAC_CARBON + #pragma options align=reset +#elif defined(WIN32) || defined(__FLAT__) || defined(__GNUC__) + #pragma pack(pop) +#elif defined __BORLANDC__ + #pragma -a- +#endif Modified: trunk/OpenMPT/soundlib/Snd_defs.h =================================================================== --- trunk/OpenMPT/soundlib/Snd_defs.h 2012-03-07 14:42:40 UTC (rev 1205) +++ trunk/OpenMPT/soundlib/Snd_defs.h 2012-03-07 18:55:58 UTC (rev 1206) @@ -30,6 +30,7 @@ const PATTERNINDEX PATTERNINDEX_MAX = uint16_max; const PATTERNINDEX PATTERNINDEX_INVALID = PATTERNINDEX_MAX; typedef uint8 PLUGINDEX; + const PLUGINDEX PLUGINDEX_INVALID = uint8_max; typedef uint16 TEMPO; typedef uint16 SAMPLEINDEX; const SAMPLEINDEX SAMPLEINDEX_MAX = uint16_max; @@ -293,31 +294,34 @@ #define SYSMIX_SSE 0x20 // Processor supports SSE instructions // Module flags -#define SONG_EMBEDMIDICFG 0x0001 // Embed macros in file -#define SONG_FASTVOLSLIDES 0x0002 // Old Scream Tracker 3.0 volume slides -#define SONG_ITOLDEFFECTS 0x0004 // Old Impulse Tracker effect implementations -#define SONG_ITCOMPATGXX 0x0008 // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects) -#define SONG_LINEARSLIDES 0x0010 // Linear slides vs. Amiga slides -#define SONG_PATTERNLOOP 0x0020 // Loop current pattern (pattern editor) -#define SONG_STEP 0x0040 // Song is in "step" mode (pattern editor) -#define SONG_PAUSED 0x0080 // Song is paused -#define SONG_FADINGSONG 0x0100 // Song is fading out -#define SONG_ENDREACHED 0x0200 // Song is finished -#define SONG_GLOBALFADE 0x0400 // Song is fading out -#define SONG_CPUVERYHIGH 0x0800 // High CPU usage -#define SONG_FIRSTTICK 0x1000 // Is set when the current tick is the first tick of the row -#define SONG_MPTFILTERMODE 0x2000 // Local filter mode (reset filter on each note) -#define SONG_SURROUNDPAN 0x4000 // Pan in the rear channels -#define SONG_EXFILTERRANGE 0x8000 // Cutoff Filter has double frequency range (up to ~10Khz) -#define SONG_AMIGALIMITS 0x10000 // Enforce amiga frequency limits -// -> CODE#0023 -// -> DESC="IT project files (.itp)" -#define SONG_ITPROJECT 0x20000 // Is a project file -#define SONG_ITPEMBEDIH 0x40000 // Embed instrument headers in project file -// -! NEW_FEATURE#0023 -#define SONG_BREAKTOROW 0x80000 // Break to row command encountered (internal flag, do not touch) -#define SONG_POSJUMP 0x100000 // Position jump encountered (internal flag, do not touch) -#define SONG_PT1XMODE 0x200000 // ProTracker 1.x playback mode +enum SongFlags +{ + SONG_EMBEDMIDICFG = 0x0001, // Embed macros in file + SONG_FASTVOLSLIDES = 0x0002, // Old Scream Tracker 3.0 volume slides + SONG_ITOLDEFFECTS = 0x0004, // Old Impulse Tracker effect implementations + SONG_ITCOMPATGXX = 0x0008, // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects) + SONG_LINEARSLIDES = 0x0010, // Linear slides vs. Amiga slides + SONG_PATTERNLOOP = 0x0020, // Loop current pattern (pattern editor) + SONG_STEP = 0x0040, // Song is in "step" mode (pattern editor) + SONG_PAUSED = 0x0080, // Song is paused + SONG_FADINGSONG = 0x0100, // Song is fading out + SONG_ENDREACHED = 0x0200, // Song is finished + SONG_GLOBALFADE = 0x0400, // Song is fading out + SONG_CPUVERYHIGH = 0x0800, // High CPU usage + SONG_FIRSTTICK = 0x1000, // Is set when the current tick is the first tick of the row + SONG_MPTFILTERMODE = 0x2000, // Local filter mode (reset filter on each note) + SONG_SURROUNDPAN = 0x4000, // Pan in the rear channels + SONG_EXFILTERRANGE = 0x8000, // Cutoff Filter has double frequency range (up to ~10Khz) + SONG_AMIGALIMITS = 0x10000, // Enforce amiga frequency limits + // -> CODE#0023 + // -> DESC="IT project files (.itp)" + SONG_ITPROJECT = 0x20000, // Is a project file + SONG_ITPEMBEDIH = 0x40000, // Embed instrument headers in project file + // -! NEW_FEATURE#0023 + SONG_BREAKTOROW = 0x80000, // Break to row command encountered (internal flag, do not touch) + SONG_POSJUMP = 0x100000, // Position jump encountered (internal flag, do not touch) + SONG_PT1XMODE = 0x200000, // ProTracker 1.x playback mode +}; #define SONG_FILE_FLAGS (SONG_EMBEDMIDICFG|SONG_FASTVOLSLIDES|SONG_ITOLDEFFECTS|SONG_ITCOMPATGXX|SONG_LINEARSLIDES|SONG_EXFILTERRANGE|SONG_AMIGALIMITS|SONG_ITPROJECT|SONG_ITPEMBEDIH|SONG_PT1XMODE) #define SONG_PLAY_FLAGS (~SONG_FILE_FLAGS) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-03-07 19:32:08
|
Revision: 1207 http://modplug.svn.sourceforge.net/modplug/?rev=1207&view=rev Author: saga-games Date: 2012-03-07 19:31:57 +0000 (Wed, 07 Mar 2012) Log Message: ----------- [Fix] We should probably also do some dispatching when enqueueing those VST events... Modified Paths: -------------- trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/soundlib/PluginEventQueue.h Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-03-07 18:55:58 UTC (rev 1206) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-03-07 19:31:57 UTC (rev 1207) @@ -2027,6 +2027,7 @@ } // I think we should only route events to plugins that are explicitely specified as output plugins of the current plugin. + // This should probably use GetOutputPlugList here if we ever get to support multiple output plugins. PLUGINDEX receiver = m_pMixStruct->GetOutputPlugin(); if(receiver != PLUGINDEX_INVALID) @@ -2038,7 +2039,21 @@ // Add all events to the plugin's queue. for(VstInt32 i = 0; i < events->numEvents; i++) { - vstPlugin->vstEvents.Enqueue(*events->events[i]); + // Let's do some dispatching, because the VST SDK doesn't do it for us. :-( + switch(events->events[i]->type) + { + case kVstMidiType: + vstPlugin->vstEvents.Enqueue(*reinterpret_cast<VstMidiEvent *>(events->events[i])); + break; + + case kVstSysExType: + vstPlugin->vstEvents.Enqueue(*reinterpret_cast<VstMidiSysexEvent *>(events->events[i])); + break; + + default: + vstPlugin->vstEvents.Enqueue(*events->events[i]); + break; + } } } } @@ -2508,7 +2523,8 @@ } else { // VST event queue overflow, no point in submitting more note offs. - break; //todo: secondary buffer? + // Note: This shouldn't happen anymore, since PluginEventQueue uses a secondary queue. + break; } } } Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2012-03-07 18:55:58 UTC (rev 1206) +++ trunk/OpenMPT/mptrack/Vstplug.h 2012-03-07 19:31:57 UTC (rev 1207) @@ -117,7 +117,7 @@ PluginMixBuffer<float, MIXBUFFERSIZE> mixBuffer; // Float buffers (input and output) for plugins int m_MixBuffer[MIXBUFFERSIZE * 2 + 2]; // Stereo interleaved - VSTEventBlock<VstEventQueueLength> vstEvents; // MIDI events that should be sent to the plugin + PluginEventQueue<VstEventQueueLength> vstEvents; // MIDI events that should be sent to the plugin public: CVstPlugin(HINSTANCE hLibrary, VSTPLUGINLIB *pFactory, SNDMIXPLUGIN *pMixPlugin, AEffect *pEffect); Modified: trunk/OpenMPT/soundlib/PluginEventQueue.h =================================================================== --- trunk/OpenMPT/soundlib/PluginEventQueue.h 2012-03-07 18:55:58 UTC (rev 1206) +++ trunk/OpenMPT/soundlib/PluginEventQueue.h 2012-03-07 19:31:57 UTC (rev 1207) @@ -2,7 +2,7 @@ * PluginEventQueue.h * ------------------ * Purpose: Alternative, easy to use implementation of the VST event queue mechanism. - * Notes : (currently none) + * Notes : Modelled after an idea from http://www.kvraudio.com/forum/viewtopic.php?p=3043807#3043807 * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ @@ -30,7 +30,7 @@ // Alternative, easy to use implementation of VstEvents struct. template <size_t N> -struct VSTEventBlock +struct PluginEventQueue { typedef VstMidiEvent BiggestVstEvent; static_assert(sizeof(BiggestVstEvent) >= sizeof(VstEvent) @@ -43,7 +43,7 @@ VstEvent* events[N]; ///< event pointer array std::deque<BiggestVstEvent> eventQueue; // Here we store our events. - VSTEventBlock() + PluginEventQueue() { numEvents = 0; reserved = nullptr; @@ -55,6 +55,7 @@ { VstMidiEvent midiEvent; memcpy(&midiEvent, &event, sizeof(event)); + ASSERT(event.byteSize == sizeof(event)); return Enqueue(midiEvent, insertFront); } bool Enqueue(const VstMidiEvent &event, bool insertFront = false) @@ -73,6 +74,7 @@ { VstMidiEvent midiEvent; memcpy(&midiEvent, &event, sizeof(event)); + ASSERT(event.byteSize == sizeof(event)); return Enqueue(midiEvent, insertFront); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sag...@us...> - 2012-03-07 23:51:29
|
Revision: 1209 http://modplug.svn.sourceforge.net/modplug/?rev=1209&view=rev Author: saga-games Date: 2012-03-07 23:51:23 +0000 (Wed, 07 Mar 2012) Log Message: ----------- [Fix] Added some thread saftey to the VST event queue - using f.e. the MID2VST could easily corrupt the deque when sending lots of MIDI events through that plugin. Modified Paths: -------------- trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/soundlib/PluginEventQueue.h Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-03-07 23:21:34 UTC (rev 1208) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-03-07 23:51:23 UTC (rev 1209) @@ -2006,12 +2006,8 @@ m_pEffect->dispatcher(m_pEffect, effProcessEvents, 0, 0, &vstEvents, 0); } catch (...) { - CVstPluginManager::ReportPlugException("Exception in ProcessVSTEvents() (Plugin=%s, numEvents:%d, MidicodeCh:%d, MidicodeEv:%d, MidicodeNote:%d, MidiCodeVel:%d)\n", - m_pFactory->szLibraryName, vstEvents.numEvents, - (((VstMidiEvent *)(vstEvents.events[0]))->midiData[0]) & 0x0f, - (((VstMidiEvent *)(vstEvents.events[0]))->midiData[0]) & 0xf0, - (((VstMidiEvent *)(vstEvents.events[0]))->midiData[1]) & 0xff, - (((VstMidiEvent *)(vstEvents.events[0]))->midiData[2]) & 0xff); + CVstPluginManager::ReportPlugException("Exception in ProcessVSTEvents() (Plugin=%s, numEvents:%d)\n", + m_pFactory->szLibraryName, vstEvents.GetNumEvents()); } } } @@ -2299,9 +2295,8 @@ bool insertAtFront = ((dwMidiCode & 0xF0) == 0x80); VstMidiEvent event; - MemsetZero(event); event.type = kVstMidiType; - event.byteSize = 24; + event.byteSize = sizeof(VstMidiEvent); event.deltaFrames = 0; event.flags = 0; event.noteLength = 0; Modified: trunk/OpenMPT/soundlib/PluginEventQueue.h =================================================================== --- trunk/OpenMPT/soundlib/PluginEventQueue.h 2012-03-07 23:21:34 UTC (rev 1208) +++ trunk/OpenMPT/soundlib/PluginEventQueue.h 2012-03-07 23:51:23 UTC (rev 1209) @@ -30,8 +30,10 @@ // Alternative, easy to use implementation of VstEvents struct. template <size_t N> -struct PluginEventQueue +class PluginEventQueue { +protected: + typedef VstMidiEvent BiggestVstEvent; static_assert(sizeof(BiggestVstEvent) >= sizeof(VstEvent) && sizeof(BiggestVstEvent) >= sizeof(VstMidiEvent) @@ -40,27 +42,43 @@ VstInt32 numEvents; ///< number of Events in array VstIntPtr reserved; ///< zero (Reserved for future use) - VstEvent* events[N]; ///< event pointer array + VstEvent *events[N]; ///< event pointer array std::deque<BiggestVstEvent> eventQueue; // Here we store our events. + CRITICAL_SECTION criticalSection; +public: + PluginEventQueue() { numEvents = 0; reserved = nullptr; MemsetZero(events); + MemsetZero(criticalSection); + InitializeCriticalSection(&criticalSection); } + ~PluginEventQueue() + { + DeleteCriticalSection(&criticalSection); + } + + size_t GetNumEvents() + { + return numEvents; + } + // Add a VST event to the queue. Returns true on success. bool Enqueue(const VstEvent &event, bool insertFront = false) { VstMidiEvent midiEvent; - memcpy(&midiEvent, &event, sizeof(event)); + memcpy(&midiEvent, &event, min(event.byteSize, sizeof(event))); ASSERT(event.byteSize == sizeof(event)); return Enqueue(midiEvent, insertFront); } bool Enqueue(const VstMidiEvent &event, bool insertFront = false) { static_assert(sizeof(BiggestVstEvent) <= sizeof(VstMidiEvent), "Also check implementation here."); + EnterCriticalSection(&criticalSection); if(insertFront) { eventQueue.push_front(event); @@ -68,12 +86,13 @@ { eventQueue.push_back(event); } + LeaveCriticalSection(&criticalSection); return true; } bool Enqueue(const VstMidiSysexEvent &event, bool insertFront = false) { VstMidiEvent midiEvent; - memcpy(&midiEvent, &event, sizeof(event)); + memcpy(&midiEvent, &event, min(event.byteSize, sizeof(event))); ASSERT(event.byteSize == sizeof(event)); return Enqueue(midiEvent, insertFront); } @@ -81,22 +100,26 @@ // Set up the queue for transmitting to the plugin. Returns number of elements that are going to be transmitted. VstInt32 Finalise() { + EnterCriticalSection(&criticalSection); numEvents = min(eventQueue.size(), N); for(VstInt32 i = 0; i < numEvents; i++) { events[i] = reinterpret_cast<VstEvent *>(&eventQueue[i]); } + LeaveCriticalSection(&criticalSection); return numEvents; } // Remove transmitted events from the queue void Clear() { + EnterCriticalSection(&criticalSection); if(numEvents) { eventQueue.erase(eventQueue.begin(), eventQueue.begin() + numEvents); numEvents = 0; } + LeaveCriticalSection(&criticalSection); } }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |