diff --git a/src/AdjustSync.cpp b/src/AdjustSync.cpp index f626947e87..b6d16181d8 100644 --- a/src/AdjustSync.cpp +++ b/src/AdjustSync.cpp @@ -267,7 +267,7 @@ void AdjustSync::AutosyncTempo() GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += fIntercept; const float fScaleBPM = 1.0f/(1.0f - fSlope); TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming; - vector &bpms = timing.allTimingSegments[SEGMENT_BPM]; + vector &bpms = timing.m_avpTimingSegments[SEGMENT_BPM]; for (unsigned i = 0; i < bpms.size(); i++) { BPMSegment *b = static_cast(bpms[i]); @@ -277,14 +277,14 @@ void AdjustSync::AutosyncTempo() /* We assume that the stops were measured as a number of beats. * Therefore, if we change the bpms, we need to make a similar * change to the stops. */ - vector &stops = timing.allTimingSegments[SEGMENT_STOP]; + vector &stops = timing.m_avpTimingSegments[SEGMENT_STOP]; for (unsigned i = 0; i < stops.size(); i++) { StopSegment *s = static_cast(stops[i]); s->SetPause(s->GetPause() * (1.0f - fSlope)); } // Do the same for delays. - vector &delays = timing.allTimingSegments[SEGMENT_DELAY]; + vector &delays = timing.m_avpTimingSegments[SEGMENT_DELAY]; for (unsigned i = 0; i < delays.size(); i++) { DelaySegment *s = static_cast(delays[i]); @@ -359,8 +359,8 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo ) } } - vector &bpmTest = testing.allTimingSegments[SEGMENT_BPM]; - vector &bpmOrig = original.allTimingSegments[SEGMENT_BPM]; + vector &bpmTest = testing.m_avpTimingSegments[SEGMENT_BPM]; + vector &bpmOrig = original.m_avpTimingSegments[SEGMENT_BPM]; for( unsigned i=0; i< bpmTest.size(); i++ ) { BPMSegment *bT = static_cast(bpmTest[i]); @@ -384,8 +384,8 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo ) } } - vector &stopTest = testing.allTimingSegments[SEGMENT_STOP]; - vector &stopOrig = original.allTimingSegments[SEGMENT_STOP]; + vector &stopTest = testing.m_avpTimingSegments[SEGMENT_STOP]; + vector &stopOrig = original.m_avpTimingSegments[SEGMENT_STOP]; for( unsigned i=0; i< stopTest.size(); i++ ) { StopSegment *sT = static_cast(stopTest[i]); @@ -409,8 +409,8 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo ) } } - vector &delyTest = testing.allTimingSegments[SEGMENT_DELAY]; - vector &delyOrig = original.allTimingSegments[SEGMENT_DELAY]; + vector &delyTest = testing.m_avpTimingSegments[SEGMENT_DELAY]; + vector &delyOrig = original.m_avpTimingSegments[SEGMENT_DELAY]; for( unsigned i=0; i< delyTest.size(); i++ ) { DelaySegment *sT = static_cast(delyTest[i]); diff --git a/src/Background.cpp b/src/Background.cpp index c987102faa..38214e5e50 100644 --- a/src/Background.cpp +++ b/src/Background.cpp @@ -421,7 +421,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac const TimingData &timing = m_pSong->m_SongTiming; // change BG every time signature change or 4 measures - const vector &tSigs = timing.allTimingSegments[SEGMENT_TIME_SIG]; + const vector &tSigs = timing.m_avpTimingSegments[SEGMENT_TIME_SIG]; for (unsigned i = 0; i < tSigs.size(); i++) { @@ -448,7 +448,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac } // change BG every BPM change that is at the beginning of a measure - const vector &bpms = timing.allTimingSegments[SEGMENT_BPM]; + const vector &bpms = timing.m_avpTimingSegments[SEGMENT_BPM]; for( unsigned i=0; i *segs = pTiming->allTimingSegments; + const vector *segs = pTiming->m_avpTimingSegments; unsigned i = 0; // Draw beat bars if( ( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) && pTiming != NULL ) diff --git a/src/NotesLoaderJson.cpp b/src/NotesLoaderJson.cpp index 4d3b41f85b..147f4514c6 100644 --- a/src/NotesLoaderJson.cpp +++ b/src/NotesLoaderJson.cpp @@ -41,8 +41,8 @@ static void Deserialize(TimingSegment &seg_, const Json::Value &root) static void Deserialize(TimingData &td, const Json::Value &root) { - JsonUtil::DeserializeVectorPointers( td.allTimingSegments[SEGMENT_BPM], Deserialize, root["BpmSegments"] ); - JsonUtil::DeserializeVectorPointers( td.allTimingSegments[SEGMENT_STOP], Deserialize, root["StopSegments"] ); + JsonUtil::DeserializeVectorPointers( td.m_avpTimingSegments[SEGMENT_BPM], Deserialize, root["BpmSegments"] ); + JsonUtil::DeserializeVectorPointers( td.m_avpTimingSegments[SEGMENT_STOP], Deserialize, root["StopSegments"] ); } static void Deserialize(LyricSegment &o, const Json::Value &root) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 12776584bb..644b6ab567 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -927,7 +927,7 @@ bool SMLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache } // Ensure all warps from negative time changes are in order. - vector &warps = out.m_SongTiming.allTimingSegments[SEGMENT_WARP]; + vector &warps = out.m_SongTiming.m_avpTimingSegments[SEGMENT_WARP]; sort(warps.begin(), warps.end()); TidyUpData( out, bFromCache ); return true; diff --git a/src/NotesWriterDWI.cpp b/src/NotesWriterDWI.cpp index 69e3b7c5e5..a8e1c35545 100644 --- a/src/NotesWriterDWI.cpp +++ b/src/NotesWriterDWI.cpp @@ -354,7 +354,7 @@ bool NotesWriterDWI::Write( RString sPath, const Song &out ) f.PutLine( ssprintf("#TITLE:%s;", DwiEscape(out.GetTranslitFullTitle()).c_str()) ); f.PutLine( ssprintf("#ARTIST:%s;", DwiEscape(out.GetTranslitArtist()).c_str()) ); - const vector &bpms = out.m_SongTiming.allTimingSegments[SEGMENT_BPM]; + const vector &bpms = out.m_SongTiming.m_avpTimingSegments[SEGMENT_BPM]; ASSERT_M(bpms[0]->GetRow() == 0, ssprintf("The first BPM Segment must be defined at row 0, not %d!", bpms[0]->GetRow()) ); @@ -382,7 +382,7 @@ bool NotesWriterDWI::Write( RString sPath, const Song &out ) } // TODO: Also check for delays, add them as stops minus one row? - const vector &stops = out.m_SongTiming.allTimingSegments[SEGMENT_STOP]; + const vector &stops = out.m_SongTiming.m_avpTimingSegments[SEGMENT_STOP]; if( !stops.empty() ) { f.Write( "#FREEZE:" ); diff --git a/src/NotesWriterJson.cpp b/src/NotesWriterJson.cpp index e8984a5034..927bbf5c25 100644 --- a/src/NotesWriterJson.cpp +++ b/src/NotesWriterJson.cpp @@ -24,8 +24,8 @@ static void Serialize(const TimingSegment &seg, Json::Value &root) static void Serialize(const TimingData &td, Json::Value &root) { - JsonUtil::SerializeVectorPointers( td.allTimingSegments[SEGMENT_BPM], Serialize, root["BpmSegments"] ); - JsonUtil::SerializeVectorPointers( td.allTimingSegments[SEGMENT_STOP], Serialize, root["StopSegments"] ); + JsonUtil::SerializeVectorPointers( td.m_avpTimingSegments[SEGMENT_BPM], Serialize, root["BpmSegments"] ); + JsonUtil::SerializeVectorPointers( td.m_avpTimingSegments[SEGMENT_STOP], Serialize, root["StopSegments"] ); } static void Serialize(const LyricSegment &o, Json::Value &root) diff --git a/src/NotesWriterSM.cpp b/src/NotesWriterSM.cpp index bc7e769b03..8bdffafac4 100644 --- a/src/NotesWriterSM.cpp +++ b/src/NotesWriterSM.cpp @@ -75,7 +75,7 @@ static void WriteGlobalTags( RageFile &f, Song &out ) f.Write( "#BPMS:" ); - vector &bpms = timing.allTimingSegments[SEGMENT_BPM]; + vector &bpms = timing.m_avpTimingSegments[SEGMENT_BPM]; for( unsigned i=0; i(bpms[i]); @@ -86,7 +86,7 @@ static void WriteGlobalTags( RageFile &f, Song &out ) } f.PutLine( ";" ); - vector &warps = timing.allTimingSegments[SEGMENT_WARP]; + vector &warps = timing.m_avpTimingSegments[SEGMENT_WARP]; unsigned wSize = warps.size(); if( wSize > 0 ) { @@ -102,8 +102,8 @@ static void WriteGlobalTags( RageFile &f, Song &out ) } // TODO: make Delays into Stops that start one row before. - vector &stops = timing.allTimingSegments[SEGMENT_STOP]; - vector &delays = timing.allTimingSegments[SEGMENT_DELAY]; + vector &stops = timing.m_avpTimingSegments[SEGMENT_STOP]; + vector &delays = timing.m_avpTimingSegments[SEGMENT_DELAY]; map allPauses; for( unsigned i=0; i &lines, TimingData timing, bool bIsSo unsigned i = 0; w.Init( "BPMS" ); - vector &bpms = timing.allTimingSegments[SEGMENT_BPM]; + vector &bpms = timing.m_avpTimingSegments[SEGMENT_BPM]; for (; i < bpms.size(); i++) { BPMSegment *bs = static_cast(bpms[i]); @@ -77,7 +77,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Finish(); w.Init( "STOPS" ); - vector &stops = timing.allTimingSegments[SEGMENT_STOP]; + vector &stops = timing.m_avpTimingSegments[SEGMENT_STOP]; for (i = 0; i < stops.size(); i++) { StopSegment *ss = static_cast(stops[i]); @@ -86,7 +86,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Finish(); w.Init( "DELAYS" ); - vector &delays = timing.allTimingSegments[SEGMENT_DELAY]; + vector &delays = timing.m_avpTimingSegments[SEGMENT_DELAY]; for (i = 0; i < delays.size(); i++) { DelaySegment *ss = static_cast(delays[i]); @@ -95,7 +95,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Finish(); w.Init( "WARPS" ); - vector &warps = timing.allTimingSegments[SEGMENT_WARP]; + vector &warps = timing.m_avpTimingSegments[SEGMENT_WARP]; for (i = 0; i < warps.size(); i++) { WarpSegment *ws = static_cast(warps[i]); @@ -103,7 +103,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo } w.Finish(); - vector &tSigs = timing.allTimingSegments[SEGMENT_TIME_SIG]; + vector &tSigs = timing.m_avpTimingSegments[SEGMENT_TIME_SIG]; ASSERT( !tSigs.empty() ); w.Init( "TIMESIGNATURES" ); for (i = 0; i < tSigs.size(); i++) @@ -113,7 +113,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo } w.Finish(); - vector &ticks = timing.allTimingSegments[SEGMENT_TICKCOUNT]; + vector &ticks = timing.m_avpTimingSegments[SEGMENT_TICKCOUNT]; ASSERT( !ticks.empty() ); w.Init( "TICKCOUNTS" ); for (i = 0; i < ticks.size(); i++) @@ -123,7 +123,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo } w.Finish(); - vector &combos = timing.allTimingSegments[SEGMENT_COMBO]; + vector &combos = timing.m_avpTimingSegments[SEGMENT_COMBO]; ASSERT( !combos.empty() ); w.Init( "COMBOS" ); for (i = 0; i < combos.size(); i++) @@ -137,7 +137,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Finish(); // Song Timing should only have the initial value. - vector &speeds = timing.allTimingSegments[SEGMENT_SPEED]; + vector &speeds = timing.m_avpTimingSegments[SEGMENT_SPEED]; w.Init( "SPEEDS" ); for (i = 0; i < speeds.size(); i++) { @@ -147,7 +147,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Finish(); w.Init( "SCROLLS" ); - vector &scrolls = timing.allTimingSegments[SEGMENT_SCROLL]; + vector &scrolls = timing.m_avpTimingSegments[SEGMENT_SCROLL]; for (i = 0; i < scrolls.size(); i++) { ScrollSegment *ss = static_cast(scrolls[i]); @@ -157,7 +157,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo if( !bIsSong ) { - vector &fakes = timing.allTimingSegments[SEGMENT_FAKE]; + vector &fakes = timing.m_avpTimingSegments[SEGMENT_FAKE]; w.Init( "FAKES" ); for (i = 0; i < fakes.size(); i++) { @@ -168,7 +168,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo } w.Init( "LABELS" ); - vector &labels = timing.allTimingSegments[SEGMENT_LABEL]; + vector &labels = timing.m_avpTimingSegments[SEGMENT_LABEL]; for (i = 0; i < labels.size(); i++) { LabelSegment *ls = static_cast(labels[i]); diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index aa325b842f..bc446a03cd 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1893,7 +1893,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) fDelta *= 40; } unsigned i; - vector &stops = GetAppropriateTiming().allTimingSegments[SEGMENT_STOP]; + vector &stops = GetAppropriateTiming().m_avpTimingSegments[SEGMENT_STOP]; for( i=0; iGetRow() == GetRow() ) @@ -4315,10 +4315,10 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns { /* TODO: Maybe wipe out the already there timing data first? * We need to identify the max row within the timing data first. */ - for (unsigned i = 0; i < this->clipboardTiming.allTimingSegments[tst].size(); i++) + for (unsigned i = 0; i < this->clipboardTiming.m_avpTimingSegments[tst].size(); i++) { // TODO: This REALLY needs improving. - TimingSegment * org = this->clipboardTiming.allTimingSegments[tst][i]; + TimingSegment * org = this->clipboardTiming.m_avpTimingSegments[tst][i]; TimingSegment * cpy; switch (tst) @@ -4665,7 +4665,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice break; case time_signature: { - TimeSignatureSegment * ts = GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ); + const TimeSignatureSegment *ts = GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ); ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureChange, ENTER_TIME_SIGNATURE_VALUE, @@ -4684,7 +4684,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice break; case combo: { - ComboSegment *cs = GetAppropriateTiming().GetComboSegmentAtBeat(GetBeat()); + const ComboSegment *cs = GetAppropriateTiming().GetComboSegmentAtBeat(GetBeat()); ScreenTextEntry::TextEntry(SM_BackFromComboChange, ENTER_COMBO_VALUE, ssprintf( "%d/%d", @@ -4998,8 +4998,8 @@ void ScreenEdit::CheckNumberOfNotesAndUndo() { if( EDIT_MODE.GetValue() != EditMode_Home ) return; - - TimeSignatureSegment * curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); + + const TimeSignatureSegment * curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); int rowsPerMeasure = curTime->GetDen() * curTime->GetNum(); for( int row=0; row<=m_NoteDataEdit.GetLastRow(); row+=rowsPerMeasure ) diff --git a/src/TimingData.cpp b/src/TimingData.cpp index cd290de154..141567d93d 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -8,8 +8,7 @@ #include -TimingData::TimingData(float fOffset) : - m_fBeat0OffsetInSeconds(fOffset) +TimingData::TimingData(float fOffset) : m_fBeat0OffsetInSeconds(fOffset) { } @@ -21,7 +20,7 @@ bool TimingData::empty() const { for (unsigned i = 0; i < NUM_TimingSegmentType; i++) { - if (this->allTimingSegments[i].size() > 0) + if (m_avpTimingSegments[i].size() > 0) return false; } return true; @@ -34,13 +33,13 @@ TimingData TimingData::CopyRange(int startRow, int endRow) const FOREACH_ENUM(TimingSegmentType, tst) { unsigned cnt = 0; - for (unsigned j = 0; j < this->allTimingSegments[tst].size(); j++) + for (unsigned j = 0; j < m_avpTimingSegments[tst].size(); j++) { - int row = this->allTimingSegments[tst][j]->GetRow(); + int row = m_avpTimingSegments[tst][j]->GetRow(); if (row >= startRow && row < endRow) { // TODO: This REALLY needs improving. - TimingSegment * org = this->allTimingSegments[tst][j]; + TimingSegment * org = m_avpTimingSegments[tst][j]; TimingSegment * cpy; switch (tst) @@ -117,7 +116,7 @@ void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut, float highe { fMinBPMOut = FLT_MAX; fMaxBPMOut = 0; - const vector &bpms = this->allTimingSegments[SEGMENT_BPM]; + const vector &bpms = m_avpTimingSegments[SEGMENT_BPM]; for (unsigned i = 0; i < bpms.size(); i++) { BPMSegment *seg = static_cast(bpms[i]); @@ -135,31 +134,14 @@ struct ts_less : binary_function { void TimingData::AddSegment(TimingSegmentType tst, TimingSegment * seg) { - vector &segs = this->allTimingSegments[tst]; + vector &segs = m_avpTimingSegments[tst]; // Unsure if this uses the proper comparison. segs.insert(upper_bound(segs.begin(), segs.end(), seg, ts_less()), seg); } -int TimingData::GetSegmentIndexAtRow(TimingSegmentType tst, - int row) const +float TimingData::GetNextSegmentBeatAtRow(TimingSegmentType tst, int row) const { - const vector &segs = this->allTimingSegments[tst]; - unsigned i = 0; - for (; i < segs.size() - 1; i++) - { - TimingSegment *seg = segs[i+1]; - if (seg->GetRow() > row) - { - break; - } - } - return static_cast(i); -} - -float TimingData::GetNextSegmentBeatAtRow(TimingSegmentType tst, - int row) const -{ - const vector segs = this->allTimingSegments[tst]; + const vector segs = m_avpTimingSegments[tst]; for (unsigned i = 0; i < segs.size(); i++ ) { if( segs[i]->GetRow() <= row ) @@ -171,11 +153,10 @@ float TimingData::GetNextSegmentBeatAtRow(TimingSegmentType tst, return NoteRowToBeat(row); } -float TimingData::GetPreviousSegmentBeatAtRow(TimingSegmentType tst, - int row) const +float TimingData::GetPreviousSegmentBeatAtRow(TimingSegmentType tst, int row) const { float backup = -1; - const vector segs = this->allTimingSegments[tst]; + const vector segs = m_avpTimingSegments[tst]; for (unsigned i = 0; i < segs.size(); i++ ) { if( segs[i]->GetRow() >= row ) @@ -187,13 +168,28 @@ float TimingData::GetPreviousSegmentBeatAtRow(TimingSegmentType tst, return (backup > -1) ? backup : NoteRowToBeat(row); } +unsigned TimingData::GetSegmentIndexAtRow(TimingSegmentType tst, int iRow ) const +{ + const vector &vSegments = m_avpTimingSegments[tst]; + + unsigned i = 0; + + // seek to the last segment that goes into effect before iRow. + // OPTIMIZATION OPPORTUNITY: use std::upper_bound instead? + for( ; i < vSegments.size() - 1; ++i ) + if( iRow < vSegments[i+1]->GetRow() ) + break; + + return i; +} + // TODO: Find a way to combine all of these SetAtRows to one. /* Change an existing BPM segment, merge identical segments together or insert a new one. */ void TimingData::SetBPMAtRow( int iNoteRow, float fBPM ) { unsigned i; - vector &bpms = this->allTimingSegments[SEGMENT_BPM]; + vector &bpms = m_avpTimingSegments[SEGMENT_BPM]; for( i=0; iGetRow() >= iNoteRow ) break; @@ -219,7 +215,7 @@ void TimingData::SetBPMAtRow( int iNoteRow, float fBPM ) void TimingData::SetStopAtRow( int iRow, float fSeconds ) { unsigned i; - vector &stops = this->allTimingSegments[SEGMENT_STOP]; + vector &stops = m_avpTimingSegments[SEGMENT_STOP]; for( i=0; iGetRow() == iRow) break; @@ -247,7 +243,7 @@ void TimingData::SetStopAtRow( int iRow, float fSeconds ) void TimingData::SetDelayAtRow( int iRow, float fSeconds ) { unsigned i; - vector &stops = this->allTimingSegments[SEGMENT_DELAY]; + vector &stops = m_avpTimingSegments[SEGMENT_DELAY]; for( i=0; iGetRow() == iRow) break; @@ -275,7 +271,7 @@ void TimingData::SetDelayAtRow( int iRow, float fSeconds ) void TimingData::SetTimeSignatureAtRow( int iRow, int iNumerator, int iDenominator ) { unsigned i; - vector &tSigs = this->allTimingSegments[SEGMENT_TIME_SIG]; + vector &tSigs = m_avpTimingSegments[SEGMENT_TIME_SIG]; for( i = 0; i < tSigs.size(); i++ ) { if( tSigs[i]->GetRow() >= iRow) @@ -304,24 +300,22 @@ void TimingData::SetTimeSignatureAtRow( int iRow, int iNumerator, int iDenominat } } -void TimingData::SetTimeSignatureNumeratorAtRow( int iRow, int iNumerator ) +void TimingData::SetTimeSignatureNumeratorAtRow( int iRow, int iNum ) { - this->SetTimeSignatureAtRow(iRow, - iNumerator, - GetTimeSignatureSegmentAtRow(iRow)->GetDen()); + unsigned iDenom = GetTimeSignatureSegmentAtRow(iRow)->GetDen(); + SetTimeSignatureAtRow(iRow, iNum, iDenom ); } -void TimingData::SetTimeSignatureDenominatorAtRow( int iRow, int iDenominator ) +void TimingData::SetTimeSignatureDenominatorAtRow( int iRow, int iDenom ) { - this->SetTimeSignatureAtRow(iRow, - GetTimeSignatureSegmentAtRow(iRow)->GetNum(), - iDenominator); + unsigned iNum = GetTimeSignatureSegmentAtRow(iRow)->GetNum(); + SetTimeSignatureAtRow( iRow, iNum, iDenom ); } void TimingData::SetWarpAtRow( int iRow, float fNew ) { unsigned i; - vector &warps = this->allTimingSegments[SEGMENT_WARP]; + vector &warps = m_avpTimingSegments[SEGMENT_WARP]; for( i=0; iGetRow() == iRow ) break; @@ -348,7 +342,7 @@ void TimingData::SetWarpAtRow( int iRow, float fNew ) void TimingData::SetTickcountAtRow( int iRow, int iTicks ) { unsigned i = 0; - vector &ticks = this->allTimingSegments[SEGMENT_TICKCOUNT]; + vector &ticks = m_avpTimingSegments[SEGMENT_TICKCOUNT]; for( i=0; iGetRow() >= iRow ) break; @@ -373,7 +367,7 @@ void TimingData::SetTickcountAtRow( int iRow, int iTicks ) void TimingData::SetComboAtRow( int iRow, int iCombo, int iMiss ) { unsigned i; - vector &combos = this->allTimingSegments[SEGMENT_COMBO]; + vector &combos = m_avpTimingSegments[SEGMENT_COMBO]; for( i=0; iGetRow() >= iRow ) break; @@ -401,22 +395,22 @@ void TimingData::SetComboAtRow( int iRow, int iCombo, int iMiss ) void TimingData::SetHitComboAtRow(int iRow, int iCombo) { - this->SetComboAtRow(iRow, + SetComboAtRow(iRow, iCombo, - this->GetComboSegmentAtRow(iRow)->GetMissCombo()); + GetComboSegmentAtRow(iRow)->GetMissCombo()); } void TimingData::SetMissComboAtRow(int iRow, int iMiss) { - this->SetComboAtRow(iRow, - this->GetComboSegmentAtRow(iRow)->GetCombo(), + SetComboAtRow(iRow, + GetComboSegmentAtRow(iRow)->GetCombo(), iMiss); } void TimingData::SetLabelAtRow( int iRow, const RString sLabel ) { unsigned i; - vector &labels = this->allTimingSegments[SEGMENT_LABEL]; + vector &labels = m_avpTimingSegments[SEGMENT_LABEL]; for( i=0; iGetRow() >= iRow ) break; @@ -441,7 +435,7 @@ void TimingData::SetLabelAtRow( int iRow, const RString sLabel ) void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait, unsigned short usMode ) { unsigned i; - vector &speeds = this->allTimingSegments[SEGMENT_SPEED]; + vector &speeds = m_avpTimingSegments[SEGMENT_SPEED]; for( i = 0; i < speeds.size(); i++ ) { if( speeds[i]->GetRow() >= iRow) @@ -473,7 +467,7 @@ void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait, unsigned void TimingData::SetScrollAtRow( int iRow, float fPercent ) { unsigned i; - vector &scrolls = this->allTimingSegments[SEGMENT_SCROLL]; + vector &scrolls = m_avpTimingSegments[SEGMENT_SCROLL]; for( i = 0; i < scrolls.size(); i++ ) { if( scrolls[i]->GetRow() >= iRow) @@ -503,7 +497,7 @@ void TimingData::SetScrollAtRow( int iRow, float fPercent ) void TimingData::SetFakeAtRow( int iRow, float fNew ) { unsigned i; - vector &fakes = this->allTimingSegments[SEGMENT_FAKE]; + vector &fakes = m_avpTimingSegments[SEGMENT_FAKE]; for( i=0; iGetRow() == iRow ) break; @@ -552,7 +546,7 @@ void TimingData::SetSpeedModeAtRow( int iRow, unsigned short usMode ) float TimingData::GetStopAtRow( int iRow ) const { - const vector &stops = this->allTimingSegments[SEGMENT_STOP]; + const vector &stops = m_avpTimingSegments[SEGMENT_STOP]; for( unsigned i=0; i(stops[i]); @@ -567,7 +561,7 @@ float TimingData::GetStopAtRow( int iRow ) const float TimingData::GetDelayAtRow( int iRow ) const { - const vector &stops = this->allTimingSegments[SEGMENT_DELAY]; + const vector &stops = m_avpTimingSegments[SEGMENT_DELAY]; for( unsigned i=0; i(stops[i]); @@ -581,28 +575,28 @@ float TimingData::GetDelayAtRow( int iRow ) const int TimingData::GetComboAtRow( int iNoteRow ) const { - const vector &c = this->allTimingSegments[SEGMENT_COMBO]; - const int index = this->GetSegmentIndexAtRow(SEGMENT_COMBO, iNoteRow); + const vector &c = m_avpTimingSegments[SEGMENT_COMBO]; + const int index = GetSegmentIndexAtRow(SEGMENT_COMBO, iNoteRow); return static_cast(c[index])->GetCombo(); } int TimingData::GetMissComboAtRow(int iNoteRow) const { - const vector &c = this->allTimingSegments[SEGMENT_COMBO]; - const int index = this->GetSegmentIndexAtRow(SEGMENT_COMBO, iNoteRow); + const vector &c = m_avpTimingSegments[SEGMENT_COMBO]; + const int index = GetSegmentIndexAtRow(SEGMENT_COMBO, iNoteRow); return static_cast(c[index])->GetMissCombo(); } RString TimingData::GetLabelAtRow( int iRow ) const { - const vector &l = this->allTimingSegments[SEGMENT_LABEL]; - const int index = this->GetSegmentIndexAtRow(SEGMENT_LABEL, iRow); + const vector &l = m_avpTimingSegments[SEGMENT_LABEL]; + const int index = GetSegmentIndexAtRow(SEGMENT_LABEL, iRow); return static_cast(l[index])->GetLabel(); } float TimingData::GetWarpAtRow( int iWarpRow ) const { - const vector &warps = this->allTimingSegments[SEGMENT_WARP]; + const vector &warps = m_avpTimingSegments[SEGMENT_WARP]; for( unsigned i=0; iGetRow() == iWarpRow ) @@ -635,7 +629,7 @@ float TimingData::GetScrollAtRow( int iRow ) float TimingData::GetFakeAtRow( int iFakeRow ) const { - const vector &fakes = this->allTimingSegments[SEGMENT_FAKE]; + const vector &fakes = m_avpTimingSegments[SEGMENT_FAKE]; for( unsigned i=0; iGetRow() == iFakeRow ) @@ -650,7 +644,7 @@ float TimingData::GetFakeAtRow( int iFakeRow ) const void TimingData::MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor ) { // Change all other BPM segments in this range. - vector &bpms = this->allTimingSegments[SEGMENT_BPM]; + vector &bpms = m_avpTimingSegments[SEGMENT_BPM]; for( unsigned i=0; i(bpms[i]); @@ -692,7 +686,7 @@ void TimingData::MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float f float TimingData::GetBPMAtRow( int iNoteRow ) const { unsigned i; - const vector &bpms = this->allTimingSegments[SEGMENT_BPM]; + const vector &bpms = m_avpTimingSegments[SEGMENT_BPM]; for( i=0; iGetRow() > iNoteRow ) break; @@ -701,17 +695,17 @@ float TimingData::GetBPMAtRow( int iNoteRow ) const bool TimingData::IsWarpAtRow( int iNoteRow ) const { - const vector &warps = this->allTimingSegments[SEGMENT_WARP]; + const vector &warps = m_avpTimingSegments[SEGMENT_WARP]; if( warps.empty() ) return false; - + int i = GetSegmentIndexAtRow( SEGMENT_WARP, iNoteRow ); const WarpSegment *s = static_cast(warps[i]); float beatRow = NoteRowToBeat(iNoteRow); if( s->GetBeat() <= beatRow && beatRow < (s->GetBeat() + s->GetLength() ) ) { // Allow stops inside warps to allow things like stop, warp, stop, warp, stop, and so on. - if( this->allTimingSegments[SEGMENT_STOP].empty() && this->allTimingSegments[SEGMENT_DELAY].empty() ) + if( m_avpTimingSegments[SEGMENT_STOP].empty() && m_avpTimingSegments[SEGMENT_DELAY].empty() ) { return true; } @@ -726,10 +720,10 @@ bool TimingData::IsWarpAtRow( int iNoteRow ) const bool TimingData::IsFakeAtRow( int iNoteRow ) const { - const vector &fakes = this->allTimingSegments[SEGMENT_FAKE]; + const vector &fakes = m_avpTimingSegments[SEGMENT_FAKE]; if( fakes.empty() ) return false; - + int i = GetSegmentIndexAtRow( SEGMENT_FAKE, iNoteRow ); const FakeSegment *s = static_cast(fakes[i]); float beatRow = NoteRowToBeat(iNoteRow); @@ -740,44 +734,30 @@ bool TimingData::IsFakeAtRow( int iNoteRow ) const return false; } -BPMSegment* TimingData::GetBPMSegmentAtRow( int iNoteRow ) +// TODO: make this part of the TimingSegment struct +enum SegmentEffectArea { - vector &bpms = this->allTimingSegments[SEGMENT_BPM]; - if( bpms.empty() ) - return new BPMSegment(); + EffectArea_Row, // takes effect on a single row + EffectArea_Range, // takes effect until the next segment of its type + NUM_EffectArea, + EffectArea_Invalid, +}; - int i = GetSegmentIndexAtRow( SEGMENT_BPM, iNoteRow ); - return static_cast(bpms[i]); -} - -TimeSignatureSegment* TimingData::GetTimeSignatureSegmentAtRow( int iRow ) +TimingSegment* TimingData::GetSegmentAtRow( int iNoteRow, TimingSegmentType tst ) { - unsigned i; - vector &tSigs = this->allTimingSegments[SEGMENT_TIME_SIG]; - for( i=0; iGetRow() > iRow ) + vector vSegments = m_avpTimingSegments[tst]; + + if( vSegments.empty() ) + FAIL_M( ssprintf("GetSegmentAtRow: %s is empty (blame vyhd)", TimingSegmentTypeToString(tst).c_str()) ); + + unsigned index = -1; + + // seek to the last segment before this row + for( index = 0; index < vSegments.size() - 1; ++index ) + if( iNoteRow < vSegments[index+1]->GetRow() ) break; - return static_cast(tSigs[i]); -} -SpeedSegment* TimingData::GetSpeedSegmentAtRow( int iRow ) -{ - unsigned i; - vector &speeds = this->allTimingSegments[SEGMENT_SPEED]; - for( i=0; iGetRow() > iRow ) - break; - return static_cast(speeds[i]); -} - -ScrollSegment* TimingData::GetScrollSegmentAtRow( int iRow ) -{ - unsigned i; - vector &scrolls = this->allTimingSegments[SEGMENT_SCROLL]; - for( i=0; iGetRow() > iRow ) - break; - return static_cast(scrolls[i]); + return vSegments[index]; } int TimingData::GetTimeSignatureNumeratorAtRow( int iRow ) @@ -790,86 +770,16 @@ int TimingData::GetTimeSignatureDenominatorAtRow( int iRow ) return GetTimeSignatureSegmentAtRow( iRow )->GetDen(); } -ComboSegment* TimingData::GetComboSegmentAtRow( int iRow ) -{ - unsigned i; - vector &combos = this->allTimingSegments[SEGMENT_COMBO]; - for( i=0; iGetRow() > iRow ) - break; - return static_cast(combos[i]); -} - -LabelSegment* TimingData::GetLabelSegmentAtRow( int iRow ) -{ - unsigned i; - vector &labels = this->allTimingSegments[SEGMENT_LABEL]; - for( i=0; iGetRow() > iRow ) - break; - return static_cast(labels[i]); -} - -StopSegment* TimingData::GetStopSegmentAtRow( int iNoteRow ) -{ - vector &stops = this->allTimingSegments[SEGMENT_STOP]; - if( stops.empty() ) - return new StopSegment(); - - int i = GetSegmentIndexAtRow( SEGMENT_STOP, iNoteRow ); - return static_cast(stops[i]); -} - -DelaySegment* TimingData::GetDelaySegmentAtRow( int iNoteRow ) -{ - vector &stops = this->allTimingSegments[SEGMENT_DELAY]; - if( stops.empty() ) - return new DelaySegment(); - - int i = GetSegmentIndexAtRow( SEGMENT_DELAY, iNoteRow ); - return static_cast(stops[i]); -} - -WarpSegment* TimingData::GetWarpSegmentAtRow( int iRow ) -{ - vector &warps = this->allTimingSegments[SEGMENT_WARP]; - if( warps.empty() ) - return new WarpSegment(); - - int i = GetSegmentIndexAtRow( SEGMENT_WARP, iRow ); - return static_cast(warps[i]); -} - -FakeSegment* TimingData::GetFakeSegmentAtRow( int iRow ) -{ - vector &fakes = this->allTimingSegments[SEGMENT_FAKE]; - if( fakes.empty() ) - return new FakeSegment(); - - int i = GetSegmentIndexAtRow( SEGMENT_FAKE, iRow ); - return static_cast(fakes[i]); -} - -TickcountSegment* TimingData::GetTickcountSegmentAtRow( int iRow ) -{ - vector &ticks = this->allTimingSegments[SEGMENT_TICKCOUNT]; - if( ticks.empty() ) - return new TickcountSegment(); - - int i = GetSegmentIndexAtRow( SEGMENT_TICKCOUNT, iRow ); - return static_cast(ticks[i]); -} - int TimingData::GetTickcountAtRow( int iRow ) const { - const vector &ticks = this->allTimingSegments[SEGMENT_TICKCOUNT]; + const vector &ticks = m_avpTimingSegments[SEGMENT_TICKCOUNT]; const int index = GetSegmentIndexAtRow( SEGMENT_TICKCOUNT, iRow ); return static_cast(ticks[index])->GetTicks(); } bool TimingData::DoesLabelExist( RString sLabel ) const { - const vector &labels = this->allTimingSegments[SEGMENT_LABEL]; + const vector &labels = m_avpTimingSegments[SEGMENT_LABEL]; for (unsigned i = 0; i < labels.size(); i++) { if (static_cast(labels[i])->GetLabel() == sLabel) @@ -899,7 +809,7 @@ enum void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut, bool &bDelayOut, int &iWarpBeginOut, float &fWarpDestinationOut ) const { - const vector * segs = this->allTimingSegments; + const vector * segs = m_avpTimingSegments; vector::const_iterator itBPMS = segs[SEGMENT_BPM].begin(); vector::const_iterator itWS = segs[SEGMENT_WARP].begin(); vector::const_iterator itSS = segs[SEGMENT_STOP].begin(); @@ -1037,7 +947,7 @@ float TimingData::GetElapsedTimeFromBeat( float fBeat ) const float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const { - const vector * segs = this->allTimingSegments; + const vector * segs = m_avpTimingSegments; vector::const_iterator itBPMS = segs[SEGMENT_BPM].begin(); vector::const_iterator itWS = segs[SEGMENT_WARP].begin(); vector::const_iterator itSS = segs[SEGMENT_STOP].begin(); @@ -1138,7 +1048,7 @@ float TimingData::GetDisplayedBeat( float fBeat ) const { float fOutBeat = 0; unsigned i; - const vector &scrolls = this->allTimingSegments[SEGMENT_SCROLL]; + const vector &scrolls = m_avpTimingSegments[SEGMENT_SCROLL]; for( i=0; iGetBeat() > fBeat ) @@ -1160,9 +1070,9 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for (unsigned i = 0; i < NUM_TimingSegmentType; i++) { - for (unsigned j = 0; j < this->allTimingSegments[i].size(); j++) + for (unsigned j = 0; j < m_avpTimingSegments[i].size(); j++) { - this->allTimingSegments[i][j]->Scale(iStartIndex, length, newLength); + m_avpTimingSegments[i][j]->Scale(iStartIndex, length, newLength); } } @@ -1171,7 +1081,7 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool { int iNewEndIndex = iStartIndex + newLength; float fEndBPMBeforeScaling = GetBPMAtRow(iNewEndIndex); - vector &bpms = this->allTimingSegments[SEGMENT_BPM]; + vector &bpms = m_avpTimingSegments[SEGMENT_BPM]; // adjust BPM changes "between" iStartIndex and iNewEndIndex for ( unsigned i = 0; i < bpms.size(); i++ ) @@ -1197,7 +1107,7 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) { for (unsigned i = 0; i < NUM_TimingSegmentType; i++) { - vector &segs = this->allTimingSegments[i]; + vector &segs = m_avpTimingSegments[i]; for (unsigned j = 0; j < segs.size(); j++) { TimingSegment *seg = segs[j]; @@ -1211,7 +1121,7 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) { /* If we're shifting up at the beginning, we just shifted up the first * BPMSegment. That segment must always begin at 0. */ - vector &bpms = this->allTimingSegments[SEGMENT_BPM]; + vector &bpms = m_avpTimingSegments[SEGMENT_BPM]; ASSERT_M( bpms.size() > 0, "There must be at least one BPM Segment in the chart!" ); bpms[0]->SetRow(0); } @@ -1221,13 +1131,13 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) { /* Remember the BPM at the end of the region being deleted. */ - float fNewBPM = this->GetBPMAtBeat( NoteRowToBeat(iStartRow+iRowsToDelete) ); + float fNewBPM = GetBPMAtBeat( NoteRowToBeat(iStartRow+iRowsToDelete) ); /* We're moving rows up. Delete any BPM changes and stops in the region * being deleted. */ for (unsigned i = 0; i < NUM_TimingSegmentType; i++) { - vector &segs = this->allTimingSegments[i]; + vector &segs = m_avpTimingSegments[i]; for (unsigned j = 0; j < segs.size(); j++) { TimingSegment *seg = segs[j]; @@ -1248,7 +1158,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) } } - this->SetBPMAtRow( iStartRow, fNewBPM ); + SetBPMAtRow( iStartRow, fNewBPM ); } float TimingData::GetDisplayedSpeedPercent( float fSongBeat, float fMusicSeconds ) const @@ -1259,7 +1169,7 @@ float TimingData::GetDisplayedSpeedPercent( float fSongBeat, float fMusicSeconds * isn't existing. */ if (!this) return 1.0f; - const vector &speeds = this->allTimingSegments[SEGMENT_SPEED]; + const vector &speeds = m_avpTimingSegments[SEGMENT_SPEED]; if( speeds.size() == 0 ) return 1.0f; @@ -1310,7 +1220,7 @@ float TimingData::GetDisplayedSpeedPercent( float fSongBeat, float fMusicSeconds void TimingData::TidyUpData() { // If there are no BPM segments, provide a default. - vector *segs = this->allTimingSegments; + vector *segs = m_avpTimingSegments; if( segs[SEGMENT_BPM].empty() ) { LOG->UserLog( "Song file", m_sFile, "has no BPM segments, default provided." ); @@ -1367,39 +1277,39 @@ void TimingData::TidyUpData() bool TimingData::HasBpmChanges() const { - return this->allTimingSegments[SEGMENT_BPM].size()>1; + return m_avpTimingSegments[SEGMENT_BPM].size()>1; } bool TimingData::HasStops() const { - return this->allTimingSegments[SEGMENT_STOP].size()>0; + return m_avpTimingSegments[SEGMENT_STOP].size()>0; } bool TimingData::HasDelays() const { - return this->allTimingSegments[SEGMENT_DELAY].size()>0; + return m_avpTimingSegments[SEGMENT_DELAY].size()>0; } bool TimingData::HasWarps() const { - return this->allTimingSegments[SEGMENT_WARP].size()>0; + return m_avpTimingSegments[SEGMENT_WARP].size()>0; } bool TimingData::HasFakes() const { - return this->allTimingSegments[SEGMENT_FAKE].size()>0; + return m_avpTimingSegments[SEGMENT_FAKE].size()>0; } bool TimingData::HasSpeedChanges() const { - const vector &speeds = this->allTimingSegments[SEGMENT_SPEED]; + const vector &speeds = m_avpTimingSegments[SEGMENT_SPEED]; return (speeds.size()>1 || static_cast(speeds[0])->GetRatio() != 1); } bool TimingData::HasScrollChanges() const { - const vector &scrolls = this->allTimingSegments[SEGMENT_SCROLL]; + const vector &scrolls = m_avpTimingSegments[SEGMENT_SCROLL]; return (scrolls.size()>1 || static_cast(scrolls[0])->GetRatio() != 1); } @@ -1407,7 +1317,7 @@ bool TimingData::HasScrollChanges() const void TimingData::NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, int &iBeatIndexOut, int &iRowsRemainder ) const { iMeasureIndexOut = 0; - const vector &tSigs = this->allTimingSegments[SEGMENT_TIME_SIG]; + const vector &tSigs = m_avpTimingSegments[SEGMENT_TIME_SIG]; for (unsigned i = 0; i < tSigs.size(); i++) { TimeSignatureSegment *curSig = static_cast(tSigs[i]); @@ -1441,7 +1351,7 @@ void TimingData::NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, i vector TimingData::ToVectorString(TimingSegmentType tst, int dec) const { - const vector segs = this->allTimingSegments[tst]; + const vector segs = m_avpTimingSegments[tst]; vector ret; for (unsigned i = 0; i < segs.size(); i++) @@ -1513,7 +1423,7 @@ public: static int GetBPMs( T* p, lua_State *L ) { vector vBPMs; - vector &bpms = p->allTimingSegments[SEGMENT_BPM]; + vector &bpms = p->m_avpTimingSegments[SEGMENT_BPM]; for (unsigned i = 0; i < bpms.size(); i++) { BPMSegment *seg = static_cast(bpms[i]); diff --git a/src/TimingData.h b/src/TimingData.h index f62575701b..b116faea37 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -17,43 +17,33 @@ class TimingData { public: void AddSegment(TimingSegmentType tst, TimingSegment * seg); - - int GetSegmentIndexAtRow(TimingSegmentType tst, - int row) const; - - int GetSegmentIndexAtBeat(TimingSegmentType tst, - float beat) const + + unsigned GetSegmentIndexAtRow(TimingSegmentType tst, int row) const; + unsigned GetSegmentIndexAtBeat(TimingSegmentType tst, float beat) const { - return this->GetSegmentIndexAtRow(tst, BeatToNoteRow(beat)); + return GetSegmentIndexAtRow( tst, BeatToNoteRow(beat) ); } - - float GetNextSegmentBeatAtRow(TimingSegmentType tst, - int row) const; - - float GetNextSegmentBeatAtBeat(TimingSegmentType tst, - float beat) const + + float GetNextSegmentBeatAtRow(TimingSegmentType tst, int row) const; + float GetNextSegmentBeatAtBeat(TimingSegmentType tst, float beat) const { - return this->GetNextSegmentBeatAtRow(tst, BeatToNoteRow(beat)); + return GetNextSegmentBeatAtRow( tst, BeatToNoteRow(beat) ); } - - float GetPreviousSegmentBeatAtRow(TimingSegmentType tst, - int row) const; - - float GetPreviousSegmentBeatAtBeat(TimingSegmentType tst, - float beat) const + + float GetPreviousSegmentBeatAtRow(TimingSegmentType tst, int row) const; + float GetPreviousSegmentBeatAtBeat(TimingSegmentType tst, float beat) const { - return this->GetPreviousSegmentBeatAtRow(tst, BeatToNoteRow(beat)); + return GetPreviousSegmentBeatAtRow( tst, BeatToNoteRow(beat) ); } - + bool empty() const; - + /** * @brief Sets up initial timing data with a defined offset. * @param fOffset the offset from the 0th beat. */ TimingData(float fOffset = 0); - ~TimingData(); - + TimingData CopyRange(int startRow, int endRow) const; /** * @brief Gets the actual BPM of the song, @@ -89,19 +79,54 @@ public: * @param fBPM the BPM. */ void SetBPMAtBeat( float fBeat, float fBPM ) { SetBPMAtRow( BeatToNoteRow(fBeat), fBPM ); } + /** - * @brief Retrieve the BPMSegment at the specified row. - * @param iNoteRow the row that has a BPMSegment. - * @return the BPMSegment in question. + * @brief Retrieve the TimingSegment at the specified row. + * @param iNoteRow the row that has a TimingSegment. + * @param tst the TimingSegmentType requested. + * @return the segment in question. */ - BPMSegment* GetBPMSegmentAtRow( int iNoteRow ); + TimingSegment* GetSegmentAtRow( int iNoteRow, TimingSegmentType tst ); /** - * @brief Retrieve the BPMSegment at the specified beat. - * @param fBeat the beat that has a BPMSegment. - * @return the BPMSegment in question. + * @brief Retrieve the TimingSegment at the given beat. + * @param fBeat the beat that has a TimingSegment. + * @param tst the TimingSegmentType requested. + * @return the segment in question. */ - BPMSegment* GetBPMSegmentAtBeat( float fBeat ) { return GetBPMSegmentAtRow( (int)BeatToNoteRow(fBeat)); } - + TimingSegment* GetSegmentAtBeat( float fBeat, TimingSegmentType tst ) + { + return GetSegmentAtRow( BeatToNoteRow(fBeat), tst ); + } + + /* XXX: convenience shortcuts. We should get rid of these later. */ + #define GetSegmentWithName(Seg, SegType) \ + Seg* Get##Seg##AtRow( int iNoteRow ) \ + { \ + TimingSegment *t = GetSegmentAtRow( iNoteRow, SegType ); \ + return static_cast( t ); \ + } \ + Seg* Get##Seg##AtBeat( float fBeat ) \ + { \ + TimingSegment *t = GetSegmentAtBeat( fBeat, SegType ); \ + return static_cast( t ); \ + } + + // (TimeSignature,TIME_SIG) -> (TimeSignatureSegment,SEGMENT_TIME_SIG) + #define GetSegment(Seg, SegType ) \ + GetSegmentWithName( Seg##Segment, SEGMENT_##SegType ) + + GetSegment( BPM, BPM ); + GetSegment( Stop, STOP ); + GetSegment( Delay, DELAY ); + GetSegment( Warp, WARP ); + GetSegment( Label, LABEL ); + GetSegment( Tickcount, TICKCOUNT ); + GetSegment( Combo, COMBO ); + GetSegment( Speed, SPEED ); + GetSegment( Scroll, SCROLL ); + GetSegment( Fake, FAKE ); + GetSegment( TimeSignature, TIME_SIG ); + /** * @brief Retrieve the stop time at the given row. * @param iNoteRow the row in question. @@ -114,7 +139,7 @@ public: * @return the stop time. */ float GetStopAtBeat( float fBeat ) const { return GetStopAtRow( BeatToNoteRow(fBeat) ); } - + /** * @brief Set the row to have the new stop time. * @param iNoteRow the row to have the new stop time. @@ -127,20 +152,7 @@ public: * @param fSeconds the new stop time. */ void SetStopAtBeat( float fBeat, float fSeconds ) { SetStopAtRow( BeatToNoteRow(fBeat), fSeconds); } - /** - * @brief Retrieve the StopSegment at the specified row. - * @param iNoteRow the row that has a StopSegment. - * @return the StopSegment in question. - */ - StopSegment* GetStopSegmentAtRow( int iNoteRow ); - /** - * @brief Retrieve the StopSegment at the specified beat. - * @param fBeat the beat that has a StopSegment. - * @return the StopSegment in question. - */ - StopSegment* GetStopSegmentAtBeat( float fBeat ) { return GetStopSegmentAtRow( BeatToNoteRow(fBeat)); } - - + /** * @brief Retrieve the delay time at the given row. * @param iNoteRow the row in question. @@ -153,7 +165,7 @@ public: * @return the delay time. */ float GetDelayAtBeat( float fBeat ) const { return GetDelayAtRow( BeatToNoteRow(fBeat) ); } - + /** * @brief Set the row to have the new delay time. * @@ -170,19 +182,7 @@ public: * @param fSeconds the new delay time. */ void SetDelayAtBeat( float fBeat, float fSeconds ) { SetDelayAtRow( BeatToNoteRow(fBeat), fSeconds); } - /** - * @brief Retrieve the DelaySegment at the specified row. - * @param iNoteRow the row that has a DelaySegment. - * @return the DelaySegment in question. - */ - DelaySegment* GetDelaySegmentAtRow( int iNoteRow ); - /** - * @brief Retrieve the DelaySegment at the specified beat. - * @param fBeat the beat that has a DelaySegment. - * @return the DelaySegment in question. - */ - DelaySegment* GetDelaySegmentAtBeat( float fBeat ) { return GetDelaySegmentAtRow( BeatToNoteRow(fBeat)); } - + /** * @brief Retrieve the Time Signature's numerator at the given row. * @param iNoteRow the row in question. @@ -245,19 +245,7 @@ public: * @param iDenominator the denominator. */ void SetTimeSignatureDenominatorAtBeat( float fBeat, int iDenominator ) { SetTimeSignatureDenominatorAtRow( BeatToNoteRow(fBeat), iDenominator); } - /** - * @brief Retrieve the TimeSignatureSegment at the specified row. - * @param iNoteRow the row that has a TimeSignatureSegment. - * @return the TimeSignatureSegment in question. - */ - TimeSignatureSegment* GetTimeSignatureSegmentAtRow( int iNoteRow ); - /** - * @brief Retrieve the TimeSignatureSegment at the specified beat. - * @param fBeat the beat that has a TimeSignatureSegment. - * @return the TimeSignatureSegment in question. - */ - TimeSignatureSegment* GetTimeSignatureSegmentAtBeat( float fBeat ) { return GetTimeSignatureSegmentAtRow( BeatToNoteRow(fBeat) ); } - + /** * @brief Determine the beat to warp to. * @param iRow The row you start on. @@ -282,18 +270,7 @@ public: * @param fNew The destination beat. */ void SetWarpAtBeat( float fBeat, float fNew ) { SetWarpAtRow( BeatToNoteRow( fBeat ), fNew ); } - /** - * @brief Retrieve the WarpSegment at the specified row. - * @param iRow the row to focus on. - * @return the WarpSegment in question. - */ - WarpSegment* GetWarpSegmentAtRow( int iRow ); - /** - * @brief Retrieve the WarpSegment at the specified beat. - * @param fBeat the beat to focus on. - * @return the WarpSegment in question. - */ - WarpSegment* GetWarpSegmentAtBeat( float fBeat ) { return GetWarpSegmentAtRow( BeatToNoteRow( fBeat ) ); } + /** * @brief Checks if the row is inside a warp. * @param iRow the row to focus on. @@ -331,19 +308,7 @@ public: * @param iTicks the tickcount. */ void SetTickcountAtBeat( float fBeat, int iTicks ) { SetTickcountAtRow( BeatToNoteRow( fBeat ), iTicks ); } - /** - * @brief Retrieve the TickcountSegment at the specified row. - * @param iNoteRow the row that has a TickcountSegment. - * @return the TickcountSegment in question. - */ - TickcountSegment* GetTickcountSegmentAtRow( int iNoteRow ); - /** - * @brief Retrieve the TickcountSegment at the specified beat. - * @param fBeat the beat that has a TickcountSegment. - * @return the TickcountSegment in question. - */ - TickcountSegment* GetTickcountSegmentAtBeat( float fBeat ) { return GetTickcountSegmentAtRow( BeatToNoteRow(fBeat) ); } - + /** * @brief Retrieve the Combo at the given row. * @param iNoteRow the row in question. @@ -418,19 +383,7 @@ public: * @param iCombo the Miss Combo. */ void SetMissComboAtBeat( float fBeat, int iCombo ) { SetMissComboAtRow( BeatToNoteRow( fBeat ), iCombo ); } - /** - * @brief Retrieve the ComboSegment at the specified row. - * @param iNoteRow the row that has a ComboSegment. - * @return the ComboSegment in question. - */ - ComboSegment* GetComboSegmentAtRow( int iNoteRow ); - /** - * @brief Retrieve the ComboSegment at the specified beat. - * @param fBeat the beat that has a ComboSegment. - * @return the ComboSegment in question. - */ - ComboSegment* GetComboSegmentAtBeat( float fBeat ) { return GetComboSegmentAtRow( BeatToNoteRow(fBeat) ); } - + /** * @brief Retrieve the Label at the given row. * @param iNoteRow the row in question. @@ -455,25 +408,12 @@ public: * @param sLabel the Label. */ void SetLabelAtBeat( float fBeat, const RString sLabel ) { SetLabelAtRow( BeatToNoteRow( fBeat ), sLabel ); } - /** - * @brief Retrieve the LabelSegment at the specified row. - * @param iNoteRow the row that has a LabelSegment. - * @return the LabelSegment in question. - */ - LabelSegment* GetLabelSegmentAtRow( int iNoteRow ); - /** - * @brief Retrieve the LabelSegment at the specified beat. - * @param fBeat the beat that has a LabelSegment. - * @return the LabelSegment in question. - */ - LabelSegment* GetLabelSegmentAtBeat( float fBeat ) { return GetLabelSegmentAtRow( BeatToNoteRow(fBeat) ); } - + /** * @brief Determine if the requisite label already exists. * @param sLabel the label to check. * @return true if it exists, false otherwise. */ bool DoesLabelExist( RString sLabel ) const; - /** * @brief Retrieve the Speed's percent at the given row. * @param iNoteRow the row in question. @@ -562,21 +502,9 @@ public: * @param usMode the mode. */ void SetSpeedModeAtBeat( float fBeat, unsigned short usMode ) { SetSpeedModeAtRow( BeatToNoteRow(fBeat), usMode); } - /** - * @brief Retrieve the SpeedSegment at the specified row. - * @param iNoteRow the row that has a SpeedSegment. - * @return the SpeedSegment in question. - */ - SpeedSegment* GetSpeedSegmentAtRow( int iNoteRow ); - /** - * @brief Retrieve the SpeedSegment at the specified beat. - * @param fBeat the beat that has a SpeedSegment. - * @return the SpeedSegment in question. - */ - SpeedSegment* GetSpeedSegmentAtBeat( float fBeat ) { return GetSpeedSegmentAtRow( BeatToNoteRow(fBeat) ); } - + float GetDisplayedSpeedPercent( float fBeat, float fMusicSeconds ) const; - + /** * @brief Retrieve the scrolling factor at the given row. * @param iNoteRow the row in question. @@ -602,20 +530,7 @@ public: * @param fPercent the scrolling factor. */ void SetScrollAtBeat( float fBeat, float fPercent ) { SetScrollAtRow( BeatToNoteRow(fBeat), fPercent ); } - - /** - * @brief Retrieve the ScrollSegment at the specified row. - * @param iNoteRow the row that has a ScrollSegment. - * @return the ScrollSegment in question. - */ - ScrollSegment* GetScrollSegmentAtRow( int iNoteRow ); - /** - * @brief Retrieve the ScrollSegment at the specified beat. - * @param fBeat the beat that has a ScrollSegment. - * @return the ScrollSegment in question. - */ - ScrollSegment* GetScrollSegmentAtBeat( float fBeat ) { return GetScrollSegmentAtRow( BeatToNoteRow(fBeat) ); } - + /** * @brief Determine when the fakes end. * @param iRow The row you start on. @@ -640,18 +555,7 @@ public: * @param fNew The destination beat. */ void SetFakeAtBeat( float fBeat, float fNew ) { SetFakeAtRow( BeatToNoteRow( fBeat ), fNew ); } - /** - * @brief Retrieve the FakeSegment at the specified row. - * @param iRow the row to focus on. - * @return the FakeSegment in question. - */ - FakeSegment* GetFakeSegmentAtRow( int iRow ); - /** - * @brief Retrieve the FakeSegment at the specified beat. - * @param fBeat the beat to focus on. - * @return the FakeSegment in question. - */ - FakeSegment* GetFakeSegmentAtBeat( float fBeat ) { return GetFakeSegmentAtRow( BeatToNoteRow( fBeat ) ); } + /** * @brief Checks if the row is inside a fake. * @param iRow the row to focus on. @@ -741,151 +645,35 @@ public: bool HasScrollChanges() const; /** * @brief Compare two sets of timing data to see if they are equal. - * - * TODO: Make doubly sure that we're using the operator== on the proper segments, - * not the generic TimingSegment. * @param other the other TimingData. * @return the equality or lack thereof of the two TimingData. */ bool operator==( const TimingData &other ) { - unsigned i; - - COMPARE(allTimingSegments[SEGMENT_BPM].size()); - for (i = 0; i < allTimingSegments[SEGMENT_BPM].size(); i++) + FOREACH_ENUM( TimingSegmentType, tst ) { - BPMSegment * segT = - static_cast(this->allTimingSegments[SEGMENT_BPM][i]); - BPMSegment * segO = - static_cast(other.allTimingSegments[SEGMENT_BPM][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetBPS() != segO->GetBPS()) return false; + const vector &us = m_avpTimingSegments[tst]; + const vector &them = other.m_avpTimingSegments[tst]; + + // optimization: check vector sizes before contents + if( us.size() != them.size() ) + return false; + + if( !std::equal(us.begin(), us.end(), them.begin()) ) + return false; } - - COMPARE(allTimingSegments[SEGMENT_STOP].size()); - for (i = 0; i < allTimingSegments[SEGMENT_STOP].size(); i++) - { - StopSegment * segT = - static_cast(this->allTimingSegments[SEGMENT_STOP][i]); - StopSegment * segO = - static_cast(other.allTimingSegments[SEGMENT_STOP][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetPause() != segO->GetPause()) return false; - } - - COMPARE(allTimingSegments[SEGMENT_DELAY].size()); - for (i = 0; i < allTimingSegments[SEGMENT_DELAY].size(); i++) - { - DelaySegment * segT = - static_cast(this->allTimingSegments[SEGMENT_DELAY][i]); - DelaySegment * segO = - static_cast(other.allTimingSegments[SEGMENT_DELAY][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetPause() != segO->GetPause()) return false; - } - - COMPARE(allTimingSegments[SEGMENT_WARP].size()); - for (i = 0; i < allTimingSegments[SEGMENT_WARP].size(); i++) - { - WarpSegment * segT = - static_cast(this->allTimingSegments[SEGMENT_WARP][i]); - WarpSegment * segO = - static_cast(other.allTimingSegments[SEGMENT_WARP][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetLength() != segO->GetLength()) return false; - } - - COMPARE(allTimingSegments[SEGMENT_TIME_SIG].size()); - for (i = 0; i < allTimingSegments[SEGMENT_TIME_SIG].size(); i++) - { - TimeSignatureSegment * segT = - static_cast(this->allTimingSegments[SEGMENT_TIME_SIG][i]); - TimeSignatureSegment * segO = - static_cast(other.allTimingSegments[SEGMENT_TIME_SIG][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetNum() != segO->GetNum()) return false; - if (segT->GetDen() != segO->GetDen()) return false; - } - - COMPARE(allTimingSegments[SEGMENT_TICKCOUNT].size()); - for (i = 0; i < allTimingSegments[SEGMENT_TICKCOUNT].size(); i++) - { - TickcountSegment * segT = - static_cast(this->allTimingSegments[SEGMENT_TICKCOUNT][i]); - TickcountSegment * segO = - static_cast(other.allTimingSegments[SEGMENT_TICKCOUNT][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetTicks() != segO->GetTicks()) return false; - } - - COMPARE(allTimingSegments[SEGMENT_COMBO].size()); - for (i = 0; i < allTimingSegments[SEGMENT_COMBO].size(); i++) - { - ComboSegment * segT = - static_cast(this->allTimingSegments[SEGMENT_COMBO][i]); - ComboSegment * segO = - static_cast(other.allTimingSegments[SEGMENT_COMBO][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetCombo() != segO->GetCombo()) return false; - if (segT->GetMissCombo() != segO->GetMissCombo()) return false; - } - - COMPARE(allTimingSegments[SEGMENT_SPEED].size()); - for (i = 0; i < allTimingSegments[SEGMENT_SPEED].size(); i++) - { - SpeedSegment * segT = - static_cast(this->allTimingSegments[SEGMENT_SPEED][i]); - SpeedSegment * segO = - static_cast(other.allTimingSegments[SEGMENT_SPEED][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetRatio() != segO->GetRatio()) return false; - if (segT->GetLength() != segO->GetLength()) return false; - if (segT->GetUnit() != segO->GetUnit()) return false; - } - - COMPARE(allTimingSegments[SEGMENT_SCROLL].size()); - for (i = 0; i < allTimingSegments[SEGMENT_SCROLL].size(); i++) - { - ScrollSegment * segT = - static_cast(this->allTimingSegments[SEGMENT_SCROLL][i]); - ScrollSegment * segO = - static_cast(other.allTimingSegments[SEGMENT_SCROLL][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetRatio() != segO->GetRatio()) return false; - } - - COMPARE(allTimingSegments[SEGMENT_LABEL].size()); - for (i = 0; i < allTimingSegments[SEGMENT_LABEL].size(); i++) - { - LabelSegment * segT = - static_cast(this->allTimingSegments[SEGMENT_LABEL][i]); - LabelSegment * segO = - static_cast(other.allTimingSegments[SEGMENT_LABEL][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetLabel() != segO->GetLabel()) return false; - } - - COMPARE(allTimingSegments[SEGMENT_FAKE].size()); - for (i = 0; i < allTimingSegments[SEGMENT_FAKE].size(); i++) - { - FakeSegment * segT = - static_cast(this->allTimingSegments[SEGMENT_FAKE][i]); - FakeSegment * segO = - static_cast(other.allTimingSegments[SEGMENT_FAKE][i]); - if (segT->GetRow() != segO->GetRow()) return false; - if (segT->GetLength() != segO->GetLength()) return false; - } - + COMPARE( m_fBeat0OffsetInSeconds ); return true; } + /** * @brief Compare two sets of timing data to see if they are not equal. * @param other the other TimingData. * @return the inequality or lack thereof of the two TimingData. */ bool operator!=( const TimingData &other ) { return !operator==(other); } - + void ScaleRegion( float fScale = 1, int iStartRow = 0, int iEndRow = MAX_NOTE_ROW, bool bAdjustBPM = false ); void InsertRows( int iStartRow, int iRowsToAdd ); void DeleteRows( int iStartRow, int iRowsToDelete ); @@ -903,17 +691,16 @@ public: * This is for informational purposes only. */ RString m_sFile; - // All of the following vectors must be sorted before gameplay. - - vector allTimingSegments[NUM_TimingSegmentType]; - + // All of the following vectors must be sorted before gameplay. + vector m_avpTimingSegments[NUM_TimingSegmentType]; + /** * @brief The initial offset of a song. */ float m_fBeat0OffsetInSeconds; - - vector ToVectorString(TimingSegmentType tst, int dec = 6) const; + + vector ToVectorString(TimingSegmentType tst, int dec = 6) const; }; #undef COMPARE