diff --git a/stepmania/src/NoteDataUtil.cpp b/stepmania/src/NoteDataUtil.cpp index 281a364cfb..97695c9ef5 100644 --- a/stepmania/src/NoteDataUtil.cpp +++ b/stepmania/src/NoteDataUtil.cpp @@ -703,6 +703,8 @@ void NoteDataUtil::SnapToNearestNoteType( NoteData &in, NoteType nt1, NoteType n case NOTE_TYPE_16TH: fSnapInterval1 = 1/4.0f; break; case NOTE_TYPE_24TH: fSnapInterval1 = 1/6.0f; break; case NOTE_TYPE_32ND: fSnapInterval1 = 1/8.0f; break; + case NOTE_TYPE_48TH: fSnapInterval1 = 1/12.0f; break; + case NOTE_TYPE_64TH: fSnapInterval1 = 1/16.0f; break; default: ASSERT( false ); return; } @@ -714,6 +716,8 @@ void NoteDataUtil::SnapToNearestNoteType( NoteData &in, NoteType nt1, NoteType n case NOTE_TYPE_16TH: fSnapInterval2 = 1/4.0f; break; case NOTE_TYPE_24TH: fSnapInterval2 = 1/6.0f; break; case NOTE_TYPE_32ND: fSnapInterval2 = 1/8.0f; break; + case NOTE_TYPE_48TH: fSnapInterval2 = 1/12.0f; break; + case NOTE_TYPE_64TH: fSnapInterval2 = 1/16.0f; break; case -1: fSnapInterval2 = 10000; break; // nothing will ever snap to this. That's what we want! default: ASSERT( false ); return; } diff --git a/stepmania/src/NoteTypes.cpp b/stepmania/src/NoteTypes.cpp index 3afa9c52d9..4ebd5ffd80 100644 --- a/stepmania/src/NoteTypes.cpp +++ b/stepmania/src/NoteTypes.cpp @@ -22,6 +22,11 @@ float NoteTypeToBeat( NoteType nt ) case NOTE_TYPE_16TH: return 1.0f/4; // sixteenth notes case NOTE_TYPE_24TH: return 1.0f/6; // twenty-forth notes case NOTE_TYPE_32ND: return 1.0f/8; // thirty-second notes + case NOTE_TYPE_48TH: return 1.0f/12; + case NOTE_TYPE_64TH: return 1.0f/16; + // MD 11/03/03 - NOTE_TYPE_INVALID should be treated as equivalent to + // NOTE_TYPE_192ND; NOTE_TYPE_96TH should not exist. + case NOTE_TYPE_INVALID: return 1.0f/48; default: ASSERT(0); return 0; } } @@ -34,6 +39,8 @@ NoteType GetNoteType( int iNoteIndex ) else if( iNoteIndex % (ROWS_PER_MEASURE/16) == 0) return NOTE_TYPE_16TH; else if( iNoteIndex % (ROWS_PER_MEASURE/24) == 0) return NOTE_TYPE_24TH; else if( iNoteIndex % (ROWS_PER_MEASURE/32) == 0) return NOTE_TYPE_32ND; + else if( iNoteIndex % (ROWS_PER_MEASURE/48) == 0) return NOTE_TYPE_48TH; + else if( iNoteIndex % (ROWS_PER_MEASURE/64) == 0) return NOTE_TYPE_64TH; else return NOTE_TYPE_INVALID; }; @@ -47,6 +54,9 @@ CString NoteTypeToString( NoteType nt ) case NOTE_TYPE_16TH: return "16th"; case NOTE_TYPE_24TH: return "24th"; case NOTE_TYPE_32ND: return "32nd"; + case NOTE_TYPE_48TH: return "48th"; + case NOTE_TYPE_64TH: return "64th"; + case NOTE_TYPE_INVALID: return "192nd"; default: ASSERT(0); return ""; } } diff --git a/stepmania/src/NoteTypes.h b/stepmania/src/NoteTypes.h index 5e5fce98aa..2fec64e94b 100644 --- a/stepmania/src/NoteTypes.h +++ b/stepmania/src/NoteTypes.h @@ -62,7 +62,7 @@ enum }; const int BEATS_PER_MEASURE = 4; -const int ROWS_PER_BEAT = 24; // It is important that this number is evenly divisible by 2, 3, and 4. +const int ROWS_PER_BEAT = 48; // It is important that this number is evenly divisible by 2, 3, and 4. const int ROWS_PER_MEASURE = ROWS_PER_BEAT * BEATS_PER_MEASURE; enum NoteType @@ -71,8 +71,13 @@ enum NoteType NOTE_TYPE_8TH, // eighth note NOTE_TYPE_12TH, // triplet NOTE_TYPE_16TH, // sixteenth note - NOTE_TYPE_24TH, // twenty-forth note + NOTE_TYPE_24TH, // twenty-fourth note NOTE_TYPE_32ND, // thirty-second note + // MD 11/02/03 - added finer divisions + NOTE_TYPE_48TH, // forty-eighth note + NOTE_TYPE_64TH, // sixty-fourth note + // 96ths and 192nds have no place here - if you're using them, + // you have already failed as a stepmaker. :-) NUM_NOTE_TYPES, NOTE_TYPE_INVALID }; diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index c25e79bcbe..a808c412aa 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -154,15 +154,17 @@ Menu g_AreaMenu MenuRow( "Paste at current beat", true ), MenuRow( "Paste at begin marker", true ), MenuRow( "Clear", true ), - MenuRow( "Quantize", true, 0, "4TH","8TH","12TH","16TH","24TH","32ND" ), + MenuRow( "Quantize", true, 0, "4TH","8TH","12TH","16TH","24TH","32ND","48TH","64TH" ), MenuRow( "Turn", true, 0, "Left","Right","Mirror","Shuffle","Super Shuffle" ), 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( "Tempo", true, 0, "Compress 2x","Expand 2x" ), + MenuRow( "Tempo", true, 0, "Compress 2x","Compress 3->2","Compress 4->3","Expand 3->4","Expand 2->3","Expand 2x" ), MenuRow( "Play selection", true ), MenuRow( "Record in selection", true ), MenuRow( "Insert beat and shift down", true ), - MenuRow( "Delete beat and shift up", true ) + MenuRow( "Delete beat and shift up", true ), + MenuRow( "Convert beats to pause", true ), + MenuRow( "Convert pause to beats", true ) ); @@ -500,6 +502,8 @@ void ScreenEdit::UpdateTextInfo() case NOTE_TYPE_16TH: sNoteType = "16th notes"; break; case NOTE_TYPE_24TH: sNoteType = "24th notes"; break; case NOTE_TYPE_32ND: sNoteType = "32nd notes"; break; + case NOTE_TYPE_48TH: sNoteType = "48th notes"; break; + case NOTE_TYPE_64TH: sNoteType = "64th notes"; break; default: ASSERT(0); } @@ -843,6 +847,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ g_AreaMenu.rows[tempo].enabled = bAreaSelected; g_AreaMenu.rows[play].enabled = bAreaSelected; g_AreaMenu.rows[record].enabled = bAreaSelected; + g_AreaMenu.rows[convert_beats_to_pause].enabled = bAreaSelected; SCREENMAN->MiniMenu( &g_AreaMenu, SM_BackFromAreaMenu ); } break; @@ -908,6 +913,8 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ case SDLK_F7: case SDLK_F8: { + // MD 11/02/03 - start referring to Editor.ini entries + // entries here: BPMDelta, BPMDeltaFine float fBPM = m_pSong->GetBPMAtBeat( GAMESTATE->m_fSongBeat ); float fDeltaBPM; switch( DeviceI.button ) @@ -932,6 +939,8 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ case SDLK_F9: case SDLK_F10: { + // MD 11/02/03 - start referring to Editor.ini entries + // entries here: StopDelta, StopDeltaFine float fStopDelta; switch( DeviceI.button ) { @@ -939,7 +948,11 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ case SDLK_F10: fStopDelta = +0.02f; break; default: ASSERT(0); return; } - switch( type ) + // MD 11/02/03 - requested: fine adjust for stops as well + if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, SDLK_RALT)) || + INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, SDLK_LALT)) ) + fStopDelta /= 4; /* .005 */ + else switch( type ) { case IET_SLOW_REPEAT: fStopDelta *= 10; break; case IET_FAST_REPEAT: fStopDelta *= 40; break; @@ -970,6 +983,8 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ case SDLK_F11: case SDLK_F12: { + // MD 11/02/03 - start referring to Editor.ini entries + // entries here: OffsetDelta, OffsetDeltaFine float fOffsetDelta; switch( DeviceI.button ) { @@ -992,6 +1007,9 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ case SDLK_LEFTBRACKET: case SDLK_RIGHTBRACKET: { + // MD 11/02/03 - start referring to Editor.ini entries + // entries here: SampleLengthDelta, SampleLengthDeltaFine + // SampleStartDelta, SampleStartDeltaFine float fDelta; switch( DeviceI.button ) { @@ -1549,14 +1567,22 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers ) float fScale = -1; switch( at ) { - case compress_2x: fScale = 0.5f; break; - case expand_2x: fScale = 2; break; + case compress_2x: fScale = 0.5f; break; + case compress_3_2: fScale = 2.0f/3; break; + case compress_4_3: fScale = 0.75f; break; + case expand_4_3: fScale = 4.0f/3; break; + case expand_3_2: fScale = 1.5f; break; + case expand_2x: fScale = 2; break; default: ASSERT(0); } switch( 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; default: ASSERT(0); } @@ -1641,6 +1667,64 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers ) case delete_and_shift: NoteDataUtil::ShiftRows( m_NoteFieldEdit, GAMESTATE->m_fSongBeat, -1 ); break; + // MD 11/02/03 - Converting selected region to a pause of the same length. + case convert_beat_to_pause: + { + ASSERT( m_NoteFieldEdit.m_fBeginMarker!=-1 && m_NoteFieldEdit.m_fEndMarker!=-1 ); + float fStopLength = m_NoteFieldEdit.m_fEndMarker - m_NoteFieldEdit.m_fBeginMarker; + // be sure not to clobber the row at the start - a row at the end + // can be dropped safely, though + NoteDataUtil::ShiftRows( m_NoteFieldEdit, + m_NoteFieldEdit.m_fBeginMarker + 0.003f, + (m_NoteFieldEdit.m_fEndMarker-m_NoteFieldEdit.m_fBeginMarker) + ); + unsigned i; + for( i=0; im_StopSegments.size(); i++ ) + { + if( m_pSong->m_StopSegments[i].m_fStartBeat == m_NoteFieldEdit.m_fBeginMarker ) + break; + } + + if( i == m_pSong->m_StopSegments.size() ) // there is no BPMSegment at the current beat + { + m_pSong->AddStopSegment( StopSegment(GAMESTATE->m_fSongBeat, fStopLength) ); + } + else // StopSegment being extended is m_StopSegments[i] + { + m_pSong->m_StopSegments[i].m_fStopSeconds += fStopLength; + } + m_NoteFieldEdit.m_fEndMarker = -1; + break; + } + // MD 11/02/03 - Converting a pause at the current beat into beats. + // I know this will break holds that cross the pause. Anyone who + // wants to rewrite this to fix that behavior is welcome to - I'm + // not sure how exactly to do it without making this a lot longer + // than it is. + case convert_pause_to_beat: + { + float fBPMatPause = m_pSong->GetBPMAtBeat( GAMESTATE->m_fSongBeat ); + unsigned i; + for( i=0; im_StopSegments.size(); i++ ) + { + if( m_pSong->m_StopSegments[i].m_fStartBeat == GAMESTATE->m_fSongBeat ) + break; + } + + if( i == m_pSong->m_StopSegments.size() ) // there is no BPMSegment at the current beat + break; + else // StopSegment being modified is m_StopSegments[i] + { + float fStopLength = m_pSong->m_StopSegments[i].m_fStopSeconds; + m_pSong->m_StopSegments.erase( m_pSong->m_StopSegments.begin()+i, + m_pSong->m_StopSegments.begin()+i+1); + fStopLength /= fBPMatPause; + fStopLength *= 60; + // don't move the step from where it is, just move everything later + NoteDataUtil::ShiftRows( m_NoteFieldEdit, GAMESTATE->m_fSongBeat + 0.003f, fStopLength ); + } + + } default: ASSERT(0); }; diff --git a/stepmania/src/ScreenEdit.h b/stepmania/src/ScreenEdit.h index 51af053f60..ec7a1702b9 100644 --- a/stepmania/src/ScreenEdit.h +++ b/stepmania/src/ScreenEdit.h @@ -115,6 +115,7 @@ public: }; void HandleMainMenuChoice( MainMenuChoice c, int* iAnswers ); + // MD 11/02/03 - added conversions of beats to pauses and vice-versa enum AreaMenuChoice { cut, copy, @@ -130,13 +131,16 @@ public: record, insert_and_shift, delete_and_shift, + convert_beat_to_pause, + convert_pause_to_beat, NUM_AREA_MENU_CHOICES }; void HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers ); enum TurnType { left, right, mirror, shuffle, super_shuffle, NUM_TURN_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 TempoType { compress_2x, expand_2x, NUM_TEMPO_TYPES }; + // MD 11/02/03 - added additional tempo adjusts which make "sense" + enum TempoType { compress_2x, compress_3_2, compress_4_3, expand_4_3, expand_3_2, expand_2x, NUM_TEMPO_TYPES }; enum EditNotesStatisticsChoice { difficulty, diff --git a/stepmania/src/SnapDisplay.cpp b/stepmania/src/SnapDisplay.cpp index c96cf824ea..673c573a5b 100644 --- a/stepmania/src/SnapDisplay.cpp +++ b/stepmania/src/SnapDisplay.cpp @@ -24,7 +24,7 @@ SnapDisplay::SnapDisplay() int i; for( i=0; i<2; i++ ) { - m_sprIndicators[i].Load( THEME->GetPathToG("SnapDisplay icon 6x1") ); + m_sprIndicators[i].Load( THEME->GetPathToG("SnapDisplay icon 8x1") ); ASSERT( m_sprIndicators[i].GetNumStates() == NUM_NOTE_TYPES ); m_sprIndicators[i].StopAnimating(); this->AddChild( &m_sprIndicators[i] ); @@ -55,7 +55,8 @@ bool SnapDisplay::PrevSnapMode() bool SnapDisplay::NextSnapMode() { - if( m_NoteType == NOTE_TYPE_32ND ) // this is the smallest snap we should allow + if( m_NoteType == NOTE_TYPE_64TH ) // this is the smallest snap we should allow + // MD 11/02/03 - changed to 64ths because support for 48ths and 64ths comes in today. return false; m_NoteType = NoteType(m_NoteType+1);