From 61a69fe4575a864a90d117977ddc57ab11478e4f Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Fri, 16 Sep 2011 22:27:56 +0700 Subject: [PATCH] prepwork: also generate a data structure for note statistics that can determine the number of notes to display from any beat to any beat in O(log n) [n = number of non-empty rows]. it might be used to determine the first displayed beat or last displayed beat based on number of notes on screen (instead of fixed beats), if this can be implemented properly, then notes will no longer disappear or appear during a long slow scrolls/speeds [as long as the number of notes to display is in our limit]. --- src/Player.cpp | 62 +++++++++++++++++++++++++++++------------------ src/PlayerState.h | 17 ++++++++++--- 2 files changed, 53 insertions(+), 26 deletions(-) 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.