diff --git a/src/NoteDataUtil.cpp b/src/NoteDataUtil.cpp index c892d3d52b..022691c700 100644 --- a/src/NoteDataUtil.cpp +++ b/src/NoteDataUtil.cpp @@ -778,27 +778,118 @@ void NoteDataUtil::LoadTransformedLightsFromTwo( const NoteData &marquee, const NoteDataUtil::RemoveMines( out ); } +struct RadarStats { + int taps; + int jumps; + int hands; + int quads; +}; + +RadarStats CalculateRadarStatsFast( const NoteData &in, RadarStats &out ) +{ + out.taps = 0; + out.jumps = 0; + out.hands = 0; + out.quads = 0; + map simultaneousMap; + map simultaneousMapNoHold; + map simultaneousMapTapHoldHead; + map::iterator itr; + for( int t=0; tsecond++; + + if( (itr = simultaneousMapNoHold.find(r)) == simultaneousMapNoHold.end() ) + simultaneousMapNoHold[r] = 1; + else + itr->second++; + + if( tn.type == TapNote::tap || tn.type == TapNote::lift || tn.type == TapNote::hold_head ) + { + simultaneousMapTapHoldHead[r] = 1; + } + + if( tn.type == TapNote::hold_head ) + { + int searchStartRow = r + 1; + int searchEndRow = r + tn.iDuration; + FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( in, rr, searchStartRow, searchEndRow ) + { + switch( in.GetTapNote(t, rr).type ) + { + case TapNote::mine: + case TapNote::empty: + case TapNote::fake: + continue; // skip these types - they don't count + } + if( (itr = simultaneousMap.find(rr)) == simultaneousMap.end() ) + simultaneousMap[rr] = 1; + else + itr->second++; + } + } + } + } + for( itr = simultaneousMap.begin(); itr != simultaneousMap.end(); itr ++ ) + { + if( itr->second >= 3 ) + { + out.hands ++; + if( itr->second >= 4 ) + { + out.quads ++; + } + } + } + for( itr = simultaneousMapNoHold.begin(); itr != simultaneousMapNoHold.end(); itr ++ ) + { + if( itr->second >= 2 ) + { + out.jumps ++; + } + } + out.taps = simultaneousMapTapHoldHead.size(); + return out; +} + void NoteDataUtil::CalculateRadarValues( const NoteData &in, float fSongSeconds, RadarValues& out ) { + RadarStats stats; + CalculateRadarStatsFast( in, stats ); + // The for loop and the assert are used to ensure that all fields of // RadarValue get set in here. FOREACH_ENUM( RadarCategory, rc ) { switch( rc ) { - case RadarCategory_Stream: out[rc] = GetStreamRadarValue( in, fSongSeconds ); break; - case RadarCategory_Voltage: out[rc] = GetVoltageRadarValue( in, fSongSeconds ); break; - case RadarCategory_Air: out[rc] = GetAirRadarValue( in, fSongSeconds ); break; - case RadarCategory_Freeze: out[rc] = GetFreezeRadarValue( in, fSongSeconds ); break; - case RadarCategory_Chaos: out[rc] = GetChaosRadarValue( in, fSongSeconds ); break; - case RadarCategory_TapsAndHolds: out[rc] = (float) in.GetNumRowsWithTapOrHoldHead(); break; - case RadarCategory_Jumps: out[rc] = (float) in.GetNumJumps(); break; - case RadarCategory_Holds: out[rc] = (float) in.GetNumHoldNotes(); break; - case RadarCategory_Mines: out[rc] = (float) in.GetNumMines(); break; - case RadarCategory_Hands: out[rc] = (float) in.GetNumHands(); break; - case RadarCategory_Rolls: out[rc] = (float) in.GetNumRolls(); break; - case RadarCategory_Lifts: out[rc] = (float) in.GetNumLifts(); break; - case RadarCategory_Fakes: out[rc] = (float) in.GetNumFakes(); break; + case RadarCategory_Stream: out[rc] = GetStreamRadarValue( in, fSongSeconds ); break; + case RadarCategory_Voltage: out[rc] = GetVoltageRadarValue( in, fSongSeconds ); break; + case RadarCategory_Air: out[rc] = GetAirRadarValue( in, fSongSeconds ); break; + case RadarCategory_Freeze: out[rc] = GetFreezeRadarValue( in, fSongSeconds ); break; + case RadarCategory_Chaos: out[rc] = GetChaosRadarValue( in, fSongSeconds ); break; + case RadarCategory_TapsAndHolds: out[rc] = (float) stats.taps; break; + case RadarCategory_Jumps: out[rc] = (float) stats.jumps; break; + case RadarCategory_Holds: out[rc] = (float) in.GetNumHoldNotes(); break; + case RadarCategory_Mines: out[rc] = (float) in.GetNumMines(); break; + case RadarCategory_Hands: out[rc] = (float) stats.hands; break; + case RadarCategory_Rolls: out[rc] = (float) in.GetNumRolls(); break; + case RadarCategory_Lifts: out[rc] = (float) in.GetNumLifts(); break; + case RadarCategory_Fakes: out[rc] = (float) in.GetNumFakes(); break; default: ASSERT(0); } }