Compress/Expand shall not break apart hold notes that overlaps the start/end marker.
This commit is contained in:
+36
-35
@@ -2232,25 +2232,34 @@ void NoteDataUtil::AddTapAttacks( NoteData &nd, Song* pSong )
|
||||
void NoteDataUtil::Scale( NoteData &nd, float fScale )
|
||||
{
|
||||
ASSERT( fScale > 0 );
|
||||
|
||||
NoteData temp;
|
||||
temp.CopyAll( nd );
|
||||
nd.ClearAll();
|
||||
|
||||
for( int r=0; r<=temp.GetLastRow(); r++ )
|
||||
|
||||
NoteData ndOut;
|
||||
ndOut.SetNumTracks( nd.GetNumTracks() );
|
||||
|
||||
for( int t=0; t<nd.GetNumTracks(); t++ )
|
||||
{
|
||||
for( int t=0; t<temp.GetNumTracks(); t++ )
|
||||
for( NoteData::const_iterator iter = nd.begin(t); iter != nd.end(t); ++iter )
|
||||
{
|
||||
TapNote tn = temp.GetTapNote( t, r );
|
||||
if( tn != TAP_EMPTY )
|
||||
{
|
||||
temp.SetTapNote( t, r, TAP_EMPTY );
|
||||
|
||||
int new_row = int(r*fScale);
|
||||
nd.SetTapNote( t, new_row, tn );
|
||||
}
|
||||
TapNote tn = iter->second;
|
||||
int iNewRow = lrintf( fScale * iter->first );
|
||||
int iNewDuration = lrintf( fScale * (iter->first + tn.iDuration) );
|
||||
tn.iDuration = iNewDuration;
|
||||
ndOut.SetTapNote( t, iNewRow, tn );
|
||||
}
|
||||
}
|
||||
|
||||
nd.swap( ndOut );
|
||||
}
|
||||
|
||||
/* XXX: move this to an appropriate place, same place as NoteRowToBeat perhaps? */
|
||||
static inline int GetScaledRow( float fScale, int iStartIndex, int iEndIndex, int iRow )
|
||||
{
|
||||
if( iRow < iStartIndex )
|
||||
return iRow;
|
||||
else if( iRow > iEndIndex )
|
||||
return iRow + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) );
|
||||
else
|
||||
return lrintf( (iRow - iStartIndex) * fScale ) + iStartIndex;
|
||||
}
|
||||
|
||||
void NoteDataUtil::ScaleRegion( NoteData &nd, float fScale, int iStartIndex, int iEndIndex )
|
||||
@@ -2258,31 +2267,23 @@ void NoteDataUtil::ScaleRegion( NoteData &nd, float fScale, int iStartIndex, int
|
||||
ASSERT( fScale > 0 );
|
||||
ASSERT( iStartIndex < iEndIndex );
|
||||
ASSERT( iStartIndex >= 0 );
|
||||
|
||||
NoteData temp1, temp2;
|
||||
temp1.SetNumTracks( nd.GetNumTracks() );
|
||||
temp2.SetNumTracks( nd.GetNumTracks() );
|
||||
|
||||
if( iStartIndex != 0 )
|
||||
temp1.CopyRange( nd, 0, iStartIndex );
|
||||
if( iEndIndex != MAX_NOTE_ROW )
|
||||
{
|
||||
const int iScaledFirstRowAfterRegion = int(iStartIndex + (iEndIndex - iStartIndex) * fScale);
|
||||
temp1.CopyRange( nd, iEndIndex, MAX_NOTE_ROW, iScaledFirstRowAfterRegion );
|
||||
}
|
||||
temp2.CopyRange( nd, iStartIndex, iEndIndex );
|
||||
nd.ClearAll();
|
||||
|
||||
for( int t=0; t<temp2.GetNumTracks(); t++ )
|
||||
|
||||
NoteData ndOut;
|
||||
ndOut.SetNumTracks( nd.GetNumTracks() );
|
||||
|
||||
for( int t=0; t<nd.GetNumTracks(); t++ )
|
||||
{
|
||||
for( NoteData::const_iterator iter = nd.begin(t); iter != nd.end(t); ++iter )
|
||||
{
|
||||
int new_row = int( iter->first*fScale + iStartIndex );
|
||||
temp1.SetTapNote( t, new_row, iter->second );
|
||||
TapNote tn = iter->second;
|
||||
int iNewRow = GetScaledRow( fScale, iStartIndex, iEndIndex, iter->first );
|
||||
int iNewDuration = GetScaledRow( fScale, iStartIndex, iEndIndex, iter->first + tn.iDuration ) - iNewRow;
|
||||
tn.iDuration = iNewDuration;
|
||||
ndOut.SetTapNote( t, iNewRow, tn );
|
||||
}
|
||||
}
|
||||
|
||||
nd.swap( temp1 );
|
||||
|
||||
nd.swap( ndOut );
|
||||
}
|
||||
|
||||
void NoteDataUtil::InsertRows( NoteData &nd, int iStartIndex, int iRowsToAdd )
|
||||
|
||||
+13
-27
@@ -3419,11 +3419,9 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
case tempo:
|
||||
{
|
||||
// This affects all steps.
|
||||
const NoteData OldClipboard( m_Clipboard );
|
||||
HandleAreaMenuChoice( cut );
|
||||
|
||||
AlterType at = (AlterType)iAnswers[c];
|
||||
float fScale = -1;
|
||||
|
||||
switch( at )
|
||||
{
|
||||
DEFAULT_FAIL( at );
|
||||
@@ -3434,31 +3432,18 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
case expand_3_2: fScale = 1.5f; break;
|
||||
case expand_2x: fScale = 2; break;
|
||||
}
|
||||
|
||||
switch( at )
|
||||
{
|
||||
DEFAULT_FAIL( at );
|
||||
case compress_2x: NoteDataUtil::Scale( m_Clipboard, fScale ); break;
|
||||
case compress_3_2: NoteDataUtil::Scale( m_Clipboard, fScale ); break;
|
||||
case compress_4_3: NoteDataUtil::Scale( m_Clipboard, fScale ); break;
|
||||
case expand_4_3: NoteDataUtil::Scale( m_Clipboard, fScale ); break;
|
||||
case expand_3_2: NoteDataUtil::Scale( m_Clipboard, fScale ); break;
|
||||
case expand_2x: NoteDataUtil::Scale( m_Clipboard, fScale ); break;
|
||||
}
|
||||
|
||||
int iOldClipboardRow = m_NoteFieldEdit.m_iEndMarker - m_NoteFieldEdit.m_iBeginMarker;
|
||||
int iNewClipboardRow = lrintf( iOldClipboardRow * fScale );
|
||||
int iDeltaRows = iNewClipboardRow - iOldClipboardRow;
|
||||
int iNewClipboardEndRow = m_NoteFieldEdit.m_iBeginMarker + iNewClipboardRow;
|
||||
if( iDeltaRows > 0 )
|
||||
NoteDataUtil::InsertRows( m_NoteDataEdit, m_NoteFieldEdit.m_iBeginMarker, iDeltaRows );
|
||||
else
|
||||
NoteDataUtil::DeleteRows( m_NoteDataEdit, m_NoteFieldEdit.m_iBeginMarker, -iDeltaRows );
|
||||
|
||||
|
||||
int iStartIndex = m_NoteFieldEdit.m_iBeginMarker;
|
||||
int iEndIndex = m_NoteFieldEdit.m_iEndMarker;
|
||||
int iNewEndIndex = iEndIndex + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) );
|
||||
|
||||
// scale currently editing notes
|
||||
NoteDataUtil::ScaleRegion( m_NoteDataEdit, fScale, iStartIndex, iEndIndex );
|
||||
|
||||
// scale timing data
|
||||
m_pSong->m_Timing.ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true );
|
||||
|
||||
HandleAreaMenuChoice( paste_at_begin_marker );
|
||||
|
||||
// scale all other steps.
|
||||
const vector<Steps*> sIter = m_pSong->GetAllSteps();
|
||||
RString sTempStyle, sTempDiff;
|
||||
for( unsigned i = 0; i < sIter.size(); i++ )
|
||||
@@ -3478,7 +3463,8 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
sIter[i]->SetNoteData( ndTemp );
|
||||
}
|
||||
|
||||
m_NoteFieldEdit.m_iEndMarker = iNewClipboardEndRow;
|
||||
m_NoteFieldEdit.m_iEndMarker = iNewEndIndex;
|
||||
|
||||
}
|
||||
break;
|
||||
case play:
|
||||
|
||||
Reference in New Issue
Block a user