From: <sag...@us...> - 2009-08-18 18:41:23
|
Revision: 331 http://modplug.svn.sourceforge.net/modplug/?rev=331&view=rev Author: saga-games Date: 2009-08-18 18:41:12 +0000 (Tue, 18 Aug 2009) Log Message: ----------- [New] Pattern editor: Multiple orders can be selected in the pattern sequence. At the moment, it is possible to insert, delete, duplicate and dragondrop multiple orders. [Ref] Redesigned a few functions and stuff to make this new feature work; Replace UINT/DWORD/whatever by ORDERINDEX/PATTERNINDEX and BOOL by bool where appropriate [Fix] Moving orders (when duplicating them) should be aware of the max. possible order now. [Fix] 669 Loader: Small modification so corehop.669 can be loaded; Note: Loader is still buggy like hell [Imp] Added tests for bitshifting version numbers Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_pat.h trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/test/test.cpp trunk/OpenMPT/mptrack/typedefs.h trunk/OpenMPT/soundlib/Load_669.cpp trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-16 22:47:01 UTC (rev 330) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-18 18:41:12 UTC (rev 331) @@ -408,7 +408,7 @@ case CTRLMSG_SETCURRENTORDER: //Set orderlist selection and refresh GUI if change successful - m_OrderList.SetCurSel(lParam, FALSE); + m_OrderList.SetCurSel((ORDERINDEX)lParam, FALSE); break; case CTRLMSG_FORCEREFRESH: @@ -417,7 +417,7 @@ break; case CTRLMSG_GETCURRENTORDER: - return m_OrderList.GetCurSel(); + return m_OrderList.GetCurSel(true).nOrdLo; case CTRLMSG_SETCURRENTINSTRUMENT: case CTRLMSG_PAT_SETINSTRUMENT: @@ -472,11 +472,11 @@ break; case CTRLMSG_PREVORDER: - m_OrderList.SetCurSel(m_OrderList.GetCurSel()-1, TRUE); + m_OrderList.SetCurSel(m_OrderList.GetCurSel(true).nOrdLo - 1, TRUE); break; case CTRLMSG_NEXTORDER: - m_OrderList.SetCurSel(m_OrderList.GetCurSel()+1, TRUE); + m_OrderList.SetCurSel(m_OrderList.GetCurSel(true).nOrdLo + 1, TRUE); break; //rewbs.customKeys @@ -582,7 +582,7 @@ { if (pSndFile) { - for (UINT i=0; i<pSndFile->Order.size(); i++) + for (ORDERINDEX i=0; i<pSndFile->Order.size(); i++) { if (pSndFile->Order[i] == (UINT)lParam) { @@ -599,7 +599,7 @@ if (pSndFile) { lParam &= 0x7FFF; - m_OrderList.SetCurSel(lParam); + m_OrderList.SetCurSel((ORDERINDEX)lParam); SetCurrentPattern(pSndFile->Order[lParam]); } } @@ -652,7 +652,7 @@ void CCtrlPatterns::OnSequencePrev() //---------------------------------- { - m_OrderList.SetCurSel(m_OrderList.GetCurSel()-1); + m_OrderList.SetCurSel(m_OrderList.GetCurSel(true).nOrdLo - 1); m_OrderList.SetFocus(); } @@ -660,7 +660,7 @@ void CCtrlPatterns::OnSequenceNext() //---------------------------------- { - m_OrderList.SetCurSel(m_OrderList.GetCurSel()+1); + m_OrderList.SetCurSel(m_OrderList.GetCurSel(true).nOrdLo + 1); m_OrderList.SetFocus(); } @@ -844,18 +844,18 @@ if (m_pModDoc) { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - UINT nCurOrd = m_OrderList.GetCurSel(); - UINT pat = pSndFile->Order[nCurOrd]; - UINT rows = 64; + ORDERINDEX nCurOrd = m_OrderList.GetCurSel(true).nOrdLo; + PATTERNINDEX pat = pSndFile->Order[nCurOrd]; + ROWINDEX rows = 64; if ((pat < pSndFile->Patterns.Size()) && (pSndFile->Patterns[pat]) && (pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT))) { rows = pSndFile->PatternSize[pat]; if (rows < 32) rows = 32; } - LONG nNewPat = m_pModDoc->InsertPattern(nCurOrd+1, rows); + PATTERNINDEX nNewPat = m_pModDoc->InsertPattern(nCurOrd + 1, rows); if ((nNewPat >= 0) && (nNewPat < pSndFile->Patterns.Size())) { - m_OrderList.SetCurSel(nCurOrd+1); + m_OrderList.SetCurSel(nCurOrd + 1); m_OrderList.InvalidateRect(NULL, FALSE); SetCurrentPattern(nNewPat); m_pModDoc->SetModified(); @@ -869,35 +869,67 @@ void CCtrlPatterns::OnPatternDuplicate() //-------------------------------------- { + // duplicates one or more patterns. if (m_pModDoc) { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - UINT nCurOrd = m_OrderList.GetCurSel(); - UINT nCurPat = pSndFile->Order[nCurOrd]; - UINT rows = 64; - if (nCurPat < pSndFile->Patterns.Size()) + ORD_SELECTION selection = m_OrderList.GetCurSel(false); + ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo; + ORDERINDEX nInsertWhere = selection.nOrdLo + nInsertCount + 1; + bool bSuccess = false; + // has this pattern been duplicated already? (for multiselect) + PATTERNINDEX pReplaceIndex[MAX_PATTERNS]; // TODO I think this is a bit much... + memset(&pReplaceIndex, PATTERNINDEX_INVALID, sizeof(PATTERNINDEX) * MAX_PATTERNS); + + for(ORDERINDEX i = 0; i <= nInsertCount; i++) { - if ((pSndFile->Patterns[nCurPat]) && (pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT))) + PATTERNINDEX nCurPat = pSndFile->Order[selection.nOrdLo + i]; + ROWINDEX rows = 64; + if (nCurPat < pSndFile->Patterns.Size() && pReplaceIndex[nCurPat] == PATTERNINDEX_INVALID) { - rows = pSndFile->PatternSize[nCurPat]; - if (rows < pSndFile->GetModSpecifications().patternRowsMin) rows = pSndFile->GetModSpecifications().patternRowsMin; + if ((pSndFile->Patterns[nCurPat]) && (pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT))) + { + rows = pSndFile->PatternSize[nCurPat]; + if (rows < pSndFile->GetModSpecifications().patternRowsMin) rows = pSndFile->GetModSpecifications().patternRowsMin; + } + PATTERNINDEX nNewPat = m_pModDoc->InsertPattern(nInsertWhere + i, rows); + if ((nNewPat >= 0) && (nNewPat < pSndFile->Patterns.Size())) + { + MODCOMMAND *pSrc = pSndFile->Patterns[nCurPat]; + MODCOMMAND *pDest = pSndFile->Patterns[nNewPat]; + UINT n = pSndFile->PatternSize[nCurPat]; + if (pSndFile->PatternSize[nNewPat] < n) n = pSndFile->PatternSize[nNewPat]; + n *= pSndFile->m_nChannels; + if (n) memcpy(pDest, pSrc, n * sizeof(MODCOMMAND)); + bSuccess = true; + pReplaceIndex[nCurPat] = nNewPat; // mark as duplicated + } + else + { + break; + } } - LONG nNewPat = m_pModDoc->InsertPattern(nCurOrd+1, rows); - if ((nNewPat >= 0) && (nNewPat < pSndFile->Patterns.Size())) + else { - MODCOMMAND *pSrc = pSndFile->Patterns[nCurPat]; - MODCOMMAND *pDest = pSndFile->Patterns[nNewPat]; - UINT n = pSndFile->PatternSize[nCurPat]; - if (pSndFile->PatternSize[nNewPat] < n) n = pSndFile->PatternSize[nNewPat]; - n *= pSndFile->m_nChannels; - if (n) memcpy(pDest, pSrc, n * sizeof(MODCOMMAND)); - m_OrderList.SetCurSel(nCurOrd+1); - m_OrderList.InvalidateRect(NULL, FALSE); - SetCurrentPattern(nNewPat); - m_pModDoc->SetModified(); - m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE|HINT_PATNAMES, this); + // invalid pattern, or it has been duplicated before (multiselect) + for (int j = pSndFile->Order.size() - 1; j > selection.nOrdLo + i + nInsertCount + 1; j--) pSndFile->Order[j] = pSndFile->Order[j - 1]; + PATTERNINDEX nNewPat; + if(nCurPat < pSndFile->Patterns.Size() && pReplaceIndex[nCurPat] != PATTERNINDEX_INVALID) + nNewPat = pReplaceIndex[nCurPat]; // take care of patterns that have been duplicated before + else + nNewPat= pSndFile->Order[selection.nOrdLo + i]; + pSndFile->Order[selection.nOrdLo + i + nInsertCount + 1] = nNewPat; } } + if(bSuccess) + { + m_OrderList.InvalidateRect(NULL, FALSE); + m_OrderList.SetCurSel(nInsertWhere); + SetCurrentPattern(pSndFile->Order[nInsertWhere]); + m_pModDoc->SetModified(); + m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE|HINT_PATNAMES, this); + if(selection.nOrdHi != selection.nOrdLo) m_OrderList.m_nScrollPos2nd = nInsertWhere + nInsertCount; + } } SwitchToView(); } Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-08-16 22:47:01 UTC (rev 330) +++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-08-18 18:41:12 UTC (rev 331) @@ -5,6 +5,12 @@ class COrderList; class CCtrlPatterns; +struct ORD_SELECTION +{ + ORDERINDEX nOrdLo; + ORDERINDEX nOrdHi; +}; + //=========================== class COrderList: public CWnd //=========================== @@ -13,14 +19,17 @@ protected: HFONT m_hFont; COLORREF colorText, colorTextSel; - //m_nXScroll : The order at the beginning of shown orderlist? - //m_nScrollPos: The same as order? - int m_cxFont, m_cyFont, m_nXScroll, m_nScrollPos, m_nDropPos; + int m_cxFont, m_cyFont; + //m_nXScroll : The order at the beginning of shown orderlist + //m_nScrollPos: The same as order + //m_nScrollPos2nd: 2nd selection point if multiple orders are selected + // (not neccessarily the higher order - GetCurSel() is taking care of that.) + ORDERINDEX m_nXScroll, m_nScrollPos, m_nScrollPos2nd, m_nDropPos; + bool m_bScrolling, m_bDragging, m_bShift; + ORDERINDEX m_nDragOrder; //To tell how many orders('orderboxes') to show at least //on both sides of current order(when updating orderslist position). BYTE m_nOrderlistMargins; - UINT m_nDragOrder; - BOOL m_bScrolling, m_bDragging, m_bShift; CModDoc *m_pModDoc; CCtrlPatterns *m_pParent; @@ -33,9 +42,9 @@ public: BOOL Init(const CRect&, CCtrlPatterns *pParent, CModDoc *, HFONT hFont); void InvalidateSelection() const; - int GetCurSel() const { return m_nScrollPos; } UINT GetCurrentPattern() const; - BOOL SetCurSel(int sel, BOOL bEdit=TRUE); + ORD_SELECTION GetCurSel(bool bIgnoreSelection) const; + bool SetCurSel(ORDERINDEX sel, bool bEdit = true, bool bShiftClick = false); BOOL ProcessKeyDown(UINT nChar); BOOL ProcessChar(UINT nChar); BOOL UpdateScrollInfo(); Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-16 22:47:01 UTC (rev 330) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-18 18:41:12 UTC (rev 331) @@ -5,7 +5,6 @@ #include "globals.h" #include "ctrl_pat.h" #include "view_pat.h" -#include ".\ctrl_pat.h" ////////////////////////////////////////////////////////////// // CPatEdit @@ -75,14 +74,15 @@ //---------------------- { m_hFont = NULL; - m_pParent = NULL; + m_pParent = nullptr; m_cxFont = m_cyFont = 0; - m_pModDoc = NULL; + m_pModDoc = nullptr; m_nScrollPos = m_nXScroll = 0; + m_nScrollPos2nd = ORDERINDEX_INVALID; m_nOrderlistMargins = s_nDefaultMargins; - m_bScrolling = FALSE; - m_bDragging = FALSE; - m_bShift = FALSE; + m_bScrolling = false; + m_bDragging = false; + m_bShift = false; } @@ -159,11 +159,27 @@ void COrderList::InvalidateSelection() const //------------------------------------------ { + ORDERINDEX nOrdLo = m_nScrollPos, nCount = 1; + static ORDERINDEX m_nScrollPos2Old = m_nScrollPos2nd; + if(m_nScrollPos2Old != ORDERINDEX_INVALID) + { + // there were multiple orders selected - remove them all + ORDERINDEX nOrdHi = m_nScrollPos; + if(m_nScrollPos2Old < m_nScrollPos) + { + nOrdLo = m_nScrollPos2Old; + } else + { + nOrdHi = m_nScrollPos2Old; + } + nCount = nOrdHi - nOrdLo + 1; + } + m_nScrollPos2Old = m_nScrollPos2nd; CRect rcClient, rect; GetClientRect(&rcClient); - rect.left = rcClient.left + (m_nScrollPos - m_nXScroll) * m_cxFont; + rect.left = rcClient.left + (nOrdLo - m_nXScroll) * m_cxFont; rect.top = rcClient.top; - rect.right = rect.left + m_cxFont; + rect.right = rect.left + m_cxFont * nCount; rect.bottom = rcClient.bottom; if (rect.right > rcClient.right) rect.right = rcClient.right; if (rect.left < rcClient.left) rect.left = rcClient.left; @@ -186,34 +202,51 @@ } -BOOL COrderList::SetCurSel(int sel, BOOL bEdit) -//--------------------------------------------- +ORD_SELECTION COrderList::GetCurSel(bool bIgnoreSelection) const +//-------------------------------------------------------------- { + // returns the currently selected order(s) + ORD_SELECTION result; + result.nOrdLo = result.nOrdHi = m_nScrollPos; + // bIgnoreSelection: true if only first selection marker is important. + if(!bIgnoreSelection && m_nScrollPos2nd != ORDERINDEX_INVALID) { + if(m_nScrollPos2nd < m_nScrollPos) // ord2 < ord1 + result.nOrdLo = m_nScrollPos2nd; + else + result.nOrdHi = m_nScrollPos2nd; + } + return result; +} + +bool COrderList::SetCurSel(ORDERINDEX sel, bool bEdit, bool bShiftClick) +//---------------------------------------------------------------------- +{ CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + ORDERINDEX *nOrder = (bShiftClick) ? &m_nScrollPos2nd : &m_nScrollPos; - if ((sel < 0) || (sel >= int(pSndFile->Order.size())) || (!m_pParent) || (!pMainFrm)) return FALSE; - if (sel == m_nScrollPos) return TRUE; + if ((sel < 0) || (sel >= int(pSndFile->Order.size())) || (!m_pParent) || (!pMainFrm)) return false; + if (sel == *nOrder) return true; const BYTE nShownLength = GetLength(); InvalidateSelection(); - m_nScrollPos = sel; + *nOrder = sel; if (!m_bScrolling) { const BYTE nMargins = GetMargins(GetMarginsMax(nShownLength)); - if ((m_nScrollPos < m_nXScroll + nMargins) || (!m_cxFont) || (!m_cyFont)) + if ((*nOrder < m_nXScroll + nMargins) || (!m_cxFont) || (!m_cyFont)) { // Must move first shown sequence item to left in order to show // the new active order. - m_nXScroll = max(0, m_nScrollPos - nMargins); + m_nXScroll = max(0, *nOrder - nMargins); SetScrollPos(SB_HORZ, m_nXScroll); InvalidateRect(NULL, FALSE); } else { - int maxsel = nShownLength; + ORDERINDEX maxsel = nShownLength; if (maxsel) maxsel--; - if (m_nScrollPos - m_nXScroll >= maxsel - nMargins) + if (*nOrder - m_nXScroll >= maxsel - nMargins) { // Must move first shown sequence item to right in order to show // the new active order. - m_nXScroll = m_nScrollPos - (maxsel - nMargins); + m_nXScroll = *nOrder - (maxsel - nMargins); SetScrollPos(SB_HORZ, m_nXScroll); InvalidateRect(NULL, FALSE); } @@ -223,7 +256,7 @@ if ((m_pParent) && (m_pModDoc) && (bEdit)) { UINT n = pSndFile->Order[m_nScrollPos]; - if ((n < pSndFile->Patterns.Size()) && (pSndFile->Patterns[n])) + if ((n < pSndFile->Patterns.Size()) && (pSndFile->Patterns[n]) && !bShiftClick) { BOOL bIsPlaying = (pMainFrm->GetModPlaying() == m_pModDoc); if ((bIsPlaying) && (pSndFile->m_dwSongFlags & SONG_PATTERNLOOP)) @@ -251,7 +284,8 @@ } } UpdateInfoText(); - return TRUE; + if(m_nScrollPos == m_nScrollPos2nd) m_nScrollPos2nd = ORDERINDEX_INVALID; + return true; } @@ -273,15 +307,15 @@ switch(nChar) { case VK_UP: - case VK_LEFT: SetCurSel(m_nScrollPos-1); break; + case VK_LEFT: SetCurSel(m_nScrollPos - 1); break; case VK_DOWN: - case VK_RIGHT: SetCurSel(m_nScrollPos+1); break; + case VK_RIGHT: SetCurSel(m_nScrollPos + 1); break; case VK_HOME: SetCurSel(0); break; case VK_END: if (m_pModDoc) { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - int i = 0; + ORDERINDEX i = 0; const int nSeqLength = pSndFile->Order.size(); for (i=0; i+1 < nSeqLength; i++) if (pSndFile->Order[i+1] == pSndFile->Order.GetInvalidPatIndex()) break; SetCurSel(i); @@ -492,12 +526,14 @@ CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); GetClientRect(&rcClient); rect = rcClient; - int nIndex = m_nXScroll; + ORDERINDEX nIndex = m_nXScroll; + ORD_SELECTION selection = GetCurSel(false); + //Scrolling the shown orders(the showns rectangles)? while (rect.left < rcClient.right) { - BOOL bHighLight = ((bFocus) && (nIndex == m_nScrollPos)) ? TRUE : FALSE; - int nOrder = ((nIndex >= 0) && (nIndex < int(pSndFile->Order.size()))) ? pSndFile->Order[nIndex] : -1; + bool bHighLight = ((bFocus) && (nIndex >= selection.nOrdLo && nIndex <= selection.nOrdHi)) ? true : false; + ORDERINDEX nOrder = ((nIndex >= 0) && (nIndex < int(pSndFile->Order.size()))) ? pSndFile->Order[nIndex] : -1; if ((rect.right = rect.left + m_cxFont) > rcClient.right) rect.right = rcClient.right; rect.right--; if (bHighLight) { @@ -586,10 +622,12 @@ if (ih->CtrlPressed()) { + // queue pattern + //m_nScrollPos2nd = ORDERINDEX_INVALID; if (m_pModDoc) { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - int nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont; + ORDERINDEX nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont; if ((nOrder >= 0) && (nOrder < int(pSndFile->Order.size()))) { if (pSndFile->m_nSeqOverride == static_cast<UINT>(nOrder)+1) { @@ -602,12 +640,22 @@ } } else { + // mark pattern (+skip to) const int oldXScroll = m_nXScroll; - SetCurSel(m_nXScroll + (pt.x - rect.left) / m_cxFont); - m_bDragging = IsOrderInMargins(m_nScrollPos, oldXScroll) ? FALSE : TRUE; - if(m_bDragging == TRUE) + + ORDERINDEX nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont; + ORD_SELECTION selection = GetCurSel(false); + + // check if cursor is in selection - if it is, only react on MouseUp as the user might want to drag those orders + if(m_nScrollPos2nd == ORDERINDEX_INVALID || nOrder < selection.nOrdLo || nOrder > selection.nOrdHi) { - m_nDragOrder = GetCurSel(); + m_nScrollPos2nd = ORDERINDEX_INVALID; + SetCurSel(nOrder, true, ih->ShiftPressed()); + } + m_bDragging = IsOrderInMargins(m_nScrollPos, oldXScroll) ? false : true; + if(m_bDragging == true) + { + m_nDragOrder = GetCurSel(true).nOrdLo; m_nDropPos = m_nDragOrder; SetCapture(); } @@ -622,25 +670,68 @@ void COrderList::OnLButtonUp(UINT nFlags, CPoint pt) //-------------------------------------------------- { + CRect rect; + GetClientRect(&rect); + if (m_bDragging) { - CRect rect; - - m_bDragging = FALSE; + m_bDragging = false; ReleaseCapture(); - GetClientRect(&rect); if (rect.PtInRect(pt)) { int n = m_nXScroll + (pt.x - rect.left) / m_cxFont; if ((n >= 0) && (n == m_nDropPos) && (m_pModDoc)) { - if (m_nDragOrder == (UINT)m_nDropPos) return; - if (m_pModDoc->MoveOrder(m_nDragOrder, m_nDropPos, TRUE, m_bShift)) + // drag multiple orders (not quite as easy...) + ORD_SELECTION selection = GetCurSel(false); + // move how many orders from where? + ORDERINDEX nMoveCount = (selection.nOrdHi - selection.nOrdLo), nMovePos = selection.nOrdLo; + // drop before or after the selection + bool bMoveBack = !(m_nDragOrder < (UINT)m_nDropPos); + // don't do anything if drop position is inside the selection + if(m_nDropPos >= selection.nOrdLo && m_nDropPos <= selection.nOrdHi) return; + // drag or order or multiple orders? + bool bMultiSelection = (selection.nOrdLo != selection.nOrdHi); + + for(int i = 0; i <= nMoveCount; i++) { - SetCurSel(((m_nDragOrder < (UINT)m_nDropPos) && (!m_bShift)) ? m_nDropPos-1 : m_nDropPos); - m_pModDoc->SetModified(); + if(!m_pModDoc->MoveOrder(nMovePos, m_nDropPos, true, m_bShift)) return; + if((bMoveBack ^ m_bShift) == true && bMultiSelection) + { + nMovePos++; + m_nDropPos++; + } + if(bMoveBack && m_bShift && bMultiSelection) { + nMovePos += 2; + m_nDropPos++; + } } + if(bMultiSelection) + { + // adjust selection + m_nScrollPos2nd = m_nDropPos - 1; + m_nDropPos -= nMoveCount + (bMoveBack ? 0 : 1); + SetCurSel((bMoveBack && (!m_bShift)) ? m_nDropPos - 1 : m_nDropPos); + } else + { + SetCurSel(((m_nDragOrder < (UINT)m_nDropPos) && (!m_bShift)) ? m_nDropPos - 1 : m_nDropPos); + } + m_pModDoc->SetModified(); } + else + { + ORDERINDEX nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont; + ORD_SELECTION selection = GetCurSel(false); + + // this should actually have equal signs but that breaks multiselect: nOrder >= selection.nOrdLo && nOrder <= section.nOrdHi + if (pt.y < rect.bottom && m_nScrollPos2nd != ORDERINDEX_INVALID && nOrder > selection.nOrdLo && nOrder < selection.nOrdHi) + { + // Remove selection if we didn't drag anything but multiselect was active + m_nScrollPos2nd = ORDERINDEX_INVALID; + SetFocus(); + SetCurSel(m_nXScroll + (pt.x - rect.left) / m_cxFont); + } + } } InvalidateRect(NULL, FALSE); } else @@ -658,11 +749,12 @@ CRect rect; GetClientRect(&rect); - int n = -1; + ORDERINDEX n = ORDERINDEX_INVALID; if (rect.PtInRect(pt)) { + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); n = m_nXScroll + (pt.x - rect.left) / m_cxFont; - if ((n < 0) || (n >= int(m_pModDoc->GetSoundFile()->Order.size()))) n = -1; + if (n >= int(pSndFile->Order.size()) || n >= pSndFile->GetModSpecifications().ordersMax) n = ORDERINDEX_INVALID; } if (n != (int)m_nDropPos) { @@ -673,7 +765,7 @@ SetCursor(CMainFrame::curDragging); } else { - m_nDropPos = -1; + m_nDropPos = ORDERINDEX_INVALID; SetCursor(CMainFrame::curNoDrop); } } @@ -691,39 +783,59 @@ GetClientRect(&rect); if (m_bDragging) { - m_nDropPos = -1; + m_nDropPos = ORDERINDEX_INVALID; OnLButtonUp(nFlags, pt); } - if (pt.y < rect.bottom) + if (pt.y >= rect.bottom) return; + + CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); + + bool bMultiSelection = (m_nScrollPos2nd != ORDERINDEX_INVALID); + + if(!bMultiSelection) SetCurSel(m_nXScroll + (pt.x - rect.left) / m_cxFont); + SetFocus(); + HMENU hMenu = ::CreatePopupMenu(); + if(!hMenu) return; + + // check if at least one pattern in the current selection exists + bool bPatternExists = false; + ORD_SELECTION selection = GetCurSel(false); + for(ORDERINDEX nOrd = selection.nOrdLo; nOrd <= selection.nOrdHi; nOrd++) { - SetCurSel(m_nXScroll + (pt.x - rect.left) / m_cxFont); - SetFocus(); - HMENU hMenu = ::CreatePopupMenu(); - - UINT nCurrentPattern = GetCurrentPattern(); - bool patternExists = (nCurrentPattern < m_pModDoc->GetSoundFile()->Patterns.Size() - && m_pModDoc->GetSoundFile()->Patterns[nCurrentPattern] != NULL); - DWORD greyed = patternExists?FALSE:MF_GRAYED; + bPatternExists = ((pSndFile->Order[nOrd] < pSndFile->Patterns.Size()) + && (pSndFile->Patterns[pSndFile->Order[nOrd]] != nullptr)); + if(bPatternExists) break; + } - if (hMenu) + DWORD greyed = bPatternExists ? 0 : MF_GRAYED; + + if(bMultiSelection) + { + // several patterns are selected. + AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_INSERT, "&Insert Patterns\tIns"); + AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_DELETE, "&Remove Patterns\tDel"); + AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); + AppendMenu(hMenu, MF_STRING | greyed, ID_ORDERLIST_COPY, "&Duplicate Patterns"); + } + else + { + // only one pattern is selected + AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_INSERT, "&Insert Pattern\tIns"); + AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_DELETE, "&Remove Pattern\tDel"); + AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); + AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_NEW, "Create &New Pattern"); + AppendMenu(hMenu, MF_STRING | greyed, ID_ORDERLIST_COPY, "&Duplicate Pattern"); + AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERNCOPY, "&Copy Pattern"); + AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERNPASTE, "P&aste Pattern"); + if ((m_pModDoc) && (m_pModDoc->GetSoundFile()->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT))) { - AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_INSERT, "&Insert Pattern\tIns"); - AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_DELETE, "&Remove Pattern\tDel"); AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); - AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_NEW, "Create &New Pattern"); - AppendMenu(hMenu, MF_STRING|greyed, ID_ORDERLIST_COPY, "&Duplicate Pattern"); - AppendMenu(hMenu, MF_STRING|greyed, ID_PATTERNCOPY, "&Copy Pattern"); - AppendMenu(hMenu, MF_STRING|greyed, ID_PATTERNPASTE, "P&aste Pattern"); - if ((m_pModDoc) && (m_pModDoc->GetSoundFile()->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT))) - { - AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); - AppendMenu(hMenu, MF_STRING|greyed, ID_PATTERN_PROPERTIES, "&Properties..."); - } - ClientToScreen(&pt); - ::TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL); - ::DestroyMenu(hMenu); + AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERN_PROPERTIES, "&Properties..."); } } + ClientToScreen(&pt); + ::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL); + ::DestroyMenu(hMenu); } @@ -732,6 +844,8 @@ { if ((m_pModDoc) && (m_pParent)) { + m_nScrollPos2nd = ORDERINDEX_INVALID; + SetFocus(); CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); m_pParent->SetCurrentPattern(pSndFile->Order[m_nScrollPos]); } @@ -741,11 +855,11 @@ void COrderList::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar*) //-------------------------------------------------------------- { - UINT nNewPos = m_nXScroll; + ORDERINDEX nNewPos = m_nXScroll; UINT smin, smax; GetScrollRange(SB_HORZ, (LPINT)&smin, (LPINT)&smax); - m_bScrolling = TRUE; + m_bScrolling = true; switch(nSBCode) { case SB_LEFT: nNewPos = 0; break; @@ -755,7 +869,7 @@ case SB_PAGERIGHT: if (nNewPos+4 < smax) nNewPos += 4; else nNewPos = smax; break; case SB_THUMBTRACK: case SB_THUMBPOSITION: nNewPos = nPos; if (nNewPos & 0xFFFF8000) nNewPos = smin; break; - case SB_ENDSCROLL: m_bScrolling = FALSE; break; + case SB_ENDSCROLL: m_bScrolling = false; break; } if (nNewPos > smax) nNewPos = smax; if (nNewPos != (UINT)m_nXScroll) @@ -770,12 +884,13 @@ void COrderList::OnSize(UINT nType, int cx, int cy) //------------------------------------------------- { - int smin, smax, nPos; + ORDERINDEX nPos; + int smin, smax; CWnd::OnSize(nType, cx, cy); UpdateScrollInfo(); GetScrollRange(SB_HORZ, &smin, &smax); - nPos = (short int)GetScrollPos(SB_HORZ); + nPos = (ORDERINDEX)GetScrollPos(SB_HORZ); if (nPos > smax) nPos = smax; if (m_nXScroll != nPos) { @@ -789,17 +904,34 @@ void COrderList::OnInsertOrder() //------------------------------ { + // insert the same order(s) after the currently selected order(s) if (m_pModDoc) { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - //Checking whether there is some pattern at the end of orderlist. - if(pSndFile->Order[pSndFile->Order.size()-1] < pSndFile->Patterns.Size()) + ORD_SELECTION selection = GetCurSel(false); + ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo, nInsertEnd = selection.nOrdHi; + + for(int i = 0; i <= nInsertCount; i++) { - if(pSndFile->Order.size() < pSndFile->GetModSpecifications().ordersMax) - pSndFile->Order.push_back(pSndFile->Order.GetInvalidPatIndex()); + + //Checking whether there is some pattern at the end of orderlist. + if(pSndFile->Order[pSndFile->Order.size() - 1] < pSndFile->Patterns.Size()) + { + if(pSndFile->Order.size() < pSndFile->GetModSpecifications().ordersMax) + pSndFile->Order.push_back(pSndFile->Order.GetInvalidPatIndex()); + } + + for (int i=pSndFile->Order.size() - 1; i>nInsertEnd; i--) pSndFile->Order[i] = pSndFile->Order[i - 1]; } - for (int i=pSndFile->Order.size()-1; i>m_nScrollPos; i--) pSndFile->Order[i] = pSndFile->Order[i-1]; + // now that there is enough space in the order list, overwrite the orders + for(ORDERINDEX i = 0; i <= nInsertCount; i++) + { + if(nInsertEnd + i + 1 < pSndFile->GetModSpecifications().ordersMax) + pSndFile->Order[nInsertEnd + i + 1] = pSndFile->Order[nInsertEnd - nInsertCount + i]; + } + m_nScrollPos = nInsertEnd + 1; + m_nScrollPos2nd = m_nScrollPos + nInsertCount; InvalidateRect(NULL, FALSE); m_pModDoc->SetModified(); m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this); @@ -814,14 +946,22 @@ { CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); - m_pModDoc->RemoveOrder(m_nScrollPos); + ORD_SELECTION selection = GetCurSel(false); + // remove selection + m_nScrollPos2nd = ORDERINDEX_INVALID; + + for(int i = 0; i <= (selection.nOrdHi - selection.nOrdLo); i++) + { + m_pModDoc->RemoveOrder(selection.nOrdLo); + } InvalidateRect(NULL, FALSE); m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this); - UINT nNewOrd = pSndFile->Order[m_nScrollPos]; - if ((nNewOrd < pSndFile->Patterns.Size()) && (pSndFile->Patterns[nNewOrd]) && (m_pParent)) + SetCurSel(selection.nOrdLo); + PATTERNINDEX nNewPat = pSndFile->Order[selection.nOrdLo]; + if ((nNewPat < pSndFile->Patterns.Size()) && (pSndFile->Patterns[nNewPat] != nullptr) && (m_pParent)) { - m_pParent->SetCurrentPattern(nNewOrd); + m_pParent->SetCurrentPattern(nNewPat); } } } @@ -938,7 +1078,7 @@ InvalidateRect(NULL, FALSE); m_pModDoc->SetModified(); m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this); - SetCurSel(posdest, TRUE); + SetCurSel(posdest, true); } return bCanDrop; } Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2009-08-16 22:47:01 UTC (rev 330) +++ trunk/OpenMPT/mptrack/Moddoc.h 2009-08-18 18:41:12 UTC (rev 331) @@ -197,14 +197,14 @@ void RearrangeSampleList(); BOOL CompoCleanup(); - LONG InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64); - LONG InsertSample(BOOL bLimit=FALSE); - LONG InsertInstrument(LONG lSample=0, LONG lDuplicate=0); + PATTERNINDEX InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64); + SAMPLEINDEX InsertSample(bool bLimit = false); + INSTRUMENTINDEX InsertInstrument(LONG lSample=0, LONG lDuplicate=0); void InitializeInstrument(MODINSTRUMENT *pIns, UINT nsample=0); - BOOL RemoveOrder(UINT n); - BOOL RemovePattern(UINT n); - BOOL RemoveSample(UINT n); - BOOL RemoveInstrument(UINT n); + bool RemoveOrder(ORDERINDEX n); + bool RemovePattern(PATTERNINDEX n); + bool RemoveSample(SAMPLEINDEX n); + bool RemoveInstrument(INSTRUMENTINDEX n); UINT PlayNote(UINT note, UINT nins, UINT nsmp, BOOL bpause, LONG nVol=-1, LONG loopstart=0, LONG loopend=0, int nCurrentChn=-1, const uint32 nStartPos = uint32_max); //rewbs.vstiLive: added current chan param BOOL NoteOff(UINT note, BOOL bFade=FALSE, UINT nins=-1, UINT nCurrentChn=-1); //rewbs.vstiLive: add params @@ -240,7 +240,7 @@ BOOL IsChildSample(UINT nIns, UINT nSmp) const; UINT FindSampleParent(UINT nSmp) const; UINT FindInstrumentChild(UINT nIns) const; - BOOL MoveOrder(UINT nSourceNdx, UINT nDestNdx, BOOL bUpdate=TRUE, BOOL bCopy=FALSE); + bool MoveOrder(UINT nSourceNdx, UINT nDestNdx, bool bUpdate = true, bool bCopy = false); BOOL ExpandPattern(PATTERNINDEX nPattern); BOOL ShrinkPattern(PATTERNINDEX nPattern); BOOL CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-16 22:47:01 UTC (rev 330) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-18 18:41:12 UTC (rev 331) @@ -1046,6 +1046,81 @@ } + + +void CModDoc::RearrangeSampleList() +//--------------------------------- +{ + if(m_SndFile.m_nSamples < 2) + return; + + UINT nRemap = 0; // remap count + UINT nSampleMap[MAX_SAMPLES + 1]; // map old => new + for(UINT i = 0; i <= MAX_SAMPLES; i++) + nSampleMap[i] = i; + + // First, find out which sample slots are unused and create the new sample map + for(UINT i = 1 ; i <= m_SndFile.m_nSamples; i++) { + if(!m_SndFile.Samples[i].pSample) + { + // Move all following samples + nRemap++; + nSampleMap[i] = 0; + for(UINT j = i + 1; j <= m_SndFile.m_nSamples; j++) + nSampleMap[j]--; + } + } + + if(!nRemap) + return; + + BEGIN_CRITICAL(); + + // Now, move everything around + for(UINT i = 1; i <= m_SndFile.m_nSamples; i++) + { + if(nSampleMap[i] && nSampleMap[i] != i) + { + // This gotta be moved + m_SndFile.MoveSample(i, nSampleMap[i]); + m_SndFile.Samples[i].pSample = nullptr; + strcpy(m_SndFile.m_szNames[nSampleMap[i]], m_SndFile.m_szNames[i]); + m_SndFile.m_szNames[i][0] = '\0'; + + // Also update instrument mapping (if module is in instrument mode) + for(UINT iInstr = 1; iInstr <= m_SndFile.m_nInstruments; iInstr++){ + if(m_SndFile.Instruments[iInstr]){ + MODINSTRUMENT *p = m_SndFile.Instruments[iInstr]; + for(WORD iNote =0; iNote < 128; iNote++) + if(p->Keyboard[iNote] == i) p->Keyboard[iNote] = nSampleMap[i]; + } + } + } + } + + // Go through the patterns and remap samples (if module is in sample mode) + if(!m_SndFile.m_nInstruments) + { + for (UINT nPat=0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat]) + { + MODCOMMAND *m = m_SndFile.Patterns[nPat]; + for (UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--) + { + if(nSampleMap[m->instr]) m->instr = nSampleMap[m->instr]; + } + } + } + + m_SndFile.m_nSamples -= nRemap; + + END_CRITICAL(); + + SetModified(); + UpdateAllViews(NULL, HINT_MODTYPE); + +} + + BOOL CModDoc::ConvertInstrumentsToSamples() //----------------------------------------- { @@ -1533,8 +1608,8 @@ } -LONG CModDoc::InsertPattern(ORDERINDEX nOrd, ROWINDEX nRows) -//------------------------------------------------ +PATTERNINDEX CModDoc::InsertPattern(ORDERINDEX nOrd, ROWINDEX nRows) +//------------------------------------------------------------------ { const int i = m_SndFile.Patterns.Insert(nRows); if(i < 0) @@ -1573,8 +1648,8 @@ } -LONG CModDoc::InsertSample(BOOL bLimit) -//------------------------------------- +SAMPLEINDEX CModDoc::InsertSample(bool bLimit) +//-------------------------------------------- { UINT i = 1; for (i=1; i<=m_SndFile.m_nSamples; i++) @@ -1611,7 +1686,7 @@ } -LONG CModDoc::InsertInstrument(LONG lSample, LONG lDuplicate) +INSTRUMENTINDEX CModDoc::InsertInstrument(LONG lSample, LONG lDuplicate) //----------------------------------------------------------- { MODINSTRUMENT *pDup = NULL; @@ -1733,44 +1808,44 @@ } -BOOL CModDoc::RemoveOrder(UINT n) +bool CModDoc::RemoveOrder(ORDERINDEX n) //------------------------------- { if (n < m_SndFile.Order.size()) { BEGIN_CRITICAL(); - for (UINT i=n; i<m_SndFile.Order.size()-1; i++) + for (ORDERINDEX i=n; i<m_SndFile.Order.size()-1; i++) { m_SndFile.Order[i] = m_SndFile.Order[i+1]; } m_SndFile.Order[m_SndFile.Order.size()-1] = m_SndFile.Order.GetInvalidPatIndex(); END_CRITICAL(); SetModified(); - return TRUE; + return true; } - return FALSE; + return false; } -BOOL CModDoc::RemovePattern(UINT n) +bool CModDoc::RemovePattern(PATTERNINDEX n) //--------------------------------- { if ((n < m_SndFile.Patterns.Size()) && (m_SndFile.Patterns[n])) { BEGIN_CRITICAL(); LPVOID p = m_SndFile.Patterns[n]; - m_SndFile.Patterns[n] = NULL; + m_SndFile.Patterns[n] = nullptr; m_SndFile.SetPatternName(n, ""); CSoundFile::FreePattern(p); END_CRITICAL(); SetModified(); - return TRUE; + return true; } - return FALSE; + return false; } -BOOL CModDoc::RemoveSample(UINT n) +bool CModDoc::RemoveSample(SAMPLEINDEX n) //-------------------------------- { if ((n) && (n <= m_SndFile.m_nSamples)) @@ -1783,86 +1858,13 @@ && (!m_SndFile.Samples[m_SndFile.m_nSamples].pSample)) m_SndFile.m_nSamples--; END_CRITICAL(); SetModified(); - return TRUE; + return true; } - return FALSE; + return false; } -void CModDoc::RearrangeSampleList() -//--------------------------------- -{ - if(m_SndFile.m_nSamples < 2) - return; - - UINT nRemap = 0; // remap count - UINT nSampleMap[MAX_SAMPLES + 1]; // map old => new - for(UINT i = 0; i <= MAX_SAMPLES; i++) - nSampleMap[i] = i; - - // First, find out which sample slots are unused and create the new sample map - for(UINT i = 1 ; i <= m_SndFile.m_nSamples; i++) { - if(!m_SndFile.Samples[i].pSample) - { - // Move all following samples - nRemap++; - nSampleMap[i] = 0; - for(UINT j = i + 1; j <= m_SndFile.m_nSamples; j++) - nSampleMap[j]--; - } - } - - if(!nRemap) - return; - - BEGIN_CRITICAL(); - - // Now, move everything around - for(UINT i = 1; i <= m_SndFile.m_nSamples; i++) - { - if(nSampleMap[i] && nSampleMap[i] != i) - { - // This gotta be moved - m_SndFile.MoveSample(i, nSampleMap[i]); - m_SndFile.Samples[i].pSample = nullptr; - strcpy(m_SndFile.m_szNames[nSampleMap[i]], m_SndFile.m_szNames[i]); - m_SndFile.m_szNames[i][0] = '\0'; - - // Also update instrument mapping (if module is in instrument mode) - for(UINT iInstr = 1; iInstr <= m_SndFile.m_nInstruments; iInstr++){ - if(m_SndFile.Instruments[iInstr]){ - MODINSTRUMENT *p = m_SndFile.Instruments[iInstr]; - for(WORD iNote =0; iNote < 128; iNote++) - if(p->Keyboard[iNote] == i) p->Keyboard[iNote] = nSampleMap[i]; - } - } - } - } - - // Go through the patterns and remap samples (if module is in sample mode) - if(!m_SndFile.m_nInstruments) - { - for (UINT nPat=0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat]) - { - MODCOMMAND *m = m_SndFile.Patterns[nPat]; - for (UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--) - { - if(nSampleMap[m->instr]) m->instr = nSampleMap[m->instr]; - } - } - } - - m_SndFile.m_nSamples -= nRemap; - - END_CRITICAL(); - - SetModified(); - UpdateAllViews(NULL, HINT_MODTYPE); - -} - - -BOOL CModDoc::RemoveInstrument(UINT n) +bool CModDoc::RemoveInstrument(INSTRUMENTINDEX n) //------------------------------------ { if ((n) && (n <= m_SndFile.m_nInstruments) && (m_SndFile.Instruments[n])) @@ -1875,31 +1877,32 @@ if (!bIns) m_SndFile.m_nInstruments = 0; END_CRITICAL(); SetModified(); - return TRUE; + return true; } - return FALSE; + return false; } -BOOL CModDoc::MoveOrder(UINT nSourceNdx, UINT nDestNdx, BOOL bUpdate, BOOL bCopy) +bool CModDoc::MoveOrder(UINT nSourceNdx, UINT nDestNdx, bool bUpdate, bool bCopy) //------------------------------------------------------------------------------- { - if ((nSourceNdx >= m_SndFile.Order.size()) || (nDestNdx >= m_SndFile.Order.size())) return FALSE; - UINT n = m_SndFile.Order[nSourceNdx]; + if ((nSourceNdx >= m_SndFile.Order.size()) || (nDestNdx >= m_SndFile.Order.size())) return false; + if (nDestNdx >= m_SndFile.GetModSpecifications().ordersMax) return false; + ORDERINDEX n = m_SndFile.Order[nSourceNdx]; // Delete source if (!bCopy) { - for (UINT i=nSourceNdx; i<m_SndFile.Order.size()-1; i++) m_SndFile.Order[i] = m_SndFile.Order[i+1]; + 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 (UINT j=m_SndFile.Order.size()-1; j>nDestNdx; j--) m_SndFile.Order[j] = m_SndFile.Order[j-1]; + 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; if (bUpdate) { UpdateAllViews(NULL, HINT_MODSEQUENCE, NULL); } - return TRUE; + return true; } Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-08-16 22:47:01 UTC (rev 330) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-08-18 18:41:12 UTC (rev 331) @@ -1870,7 +1870,7 @@ { if (bDoDrop) { - if (dwItemDrag != dwItemDrop) pModDoc->MoveOrder(dwItemDrag, dwItemDrop, TRUE); + if (dwItemDrag != dwItemDrop) pModDoc->MoveOrder(dwItemDrag, dwItemDrop, true); } return TRUE; } Modified: trunk/OpenMPT/mptrack/test/test.cpp =================================================================== --- trunk/OpenMPT/mptrack/test/test.cpp 2009-08-16 22:47:01 UTC (rev 330) +++ trunk/OpenMPT/mptrack/test/test.cpp 2009-08-18 18:41:12 UTC (rev 331) @@ -95,6 +95,9 @@ STATIC_ASSERT( MAKE_VERSION_NUMERIC(1,17,2,28) == 18285096 ); STATIC_ASSERT( MAKE_VERSION_NUMERIC(1,17,02,48) == 18285128 ); STATIC_ASSERT( MAKE_VERSION_NUMERIC(01,17,02,52) == 18285138 ); + // Ensure that bit-shifting works (used in some mod loaders for example) + STATIC_ASSERT( MAKE_VERSION_NUMERIC(01,17,00,00) == 0x0117 << 16 ); + STATIC_ASSERT( MAKE_VERSION_NUMERIC(01,17,03,00) >> 8 == 0x011703 ); } //Verify that the version obtained from the executable file is the same as Modified: trunk/OpenMPT/mptrack/typedefs.h =================================================================== --- trunk/OpenMPT/mptrack/typedefs.h 2009-08-16 22:47:01 UTC (rev 330) +++ trunk/OpenMPT/mptrack/typedefs.h 2009-08-18 18:41:12 UTC (rev 331) @@ -36,7 +36,10 @@ typedef uint16 CHANNELINDEX; typedef uint16 ORDERINDEX; const ORDERINDEX ORDERINDEX_MAX = uint16_max; + const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX; typedef uint16 PATTERNINDEX; + const PATTERNINDEX PATTERNINDEX_MAX = uint16_max; + const PATTERNINDEX PATTERNINDEX_INVALID = PATTERNINDEX_MAX; typedef uint8 PLUGINDEX; typedef uint16 TEMPO; typedef uint16 SAMPLEINDEX; Modified: trunk/OpenMPT/soundlib/Load_669.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_669.cpp 2009-08-16 22:47:01 UTC (rev 330) +++ trunk/OpenMPT/soundlib/Load_669.cpp 2009-08-18 18:41:12 UTC (rev 331) @@ -59,7 +59,7 @@ DWORD len = LittleEndian(*((DWORD *)(&psmp[ichk].length))); dontfuckwithme += len; } - if (dontfuckwithme > dwMemLength) return false; + if (dontfuckwithme - 0x1F1 > dwMemLength) return false; // That should be enough checking: this must be a 669 module. m_nType = MOD_TYPE_669; m_dwSongFlags |= SONG_LINEARSLIDES; Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-16 22:47:01 UTC (rev 330) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-18 18:41:12 UTC (rev 331) @@ -855,9 +855,7 @@ //if(!(pChn->dwFlags & CHN_MUTE)) //removed by rewbs: fix http://www.modplug.com/forum/viewtopic.php?t=3358 nchn32++; } - if(nchn32 < 1) nchn32 = 1; - if(nchn32 > 31) nchn32 = 31; - + nchn32 = CLAMP(nchn32, 1, 31); DWORD mastervol; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |