From: <sag...@us...> - 2011-07-26 19:04:14
|
Revision: 929 http://modplug.svn.sourceforge.net/modplug/?rev=929&view=rev Author: saga-games Date: 2011-07-26 19:04:08 +0000 (Tue, 26 Jul 2011) Log Message: ----------- Experimental new code... [New] Adding / removing channels through the pattern editor now creates an undo point. [Fix] Moving channels and then undoing the move preserves old channel settings (http://bugs.openmpt.org/view.php?id=156). Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Undo.cpp trunk/OpenMPT/mptrack/Undo.h Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2011-07-26 00:22:44 UTC (rev 928) +++ trunk/OpenMPT/mptrack/Moddoc.h 2011-07-26 19:04:08 UTC (rev 929) @@ -277,9 +277,9 @@ bool ChangeModType(MODTYPE wType); bool ChangeNumChannels(CHANNELINDEX nNewChannels, const bool showCancelInRemoveDlg = true); - CHANNELINDEX ReArrangeChannels(const vector<CHANNELINDEX> &fromToArray); + bool RemoveChannels(const vector<bool> &keepMask); + CHANNELINDEX ReArrangeChannels(const vector<CHANNELINDEX> &fromToArray, const bool createUndoPoint = true); bool MoveChannel(CHANNELINDEX chn_from, CHANNELINDEX chn_to); - bool RemoveChannels(const vector<bool> &keepMask); void CheckUsedChannels(vector<bool> &usedMask, CHANNELINDEX maxRemoveCount = MAX_BASECHANNELS) const; bool ConvertInstrumentsToSamples(); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2011-07-26 00:22:44 UTC (rev 928) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2011-07-26 19:04:08 UTC (rev 929) @@ -138,8 +138,8 @@ // Base code for adding, removing, moving and duplicating channels. Returns new number of channels on success, CHANNELINDEX_INVALID otherwise. // The new channel vector can contain CHANNELINDEX_INVALID for adding new (empty) channels. -CHANNELINDEX CModDoc::ReArrangeChannels(const vector<CHANNELINDEX> &newOrder) -//--------------------------------------------------------------------------- +CHANNELINDEX CModDoc::ReArrangeChannels(const vector<CHANNELINDEX> &newOrder, const bool createUndoPoint) +//------------------------------------------------------------------------------------------------------- { //newOrder[i] tells which current channel should be placed to i:th position in //the new order, or if i is not an index of current channels, then new channel is @@ -157,20 +157,25 @@ } bool first = true; - if(nRemainingChannels != GetNumChannels()) + // Find highest valid pattern number for storing channel undo data with, since the pattern with the highest number will be undone first. + PATTERNINDEX highestPattern = 0; + for(PATTERNINDEX nPat = m_SndFile.Patterns.Size() - 1; nPat > 0; nPat--) { - // For now, changing number of channels can't be undone - GetPatternUndo()->ClearUndo(); + if(m_SndFile.Patterns.IsValidPat(nPat)) + { + highestPattern = nPat; + break; + } } BEGIN_CRITICAL(); - for(PATTERNINDEX nPat = 0; nPat < m_SndFile.Patterns.Size(); nPat++) + for(PATTERNINDEX nPat = 0; nPat <= highestPattern; nPat++) { - if(m_SndFile.Patterns[nPat]) + if(m_SndFile.Patterns.IsValidPat(nPat)) { - if(nRemainingChannels == GetNumChannels()) + if(createUndoPoint) { - GetPatternUndo()->PrepareUndo(nPat, 0, 0, GetNumChannels(), m_SndFile.Patterns[nPat].GetNumRows(), !first); + GetPatternUndo()->PrepareUndo(nPat, 0, 0, GetNumChannels(), m_SndFile.Patterns[nPat].GetNumRows(), !first, (nPat == highestPattern)); first = false; } @@ -795,9 +800,9 @@ 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; + 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]; Modified: trunk/OpenMPT/mptrack/Undo.cpp =================================================================== --- trunk/OpenMPT/mptrack/Undo.cpp 2011-07-26 00:22:44 UTC (rev 928) +++ trunk/OpenMPT/mptrack/Undo.cpp 2011-07-26 19:04:08 UTC (rev 929) @@ -39,8 +39,9 @@ // - numChns: width // - numRows: height // - linkToPrevious: Don't create a separate undo step, but link this to the previous undo event. Useful for commands that modify several patterns at once. -bool CPatternUndo::PrepareUndo(PATTERNINDEX pattern, CHANNELINDEX firstChn, ROWINDEX firstRow, CHANNELINDEX numChns, ROWINDEX numRows, bool linkToPrevious) -//--------------------------------------------------------------------------------------------------------------------------------------------------------- +// - storeChannelInfo: Also store current channel header information (pan / volume / etc. settings) and number of channels in this undo point. +bool CPatternUndo::PrepareUndo(PATTERNINDEX pattern, CHANNELINDEX firstChn, ROWINDEX firstRow, CHANNELINDEX numChns, ROWINDEX numRows, bool linkToPrevious, bool storeChannelInfo) +//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { if(m_pModDoc == nullptr) return false; CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); @@ -84,6 +85,17 @@ pPattern += pSndFile->GetNumChannels(); } + if(storeChannelInfo) + { + sUndo.channelInfo = new PATTERNUNDOINFO; + sUndo.channelInfo->oldNumChannels = pSndFile->GetNumChannels(); + sUndo.channelInfo->settings = new MODCHANNELSETTINGS[pSndFile->GetNumChannels()]; + memcpy(sUndo.channelInfo->settings, pSndFile->ChnSettings, sizeof(MODCHANNELSETTINGS) * pSndFile->GetNumChannels()); + } else + { + sUndo.channelInfo = nullptr; + } + UndoBuffer.push_back(sUndo); if (bUpdate) m_pModDoc->UpdateAllViews(NULL, HINT_UNDO); @@ -127,6 +139,30 @@ // Select most recent undo slot const PATTERNUNDOBUFFER *pUndo = &UndoBuffer.back(); + if(pUndo->channelInfo != nullptr) + { + if(pUndo->channelInfo->oldNumChannels > pSndFile->GetNumChannels()) + { + // First add some channels again... + vector<CHANNELINDEX> channels(pUndo->channelInfo->oldNumChannels, CHANNELINDEX_INVALID); + for(CHANNELINDEX i = 0; i < pSndFile->GetNumChannels(); i++) + { + channels[i] = i; + } + m_pModDoc->ReArrangeChannels(channels, false); + } else if(pUndo->channelInfo->oldNumChannels < pSndFile->GetNumChannels()) + { + // ... or remove newly added channels + vector<CHANNELINDEX> channels(pUndo->channelInfo->oldNumChannels); + for(CHANNELINDEX i = 0; i < pUndo->channelInfo->oldNumChannels; i++) + { + channels[i] = i; + } + m_pModDoc->ReArrangeChannels(channels, false); + } + memcpy(pSndFile->ChnSettings, pUndo->channelInfo->settings, sizeof(MODCHANNELSETTINGS) * pUndo->channelInfo->oldNumChannels); + } + nPattern = pUndo->pattern; nRows = pUndo->patternsize; if(pUndo->firstChannel + pUndo->numChannels <= pSndFile->GetNumChannels()) @@ -159,14 +195,14 @@ RemoveLastUndoStep(); - if (CanUndo() == false) m_pModDoc->UpdateAllViews(NULL, HINT_UNDO); + if(CanUndo() == false) m_pModDoc->UpdateAllViews(NULL, HINT_UNDO); + if(linkToPrevious) { - return Undo(true); - } else - { - return nPattern; + nPattern = Undo(true); } + + return nPattern; } @@ -183,7 +219,12 @@ //------------------------------------------- { if(nStep >= UndoBuffer.size()) return; - if (UndoBuffer[nStep].pbuffer) delete[] UndoBuffer[nStep].pbuffer; + if(UndoBuffer[nStep].pbuffer) delete[] UndoBuffer[nStep].pbuffer; + if(UndoBuffer[nStep].channelInfo) + { + delete[] UndoBuffer[nStep].channelInfo->settings; + delete UndoBuffer[nStep].channelInfo; + } UndoBuffer.erase(UndoBuffer.begin() + nStep); } Modified: trunk/OpenMPT/mptrack/Undo.h =================================================================== --- trunk/OpenMPT/mptrack/Undo.h 2011-07-26 00:22:44 UTC (rev 928) +++ trunk/OpenMPT/mptrack/Undo.h 2011-07-26 19:04:08 UTC (rev 929) @@ -14,6 +14,13 @@ ///////////////////////////////////////////////////////////////////////////////////////// // Pattern Undo +// Additional undo information, as required +struct PATTERNUNDOINFO +{ + MODCHANNELSETTINGS *settings; + CHANNELINDEX oldNumChannels; +}; + struct PATTERNUNDOBUFFER { PATTERNINDEX pattern; @@ -21,6 +28,7 @@ CHANNELINDEX firstChannel, numChannels; ROWINDEX firstRow, numRows; MODCOMMAND *pbuffer; + PATTERNUNDOINFO *channelInfo; bool linkToPrevious; }; @@ -29,7 +37,7 @@ //================ { -private: +protected: std::vector<PATTERNUNDOBUFFER> UndoBuffer; CModDoc *m_pModDoc; @@ -42,7 +50,7 @@ // Pattern undo functions void ClearUndo(); - bool PrepareUndo(PATTERNINDEX pattern, CHANNELINDEX firstChn, ROWINDEX firstRow, CHANNELINDEX numChns, ROWINDEX numRows, bool linkToPrevious = false); + bool PrepareUndo(PATTERNINDEX pattern, CHANNELINDEX firstChn, ROWINDEX firstRow, CHANNELINDEX numChns, ROWINDEX numRows, bool linkToPrevious = false, bool storeChannelInfo = false); PATTERNINDEX Undo(); bool CanUndo(); void RemoveLastUndoStep(); @@ -93,7 +101,7 @@ //=============== { -private: +protected: // Undo buffer std::vector<std::vector<SAMPLEUNDOBUFFER> > UndoBuffer; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |