diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index b2b6d60941..318bd75e01 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -211,6 +211,46 @@ void ArrowEffects::Update() } } +float GetSpeedMultiplier( float fSongBeat, float fMusicSeconds, const TimingData &tim ) +{ + if( tim.m_SpeedSegments.size() == 0 ) + return 1.0; + + const int index = tim.GetSpeedSegmentIndexAtBeat( fSongBeat ); + + const SpeedSegment &seg = tim.m_SpeedSegments[index]; + float fStartBeat = NoteRowToBeat(seg.m_iStartRow); + float fStartTime = tim.GetElapsedTimeFromBeat( fStartBeat ) - tim.GetDelayAtBeat( fStartBeat ); + float fEndTime; + float fCurTime = fMusicSeconds; + + if( seg.m_usMode == 1 ) // seconds + { + fEndTime = fStartTime + seg.m_fWait; + } + else + { + fEndTime = tim.GetElapsedTimeFromBeat( fStartBeat + seg.m_fWait ) - tim.GetDelayAtBeat( fStartBeat + seg.m_fWait ); + } + + if( fEndTime >= fCurTime && ( index > 0 || tim.m_SpeedSegments[0].m_fWait > 0.0 ) ) + { + const float fPriorSpeed = ( index == 0 ? 1 : tim.m_SpeedSegments[index - 1].m_fPercent ); + float fTimeUsed = fCurTime - fStartTime; + float fDuration = fEndTime - fStartTime; + float fRatioUsed = fDuration == 0.0 ? 1 : fTimeUsed / fDuration; + + float fDistance = fPriorSpeed - seg.m_fPercent; + float fRatioNeed = fRatioUsed * -fDistance; + return (fPriorSpeed + fRatioNeed); + } + else + { + return seg.m_fPercent; + } + +} + /* For visibility testing: if bAbsolute is false, random modifiers must return * the minimum possible scroll speed. */ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float fNoteBeat, float &fPeakYOffsetOut, bool &bIsPastPeakOut, bool bAbsolute ) @@ -233,7 +273,8 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float { float fBeatsUntilStep = fNoteBeat - fSongBeat; float fYOffsetBeatSpacing = fBeatsUntilStep; - fYOffset += fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); + float fSpeedMultiplier = GAMESTATE->m_bInStepEditor ? 1.0 : GetSpeedMultiplier( position.m_fSongBeatVisible, position.m_fMusicSecondsVisible, pCurSteps->m_Timing ); + fYOffset += fSpeedMultiplier * fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); } if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 0.0f ) @@ -251,42 +292,6 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float // (per issue 24), edit this to reflect that. -aj fYOffset *= ARROW_SPACING; - // Factor in the SpeedSegment. - TimingData &tim = pCurSteps->m_Timing; - - const int index = tim.GetSpeedSegmentIndexAtBeat( fSongBeat ); - if( !GAMESTATE->m_bInStepEditor && index > 0 ) - { - SpeedSegment &seg = tim.GetSpeedSegmentAtBeat( fSongBeat ); - float fStartBeat = NoteRowToBeat(seg.m_iStartRow); - float fStartTime = tim.GetElapsedTimeFromBeat( fStartBeat ); - float fEndTime; - - if( seg.m_usMode == 1 ) // seconds - { - fEndTime = fStartTime + seg.m_fWait; - } - else - { - fEndTime = tim.GetElapsedTimeFromBeat( fStartBeat + seg.m_fWait ); - } - float fCurTime = tim.GetElapsedTimeFromBeat( fSongBeat ); - - if( fEndTime >= fCurTime ) - { - const float fPriorSpeed = tim.m_SpeedSegments[index - 1].m_fPercent; - float fTimeUsed = fCurTime - fStartTime; - float fRatioUsed = fTimeUsed / (fEndTime - fStartTime); - - float fDistance = fPriorSpeed - seg.m_fPercent; - float fRatioNeed = fRatioUsed * -fDistance; - fYOffset *= (fPriorSpeed + fRatioNeed); - } - else - { - fYOffset *= seg.m_fPercent; - } - } // don't mess with the arrows after they've crossed 0 if( fYOffset < 0 ) return fYOffset * pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollSpeed; diff --git a/src/GameState.cpp b/src/GameState.cpp index 3b4f792986..76bd07acd5 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -128,7 +128,8 @@ GameState::GameState() : m_stEditSource( Message_EditSourceStepsTypeChanged ), m_iEditCourseEntryIndex( Message_EditCourseEntryIndexChanged ), m_sEditLocalProfileID( Message_EditLocalProfileIDChanged ), - m_bIsEditorStepTiming( true ) + m_bIsEditorStepTiming( true ), + m_bInStepEditor( false ) { g_pImpl = new GameStateImpl;