diff --git a/src/Player.cpp b/src/Player.cpp index dc6d2bf2ac..6f4b111c2b 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -583,6 +583,42 @@ static bool NeedsHoldJudging( const TapNote &tn ) } } +static void GenerateCacheDataStructure(PlayerState *pPlayerState, const NoteData ¬es) { + + pPlayerState->m_CacheDisplayedBeat.clear(); + + const vector vScrolls = pPlayerState->GetDisplayedTiming().GetTimingSegments( SEGMENT_SCROLL ); + + float displayedBeat = 0.0f; + float lastRealBeat = 0.0f; + float lastRatio = 1.0f; + for ( unsigned i = 0; i < vScrolls.size(); i++ ) + { + ScrollSegment *seg = ToScroll( vScrolls[i] ); + displayedBeat += ( seg->GetBeat() - lastRealBeat ) * lastRatio; + lastRealBeat = seg->GetBeat(); + lastRatio = seg->GetRatio(); + CacheDisplayedBeat c = { seg->GetBeat(), displayedBeat, seg->GetRatio() }; + pPlayerState->m_CacheDisplayedBeat.push_back( c ); + } + + pPlayerState->m_CacheNoteStat.clear(); + + NoteData::all_tracks_const_iterator it = notes.GetTapNoteRangeAllTracks( 0, MAX_NOTE_ROW, true ); + int count = 0, lastCount = 0; + for( ; !it.IsAtEnd(); ++it ) + { + for( int t = 0; t < notes.GetNumTracks(); t++ ) + { + if( notes.GetTapNote( t, it.Row() ) != TAP_EMPTY ) count ++; + } + CacheNoteStat c = { NoteRowToBeat(it.Row()), lastCount, count }; + lastCount = count; + pPlayerState->m_CacheNoteStat.push_back(c); + } + +} + void Player::Load() { m_bLoaded = true; @@ -624,6 +660,9 @@ void Player::Load() m_Timing = &GAMESTATE->m_pCurSteps[pn]->m_Timing; + // Generate some cache data structure. + GenerateCacheDataStructure(m_pPlayerState, m_NoteData); + switch( GAMESTATE->m_PlayMode ) { case PLAY_MODE_RAVE: @@ -751,26 +790,6 @@ void Player::SendComboMessages( int iOldCombo, int iOldMissCombo ) } } -static void GenerateCacheDataStructure(PlayerState *pPlayerState, NoteData ¬es) { - - pPlayerState->m_CacheDisplayedBeat.clear(); - - const vector vScrolls = pPlayerState->GetDisplayedTiming().GetTimingSegments( SEGMENT_SCROLL ); - - float displayedBeat = 0.0f; - float lastRealBeat = 0.0f; - float lastRatio = 1.0f; - for ( unsigned i = 0; i < vScrolls.size(); i++ ) - { - ScrollSegment *seg = ToScroll( vScrolls[i] ); - displayedBeat += ( seg->GetBeat() - lastRealBeat ) * lastRatio; - lastRealBeat = seg->GetBeat(); - lastRatio = seg->GetRatio(); - CacheDisplayedBeat c = { seg->GetBeat(), displayedBeat, seg->GetRatio() }; - pPlayerState->m_CacheDisplayedBeat.push_back( c ); - } -} - void Player::Update( float fDeltaTime ) { const RageTimer now; @@ -900,9 +919,6 @@ void Player::Update( float fDeltaTime ) if( m_bPaused ) return; - // Generate some cache data structure. - GenerateCacheDataStructure(m_pPlayerState, m_NoteData); - // Check for a strum miss if( m_pPlayerState->m_fLastStrumMusicSeconds != -1 && m_pPlayerState->m_fLastStrumMusicSeconds + g_fTimingWindowStrum < m_pPlayerState->m_Position.m_fMusicSeconds ) diff --git a/src/PlayerState.h b/src/PlayerState.h index 4a02e8c86c..c8c059b66e 100644 --- a/src/PlayerState.h +++ b/src/PlayerState.h @@ -18,6 +18,12 @@ struct CacheDisplayedBeat { float velocity; }; +struct CacheNoteStat { + float beat; + int notesLower; + int notesUpper; +}; + /** @brief The player's indivdual state. */ class PlayerState { @@ -55,12 +61,17 @@ public: * @brief Holds a vector sorted by real beat, the beat that would be displayed * in the NoteField (because they are affected by scroll segments), and * also the velocity. - * This vector will be populated each frame by Player and will probably - * be used a lot in ArrowEffects. This is way better than iterating through - * all scroll segments per tap note per frame, which is very slow! + * This vector will be populated on Player::Load() be used a lot in + * ArrowEffects to determine the target beat in O(log N). */ vector m_CacheDisplayedBeat; + /** + * @brief Holds a vector sorted by beat, the cumulative number of notes from + * the start of the song. This will be used by [insert more description here] + */ + vector m_CacheNoteStat; + /** * @brief Change the PlayerOptions to their default. * @param l the level of mods to reset.