From: <sag...@us...> - 2009-10-06 12:44:39
|
Revision: 389 http://modplug.svn.sourceforge.net/modplug/?rev=389&view=rev Author: saga-games Date: 2009-10-06 12:44:31 +0000 (Tue, 06 Oct 2009) Log Message: ----------- [Fix] Pattern Editor: PC Notes are now deleted properly (last column) [Imp] Treeview: Can now dragondrop orders, even between sequences [Imp] Mod Conversion: Trim sequence if it's too long [New] New cleanup feature: Merge sequences [Mod] Redesigned cleanup dialog again... [Ref] Removed more compiler warnings Modified Paths: -------------- trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/CleanupSong.h trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-10-05 20:51:54 UTC (rev 388) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2009-10-06 12:44:31 UTC (rev 389) @@ -18,31 +18,30 @@ // Default checkbox state bool CModCleanupDlg::m_bCheckBoxes[CU_MAX_CLEANUP_OPTIONS] = { - // remove unused - true, true, // pat/smp - true, true, // ins/plg - // remove all - false, false, // pat/ord - false, false, // smp/ins - false, // plg - // misc - true, true, // pat/smp - true, false, // opt/reset + true, false, true, // patterns + false, false, // orders + true, false, false, true, // samples + true, false, // instruments + true, false, // plugins + false, // misc }; // Checkbox -> Control ID LUT WORD const CModCleanupDlg::m_nCleanupIDtoDlgID[CU_MAX_CLEANUP_OPTIONS] = { - // remove unused - IDC_CHK_CLEANUP_PATTERNS, IDC_CHK_CLEANUP_SAMPLES, - IDC_CHK_CLEANUP_INSTRUMENTS, IDC_CHK_CLEANUP_PLUGINS, - // remove all - IDC_CHK_REMOVE_PATTERNS, IDC_CHK_REMOVE_ORDERS, - IDC_CHK_REMOVE_SAMPLES, IDC_CHK_REMOVE_INSTRUMENTS, - IDC_CHK_REMOVE_PLUGINS, + // patterns + IDC_CHK_CLEANUP_PATTERNS, IDC_CHK_REMOVE_PATTERNS, IDC_CHK_REARRANGE_PATTERNS, + // orders + IDC_CHK_MERGE_SEQUENCES, IDC_CHK_REMOVE_ORDERS, + // samples + IDC_CHK_CLEANUP_SAMPLES, IDC_CHK_REMOVE_SAMPLES, IDC_CHK_REARRANGE_SAMPLES, + IDC_CHK_OPTIMIZE_SAMPLES, + // instruments + IDC_CHK_CLEANUP_INSTRUMENTS, IDC_CHK_REMOVE_INSTRUMENTS, + // plugins + IDC_CHK_CLEANUP_PLUGINS, IDC_CHK_REMOVE_PLUGINS, // misc - IDC_CHK_REARRANGE_PATTERNS, IDC_CHK_REARRANGE_SAMPLES, - IDC_CHK_OPTIMIZE_SAMPLES, IDC_CHK_RESET_VARIABLES, + IDC_CHK_RESET_VARIABLES, }; /////////////////////////////////////////////////////////////////////// @@ -52,6 +51,9 @@ //{{AFX_MSG_MAP(CModTypeDlg) ON_COMMAND(IDC_BTN_CLEANUP_SONG, OnPresetCleanupSong) ON_COMMAND(IDC_BTN_COMPO_CLEANUP, OnPresetCompoCleanup) + + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, &CModCleanupDlg::OnToolTipNotify) + ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, &CModCleanupDlg::OnToolTipNotify) //}}AFX_MSG_MAP END_MESSAGE_MAP() @@ -67,15 +69,19 @@ CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); if(pSndFile == nullptr) return FALSE; - GetDlgItem(m_nCleanupIDtoDlgID[CU_CLEANUP_INSTRUMENTS])->EnableWindow((pSndFile->m_nInstruments > 0) ? TRUE :FALSE); + GetDlgItem(m_nCleanupIDtoDlgID[CU_MERGE_SEQUENCES])->EnableWindow((pSndFile->m_nType & MOD_TYPE_MPT) ? TRUE : FALSE); - GetDlgItem(m_nCleanupIDtoDlgID[CU_REMOVE_INSTRUMENTS])->EnableWindow((pSndFile->m_nInstruments > 0) ? TRUE :FALSE); - GetDlgItem(m_nCleanupIDtoDlgID[CU_REMOVE_SAMPLES])->EnableWindow((pSndFile->m_nSamples > 0) ? TRUE :FALSE); + GetDlgItem(m_nCleanupIDtoDlgID[CU_REMOVE_SAMPLES])->EnableWindow((pSndFile->m_nSamples > 0) ? TRUE : FALSE); + GetDlgItem(m_nCleanupIDtoDlgID[CU_REARRANGE_SAMPLES])->EnableWindow((pSndFile->m_nSamples > 1) ? TRUE : FALSE); - GetDlgItem(m_nCleanupIDtoDlgID[CU_REARRANGE_SAMPLES])->EnableWindow((pSndFile->m_nSamples > 1) ? TRUE :FALSE); + GetDlgItem(m_nCleanupIDtoDlgID[CU_CLEANUP_INSTRUMENTS])->EnableWindow((pSndFile->m_nInstruments > 0) ? TRUE : FALSE); + GetDlgItem(m_nCleanupIDtoDlgID[CU_REMOVE_INSTRUMENTS])->EnableWindow((pSndFile->m_nInstruments > 0) ? TRUE : FALSE); + + EnableToolTips(TRUE); return TRUE; } + void CModCleanupDlg::OnOK() //------------------------- { @@ -88,6 +94,7 @@ m_pModDoc->ClearLog(); // Orders + if(m_bCheckBoxes[CU_MERGE_SEQUENCES]) bModified |= MergeSequences(); if(m_bCheckBoxes[CU_REMOVE_ORDERS]) bModified |= RemoveAllOrders(); // Patterns @@ -136,46 +143,137 @@ void CModCleanupDlg::OnPresetCleanupSong() //---------------------------------------- { - // remove unused + // patterns CheckDlgButton(IDC_CHK_CLEANUP_PATTERNS, MF_CHECKED); - CheckDlgButton(IDC_CHK_CLEANUP_SAMPLES, MF_CHECKED); - CheckDlgButton(IDC_CHK_CLEANUP_INSTRUMENTS, MF_CHECKED); - CheckDlgButton(IDC_CHK_CLEANUP_PLUGINS, MF_CHECKED); - // remove all CheckDlgButton(IDC_CHK_REMOVE_PATTERNS, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_PATTERNS, MF_UNCHECKED); + // orders + CheckDlgButton(IDC_CHK_MERGE_SEQUENCES, MF_UNCHECKED); CheckDlgButton(IDC_CHK_REMOVE_ORDERS, MF_UNCHECKED); + // samples + CheckDlgButton(IDC_CHK_CLEANUP_SAMPLES, MF_CHECKED); CheckDlgButton(IDC_CHK_REMOVE_SAMPLES, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_SAMPLES, MF_CHECKED); + CheckDlgButton(IDC_CHK_OPTIMIZE_SAMPLES, MF_CHECKED); + // instruments + CheckDlgButton(IDC_CHK_CLEANUP_INSTRUMENTS, MF_CHECKED); CheckDlgButton(IDC_CHK_REMOVE_INSTRUMENTS, MF_UNCHECKED); + // plugins + CheckDlgButton(IDC_CHK_CLEANUP_PLUGINS, MF_CHECKED); CheckDlgButton(IDC_CHK_REMOVE_PLUGINS, MF_UNCHECKED); // misc - CheckDlgButton(IDC_CHK_REARRANGE_PATTERNS, MF_CHECKED); - CheckDlgButton(IDC_CHK_REARRANGE_SAMPLES, MF_CHECKED); - CheckDlgButton(IDC_CHK_OPTIMIZE_SAMPLES, MF_CHECKED); CheckDlgButton(IDC_CHK_SAMPLEPACK, MF_UNCHECKED); } void CModCleanupDlg::OnPresetCompoCleanup() //---------------------------------------- { - // remove unused + // patterns CheckDlgButton(IDC_CHK_CLEANUP_PATTERNS, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_CLEANUP_SAMPLES, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_CLEANUP_INSTRUMENTS, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_CLEANUP_PLUGINS, MF_UNCHECKED); - // remove all CheckDlgButton(IDC_CHK_REMOVE_PATTERNS, MF_CHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_PATTERNS, MF_UNCHECKED); + // orders + CheckDlgButton(IDC_CHK_MERGE_SEQUENCES, MF_UNCHECKED); CheckDlgButton(IDC_CHK_REMOVE_ORDERS, MF_CHECKED); + // samples + CheckDlgButton(IDC_CHK_CLEANUP_SAMPLES, MF_UNCHECKED); CheckDlgButton(IDC_CHK_REMOVE_SAMPLES, MF_UNCHECKED); + CheckDlgButton(IDC_CHK_REARRANGE_SAMPLES, MF_CHECKED); + CheckDlgButton(IDC_CHK_OPTIMIZE_SAMPLES, MF_UNCHECKED); + // instruments + CheckDlgButton(IDC_CHK_CLEANUP_INSTRUMENTS, MF_UNCHECKED); CheckDlgButton(IDC_CHK_REMOVE_INSTRUMENTS, MF_CHECKED); + // plugins + CheckDlgButton(IDC_CHK_CLEANUP_PLUGINS, MF_UNCHECKED); CheckDlgButton(IDC_CHK_REMOVE_PLUGINS, MF_CHECKED); // misc - CheckDlgButton(IDC_CHK_REARRANGE_PATTERNS, MF_UNCHECKED); - CheckDlgButton(IDC_CHK_REARRANGE_SAMPLES, MF_CHECKED); - CheckDlgButton(IDC_CHK_OPTIMIZE_SAMPLES, MF_UNCHECKED); CheckDlgButton(IDC_CHK_SAMPLEPACK, MF_CHECKED); } +BOOL CModCleanupDlg::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult) +{ + UNREFERENCED_PARAMETER(id); + UNREFERENCED_PARAMETER(pResult); + // need to handle both ANSI and UNICODE versions of the message + TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; + TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; + CStringA strTipText = ""; + UINT_PTR nID = pNMHDR->idFrom; + if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) || + pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND)) + { + // idFrom is actually the HWND of the tool + nID = ::GetDlgCtrlID((HWND)nID); + } + + switch(nID) + { + // patterns + case IDC_CHK_CLEANUP_PATTERNS: + strTipText = "Remove all unused patterns and rearrange them."; + break; + case IDC_CHK_REMOVE_PATTERNS: + strTipText = "Remove all patterns."; + break; + case IDC_CHK_REARRANGE_PATTERNS: + strTipText = "Number the patterns given by their order in the sequence."; + break; + // orders + case IDC_CHK_REMOVE_ORDERS: + strTipText = "Reset the order list."; + break; + case IDC_CHK_MERGE_SEQUENCES: + strTipText = "Merge multiple sequences into one."; + break; + // samples + case IDC_CHK_CLEANUP_SAMPLES: + strTipText = "Remove all unused samples."; + break; + case IDC_CHK_REMOVE_SAMPLES: + strTipText = "Remove all samples."; + break; + case IDC_CHK_REARRANGE_SAMPLES: + strTipText = "Reorder sample list by removing empty samples."; + break; + case IDC_CHK_OPTIMIZE_SAMPLES: + strTipText = "Remove unused data after the sample loop end."; + break; + // instruments + case IDC_CHK_CLEANUP_INSTRUMENTS: + strTipText = "Remove all unused instruments."; + break; + case IDC_CHK_REMOVE_INSTRUMENTS: + strTipText = "Remove all instruments and convert them to samples."; + break; + // plugins + case IDC_CHK_CLEANUP_PLUGINS: + strTipText = "Remove all unused plugins."; + break; + case IDC_CHK_REMOVE_PLUGINS: + strTipText = "Remove all plugins."; + break; + // misc + case IDC_CHK_SAMPLEPACK: + strTipText = "Convert the module to .IT and reset song, sample and instrument variables"; + break; + } + + if (pNMHDR->code == TTN_NEEDTEXTA) + { + strncpy_s(pTTTA->szText, sizeof(pTTTA->szText), strTipText, + strTipText.GetLength() + 1); + } + else + { + ::MultiByteToWideChar(CP_ACP , 0, strTipText, strTipText.GetLength() + 1, + pTTTW->szText, sizeof(pTTTW->szText)/(sizeof pTTTW->szText[0])); + } + + return TRUE; +} + + /////////////////////////////////////////////////////////////////////// // Actual cleanup implementations @@ -807,8 +905,12 @@ CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); if(pSndFile == nullptr) return false; + pSndFile->Order.SetSequence(0); + while(pSndFile->Order.GetNumSequences() > 1) + { + pSndFile->Order.RemoveSequence(1); + } pSndFile->Order.Init(); - pSndFile->Order.SetSequence(0); pSndFile->Order[0] = 0; pSndFile->SetCurrentOrder(0); return true; @@ -876,3 +978,10 @@ m_pModDoc->RemovePlugs(keepMask); return true; } + +// Remove all plugins +bool CModCleanupDlg::MergeSequences() +//------------------------------------- +{ + return m_pModDoc->MergeSequences(); +} Modified: trunk/OpenMPT/mptrack/CleanupSong.h =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.h 2009-10-05 20:51:54 UTC (rev 388) +++ trunk/OpenMPT/mptrack/CleanupSong.h 2009-10-06 12:44:31 UTC (rev 389) @@ -10,21 +10,25 @@ enum ENUM_CLEANUP_OPTIONS { - // remove unused + // patterns CU_CLEANUP_PATTERNS = 0, - CU_CLEANUP_SAMPLES, - CU_CLEANUP_INSTRUMENTS, - CU_CLEANUP_PLUGINS, - // remove all CU_REMOVE_PATTERNS, + CU_REARRANGE_PATTERNS, + // orders + CU_MERGE_SEQUENCES, CU_REMOVE_ORDERS, + // samples + CU_CLEANUP_SAMPLES, CU_REMOVE_SAMPLES, + CU_REARRANGE_SAMPLES, + CU_OPTIMIZE_SAMPLES, + // instruments + CU_CLEANUP_INSTRUMENTS, CU_REMOVE_INSTRUMENTS, + // plugins + CU_CLEANUP_PLUGINS, CU_REMOVE_PLUGINS, // misc - CU_REARRANGE_PATTERNS, - CU_REARRANGE_SAMPLES, - CU_OPTIMIZE_SAMPLES, CU_RESET_VARIABLES, CU_MAX_CLEANUP_OPTIONS @@ -40,20 +44,25 @@ static bool m_bCheckBoxes[CU_MAX_CLEANUP_OPTIONS]; // Checkbox state static const WORD m_nCleanupIDtoDlgID[CU_MAX_CLEANUP_OPTIONS]; // Checkbox -> Control ID LUT - // Actual cleanup implementations + // Actual cleanup implementations: + // Patterns bool RemoveUnusedPatterns(bool bRemove = true); // Remove unused patterns / rearrange patterns - bool RemoveUnusedSamples(); // Remove unused samples - bool RemoveUnusedInstruments(); // Remove unused instruments - bool RemoveUnusedPlugins(); // Remove ununsed plugins - // Zap bool RemoveAllPatterns(); + // Orders + bool MergeSequences(); bool RemoveAllOrders(); + // Samples + bool RemoveUnusedSamples(); // Remove unused samples bool RemoveAllSamples(); + bool RearrangeSamples(); // Rearrange sample list + bool OptimizeSamples(); // Remove unused sample data + // Instruments + bool RemoveUnusedInstruments(); // Remove unused instruments bool RemoveAllInstruments(bool bConfirm = true); + // Plugins + bool RemoveUnusedPlugins(); // Remove ununsed plugins bool RemoveAllPlugins(); // Misc - bool RearrangeSamples(); // Rearrange sample list - bool OptimizeSamples(); // Remove unused sample data bool ResetVariables(); // Turn module into samplepack (convert to IT, remove patterns, etc.) public: @@ -66,6 +75,8 @@ virtual void OnCancel(); //}}AFX_VIRTUAL + BOOL OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult); + //{{AFX_MSG(CModCleanupDlg) afx_msg void OnPresetCleanupSong(); afx_msg void OnPresetCompoCleanup(); Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-10-05 20:51:54 UTC (rev 388) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-10-06 12:44:31 UTC (rev 389) @@ -258,6 +258,8 @@ BOOL RemoveChannels(BOOL bChnMask[MAX_CHANNELS]); + bool MergeSequences(); + bool m_bHasValidPath; //becomes true if document is loaded or saved. // Fix: save pattern scrollbar position when switching to other tab CSize GetOldPatternScrollbarsPos() const { return m_szOldPatternScrollbarsPos; }; Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-05 20:51:54 UTC (rev 388) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-10-06 12:44:31 UTC (rev 389) @@ -100,75 +100,6 @@ -Alternative tempomodes -For more info, see e.g. SaveExtendedSongProperties(), SaveExtendedInstrumentProperties() */ - - // Merge multiple sequences - m_SndFile.Order.SetSequence(0); - m_SndFile.Order.resize(m_SndFile.Order.GetLengthTailTrimmed()); - SEQUENCEINDEX removedSequences = 0; // sequence count - vector <SEQUENCEINDEX> patternsFixed; // pattern fixed by other sequence already? - patternsFixed.resize(m_SndFile.Patterns.Size(), SEQUENCEINDEX_INVALID); - // Set up vector - for(ORDERINDEX nOrd = 0; nOrd < m_SndFile.Order.GetLengthTailTrimmed(); nOrd++) - { - PATTERNINDEX nPat = m_SndFile.Order[nOrd]; - if(!m_SndFile.Patterns.IsValidPat(nPat)) continue; - patternsFixed[nPat] = 0; - } - - while(m_SndFile.Order.GetNumSequences() > 1) - { - removedSequences++; - const ORDERINDEX nFirstOrder = m_SndFile.Order.GetLengthTailTrimmed() + 1; // +1 for separator item - if(nFirstOrder + m_SndFile.Order.GetSequence(1).GetLengthTailTrimmed() > m_SndFile.GetModSpecifications(nNewType).ordersMax) - { - wsprintf(s, "WARNING: Cannot merge Sequence %d (too long!)\n", removedSequences); - AddToLog(s); - m_SndFile.Order.RemoveSequence(1); - continue; - } - m_SndFile.Order.Append(m_SndFile.Order.GetInvalidPatIndex()); // Separator item - for(ORDERINDEX nOrd = 0; nOrd < m_SndFile.Order.GetSequence(1).GetLengthTailTrimmed(); nOrd++) - { - PATTERNINDEX nPat = m_SndFile.Order.GetSequence(1)[nOrd]; - m_SndFile.Order.Append(nPat); - - // Try to fix patterns (Bxx commands) - if(!m_SndFile.Patterns.IsValidPat(nPat)) continue; - - MODCOMMAND *m = m_SndFile.Patterns[nPat]; - for (UINT len = 0; len < m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; m++, len++) - { - if(m->command == CMD_POSITIONJUMP) - { - if(patternsFixed[nPat] != SEQUENCEINDEX_INVALID && patternsFixed[nPat] != removedSequences) - { - // Oops, some other sequence uses this pattern already. - const PATTERNINDEX nNewPat = m_SndFile.Patterns.Insert(m_SndFile.PatternSize[nPat]); - if(nNewPat != SEQUENCEINDEX_INVALID) - { - // could create new pattern - copy data over and continue from here. - m_SndFile.Order[nFirstOrder + nOrd] = nNewPat; - MODCOMMAND *pSrc = m_SndFile.Patterns[nPat]; - MODCOMMAND *pDest = m_SndFile.Patterns[nNewPat]; - memcpy(pDest, pSrc, m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels * sizeof(MODCOMMAND)); - m = pDest + len; - patternsFixed.resize(max(nNewPat + 1, (PATTERNINDEX)patternsFixed.size()), SEQUENCEINDEX_INVALID); - nPat = nNewPat; - } else - { - // cannot create new pattern: notify the user - wsprintf(s, "CONFLICT: Pattern break commands in Pattern %d might be broken since it has been used in several sequences!", nPat); - AddToLog(s); - } - } - m->param += nFirstOrder; - patternsFixed[nPat] = removedSequences; - } - } - - } - m_SndFile.Order.RemoveSequence(1); - } } // Check if conversion to 64 rows is necessary @@ -802,6 +733,9 @@ END_CRITICAL(); ChangeFileExtension(nNewType); + // Multisequences not suppported by other formats + if(!(m_SndFile.m_nType & MOD_TYPE_MPT)) MergeSequences(); + //rewbs.cutomKeys: update effect key commands CInputHandler *ih = CMainFrame::GetMainFrame()->GetInputHandler(); if (newTypeIsMOD_XM) { @@ -826,6 +760,22 @@ if(bTrimmedEnvelopes == true) AddToLog("WARNING: Instrument envelopes have been shortened.\n"); + // Order list too long -> remove unnecessary order items first. + if(m_SndFile.Order.GetLengthTailTrimmed() > specs.ordersMax) + { + for(ORDERINDEX nOrd = m_SndFile.Order.GetLengthTailTrimmed() - 1; nOrd >= 0; nOrd--) + { + if(m_SndFile.Patterns.IsValidPat(m_SndFile.Order[nOrd]) == false) + { + for(ORDERINDEX nMoveOrd = nOrd; nMoveOrd < m_SndFile.Order.GetLengthTailTrimmed(); nMoveOrd++) + { + m_SndFile.Order[nMoveOrd] = m_SndFile.Order[nMoveOrd + 1]; + } + } + } + m_SndFile.Order.resize(specs.ordersMax); + } + SetModified(); ClearUndo(); UpdateAllViews(NULL, HINT_MODTYPE | HINT_MODGENERAL); @@ -1371,22 +1321,34 @@ bool CModDoc::MoveOrder(ORDERINDEX nSourceNdx, ORDERINDEX nDestNdx, bool bUpdate, bool bCopy, SEQUENCEINDEX nSourceSeq, SEQUENCEINDEX nDestSeq) //--------------------------------------------------------------------------------------------------------------------------------------------- { - if ((nSourceNdx >= m_SndFile.Order.size()) || (nDestNdx >= m_SndFile.Order.size())) return false; + if (max(nSourceNdx, nDestNdx) >= m_SndFile.Order.size()) return false; if (nDestNdx >= m_SndFile.GetModSpecifications().ordersMax) return false; - ORDERINDEX n = m_SndFile.Order[nSourceNdx]; + + if(nSourceSeq == SEQUENCEINDEX_INVALID) nSourceSeq = m_SndFile.Order.GetCurrentSequenceIndex(); + if(nDestSeq == SEQUENCEINDEX_INVALID) nDestSeq = m_SndFile.Order.GetCurrentSequenceIndex(); + if (max(nSourceSeq, nDestSeq) >= m_SndFile.Order.GetNumSequences()) return false; + PATTERNINDEX nSourcePat = m_SndFile.Order.GetSequence(nSourceSeq)[nSourceNdx]; + + // save current working sequence + SEQUENCEINDEX nWorkingSeq = m_SndFile.Order.GetCurrentSequenceIndex(); + // Delete source if (!bCopy) { - for (ORDERINDEX i = nSourceNdx; i < m_SndFile.Order.size() - 1; i++) m_SndFile.Order[i] = m_SndFile.Order[i+1]; + m_SndFile.Order.SetSequence(nSourceSeq); + for (ORDERINDEX i = nSourceNdx; i < m_SndFile.Order.size() - 1; i++) m_SndFile.Order[i] = m_SndFile.Order[i + 1]; if (nSourceNdx < nDestNdx) nDestNdx--; } // Insert at dest - for (ORDERINDEX j = m_SndFile.Order.size() - 1; j > nDestNdx; j--) m_SndFile.Order[j] = m_SndFile.Order[j-1]; - m_SndFile.Order[nDestNdx] = n; + m_SndFile.Order.SetSequence(nDestSeq); + for (ORDERINDEX nOrd = m_SndFile.Order.size() - 1; nOrd > nDestNdx; nOrd--) m_SndFile.Order[nOrd] = m_SndFile.Order[nOrd - 1]; + m_SndFile.Order[nDestNdx] = nSourcePat; if (bUpdate) { UpdateAllViews(NULL, HINT_MODSEQUENCE, NULL); } + + m_SndFile.Order.SetSequence(nWorkingSeq); return true; } @@ -2147,4 +2109,80 @@ } } +// Merge multiple sequences +bool CModDoc::MergeSequences() +//---------------------------- +{ + if(m_SndFile.Order.GetNumSequences() <= 1) return false; + CHAR s[256]; + m_SndFile.Order.SetSequence(0); + m_SndFile.Order.resize(m_SndFile.Order.GetLengthTailTrimmed()); + SEQUENCEINDEX removedSequences = 0; // sequence count + vector <SEQUENCEINDEX> patternsFixed; // pattern fixed by other sequence already? + patternsFixed.resize(m_SndFile.Patterns.Size(), SEQUENCEINDEX_INVALID); + // Set up vector + for(ORDERINDEX nOrd = 0; nOrd < m_SndFile.Order.GetLengthTailTrimmed(); nOrd++) + { + PATTERNINDEX nPat = m_SndFile.Order[nOrd]; + if(!m_SndFile.Patterns.IsValidPat(nPat)) continue; + patternsFixed[nPat] = 0; + } + + while(m_SndFile.Order.GetNumSequences() > 1) + { + removedSequences++; + const ORDERINDEX nFirstOrder = m_SndFile.Order.GetLengthTailTrimmed() + 1; // +1 for separator item + if(nFirstOrder + m_SndFile.Order.GetSequence(1).GetLengthTailTrimmed() > m_SndFile.GetModSpecifications().ordersMax) + { + wsprintf(s, "WARNING: Cannot merge Sequence %d (too long!)\n", removedSequences); + AddToLog(s); + m_SndFile.Order.RemoveSequence(1); + continue; + } + m_SndFile.Order.Append(m_SndFile.Order.GetInvalidPatIndex()); // Separator item + for(ORDERINDEX nOrd = 0; nOrd < m_SndFile.Order.GetSequence(1).GetLengthTailTrimmed(); nOrd++) + { + PATTERNINDEX nPat = m_SndFile.Order.GetSequence(1)[nOrd]; + m_SndFile.Order.Append(nPat); + + // Try to fix patterns (Bxx commands) + if(!m_SndFile.Patterns.IsValidPat(nPat)) continue; + + MODCOMMAND *m = m_SndFile.Patterns[nPat]; + for (UINT len = 0; len < m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; m++, len++) + { + if(m->command == CMD_POSITIONJUMP) + { + if(patternsFixed[nPat] != SEQUENCEINDEX_INVALID && patternsFixed[nPat] != removedSequences) + { + // Oops, some other sequence uses this pattern already. + const PATTERNINDEX nNewPat = m_SndFile.Patterns.Insert(m_SndFile.PatternSize[nPat]); + if(nNewPat != SEQUENCEINDEX_INVALID) + { + // could create new pattern - copy data over and continue from here. + m_SndFile.Order[nFirstOrder + nOrd] = nNewPat; + MODCOMMAND *pSrc = m_SndFile.Patterns[nPat]; + MODCOMMAND *pDest = m_SndFile.Patterns[nNewPat]; + memcpy(pDest, pSrc, m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels * sizeof(MODCOMMAND)); + m = pDest + len; + patternsFixed.resize(max(nNewPat + 1, (PATTERNINDEX)patternsFixed.size()), SEQUENCEINDEX_INVALID); + nPat = nNewPat; + } else + { + // cannot create new pattern: notify the user + wsprintf(s, "CONFLICT: Pattern break commands in Pattern %d might be broken since it has been used in several sequences!", nPat); + AddToLog(s); + } + } + m->param += nFirstOrder; + patternsFixed[nPat] = removedSequences; + } + } + + } + m_SndFile.Order.RemoveSequence(1); + } + return true; +} + Modified: trunk/OpenMPT/mptrack/View_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp 2009-10-05 20:51:54 UTC (rev 388) +++ trunk/OpenMPT/mptrack/View_gen.cpp 2009-10-06 12:44:31 UTC (rev 389) @@ -562,14 +562,14 @@ } void CViewGlobals::OnMute(const CHANNELINDEX chnMod4, const UINT itemID) -//--------------------------------------------------------- +//---------------------------------------------------------------------- { CModDoc *pModDoc = GetDocument(); if (pModDoc) { - const BOOL b = (IsDlgButtonChecked(itemID)) ? TRUE : FALSE; - const UINT nChn = m_nActiveTab * 4 + chnMod4; + const bool b = (IsDlgButtonChecked(itemID)) ? true : false; + const CHANNELINDEX nChn = (CHANNELINDEX)(m_nActiveTab * 4) + chnMod4; pModDoc->MuteChannel(nChn, b); pModDoc->UpdateAllViews(this, HINT_MODCHANNELS | (m_nActiveTab << HINT_SHIFT_CHNTAB)); } @@ -582,14 +582,14 @@ void CViewGlobals::OnSurround(const CHANNELINDEX chnMod4, const UINT itemID) -//-------------------------------------------------------------- +//-------------------------------------------------------------------------- { CModDoc *pModDoc = GetDocument(); if (pModDoc) { - const BOOL b = (IsDlgButtonChecked(itemID)) ? TRUE : FALSE; - const UINT nChn = m_nActiveTab * 4 + chnMod4; + const bool b = (IsDlgButtonChecked(itemID)) ? true : false; + const CHANNELINDEX nChn = (CHANNELINDEX)(m_nActiveTab * 4) + chnMod4; pModDoc->SurroundChannel(nChn, b); pModDoc->UpdateAllViews(this, HINT_MODCHANNELS | (m_nActiveTab << HINT_SHIFT_CHNTAB)); } @@ -601,10 +601,10 @@ void CViewGlobals::OnSurround4() {OnSurround(3, IDC_CHECK8);} void CViewGlobals::OnEditVol(const CHANNELINDEX chnMod4, const UINT itemID) -//------------------------------------------------------------ +//------------------------------------------------------------------------- { CModDoc *pModDoc = GetDocument(); - const UINT nChn = m_nActiveTab * 4 + chnMod4; + const CHANNELINDEX nChn = (CHANNELINDEX)(m_nActiveTab * 4) + chnMod4; const int vol = GetDlgItemIntEx(itemID); if ((pModDoc) && (vol >= 0) && (vol <= 64) && (!m_nLockCount)) { @@ -623,10 +623,10 @@ void CViewGlobals::OnEditPan(const CHANNELINDEX chnMod4, const UINT itemID) -//-------------------------------------------------------- +//------------------------------------------------------------------------- { CModDoc *pModDoc = GetDocument(); - const UINT nChn = m_nActiveTab * 4 + chnMod4; + const CHANNELINDEX nChn = (CHANNELINDEX)(m_nActiveTab * 4) + chnMod4; const int pan = GetDlgItemIntEx(itemID); if ((pModDoc) && (pan >= 0) && (pan <= 256) && (!m_nLockCount)) { @@ -650,26 +650,26 @@ { CHAR s[64]; CModDoc *pModDoc; - UINT nChn; + CHANNELINDEX nChn; CFormView::OnHScroll(nSBCode, nPos, pScrollBar); pModDoc = GetDocument(); - nChn = m_nActiveTab * 4; + nChn = (CHANNELINDEX)(m_nActiveTab * 4); if ((pModDoc) && (!IsLocked()) && (nChn < MAX_BASECHANNELS)) { BOOL bUpdate = FALSE; short int pos; LockControls(); - const UINT nLoopLimit = min(4, pModDoc->GetSoundFile()->GetNumChannels() - nChn); - for (UINT iCh=0; iCh<nLoopLimit; iCh++) + const CHANNELINDEX nLoopLimit = min(4, pModDoc->GetSoundFile()->GetNumChannels() - nChn); + for (CHANNELINDEX iCh = 0; iCh < nLoopLimit; iCh++) { // Volume sliders pos = (short int)m_sbVolume[iCh].GetPos(); if ((pos >= 0) && (pos <= 64)) { - if (pModDoc->SetChannelGlobalVolume(nChn+iCh, pos)) + if (pModDoc->SetChannelGlobalVolume(nChn + iCh, pos)) { SetDlgItemInt(IDC_EDIT1+iCh*2, pos); bUpdate = TRUE; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-05 20:51:54 UTC (rev 388) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-10-06 12:44:31 UTC (rev 389) @@ -4486,6 +4486,8 @@ case 4: p->param = 0; break; //Param default: p->Clear(); //If not specified, delete them all! :) } + if((field == 3 || field == 4) && (p->note == NOTE_PC || p->note == NOTE_PCS)) + p->command = p->param = 0; if(IsEditingEnabled_bmsg()) { Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-05 20:51:54 UTC (rev 388) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-10-06 12:44:31 UTC (rev 389) @@ -771,8 +771,17 @@ } } else { - wsprintf(s, "[%02d] Skip", iOrd); + if(pSndFile->Order.GetSequence(nSeq)[iOrd] == pSndFile->Order.GetIgnoreIndex()) + { + // +++ Item + wsprintf(s, "[%02d] Skip", iOrd); + } else + { + // --- Item + wsprintf(s, "[%02d] Stop", iOrd); + } } + if (pInfo->tiOrders[nSeq][iOrd]) { tvi.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_STATE; @@ -1930,11 +1939,27 @@ switch(dwDropType) { case MODITEM_ORDER: + case MODITEM_SEQUENCE: if ((dwDragType == MODITEM_ORDER) && (pModDoc) && (m_nDocNdx == m_nDragDocNdx)) { if (bDoDrop) { - if (dwItemDrag != qwItemDrop) pModDoc->MoveOrder((ORDERINDEX)dwItemDrag, (ORDERINDEX)qwItemDrop, true); + SEQUENCEINDEX nSeqFrom = (SEQUENCEINDEX)(dwItemDrag >> 16), nSeqTo = (SEQUENCEINDEX)(qwItemDrop >> 16); + ORDERINDEX nOrdFrom = (ORDERINDEX)(dwItemDrag & 0xFFFF), nOrdTo = (ORDERINDEX)(qwItemDrop & 0xFFFF); + if(dwDropType == MODITEM_SEQUENCE) + { + // drop on sequence -> attach + nSeqTo = (SEQUENCEINDEX)(qwItemDrop & 0xFFFF); + nOrdTo = pModDoc->GetSoundFile()->Order.GetSequence(nSeqTo).GetLengthTailTrimmed(); + } + + if (nSeqFrom != nSeqTo || nOrdFrom != nOrdTo) + { + if(pModDoc->MoveOrder(nOrdFrom, nOrdTo, true, false, nSeqFrom, nSeqTo) == true) + { + pModDoc->SetModified(); + } + } } return TRUE; } @@ -2607,20 +2632,19 @@ pModDoc = GetDocumentFromItem(hItem); if (pModDoc) { - SAMPLEINDEX nSamples = pModDoc->GetNumSamples(); INSTRUMENTINDEX nInstruments = pModDoc->GetNumInstruments(); if ((qwItemType == MODITEM_SAMPLE) && (!nInstruments)) { - for (SAMPLEINDEX i=1; i<=nSamples; i++) + for (SAMPLEINDEX nSmp = 1; nSmp <= pModDoc->GetNumSamples(); nSmp++) { - pModDoc->MuteSample(i, (i == dwItemNo) ? false : true); + pModDoc->MuteSample(nSmp, (nSmp == dwItemNo) ? false : true); } } else if ((qwItemType == MODITEM_INSTRUMENT) && (nInstruments)) { - for (INSTRUMENTINDEX i=1; i<=nInstruments; i++) + for (INSTRUMENTINDEX nIns = 1; nIns <= nInstruments; nIns++) { - pModDoc->MuteInstrument(i, (i == dwItemNo) ? false : true); + pModDoc->MuteInstrument(nIns, (nIns == dwItemNo) ? false : true); } } } @@ -2638,17 +2662,15 @@ pModDoc = GetDocumentFromItem(hItem); if (pModDoc) { - SAMPLEINDEX nSamples = pModDoc->GetNumSamples(); - INSTRUMENTINDEX nInstruments = pModDoc->GetNumInstruments(); if ((qwItemType == MODITEM_SAMPLE) || (qwItemType == MODITEM_INSTRUMENT)) { - for (SAMPLEINDEX i=1; i<=nSamples; i++) + for (SAMPLEINDEX nSmp = 1; nSmp <= pModDoc->GetNumSamples(); nSmp++) { - pModDoc->MuteSample(i, FALSE); + pModDoc->MuteSample(nSmp, FALSE); } - for (INSTRUMENTINDEX j=1; j<=nInstruments; j++) + for (INSTRUMENTINDEX nIns = 1; nIns <= pModDoc->GetNumInstruments(); nIns++) { - pModDoc->MuteInstrument(j, FALSE); + pModDoc->MuteInstrument(nIns, FALSE); } } } Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-10-05 20:51:54 UTC (rev 388) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-10-06 12:44:31 UTC (rev 389) @@ -36,32 +36,38 @@ LTEXT "The following problems have been encountered when loading this module:",IDC_STATIC,6,6,237,8 END -IDD_CLEANUP_SONG DIALOGEX 0, 0, 262, 209 +IDD_CLEANUP_SONG DIALOGEX 0, 0, 370, 281 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Cleanup" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - DEFPUSHBUTTON "OK",IDOK,204,6,50,14 - PUSHBUTTON "Cancel",IDCANCEL,204,24,50,14 - GROUPBOX "Remove unused...",IDC_STATIC,6,6,192,42 - CONTROL "Patterns",IDC_CHK_CLEANUP_PATTERNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,18,90,10 - CONTROL "Samples",IDC_CHK_CLEANUP_SAMPLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,18,90,10 - CONTROL "Instruments",IDC_CHK_CLEANUP_INSTRUMENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,30,90,10 - CONTROL "Plugins",IDC_CHK_CLEANUP_PLUGINS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,30,90,10 - GROUPBOX "Remove all...",IDC_STATIC,6,54,192,54 - CONTROL "Patterns",IDC_CHK_REMOVE_PATTERNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,66,90,10 - CONTROL "Orders",IDC_CHK_REMOVE_ORDERS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,66,90,10 - CONTROL "Samples",IDC_CHK_REMOVE_SAMPLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,78,90,10 - CONTROL "Instruments",IDC_CHK_REMOVE_INSTRUMENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,78,90,10 - CONTROL "Plugins",IDC_CHK_REMOVE_PLUGINS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,90,90,10 - GROUPBOX "Misc.",IDC_STATIC,6,114,192,42 - CONTROL "Rearrange patterns",IDC_CHK_REARRANGE_PATTERNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,126,90,10 - CONTROL "Rearrange samples",IDC_CHK_REARRANGE_SAMPLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,126,90,10 - CONTROL "Optimize sample loops",IDC_CHK_OPTIMIZE_SAMPLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,138,90,10 - CONTROL "Reset all variables",IDC_CHK_RESET_VARIABLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,138,90,10 - GROUPBOX "Presets",IDC_STATIC,6,162,192,36 - PUSHBUTTON "Remove all unused stuff",IDC_BTN_CLEANUP_SONG,12,174,96,18 - PUSHBUTTON "Compo cleanup",IDC_BTN_COMPO_CLEANUP,114,174,78,18 + DEFPUSHBUTTON "OK",IDOK,306,6,60,14 + PUSHBUTTON "Cancel",IDCANCEL,306,24,60,14 + CONTROL "Remove unused",IDC_CHK_CLEANUP_PATTERNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,18,90,10 + CONTROL "Remove all",IDC_CHK_REMOVE_PATTERNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,108,18,90,10 + CONTROL "Rearrange",IDC_CHK_REARRANGE_PATTERNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,204,18,90,10 + CONTROL "Merge sequences",IDC_CHK_MERGE_SEQUENCES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,54,90,10 + CONTROL "Remove all orders",IDC_CHK_REMOVE_ORDERS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,108,54,90,10 + CONTROL "Remove unused",IDC_CHK_CLEANUP_SAMPLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,90,90,10 + CONTROL "Remove all",IDC_CHK_REMOVE_SAMPLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,108,90,90,10 + CONTROL "Rearrange",IDC_CHK_REARRANGE_SAMPLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,204,90,90,10 + CONTROL "Remove data after loop end",IDC_CHK_OPTIMIZE_SAMPLES, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,102,108,10 + CONTROL "Remove unused",IDC_CHK_CLEANUP_INSTRUMENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,138,90,10 + CONTROL "Remove all (convert to samples)",IDC_CHK_REMOVE_INSTRUMENTS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,108,138,120,10 + CONTROL "Remove unused",IDC_CHK_CLEANUP_PLUGINS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,174,90,10 + CONTROL "Remove all",IDC_CHK_REMOVE_PLUGINS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,108,174,90,10 + CONTROL "Reset all variables",IDC_CHK_RESET_VARIABLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,210,90,10 + PUSHBUTTON "Remove all unused stuff",IDC_BTN_CLEANUP_SONG,18,246,90,18 + PUSHBUTTON "Compo cleanup",IDC_BTN_COMPO_CLEANUP,120,246,90,18 + GROUPBOX "Patterns",IDC_STATIC,6,6,294,30 + GROUPBOX "Orders / Sequences",IDC_STATIC,6,42,294,30 + GROUPBOX "Samples",IDC_STATIC,6,78,294,42 + GROUPBOX "Instruments",IDC_STATIC,6,126,294,30 + GROUPBOX "Plugins",IDC_STATIC,6,162,294,30 + GROUPBOX "Miscellaneous",IDC_STATIC,6,198,294,30 + GROUPBOX "Presets",IDC_STATIC,6,234,294,36 END @@ -84,9 +90,9 @@ IDD_CLEANUP_SONG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 255 + RIGHTMARGIN, 363 TOPMARGIN, 7 - BOTTOMMARGIN, 202 + BOTTOMMARGIN, 274 END END #endif // APSTUDIO_INVOKED Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-10-05 20:51:54 UTC (rev 388) +++ trunk/OpenMPT/mptrack/resource.h 2009-10-06 12:44:31 UTC (rev 389) @@ -907,6 +907,7 @@ #define IDC_CHK_REMOVE_SAMPLES 2404 #define IDC_CHK_REMOVE_PLUGINS 2405 #define IDC_CHK_OPTIMIZE_SAMPLES 2406 +#define IDC_CHK_MERGE_SEQUENCES 2408 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1151,7 +1152,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 522 #define _APS_NEXT_COMMAND_VALUE 59231 -#define _APS_NEXT_CONTROL_VALUE 2407 +#define _APS_NEXT_CONTROL_VALUE 2409 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |