From 60a0ce8eb02445d92045991cd6df97364244038f Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Sun, 23 Jan 2005 04:57:43 +0000 Subject: [PATCH] implement NoteData::ClearRange and NoteData::CopyRange without 4s --- stepmania/src/NoteData.cpp | 113 +++++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 12 deletions(-) diff --git a/stepmania/src/NoteData.cpp b/stepmania/src/NoteData.cpp index 9bc10b88f2..c5800f409b 100644 --- a/stepmania/src/NoteData.cpp +++ b/stepmania/src/NoteData.cpp @@ -42,13 +42,43 @@ void NoteData::SetNumTracks( int iNewNumTracks ) /* Clear [rowBegin,rowEnd]; that is, including rowEnd. */ void NoteData::ClearRange( int rowBegin, int rowEnd ) { - this->ConvertHoldNotesTo4s(); + /* Crop or split hold notes overlapping the range. */ + for( int i = GetNumHoldNotes()-1; i >= 0; --i ) // for each HoldNote + { + HoldNote hn = GetHoldNote(i); + if( !hn.RangeOverlaps(rowBegin, rowEnd) ) + continue; + + this->RemoveHoldNote( i ); + + /* If the range encloses the hold note completely, just delete it. */ + if( hn.ContainedByRange(rowBegin, rowEnd) ) + continue; + + if( hn.RangeInside(rowBegin, rowEnd) ) + { + /* The hold note encloses the range, so we need to split the hold note. */ + HoldNote hnLater(hn); + hn.iEndRow = rowBegin; + hnLater.iStartRow = rowEnd; + this->AddHoldNote( hn ); + this->AddHoldNote( hnLater ); + continue; + } + + if( hn.iStartRow < rowBegin ) + hn.iEndRow = min( hn.iEndRow, rowBegin ); + else + hn.iStartRow = max( hn.iStartRow, rowEnd ); + this->AddHoldNote( hn ); + } + + /* Clear other notes in the region. */ for( int t=0; tConvert4sToHoldNotes(); } void NoteData::ClearAll() @@ -64,23 +94,82 @@ void NoteData::CopyRange( const NoteData& from, int rowFromBegin, int rowFromEnd { ASSERT( from.GetNumTracks() == GetNumTracks() ); - NoteData From, To; - From.To4s( from ); - To.To4s( *this ); + int rowToEnd = (rowFromEnd-rowFromBegin) + rowToBegin; - // copy recorded TapNotes - + /* Clear the region. */ + ClearRange( rowToBegin, rowToEnd ); + + /* Copy everything except for hold notes. */ for( int t=0; tSetTapNote( t, iTo, tn ); } } - this->From4s( To ); + /* Copy hold notes. */ + for( int i=0; iGetNumHoldNotes(); ++j ) // for each HoldNote + { + const HoldNote &hn2 = this->GetHoldNote(j); + if( hn2.iEndRow == hn.iStartRow ) + iEarlierHoldNote = j; + if( hn2.iStartRow == hn.iEndRow ) + iLaterHoldNote = j; + } + + if( iEarlierHoldNote != -1 && iLaterHoldNote != -1 ) + { + HoldNote &hnEarlier = this->GetHoldNote( iEarlierHoldNote ); + const HoldNote &hnLater = this->GetHoldNote( iLaterHoldNote ); + hnEarlier.iEndRow = hnLater.iEndRow; + + this->RemoveHoldNote( iLaterHoldNote ); + } + else if( iEarlierHoldNote == -1 && iLaterHoldNote == -1 ) + AddHoldNote( hn ); + else if( iEarlierHoldNote != -1 ) + { + HoldNote &hn2 = this->GetHoldNote(iEarlierHoldNote); + hn2.iEndRow = hn.iEndRow; + } + else if( iLaterHoldNote != -1 ) + { + HoldNote &hn2 = this->GetHoldNote(iLaterHoldNote); + hn2.iStartRow = hn.iStartRow; + } + else + FAIL_M(ssprintf("%i,%i", iEarlierHoldNote, iLaterHoldNote)); + } } void NoteData::Config( const NoteData& from )