From: <sag...@us...> - 2012-11-17 16:04:20
|
Revision: 1430 http://modplug.svn.sourceforge.net/modplug/?rev=1430&view=rev Author: saga-games Date: 2012-11-17 16:04:12 +0000 (Sat, 17 Nov 2012) Log Message: ----------- [Fix] Some weird pattern loops that are obfuscated through pattern jump commands should now also work correctly when "Loop Song" is off and during Wave Export (http://bugs.openmpt.org/view.php?id=311). [Fix] Song Cleanup: Reordering instruments was not working in all cases. Modified Paths: -------------- trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/soundlib/RowVisitor.cpp trunk/OpenMPT/soundlib/RowVisitor.h trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp =================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-11-16 22:44:07 UTC (rev 1429) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp 2012-11-17 16:04:12 UTC (rev 1430) @@ -708,7 +708,7 @@ EndWaitCursor(); - if(reorder && numUsed > 1) + if(reorder && numUsed >= 1) { reorder = (Reporting::Confirm("Do you want to reorganize the remaining instruments?", "Removing unused instruments", false, false, this) == cnfYes); } else @@ -922,11 +922,11 @@ CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); if(pSndFile == nullptr) return false; - if (pSndFile->GetNumInstruments() == 0) return false; + if(pSndFile->GetNumInstruments() == 0) return false; m_pModDoc->ConvertInstrumentsToSamples(); - for (INSTRUMENTINDEX i = 1; i <= pSndFile->GetNumInstruments(); i++) + for(INSTRUMENTINDEX i = 1; i <= pSndFile->GetNumInstruments(); i++) { pSndFile->DestroyInstrument(i, doNoDeleteAssociatedSamples); } Modified: trunk/OpenMPT/soundlib/RowVisitor.cpp =================================================================== --- trunk/OpenMPT/soundlib/RowVisitor.cpp 2012-11-16 22:44:07 UTC (rev 1429) +++ trunk/OpenMPT/soundlib/RowVisitor.cpp 2012-11-17 16:04:12 UTC (rev 1430) @@ -31,6 +31,7 @@ { const ORDERINDEX endOrder = sndFile.Order.GetLengthTailTrimmed(); visitedRows.resize(endOrder); + visitOrder.clear(); for(ORDERINDEX order = 0; order < endOrder; order++) { @@ -64,6 +65,10 @@ } visitedRows[order][row] = visited; + if(visited) + { + AddVisitedRow(order, row); + } } @@ -96,6 +101,7 @@ } else if(autoSet) { visitedRows[order][row] = true; + AddVisitedRow(order, row); } return false; @@ -155,3 +161,40 @@ row = ROWINDEX_INVALID; return false; } + + +// Set all rows of a previous pattern loop as unvisited. +void RowVisitor::ResetPatternLoop(ORDERINDEX order, ROWINDEX startRow) +//-------------------------------------------------------------------- +{ + ASSERT(order == currentOrder); // Should never trigger. + + // Unvisit all rows that are in the visited row buffer, until we hit the start row for this pattern loop. + while(!visitOrder.empty()) + { + ROWINDEX row = visitOrder.back(); + visitOrder.pop_back(); + Unvisit(order, row); + if(row == startRow) + { + break; + } + } + visitOrder.clear(); +} + + +// Add a row to the visited row memory for this pattern. +void RowVisitor::AddVisitedRow(ORDERINDEX order, ROWINDEX row) +//------------------------------------------------------------ +{ + // Update Pattern Loop memory + if(order != currentOrder) + { + // We're in a new pattern! Forget about which rows we previously visited... + visitOrder.clear(); + visitOrder.reserve(GetVisitedRowsVectorSize(sndFile.Order[order])); + currentOrder = order; + } + visitOrder.push_back(row); +} \ No newline at end of file Modified: trunk/OpenMPT/soundlib/RowVisitor.h =================================================================== --- trunk/OpenMPT/soundlib/RowVisitor.h 2012-11-16 22:44:07 UTC (rev 1429) +++ trunk/OpenMPT/soundlib/RowVisitor.h 2012-11-17 16:04:12 UTC (rev 1430) @@ -24,17 +24,21 @@ typedef std::vector<bool> VisitedRowsBaseType; typedef std::vector<VisitedRowsBaseType> VisitedRowsType; + // Memory for every row in the module if it has been visited or not. VisitedRowsType visitedRows; + // Memory of visited rows (including their order) to reset pattern loops. + std::vector<ROWINDEX> visitOrder; const CSoundFile &sndFile; + ORDERINDEX currentOrder; public: - RowVisitor(const CSoundFile &sf) : sndFile(sf) + RowVisitor(const CSoundFile &sf) : sndFile(sf), currentOrder(0) { Initialize(true); }; - RowVisitor(const RowVisitor &other) : sndFile(other.sndFile), visitedRows(other.visitedRows) { }; + RowVisitor(const RowVisitor &other) : sndFile(other.sndFile), visitedRows(other.visitedRows), visitOrder(other.visitOrder), currentOrder(other.currentOrder) { }; // Resize / Clear the row vector. // If reset is true, the vector is not only resized to the required dimensions, but also completely cleared (i.e. all visited rows are unset). @@ -72,6 +76,9 @@ visitedRows = other.visitedRows; } + // Set all rows of a previous pattern loop as unvisited. + void ResetPatternLoop(ORDERINDEX order, ROWINDEX startRow); + protected: // (Un)sets a given row as visited. @@ -79,4 +86,7 @@ // If visited is true, the row will be set as visited. void SetVisited(ORDERINDEX order, ROWINDEX row, bool visited); + // Add a row to the visited row memory for this pattern. + void AddVisitedRow(ORDERINDEX order, ROWINDEX row); + }; Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-11-16 22:44:07 UTC (rev 1429) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-11-17 16:04:12 UTC (rev 1430) @@ -1989,7 +1989,7 @@ { pChn->nPan = 0; } - break; + // Intentional fall-through default: // no memory here. volcmd = VOLCMD_NONE; @@ -2506,10 +2506,7 @@ } // As long as the pattern loop is running, mark the looped rows as not visited yet - for(ROWINDEX nRow = nPatLoopRow; nRow <= m_nRow; nRow++) - { - visitedSongRows.Unvisit(m_nCurrentOrder, nRow); - } + visitedSongRows.ResetPatternLoop(m_nCurrentOrder, nPatLoopRow); } // Pattern Break / Position Jump only if no loop running This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |