diff --git a/src/NoteDataUtil.cpp b/src/NoteDataUtil.cpp index d48de7a147..879e38d70a 100644 --- a/src/NoteDataUtil.cpp +++ b/src/NoteDataUtil.cpp @@ -951,13 +951,13 @@ void NoteDataUtil::AutogenKickbox(const NoteData& in, NoteData& out, const Timin out.RevalidateATIs(vector(), false); } -struct recent_note_t +struct recent_note { int row; int track; - recent_note_t() + recent_note() :row(0), track(0) {} - recent_note_t(int r, int t) + recent_note(int r, int t) :row(r), track(t) {} }; @@ -967,7 +967,7 @@ struct recent_note_t // its loop. So this state structure exists to be passed to a function that // can be called from both places to do the work. If this were Lua, // DoRowEndRadarCalc would be a nested function. -Kyz -struct crv_state_t +struct crv_state { bool judgable; // hold_ends tracks where currently active holds will end, which is used @@ -978,12 +978,12 @@ struct crv_state_t int num_holds_on_curr_row; int num_notes_on_curr_row; - crv_state_t() + crv_state() :judgable(false), num_holds_on_curr_row(0), num_notes_on_curr_row(0) {} }; -static void DoRowEndRadarCalc(crv_state_t& state, RadarValues& out) +static void DoRowEndRadarCalc(crv_state& state, RadarValues& out) { if(state.judgable) { @@ -1006,7 +1006,7 @@ void NoteDataUtil::CalculateRadarValues( const NoteData &in, float fSongSeconds, // and track number of a tap note. When the pair at the beginning is too // old, it's deleted. This provides a way to have a rolling window // that scans for the peak step density. -Kyz - vector recent_notes; + vector recent_notes; NoteData::all_tracks_const_iterator curr_note= in.GetTapNoteRangeAllTracks(0, MAX_NOTE_ROW); TimingData* timing= GAMESTATE->GetProcessedTimingData(); @@ -1017,7 +1017,7 @@ void NoteDataUtil::CalculateRadarValues( const NoteData &in, float fSongSeconds, const int voltage_window= BeatToNoteRow(voltage_window_beats); size_t max_notes_in_voltage_window= 0; int num_chaos_rows= 0; - crv_state_t state; + crv_state state; while(!curr_note.IsAtEnd()) { @@ -1073,7 +1073,7 @@ void NoteDataUtil::CalculateRadarValues( const NoteData &in, float fSongSeconds, ++state.num_notes_on_curr_row; ++total_taps; recent_notes.push_back( - recent_note_t(curr_row, curr_note.Track())); + recent_note(curr_row, curr_note.Track())); max_notes_in_voltage_window= max(recent_notes.size(), max_notes_in_voltage_window); // If there is one hold active, and one tap on this row, it does diff --git a/src/NoteDataWithScoring.cpp b/src/NoteDataWithScoring.cpp index e5ed1190e3..b0ac95ee3b 100644 --- a/src/NoteDataWithScoring.cpp +++ b/src/NoteDataWithScoring.cpp @@ -178,16 +178,16 @@ float GetActualChaosRadarValue( const NoteData &in, float fSongSeconds, const Pl } } -struct hold_status_t +struct hold_status { int end_row; int last_held_row; - hold_status_t(int e, int l) + hold_status(int e, int l) :end_row(e), last_held_row(l) {} }; -struct garv_state_t +struct garv_state { int curr_row; int notes_hit_for_stream; @@ -202,7 +202,7 @@ struct garv_state_t int lifts_hit; // hold_ends tracks where currently active holds will end, which is used // to count the number of hands. -Kyz - vector hold_ends; + vector hold_ends; int num_notes_on_curr_row; // num_holds_on_curr_row saves us the work of tracking where holds started // just to keep a jump of two holds from counting as a hand. @@ -222,7 +222,7 @@ struct garv_state_t TapNoteScore hands_tns; TapNoteScore lifts_tns; bool judgable; - garv_state_t() + garv_state() :curr_row(0), notes_hit_for_stream(0), jumps_hit_for_air(0), holds_held(0), rolls_held(0), notes_hit(0), taps_hit(0), jumps_hit(0), hands_hit(0), mines_avoided(0), lifts_hit(0), num_notes_on_curr_row(0), @@ -235,7 +235,7 @@ struct garv_state_t {} }; -static void DoRowEndRadarActualCalc(garv_state_t& state, RadarValues& out) +static void DoRowEndRadarActualCalc(garv_state& state, RadarValues& out) { if(state.judgable && state.last_tns_on_row != TapNoteScore_Invalid) { @@ -274,7 +274,7 @@ void NoteDataWithScoring::GetActualRadarValues(const NoteData &in, // NoteDataUtil::CalculateRadarValues because I couldn't figure out a good // way to combine them into one. -Kyz PlayerNumber pn= pss.m_player_number; - garv_state_t state; + garv_state state; NoteData::all_tracks_const_iterator curr_note= in.GetTapNoteRangeAllTracks(0, MAX_NOTE_ROW); @@ -336,7 +336,7 @@ void NoteDataWithScoring::GetActualRadarValues(const NoteData &in, state.rolls_held+= (curr_note->HoldResult.hns >= HNS_Held); } state.hold_ends.push_back( - hold_status_t(state.curr_row + curr_note->iDuration, + hold_status(state.curr_row + curr_note->iDuration, curr_note->HoldResult.iLastHeldRow)); ++state.num_holds_on_curr_row; } diff --git a/src/TimingData.cpp b/src/TimingData.cpp index c684de6ff6..b0becfecec 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -780,9 +780,21 @@ float TimingData::GetElapsedTimeInternal(GetBeatStarts& start, float beat, float bps= GetBPMAtRow(start.last_row) / 60.0f; #define INC_INDEX(index) ++curr_segment; ++index; bool find_marker= beat < FLT_MAX; + // Stops require this special kluge to handle the case where a stop and a + // warp are on the same row and the lookup table entry would be between + // the stop and the warp. If that happens, then the last_time in the entry + // is pushed past the marker by the stop, so the marker can't be found and + // the step that is on that row comes up as a miss. + // So this kluge backs up the lookup table entry by one step if the last + // thing found was a stop. -Kyz + bool last_found_was_a_stop= false; + GetBeatStarts pre_stop_state= start; + unsigned int start_segment= curr_segment; - while(curr_segment < max_segment) + while(curr_segment < max_segment || curr_segment - start_segment <= 1) { + last_found_was_a_stop= false; + pre_stop_state= start; int event_row= INT_MAX; int event_type= NOT_FOUND; FindEvent(event_row, event_type, start, beat, find_marker, bpms, warps, stops, @@ -802,6 +814,7 @@ float TimingData::GetElapsedTimeInternal(GetBeatStarts& start, float beat, break; case FOUND_STOP: case FOUND_STOP_DELAY: + last_found_was_a_stop= true; time_to_next_event= ToStop(stops[start.stop])->GetPause(); next_event_time= start.last_time + time_to_next_event; start.last_time= next_event_time; @@ -831,6 +844,10 @@ float TimingData::GetElapsedTimeInternal(GetBeatStarts& start, float beat, start.last_row= event_row; } #undef INC_INDEX + if(last_found_was_a_stop) + { + start= pre_stop_state; + } return start.last_time; }