diff --git a/stepmania/src/GameplayAssist.cpp b/stepmania/src/GameplayAssist.cpp index 5a93f2ccd0..9da3e356b9 100644 --- a/stepmania/src/GameplayAssist.cpp +++ b/stepmania/src/GameplayAssist.cpp @@ -9,14 +9,18 @@ void GameplayAssist::Init() { - m_soundAssistTick.Load( THEME->GetPathS("ScreenEdit","assist tick"), true ); + m_soundAssistClap.Load( THEME->GetPathS("GameplayAssist","clap"), true ); + m_soundAssistMetronomeMeasure.Load( THEME->GetPathS("GameplayAssist","metronome measure"), true ); + m_soundAssistMetronomeBeat.Load( THEME->GetPathS("GameplayAssist","metronome beat"), true ); } void GameplayAssist::PlayTicks( const NoteData &nd ) { - if( !GAMESTATE->m_SongOptions.GetStage().m_bAssistTick ) + bool bClap = GAMESTATE->m_SongOptions.GetCurrent().m_bAssistClap; + bool bMetronome = GAMESTATE->m_SongOptions.GetCurrent().m_bAssistMetronome; + if( !bClap && !bMetronome ) return; - + /* Sound cards have a latency between when a sample is Play()ed and when the sound * will start coming out the speaker. Compensate for this by boosting fPositionSeconds * ahead. This is just to make sure that we request the sound early enough for it to @@ -30,30 +34,67 @@ void GameplayAssist::PlayTicks( const NoteData &nd ) if( iSongRow < iRowLastCrossed ) iRowLastCrossed = iSongRow; - int iTickRow = -1; - // for each index we crossed since the last update: - FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( nd, r, iRowLastCrossed+1, iSongRow+1 ) - if( nd.IsThereATapOrHoldHeadAtRow( r ) ) - iTickRow = r; + if( bClap ) + { + int iClapRow = -1; + // for each index we crossed since the last update: + FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( nd, r, iRowLastCrossed+1, iSongRow+1 ) + if( nd.IsThereATapOrHoldHeadAtRow( r ) ) + iClapRow = r; + + if( iClapRow != -1 ) + { + const float fTickBeat = NoteRowToBeat( iClapRow ); + const float fTickSecond = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeatNoOffset( fTickBeat ); + float fSecondsUntil = fTickSecond - GAMESTATE->m_fMusicSeconds; + fSecondsUntil /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; /* 2x music rate means the time until the tick is halved */ + + RageSoundParams p; + p.m_StartTime = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); + m_soundAssistClap.Play( &p ); + } + } + + if( bMetronome ) + { + //iRowLastCrossed+1, iSongRow+1 + + int iLastCrossedBeat = iRowLastCrossed / ROWS_PER_BEAT; + int iCurrentBeat = iSongRow / ROWS_PER_BEAT; + + int iMetronomeRow = -1; + bool bIsMeasure = false; + + if( iLastCrossedBeat != iCurrentBeat ) + { + iMetronomeRow = iCurrentBeat * ROWS_PER_BEAT; + bIsMeasure = (iCurrentBeat % BEATS_PER_MEASURE) == 0; + } + + if( iMetronomeRow != -1 ) + { + const float fTickBeat = NoteRowToBeat( iMetronomeRow ); + const float fTickSecond = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeatNoOffset( fTickBeat ); + float fSecondsUntil = fTickSecond - GAMESTATE->m_fMusicSeconds; + fSecondsUntil /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; /* 2x music rate means the time until the tick is halved */ + + RageSoundParams p; + p.m_StartTime = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); + if( bIsMeasure ) + m_soundAssistMetronomeMeasure.Play( &p ); + else + m_soundAssistMetronomeBeat.Play( &p ); + } + } iRowLastCrossed = iSongRow; - - if( iTickRow != -1 ) - { - const float fTickBeat = NoteRowToBeat( iTickRow ); - const float fTickSecond = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeatNoOffset( fTickBeat ); - float fSecondsUntil = fTickSecond - GAMESTATE->m_fMusicSeconds; - fSecondsUntil /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; /* 2x music rate means the time until the tick is halved */ - - RageSoundParams p; - p.m_StartTime = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); - m_soundAssistTick.Play( &p ); - } } void GameplayAssist::StopPlaying() { - m_soundAssistTick.StopPlaying(); + m_soundAssistClap.StopPlaying(); + m_soundAssistMetronomeMeasure.StopPlaying(); + m_soundAssistMetronomeBeat.StopPlaying(); } /* diff --git a/stepmania/src/GameplayAssist.h b/stepmania/src/GameplayAssist.h index 87bc0f3c28..16305a810c 100644 --- a/stepmania/src/GameplayAssist.h +++ b/stepmania/src/GameplayAssist.h @@ -14,7 +14,9 @@ public: void PlayTicks( const NoteData &nd ); void StopPlaying(); private: - RageSound m_soundAssistTick; + RageSound m_soundAssistClap; + RageSound m_soundAssistMetronomeMeasure; + RageSound m_soundAssistMetronomeBeat; }; diff --git a/stepmania/src/ScreenDebugOverlay.cpp b/stepmania/src/ScreenDebugOverlay.cpp index 3d7c6c9989..75f6d47669 100644 --- a/stepmania/src/ScreenDebugOverlay.cpp +++ b/stepmania/src/ScreenDebugOverlay.cpp @@ -413,7 +413,7 @@ void ChangeVolume( float fDelta ) static LocalizedString AUTO_PLAY ( "ScreenDebugOverlay", "AutoPlay" ); -static LocalizedString ASSIST_TICK ( "ScreenDebugOverlay", "AssistTick" ); +static LocalizedString ASSIST ( "ScreenDebugOverlay", "Assist" ); static LocalizedString AUTOSYNC ( "ScreenDebugOverlay", "Autosync" ); static LocalizedString COIN_MODE ( "ScreenDebugOverlay", "CoinMode" ); static LocalizedString HALT ( "ScreenDebugOverlay", "Halt" ); @@ -478,16 +478,34 @@ class DebugLineAutoplay : public IDebugLine } }; -class DebugLineAssistTick : public IDebugLine +class DebugLineAssist : public IDebugLine { - virtual RString GetDescription() { return ASSIST_TICK.GetValue(); } + virtual RString GetDescription() { return ASSIST.GetValue(); } virtual Type GetType() const { return gameplay_only; } - virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_bAssistTick; } + virtual RString GetValue() { + SongOptions so; + so.m_bAssistClap = GAMESTATE->m_SongOptions.GetSong().m_bAssistClap; + so.m_bAssistMetronome = GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome; + if( so.m_bAssistClap || so.m_bAssistMetronome ) + return so.GetLocalizedString(); + else + return OFF.GetValue(); + } + virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_bAssistClap || GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome; } virtual void Do( RString &sMessageOut ) { - bool bAssistTick = !GAMESTATE->m_SongOptions.GetSong().m_bAssistTick; - SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_bAssistTick, bAssistTick ); - MESSAGEMAN->Broadcast( Message_AssistTickChanged ); + ASSERT( GAMESTATE->m_MasterPlayerNumber != PLAYER_INVALID ); + bool bHoldingShift = INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT) ); + bool b; + if( bHoldingShift ) + b = !GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome; + else + b = !GAMESTATE->m_SongOptions.GetSong().m_bAssistClap; + if( bHoldingShift ) + SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_bAssistMetronome, b ); + else + SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_bAssistClap, b ); + IDebugLine::Do( sMessageOut ); } }; @@ -918,7 +936,7 @@ class DebugLineUptime : public IDebugLine */ DECLARE_ONE( DebugLineAutoplay ); -DECLARE_ONE( DebugLineAssistTick ); +DECLARE_ONE( DebugLineAssist ); DECLARE_ONE( DebugLineAutosync ); DECLARE_ONE( DebugLineCoinMode ); DECLARE_ONE( DebugLineSlow ); diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 5a9fb0675a..9241045039 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -1374,7 +1374,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) DoHelp(); break; case EDIT_BUTTON_TOGGLE_ASSIST_TICK: - SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_bAssistTick, !GAMESTATE->m_SongOptions.GetStage().m_bAssistTick ); + SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_bAssistClap, !GAMESTATE->m_SongOptions.GetStage().m_bAssistClap ); break; case EDIT_BUTTON_OPEN_NEXT_STEPS: case EDIT_BUTTON_OPEN_PREV_STEPS: @@ -2016,7 +2016,7 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB ) TransitionEditState( STATE_EDITING ); break; case EDIT_BUTTON_TOGGLE_ASSIST_TICK: - SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_bAssistTick, !GAMESTATE->m_SongOptions.GetStage().m_bAssistTick ); + SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_bAssistClap, !GAMESTATE->m_SongOptions.GetStage().m_bAssistClap ); break; case EDIT_BUTTON_TOGGLE_AUTOPLAY: { diff --git a/stepmania/src/SongOptions.cpp b/stepmania/src/SongOptions.cpp index 030cf6d6cf..60dd4bc6eb 100644 --- a/stepmania/src/SongOptions.cpp +++ b/stepmania/src/SongOptions.cpp @@ -10,7 +10,8 @@ void SongOptions::Init() m_DrainType = DRAIN_NORMAL; m_iBatteryLives = 4; m_FailType = FAIL_IMMEDIATE; - m_bAssistTick = false; + m_bAssistClap = false; + m_bAssistMetronome = false; m_fMusicRate = 1.0f; m_SpeedfMusicRate = 1.0f; m_fHaste = 0.0f; @@ -32,7 +33,8 @@ void SongOptions::Approach( const SongOptions& other, float fDeltaSeconds ) DO_COPY( m_iBatteryLives ); APPROACH( fMusicRate ); APPROACH( fHaste ); - DO_COPY( m_bAssistTick ); + DO_COPY( m_bAssistClap ); + DO_COPY( m_bAssistMetronome ); DO_COPY( m_AutosyncType ); DO_COPY( m_SoundEffectType ); DO_COPY( m_bSaveScore ); @@ -107,13 +109,17 @@ void SongOptions::GetMods( vector &AddTo ) const case SOUNDEFFECT_PITCH: AddTo.push_back("EffectPitch"); break; default: ASSERT(0); } + + if( m_bAssistClap ) + AddTo.push_back( "Clap" ); + if( m_bAssistMetronome ) + AddTo.push_back( "Metronome" ); } -void SongOptions::GetLocalizedMods( vector &AddTo ) const +void SongOptions::GetLocalizedMods( vector &v ) const { - vector vMods; - GetMods( vMods ); - FOREACH( RString, vMods, s ) + GetMods( v ); + FOREACH( RString, v, s ) { *s = CommonMetrics::LocalizeOptionItem( *s, true ); } @@ -190,7 +196,8 @@ void SongOptions::FromString( const RString &sOptions ) m_FailType = so.m_FailType; } - else if( sBit == "assisttick" ) m_bAssistTick = on; + else if( sBit == "clap" ) m_bAssistClap = on; + else if( sBit == "metronome" ) m_bAssistMetronome = on; else if( sBit == "autosync" || sBit == "autosyncsong" ) m_AutosyncType = on ? AUTOSYNC_SONG : AUTOSYNC_OFF; else if( sBit == "autosyncmachine" ) @@ -220,7 +227,8 @@ bool SongOptions::operator==( const SongOptions &other ) const COMPARE( m_FailType ); COMPARE( m_fMusicRate ); COMPARE( m_fHaste ); - COMPARE( m_bAssistTick ); + COMPARE( m_bAssistClap ); + COMPARE( m_bAssistMetronome ); COMPARE( m_AutosyncType ); COMPARE( m_SoundEffectType ); COMPARE( m_bSaveScore ); diff --git a/stepmania/src/SongOptions.h b/stepmania/src/SongOptions.h index 8287f3b10e..76e25b78e9 100644 --- a/stepmania/src/SongOptions.h +++ b/stepmania/src/SongOptions.h @@ -30,7 +30,8 @@ public: FailType m_FailType; float m_fMusicRate, m_SpeedfMusicRate; float m_fHaste, m_SpeedfHaste; - bool m_bAssistTick; + bool m_bAssistClap; + bool m_bAssistMetronome; enum AutosyncType { AUTOSYNC_OFF, AUTOSYNC_SONG,