From: <rel...@us...> - 2008-03-15 12:38:58
|
Revision: 204 http://modplug.svn.sourceforge.net/modplug/?rev=204&view=rev Author: relabsoluness Date: 2008-03-15 05:38:52 -0700 (Sat, 15 Mar 2008) Log Message: ----------- Bug fixing . Fix to MIDI drum export (http://lpchip.com/modplug/viewtopic.php?t=2024) . Fix to possible crash on MIDI export if exporting module with more than 64 channels. / MIDI export won't anymore export muted channels(http://lpchip.com/modplug/viewtopic.php?t=2017) . When converting MOD->S3M/IT/MPTM, finetune setting was ignored (http://lpchip.com/modplug/viewtopic.php?t=1706) . Fix to messy view in general tab on certain cases(http://lpchip.com/modplug/viewtopic.php?t=1324) . IT compatibility: Fix to not resetting envelopes on new instrument (http://lpchip.com/modplug/viewtopic.php?t=1869) . IT compatibility: Fix to bidi loop resetting (http://lpchip.com/modplug/viewtopic.php?t=788) . IT compatibility: Fix to note trigger after note cut(http://lpchip.com/modplug/viewtopic.php?t=2080) Modified Paths: -------------- trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/mptrack/mod2midi.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2008-02-23 12:51:23 UTC (rev 203) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2008-03-15 12:38:52 UTC (rev 204) @@ -25,8 +25,10 @@ { CHAR s[256]; UINT b64 = 0; + + const MODTYPE oldtype = m_SndFile.GetType(); - if (nNewType == m_SndFile.GetType() && nNewType == MOD_TYPE_IT){ + if (nNewType == oldtype && nNewType == MOD_TYPE_IT){ // Even if m_nType doesn't change, we might need to change extension in itp<->it case. // This is because ITP is a HACK and doesn't genuinely change m_nType, // but uses flages instead. @@ -34,9 +36,21 @@ return TRUE; } - if(nNewType == m_SndFile.GetType()) return TRUE; + if(nNewType == oldtype) return TRUE; - if(m_SndFile.m_nType == MOD_TYPE_MPT) + const bool oldTypeIsMOD = (oldtype == MOD_TYPE_MOD), oldTypeIsXM = (oldtype == MOD_TYPE_XM), + oldTypeIsS3M = (oldtype == MOD_TYPE_S3M), oldTypeIsIT = (oldtype == MOD_TYPE_IT), + oldTypeIsMPT = (oldtype == MOD_TYPE_MPT), oldTypeIsMOD_XM = (oldTypeIsMOD || oldTypeIsXM), + oldTypeIsS3M_IT_MPT = (oldTypeIsS3M || oldTypeIsIT || oldTypeIsMPT); + + const bool newTypeIsMOD = (nNewType == MOD_TYPE_MOD), newTypeIsXM = (nNewType == MOD_TYPE_XM), + newTypeIsS3M = (nNewType == MOD_TYPE_S3M), newTypeIsIT = (nNewType == MOD_TYPE_IT), + newTypeIsMPT = (nNewType == MOD_TYPE_MPT), newTypeIsMOD_XM = (newTypeIsMOD || newTypeIsXM), + newTypeIsS3M_IT_MPT = (newTypeIsS3M || newTypeIsIT || newTypeIsMPT), + newTypeIsXM_IT_MPT = (newTypeIsXM || newTypeIsIT || newTypeIsMPT), + newTypeIsIT_MPT = (newTypeIsIT || newTypeIsMPT); + + if(oldTypeIsMPT) { if(::MessageBox(NULL, "Convertion from MPTm to any other modtype makes certain features unavailable and is not guaranteed to work properly; Do the convertion anyway?", "Notice", MB_YESNO) != IDYES) @@ -96,7 +110,7 @@ } //End if (((m_SndFile.m_nInstruments) || (b64)) && (nNewType & (MOD_TYPE_MOD|MOD_TYPE_S3M))) BeginWaitCursor(); // Adjust pattern data - if ((m_SndFile.m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM)) && (nNewType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT))) + if(oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) { for (UINT nPat=0; nPat<m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat]) { @@ -152,7 +166,7 @@ } } } else - if ((m_SndFile.m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) && (nNewType & (MOD_TYPE_MOD|MOD_TYPE_XM))) + if (oldTypeIsS3M_IT_MPT && newTypeIsMOD_XM) { for (UINT nPat=0; nPat<m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat]) { @@ -224,15 +238,15 @@ } } // Convert XM to MOD - if ((m_SndFile.m_nType == MOD_TYPE_XM) && (nNewType == MOD_TYPE_MOD)) + if (oldTypeIsXM && newTypeIsMOD) { } else // Convert MOD to XM - if ((m_SndFile.m_nType == MOD_TYPE_MOD) && (nNewType == MOD_TYPE_XM)) + if (oldTypeIsMOD && newTypeIsXM) { } else - // Convert XM to S3M/IT/MPT - if ((m_SndFile.m_nType == MOD_TYPE_XM) && (nNewType != MOD_TYPE_XM)) + // Convert MOD/XM to S3M/IT/MPT + if (oldTypeIsMOD_XM && newTypeIsS3M_IT_MPT) { for (UINT i=1; i<=m_SndFile.m_nSamples; i++) { @@ -240,10 +254,10 @@ m_SndFile.Ins[i].RelativeTone = 0; m_SndFile.Ins[i].nFineTune = 0; } - if (nNewType & (MOD_TYPE_IT|MOD_TYPE_MPT)) m_SndFile.m_dwSongFlags |= SONG_ITCOMPATMODE; + if (oldTypeIsXM && newTypeIsIT_MPT) m_SndFile.m_dwSongFlags |= SONG_ITCOMPATMODE; } else // Convert S3M/IT/MPT to XM - if ((m_SndFile.m_nType != MOD_TYPE_XM) && (nNewType == MOD_TYPE_XM)) + if (oldTypeIsS3M_IT_MPT && newTypeIsXM) { for (UINT i=1; i<=m_SndFile.m_nSamples; i++) { @@ -272,25 +286,25 @@ if (bBrokenNoteMap) AddToLog("WARNING: Note Mapping will be lost when saving as XM\n"); } // Too many samples ? - if ((nNewType == MOD_TYPE_MOD) && (m_SndFile.m_nSamples > 31)) + if (newTypeIsMOD && (m_SndFile.m_nSamples > 31)) { AddToLog("WARNING: Samples above 31 will be lost when saving this file as MOD!\n"); } BEGIN_CRITICAL(); m_SndFile.ChangeModTypeTo(nNewType); - if ((!(nNewType & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_XM))) && (m_SndFile.m_dwSongFlags & SONG_LINEARSLIDES)) + if (!newTypeIsXM_IT_MPT && (m_SndFile.m_dwSongFlags & SONG_LINEARSLIDES)) { AddToLog("WARNING: Linear Frequency Slides not supported by the new format.\n"); m_SndFile.m_dwSongFlags &= ~SONG_LINEARSLIDES; } - if (!(nNewType & (MOD_TYPE_IT|MOD_TYPE_MPT))) m_SndFile.m_dwSongFlags &= ~(SONG_ITOLDEFFECTS|SONG_ITCOMPATMODE); - if (nNewType != MOD_TYPE_S3M) m_SndFile.m_dwSongFlags &= ~SONG_FASTVOLSLIDES; + if (!newTypeIsIT_MPT) m_SndFile.m_dwSongFlags &= ~(SONG_ITOLDEFFECTS|SONG_ITCOMPATMODE); + if (!newTypeIsS3M) m_SndFile.m_dwSongFlags &= ~SONG_FASTVOLSLIDES; END_CRITICAL(); ChangeFileExtension(nNewType); //rewbs.cutomKeys: update effect key commands CInputHandler *ih = CMainFrame::GetMainFrame()->GetInputHandler(); - if (nNewType & (MOD_TYPE_MOD|MOD_TYPE_XM)) { + if (newTypeIsMOD_XM) { ih->SetXMEffects(); } else { ih->SetITEffects(); Modified: trunk/OpenMPT/mptrack/View_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp 2008-02-23 12:51:23 UTC (rev 203) +++ trunk/OpenMPT/mptrack/View_gen.cpp 2008-03-15 12:38:52 UTC (rev 204) @@ -177,6 +177,7 @@ GetDeviceScrollSizes(nMapMode, sizeTotal, sizePage, sizeLine); m_rcClient.SetRect(0, 0, sizeTotal.cx, sizeTotal.cy); RecalcLayout(); + // Initializing scroll ranges for (int ichn=0; ichn<4; ichn++) { @@ -241,6 +242,7 @@ // -> CODE#0015 // -> DESC="channels management dlg" void CViewGlobals::OnDraw(CDC* pDC) +//--------------------------------- { CView::OnDraw(pDC); @@ -326,8 +328,11 @@ m_TabCtrl.InsertItem(iItem, &tci); } if (nOldSel >= (UINT)nTabCount) nOldSel = 0; + + //Changing the order of these calls seemed to fix a GUI bug (http://lpchip.com/modplug/viewtopic.php?t=1324) + m_TabCtrl.SetRedraw(TRUE); m_TabCtrl.SetCurSel(nOldSel); - m_TabCtrl.SetRedraw(TRUE); + InvalidateRect(NULL, FALSE); } nTabIndex = m_TabCtrl.GetCurSel(); @@ -1274,6 +1279,7 @@ // -> CODE#0002 // -> DESC="VST plugins presets" void CViewGlobals::OnProgramChanged() +//----------------------------------- { int cursel = m_CbnPreset.GetCurSel(); CModDoc *pModDoc = GetDocument(); @@ -1296,6 +1302,7 @@ } void CViewGlobals::OnLoadParam() +//------------------------------ { CModDoc *pModDoc = GetDocument(); CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; @@ -1321,6 +1328,7 @@ } void CViewGlobals::OnSaveParam() +//------------------------------ { CModDoc *pModDoc = GetDocument(); CSoundFile *pSndFile = pModDoc ? pModDoc->GetSoundFile() : NULL; @@ -1467,6 +1475,7 @@ // -> CODE#0028 // -> DESC="effect plugin mixing mode combo" void CViewGlobals::OnWetDryExpandChanged() +//---------------------------------------- { CModDoc *pModDoc = GetDocument(); PSNDMIXPLUGIN pPlugin; Modified: trunk/OpenMPT/mptrack/mod2midi.cpp =================================================================== --- trunk/OpenMPT/mptrack/mod2midi.cpp 2008-02-23 12:51:23 UTC (rev 203) +++ trunk/OpenMPT/mptrack/mod2midi.cpp 2008-03-15 12:38:52 UTC (rev 204) @@ -145,7 +145,7 @@ if ((penv->nMidiProgram > 20) && (penv->nMidiProgram < 120)) m_InstrMap[nIns].nProgram = penv->nMidiProgram; else - m_InstrMap[nIns].nProgram = penv->NoteMap[60] & 0x7f; + m_InstrMap[nIns].nProgram = (penv->NoteMap[60]-1) & 0x7f; } else { m_InstrMap[nIns].nProgram = penv->nMidiProgram & 0x7f; @@ -350,6 +350,10 @@ UINT nSpeed; CFile f; + const CHANNELINDEX chnCount = min(64, m_pSndFile->GetNumChannels()); + if(chnCount < m_pSndFile->GetNumChannels()) + MessageBox("Note: Only 64 channels will be exported."); + if (!f.Open(m_szFileName, CFile::modeCreate | CFile::modeWrite)) { return FALSE; @@ -366,10 +370,14 @@ mthd.id = 0x6468544d; // "MThd" mthd.len = BigEndian(sizeof(mthd)-8); mthd.wFmt = BigEndianW(1); - mthd.wTrks = BigEndianW(m_pSndFile->m_nChannels); // 1 track/channel + mthd.wTrks = chnCount; // 1 track/channel + mthd.wTrks = BigEndianW(mthd.wTrks); //Convert to big endian value. mthd.wDivision = BigEndianW(nPPQN); if (m_bRmi) f.Write(&rmid, sizeof(rmid)); f.Write(&mthd, sizeof(mthd)); + + + // Add Song Name on track 0 m_pSndFile->GetTitle(s); if (s[0]) @@ -388,7 +396,7 @@ Tracks[0].Write(m_pSndFile->m_lpszSongComments, strlen(m_pSndFile->m_lpszSongComments)); } // Add channel names - for (UINT iInit=0; iInit<m_pSndFile->m_nChannels; iInit++) + for (UINT iInit=0; iInit<chnCount; iInit++) { PDYNMIDITRACK pTrk = &Tracks[iInit]; lstrcpyn(s, m_pSndFile->ChnSettings[iInit].szName, MAX_CHANNELNAME); @@ -422,10 +430,13 @@ nRow = 0; continue; } - for (UINT nChn=0; nChn<m_pSndFile->m_nChannels; nChn++) + for (UINT nChn=0; nChn<chnCount; nChn++) { + //Skip muted channels. + if(m_pSndFile->ChnSettings[nChn].dwFlags & CHN_MUTE) continue; + PDYNMIDITRACK pTrk = &Tracks[nChn]; - MODCOMMAND *m = m_pSndFile->Patterns[nPat] + nRow*m_pSndFile->m_nChannels + nChn; + MODCOMMAND *m = m_pSndFile->Patterns[nPat].GetpModCommand(nRow, nChn); UINT delta_time = nClock - pTrk->nLastEventClock; UINT len = 0; @@ -523,7 +534,7 @@ } } // Write midi tracks - for (UINT iTrk=0; iTrk<m_pSndFile->m_nChannels; iTrk++) + for (UINT iTrk=0; iTrk<chnCount; iTrk++) { tmp[0] = 0x00; tmp[1] = 0xff; Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2008-02-23 12:51:23 UTC (rev 203) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2008-03-15 12:38:52 UTC (rev 204) @@ -413,6 +413,8 @@ MODINSTRUMENT *psmp = &Ins[instr]; UINT note = pChn->nNewNote; + if(note == 0 && TypeIsIT_MPT() && GetModFlag(MSF_IT_COMPATIBLE_PLAY)) return; + if ((penv) && (note) && (note <= 128)) { if (penv->NoteMap[note-1] >= 0xFE) return; @@ -426,7 +428,8 @@ } const bool bNewTuning = (m_nType == MOD_TYPE_MPT && penv && penv->pTuning); - //Playback behavior change for MPT: Don't change sample if it is in the same instrument as previous sample. + //Playback behavior change for MPT: With portamento don't change sample if it is in + //the same instrument as previous sample. if(bPorta && bNewTuning && penv == pChn->pHeader) return; @@ -436,14 +439,17 @@ { bInstrumentChanged = TRUE; pChn->pHeader = penv; - } else - // Special XM hack - if ((bPorta) && (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (penv) - && (pChn->pInstrument) && (psmp != pChn->pInstrument)) - { - // FT2 doesn't change the sample in this case, - // but still uses the sample info from the old one (bug?) - returnAfterVolumeAdjust = true; + } + else + { + // Special XM hack + if ((bPorta) && (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (penv) + && (pChn->pInstrument) && (psmp != pChn->pInstrument)) + { + // FT2 doesn't change the sample in this case, + // but still uses the sample info from the old one (bug?) + returnAfterVolumeAdjust = true; + } } // Update Volume @@ -486,7 +492,9 @@ if (bResetEnv) { if ((!bPorta) || (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) || (m_dwSongFlags & SONG_ITCOMPATMODE) - || (!pChn->nLength) || ((pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol))) + || (!pChn->nLength) || ((pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol)) + //IT compatibility tentative fix: Reset envelopes when instrument changes. + || (TypeIsIT_MPT() && GetModFlag(MSF_IT_COMPATIBLE_PLAY) && bInstrumentChanged)) { pChn->dwFlags |= CHN_FASTVOLRAMP; if ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!bInstrumentChanged) && (penv) && (!(pChn->dwFlags & (CHN_KEYOFF|CHN_NOTEFADE)))) @@ -520,7 +528,15 @@ } else { pChn->dwFlags &= ~(CHN_KEYOFF|CHN_NOTEFADE|CHN_VOLENV|CHN_PANENV|CHN_PITCHENV); - pChn->dwFlags = (pChn->dwFlags & 0xFFFFFF00) | (psmp->uFlags & 0xFF); + + //IT compatibility tentative fix: Don't anymore change bidi loop direction when + //no sample nor instrument is changed. + if(TypeIsIT_MPT() && GetModFlag(MSF_IT_COMPATIBLE_PLAY) && psmp == pChn->pInstrument && !bInstrumentChanged) + pChn->dwFlags = (pChn->dwFlags & (0xFFFFFF00 | CHN_PINGPONGFLAG)) | (psmp->uFlags & 0xFF); + else + pChn->dwFlags = (pChn->dwFlags & 0xFFFFFF00) | (psmp->uFlags & 0xFF); + + if (penv) { if (penv->dwFlags & ENV_VOLUME) pChn->dwFlags |= CHN_VOLENV; @@ -594,11 +610,17 @@ // Key Off KeyOff(nChn); // Note Cut - if (note == 0xFE) + if (note == NOTE_NOTECUT) { pChn->dwFlags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP); if ((!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) || (m_nInstruments)) pChn->nVolume = 0; pChn->nFadeOutVol = 0; + + //IT compatibility tentative fix: Clear channel note memory on note cut. + if(TypeIsIT_MPT() && GetModFlag(MSF_IT_COMPATIBLE_PLAY)) + { + pChn->nNote = pChn->nNewNote = 0; + } } return; } @@ -667,7 +689,10 @@ if (pChn->nTremoloType < 4) pChn->nTremoloPos = 0; } if (pChn->nPos >= pChn->nLength) pChn->nPos = pChn->nLoopStart; - } else bPorta = FALSE; + } + else + bPorta = FALSE; + if ((!bPorta) || (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) || ((pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol)) || ((m_dwSongFlags & SONG_ITCOMPATMODE) && (pChn->nRowInstr))) @@ -1113,13 +1138,11 @@ { if(instr < MAX_INSTRUMENTS && pChn->pHeader != Headers[instr]) note = pChn->nNote; - } else //Case: Only samples used { if(instr < MAX_SAMPLES && pChn->pSample != Ins[instr].pSample) note = pChn->nNote; - } } @@ -1188,7 +1211,7 @@ InstrumentChange(pChn, instr, bPorta, TRUE); pChn->nNewIns = 0; // Special IT case: portamento+note causes sample change -> ignore portamento - if ((m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT)) + if ((m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) && (psmp != pChn->pInstrument) && (note) && (note < 0x80)) { bPorta = FALSE; @@ -1406,34 +1429,6 @@ if (m_nTickCount) break; //rewbs.volOffset: moved sample offset code to own method SampleOffset(nChn, param, bPorta); - - -/* if (param) pChn->nOldOffset = param; else param = pChn->nOldOffset; - param <<= 8; - param |= (UINT)(pChn->nOldHiOffset) << 16; - if ((pChn->nRowNote) && (pChn->nRowNote < 0x80)) - { - if (bPorta) - pChn->nPos = param; - else - pChn->nPos += param; - if (pChn->nPos >= pChn->nLength) - { - if (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) - { - pChn->nPos = pChn->nLoopStart; - if ((m_dwSongFlags & SONG_ITOLDEFFECTS) && (pChn->nLength > 4)) - { - pChn->nPos = pChn->nLength - 2; - } - } - } - } else - if ((param < pChn->nLength) && (m_nType & (MOD_TYPE_MTM|MOD_TYPE_DMF))) - { - pChn->nPos = param; - } -*/ break; // Arpeggio Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2008-02-23 12:51:23 UTC (rev 203) +++ trunk/OpenMPT/soundlib/Sndfile.h 2008-03-15 12:38:52 UTC (rev 204) @@ -110,7 +110,7 @@ #define CHN_PINGPONGSUSTAIN 0x10 #define CHN_PANNING 0x20 #define CHN_STEREO 0x40 -#define CHN_PINGPONGFLAG 0x80 +#define CHN_PINGPONGFLAG 0x80 //When flag is on, bidiloop is processed backwards? // Bits 8-31: Channel Flags #define CHN_MUTE 0x100 #define CHN_KEYOFF 0x200 @@ -959,6 +959,7 @@ BOOL Create(LPCBYTE lpStream, CModDoc *pModDoc, DWORD dwMemLength=0); BOOL Destroy(); MODTYPE GetType() const { return m_nType; } + inline bool TypeIsIT_MPT() const {return (m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) != 0;} CModDoc* GetpModDoc() {return m_pModDoc;} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |