add tempo compress/expand in editor
This commit is contained in:
@@ -980,3 +980,46 @@ void NoteDataUtil::TransformNoteData( NoteData &nd, PlayerOptions &po, StepsType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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++ )
|
||||||
|
{
|
||||||
|
for( int t=0; t<temp.GetNumTracks(); t++ )
|
||||||
|
{
|
||||||
|
TapNote tn = temp.GetTapNote( t, r );
|
||||||
|
if( tn != TAP_EMPTY )
|
||||||
|
{
|
||||||
|
temp.SetTapNote( t, r, TAP_EMPTY );
|
||||||
|
|
||||||
|
int new_row = r*fScale;
|
||||||
|
nd.SetTapNote( t, new_row, tn );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NoteDataUtil::ShiftRows( NoteData &nd, float fStartBeat, float fBeatsToShift )
|
||||||
|
{
|
||||||
|
NoteData temp;
|
||||||
|
temp.SetNumTracks( nd.GetNumTracks() );
|
||||||
|
int iTakeFromRow=0;
|
||||||
|
int iPasteAtRow;
|
||||||
|
|
||||||
|
iTakeFromRow = BeatToNoteRow( fStartBeat );
|
||||||
|
iPasteAtRow = BeatToNoteRow( fStartBeat );
|
||||||
|
|
||||||
|
if( fBeatsToShift > 0 ) // add blank rows
|
||||||
|
iPasteAtRow += BeatToNoteRow( fBeatsToShift );
|
||||||
|
else // delete rows
|
||||||
|
iTakeFromRow += BeatToNoteRow( -fBeatsToShift );
|
||||||
|
|
||||||
|
temp.CopyRange( &nd, iTakeFromRow, nd.GetLastRow() );
|
||||||
|
nd.ClearRange( min(iTakeFromRow,iPasteAtRow), nd.GetLastRow() );
|
||||||
|
nd.CopyRange( &temp, 0, temp.GetLastRow(), iPasteAtRow );
|
||||||
|
}
|
||||||
@@ -77,6 +77,11 @@ namespace NoteDataUtil
|
|||||||
void EliminateNonPassingTaps( NoteData &in, int row, const bool bValidMask[] );
|
void EliminateNonPassingTaps( NoteData &in, int row, const bool bValidMask[] );
|
||||||
|
|
||||||
void TransformNoteData( NoteData &nd, PlayerOptions &po, StepsType st );
|
void TransformNoteData( NoteData &nd, PlayerOptions &po, StepsType st );
|
||||||
|
|
||||||
|
void Scale( NoteData &nd, float fScale );
|
||||||
|
|
||||||
|
// If fBeatsToShift>0, add blank rows. If fBeatsToShift<0, delete rows
|
||||||
|
void ShiftRows( NoteData &nd, float fStartBeat, float fBeatsToShift );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ Menu g_AreaMenu
|
|||||||
MenuRow( "Turn", true, 0, "Left","Right","Mirror","Shuffle","Super Shuffle" ),
|
MenuRow( "Turn", true, 0, "Left","Right","Mirror","Shuffle","Super Shuffle" ),
|
||||||
MenuRow( "Transform", true, 0, "Little","Wide","Big","Quick","Skippy" ),
|
MenuRow( "Transform", true, 0, "Little","Wide","Big","Quick","Skippy" ),
|
||||||
MenuRow( "Alter", true, 0, "Backwards","Swap Sides","Copy Left To Right","Copy Right To Left","Clear Left","Clear Right","Collapse To One","Shift Left","Shift Right" ),
|
MenuRow( "Alter", true, 0, "Backwards","Swap Sides","Copy Left To Right","Copy Right To Left","Clear Left","Clear Right","Collapse To One","Shift Left","Shift Right" ),
|
||||||
|
MenuRow( "Tempo", true, 0, "Compress 2x","Expand 2x" ),
|
||||||
MenuRow( "Play selection", true ),
|
MenuRow( "Play selection", true ),
|
||||||
MenuRow( "Record in selection", true ),
|
MenuRow( "Record in selection", true ),
|
||||||
MenuRow( "Insert beat and shift down", true ),
|
MenuRow( "Insert beat and shift down", true ),
|
||||||
@@ -569,6 +570,7 @@ void ScreenEdit::Input( const DeviceInput& DeviceI, const InputEventType type, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI )
|
void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI )
|
||||||
{
|
{
|
||||||
if( DeviceI.device != DEVICE_KEYBOARD )
|
if( DeviceI.device != DEVICE_KEYBOARD )
|
||||||
@@ -826,6 +828,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
|
|||||||
g_AreaMenu.rows[turn].enabled = bAreaSelected;
|
g_AreaMenu.rows[turn].enabled = bAreaSelected;
|
||||||
g_AreaMenu.rows[transform].enabled = bAreaSelected;
|
g_AreaMenu.rows[transform].enabled = bAreaSelected;
|
||||||
g_AreaMenu.rows[alter].enabled = bAreaSelected;
|
g_AreaMenu.rows[alter].enabled = bAreaSelected;
|
||||||
|
g_AreaMenu.rows[tempo].enabled = bAreaSelected;
|
||||||
g_AreaMenu.rows[play].enabled = bAreaSelected;
|
g_AreaMenu.rows[play].enabled = bAreaSelected;
|
||||||
g_AreaMenu.rows[record].enabled = bAreaSelected;
|
g_AreaMenu.rows[record].enabled = bAreaSelected;
|
||||||
SCREENMAN->MiniMenu( &g_AreaMenu, SM_BackFromAreaMenu );
|
SCREENMAN->MiniMenu( &g_AreaMenu, SM_BackFromAreaMenu );
|
||||||
@@ -909,26 +912,9 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
|
|||||||
case IET_SLOW_REPEAT: fDeltaBPM *= 10; break;
|
case IET_SLOW_REPEAT: fDeltaBPM *= 10; break;
|
||||||
case IET_FAST_REPEAT: fDeltaBPM *= 40; break;
|
case IET_FAST_REPEAT: fDeltaBPM *= 40; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float fNewBPM = fBPM + fDeltaBPM;
|
float fNewBPM = fBPM + fDeltaBPM;
|
||||||
|
m_pSong->SetBPMAtBeat( GAMESTATE->m_fSongBeat, fNewBPM );
|
||||||
unsigned i;
|
|
||||||
for( i=0; i<m_pSong->m_BPMSegments.size(); i++ )
|
|
||||||
if( m_pSong->m_BPMSegments[i].m_fStartBeat == GAMESTATE->m_fSongBeat )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( i == m_pSong->m_BPMSegments.size() ) // there is no BPMSegment at the current beat
|
|
||||||
{
|
|
||||||
// create a new BPMSegment
|
|
||||||
m_pSong->AddBPMSegment( BPMSegment(GAMESTATE->m_fSongBeat, fNewBPM) );
|
|
||||||
}
|
|
||||||
else // BPMSegment being modified is m_BPMSegments[i]
|
|
||||||
{
|
|
||||||
if( i > 0 && fabsf(m_pSong->m_BPMSegments[i-1].m_fBPM - fNewBPM) < 0.009f )
|
|
||||||
m_pSong->m_BPMSegments.erase( m_pSong->m_BPMSegments.begin()+i,
|
|
||||||
m_pSong->m_BPMSegments.begin()+i+1);
|
|
||||||
else
|
|
||||||
m_pSong->m_BPMSegments[i].m_fBPM = fNewBPM;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDLK_F9:
|
case SDLK_F9:
|
||||||
@@ -1501,8 +1487,6 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
|
|||||||
break;
|
break;
|
||||||
case transform:
|
case transform:
|
||||||
{
|
{
|
||||||
// HandleAreaMenuChoice( cut, NULL );
|
|
||||||
|
|
||||||
float fBeginBeat = m_NoteFieldEdit.m_fBeginMarker;
|
float fBeginBeat = m_NoteFieldEdit.m_fBeginMarker;
|
||||||
float fEndBeat = m_NoteFieldEdit.m_fEndMarker;
|
float fEndBeat = m_NoteFieldEdit.m_fEndMarker;
|
||||||
TransformType tt = (TransformType)iAnswers[c];
|
TransformType tt = (TransformType)iAnswers[c];
|
||||||
@@ -1518,8 +1502,6 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
|
|||||||
|
|
||||||
// bake in the additions
|
// bake in the additions
|
||||||
NoteDataUtil::ConvertAdditionsToRegular( m_NoteFieldEdit );
|
NoteDataUtil::ConvertAdditionsToRegular( m_NoteFieldEdit );
|
||||||
|
|
||||||
// HandleAreaMenuChoice( paste_at_begin_marker, NULL );
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case alter:
|
case alter:
|
||||||
@@ -1544,6 +1526,43 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
|
|||||||
HandleAreaMenuChoice( paste_at_begin_marker, NULL );
|
HandleAreaMenuChoice( paste_at_begin_marker, NULL );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case tempo:
|
||||||
|
{
|
||||||
|
HandleAreaMenuChoice( cut, NULL );
|
||||||
|
|
||||||
|
AlterType at = (AlterType)iAnswers[c];
|
||||||
|
float fScale = -1;
|
||||||
|
switch( at )
|
||||||
|
{
|
||||||
|
case compress_2x: fScale = 0.5f; break;
|
||||||
|
case expand_2x: fScale = 2; break;
|
||||||
|
default: ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( at )
|
||||||
|
{
|
||||||
|
case compress_2x: NoteDataUtil::Scale( m_Clipboard, fScale ); break;
|
||||||
|
case expand_2x: NoteDataUtil::Scale( m_Clipboard, fScale ); break;
|
||||||
|
default: ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float fOldClipboardEndBeat = m_NoteFieldEdit.m_fEndMarker;
|
||||||
|
float fOldClipboardBeats = m_NoteFieldEdit.m_fEndMarker - m_NoteFieldEdit.m_fBeginMarker;
|
||||||
|
float fNewClipboardBeats = fOldClipboardBeats * fScale;
|
||||||
|
float fDeltaBeats = fNewClipboardBeats - fOldClipboardBeats;
|
||||||
|
float fNewClipboardEndBeat = m_NoteFieldEdit.m_fBeginMarker + fNewClipboardBeats;
|
||||||
|
NoteDataUtil::ShiftRows( m_NoteFieldEdit, m_NoteFieldEdit.m_fBeginMarker, fDeltaBeats );
|
||||||
|
|
||||||
|
HandleAreaMenuChoice( paste_at_begin_marker, NULL );
|
||||||
|
|
||||||
|
m_NoteFieldEdit.m_fEndMarker = fNewClipboardEndBeat;
|
||||||
|
|
||||||
|
float fOldBPM = m_pSong->GetBPMAtBeat( m_NoteFieldEdit.m_fBeginMarker );
|
||||||
|
float fNewBPM = fOldBPM * fScale;
|
||||||
|
m_pSong->SetBPMAtBeat( m_NoteFieldEdit.m_fBeginMarker, fNewBPM );
|
||||||
|
m_pSong->SetBPMAtBeat( fNewClipboardEndBeat, fOldBPM );
|
||||||
|
}
|
||||||
|
break;
|
||||||
case play:
|
case play:
|
||||||
{
|
{
|
||||||
ASSERT( m_NoteFieldEdit.m_fBeginMarker!=-1 && m_NoteFieldEdit.m_fEndMarker!=-1 );
|
ASSERT( m_NoteFieldEdit.m_fBeginMarker!=-1 && m_NoteFieldEdit.m_fEndMarker!=-1 );
|
||||||
@@ -1596,34 +1615,10 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case insert_and_shift:
|
case insert_and_shift:
|
||||||
{
|
NoteDataUtil::ShiftRows( m_NoteFieldEdit, GAMESTATE->m_fSongBeat, 1 );
|
||||||
NoteData temp;
|
|
||||||
temp.SetNumTracks( m_NoteFieldEdit.GetNumTracks() );
|
|
||||||
int iTakeFromRow=0;
|
|
||||||
int iPasteAtRow;
|
|
||||||
|
|
||||||
iTakeFromRow = BeatToNoteRow( GAMESTATE->m_fSongBeat );
|
|
||||||
iPasteAtRow = BeatToNoteRow( GAMESTATE->m_fSongBeat+1 );
|
|
||||||
|
|
||||||
temp.CopyRange( &m_NoteFieldEdit, iTakeFromRow, m_NoteFieldEdit.GetLastRow() );
|
|
||||||
m_NoteFieldEdit.ClearRange( min(iTakeFromRow,iPasteAtRow), m_NoteFieldEdit.GetLastRow() );
|
|
||||||
m_NoteFieldEdit.CopyRange( &temp, 0, temp.GetLastRow(), iPasteAtRow );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case delete_and_shift:
|
case delete_and_shift:
|
||||||
{
|
NoteDataUtil::ShiftRows( m_NoteFieldEdit, GAMESTATE->m_fSongBeat, -1 );
|
||||||
NoteData temp;
|
|
||||||
temp.SetNumTracks( m_NoteFieldEdit.GetNumTracks() );
|
|
||||||
int iTakeFromRow=0;
|
|
||||||
int iPasteAtRow;
|
|
||||||
|
|
||||||
iTakeFromRow = BeatToNoteRow( GAMESTATE->m_fSongBeat+1 );
|
|
||||||
iPasteAtRow = BeatToNoteRow( GAMESTATE->m_fSongBeat );
|
|
||||||
|
|
||||||
temp.CopyRange( &m_NoteFieldEdit, iTakeFromRow, m_NoteFieldEdit.GetLastRow() );
|
|
||||||
m_NoteFieldEdit.ClearRange( min(iTakeFromRow,iPasteAtRow), m_NoteFieldEdit.GetLastRow() );
|
|
||||||
m_NoteFieldEdit.CopyRange( &temp, 0, temp.GetLastRow(), iPasteAtRow );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
|
|||||||
@@ -107,8 +107,6 @@ public:
|
|||||||
player_options,
|
player_options,
|
||||||
song_options,
|
song_options,
|
||||||
edit_song_info,
|
edit_song_info,
|
||||||
// edit_bpm,
|
|
||||||
// edit_stop,
|
|
||||||
edit_bg_change,
|
edit_bg_change,
|
||||||
play_preview_music,
|
play_preview_music,
|
||||||
exit,
|
exit,
|
||||||
@@ -126,6 +124,7 @@ public:
|
|||||||
turn,
|
turn,
|
||||||
transform,
|
transform,
|
||||||
alter,
|
alter,
|
||||||
|
tempo,
|
||||||
play,
|
play,
|
||||||
record,
|
record,
|
||||||
insert_and_shift,
|
insert_and_shift,
|
||||||
@@ -136,6 +135,7 @@ public:
|
|||||||
enum TurnType { left, right, mirror, shuffle, super_shuffle, NUM_TURN_TYPES };
|
enum TurnType { left, right, mirror, shuffle, super_shuffle, NUM_TURN_TYPES };
|
||||||
enum TransformType { little, wide, big, quick, skippy, NUM_TRANSFORM_TYPES };
|
enum TransformType { little, wide, big, quick, skippy, NUM_TRANSFORM_TYPES };
|
||||||
enum AlterType { backwards, swap_sides, copy_left_to_right, copy_right_to_left, clear_left, clear_right, collapse_to_one, shift_left, shift_right, NUM_ALTER_TYPES };
|
enum AlterType { backwards, swap_sides, copy_left_to_right, copy_right_to_left, clear_left, clear_right, collapse_to_one, shift_left, shift_right, NUM_ALTER_TYPES };
|
||||||
|
enum TempoType { compress_2x, expand_2x, NUM_TEMPO_TYPES };
|
||||||
|
|
||||||
enum EditNotesStatisticsChoice {
|
enum EditNotesStatisticsChoice {
|
||||||
difficulty,
|
difficulty,
|
||||||
|
|||||||
@@ -130,6 +130,27 @@ void Song::AddBPMSegment( BPMSegment seg )
|
|||||||
SortBPMSegmentsArray( m_BPMSegments );
|
SortBPMSegmentsArray( m_BPMSegments );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Song::SetBPMAtBeat( float fBeat, float fBPM )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for( i=0; i<m_BPMSegments.size(); i++ )
|
||||||
|
if( m_BPMSegments[i].m_fStartBeat == fBeat )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( i == m_BPMSegments.size() ) // there is no BPMSegment at the current beat
|
||||||
|
{
|
||||||
|
// create a new BPMSegment
|
||||||
|
AddBPMSegment( BPMSegment(fBeat, fBPM) );
|
||||||
|
}
|
||||||
|
else // BPMSegment being modified is m_BPMSegments[i]
|
||||||
|
{
|
||||||
|
if( i > 0 && fabsf(m_BPMSegments[i-1].m_fBPM - fBPM) < 0.009f )
|
||||||
|
m_BPMSegments.erase( m_BPMSegments.begin()+i,
|
||||||
|
m_BPMSegments.begin()+i+1);
|
||||||
|
else
|
||||||
|
m_BPMSegments[i].m_fBPM = fBPM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Song::AddStopSegment( StopSegment seg )
|
void Song::AddStopSegment( StopSegment seg )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
return m_BPMSegments[i].m_fBPM;
|
return m_BPMSegments[i].m_fBPM;
|
||||||
}
|
}
|
||||||
|
void SetBPMAtBeat( float fBeat, float fBPM );
|
||||||
BPMSegment& GetBPMSegmentAtBeat( float fBeat )
|
BPMSegment& GetBPMSegmentAtBeat( float fBeat )
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|||||||
Reference in New Issue
Block a user