diff --git a/src/AdjustSync.cpp b/src/AdjustSync.cpp index 7e7ec96247..f626947e87 100644 --- a/src/AdjustSync.cpp +++ b/src/AdjustSync.cpp @@ -277,12 +277,19 @@ 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_DELAY]; + vector &stops = timing.allTimingSegments[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]; + for (unsigned i = 0; i < delays.size(); i++) + { + DelaySegment *s = static_cast(delays[i]); + s->SetPause(s->GetPause() * (1.0f - fSlope)); + } SCREENMAN->SystemMessage( AUTOSYNC_CORRECTION_APPLIED.GetValue() ); } @@ -377,8 +384,8 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo ) } } - vector &stopTest = testing.allTimingSegments[SEGMENT_STOP_DELAY]; - vector &stopOrig = original.allTimingSegments[SEGMENT_STOP_DELAY]; + vector &stopTest = testing.allTimingSegments[SEGMENT_STOP]; + vector &stopOrig = original.allTimingSegments[SEGMENT_STOP]; for( unsigned i=0; i< stopTest.size(); i++ ) { StopSegment *sT = static_cast(stopTest[i]); @@ -401,6 +408,31 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo ) fNew ) ); } } + + vector &delyTest = testing.allTimingSegments[SEGMENT_DELAY]; + vector &delyOrig = original.allTimingSegments[SEGMENT_DELAY]; + for( unsigned i=0; i< delyTest.size(); i++ ) + { + DelaySegment *sT = static_cast(delyTest[i]); + DelaySegment *sO = static_cast(delyOrig[i]); + float fOld = Quantize( sO->GetPause(), 0.001f ); + float fNew = Quantize( sT->GetPause(), 0.001f ); + float fDelta = fNew - fOld; + + if( fabsf(fDelta) > 0.0001f ) + { + if ( i >= 4 ) + { + vsAddTo.push_back(ETC.GetValue()); + break; + } + vsAddTo.push_back( ssprintf( + CHANGED_STOP.GetValue(), + i+1, + fOld, + fNew ) ); + } + } if( vsAddTo.size() > iOriginalSize && s_fAverageError > 0.0f ) { diff --git a/src/NoteField.cpp b/src/NoteField.cpp index c2f4885609..3605d5e56e 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -500,27 +500,35 @@ void NoteField::DrawBPMText( const float fBeat, const float fBPM ) m_textMeasureNumber.Draw(); } -void NoteField::DrawFreezeText( const float fBeat, const float fSecs, const float bDelay ) +void NoteField::DrawFreezeText( const float fBeat, const float fSecs ) { const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat ); const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels ); const float fZoom = ArrowEffects::GetZoom( m_pPlayerState ); const float xBase = GetWidth()/2.f; - const float xOffset = (bDelay ? DELAY_OFFSETX : STOP_OFFSETX) * fZoom; + const float xOffset = STOP_OFFSETX * fZoom; m_textMeasureNumber.SetZoom( fZoom ); - if(bDelay) - { - m_textMeasureNumber.SetHorizAlign( DELAY_IS_LEFT_SIDE ? align_right : align_left ); - m_textMeasureNumber.SetDiffuse( DELAY_COLOR ); - m_textMeasureNumber.SetXY( (DELAY_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos ); - } - else - { - m_textMeasureNumber.SetHorizAlign( STOP_IS_LEFT_SIDE ? align_right : align_left ); - m_textMeasureNumber.SetDiffuse( STOP_COLOR ); - m_textMeasureNumber.SetXY( (STOP_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos ); - } + m_textMeasureNumber.SetHorizAlign( STOP_IS_LEFT_SIDE ? align_right : align_left ); + m_textMeasureNumber.SetDiffuse( STOP_COLOR ); + m_textMeasureNumber.SetXY( (STOP_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos ); + m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) ); + m_textMeasureNumber.SetText( ssprintf("%.3f", fSecs) ); + m_textMeasureNumber.Draw(); +} + +void NoteField::DrawDelayText( const float fBeat, const float fSecs ) +{ + const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat ); + const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels ); + const float fZoom = ArrowEffects::GetZoom( m_pPlayerState ); + const float xBase = GetWidth()/2.f; + const float xOffset = DELAY_OFFSETX * fZoom; + + m_textMeasureNumber.SetZoom( fZoom ); + m_textMeasureNumber.SetHorizAlign( DELAY_IS_LEFT_SIDE ? align_right : align_left ); + m_textMeasureNumber.SetDiffuse( DELAY_COLOR ); + m_textMeasureNumber.SetXY( (DELAY_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos ); m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) ); m_textMeasureNumber.SetText( ssprintf("%.3f", fSecs) ); m_textMeasureNumber.Draw(); @@ -926,14 +934,26 @@ void NoteField::DrawPrimitives() } // Freeze text - for (i = 0; i < segs[SEGMENT_STOP_DELAY].size(); i++) + for (i = 0; i < segs[SEGMENT_STOP].size(); i++) { - StopSegment *seg = static_cast(segs[SEGMENT_STOP_DELAY][i]); + StopSegment *seg = static_cast(segs[SEGMENT_STOP][i]); if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawFreezeText( fBeat, seg->GetPause(), seg->GetDelay() ); + DrawFreezeText( fBeat, seg->GetPause() ); + } + } + + // Delay text + for (i = 0; i < segs[SEGMENT_DELAY].size(); i++) + { + DelaySegment *seg = static_cast(segs[SEGMENT_DELAY][i]); + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) + { + float fBeat = seg->GetBeat(); + if( IS_ON_SCREEN(fBeat) ) + DrawFreezeText( fBeat, seg->GetPause() ); } } diff --git a/src/NoteField.h b/src/NoteField.h index 2deb044350..a9ae9c861c 100644 --- a/src/NoteField.h +++ b/src/NoteField.h @@ -58,7 +58,8 @@ protected: void DrawMarkerBar( int fBeat ); void DrawAreaHighlight( int iStartBeat, int iEndBeat ); void DrawBPMText( const float fBeat, const float fBPM ); - void DrawFreezeText( const float fBeat, const float fLength, const float bDelay ); + void DrawFreezeText( const float fBeat, const float fLength ); + void DrawDelayText( const float fBeat, const float fLength ); void DrawWarpText( const float fBeat, const float fNewBeat ); void DrawTimeSignatureText( const float fBeat, int iNumerator, int iDenominator ); void DrawTickcountText( const float fBeat, int iTicks ); diff --git a/src/NotesLoaderBMS.cpp b/src/NotesLoaderBMS.cpp index 885b5df706..bd97e63d9b 100644 --- a/src/NotesLoaderBMS.cpp +++ b/src/NotesLoaderBMS.cpp @@ -667,7 +667,7 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo float fFreezeSecs = fBeats / fBPS; StopSegment * newSeg = new StopSegment( fBeat, fFreezeSecs ); - out.m_Timing.AddSegment( SEGMENT_STOP_DELAY, newSeg ); + out.m_Timing.AddSegment( SEGMENT_STOP, newSeg ); LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg->GetPause() ); } else diff --git a/src/NotesLoaderDWI.cpp b/src/NotesLoaderDWI.cpp index 242108bbe3..c0ca9e55d7 100644 --- a/src/NotesLoaderDWI.cpp +++ b/src/NotesLoaderDWI.cpp @@ -651,7 +651,7 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set &Bla int iFreezeRow = BeatToNoteRow( StringToFloat(arrayFreezeValues[0]) / 4.0f ); float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ) / 1000.0f; - out.m_SongTiming.AddSegment( SEGMENT_STOP_DELAY, new StopSegment(iFreezeRow, fFreezeSeconds) ); + out.m_SongTiming.AddSegment( SEGMENT_STOP, new StopSegment(iFreezeRow, fFreezeSeconds) ); // LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", fFreezeBeat, fFreezeSeconds ); } } diff --git a/src/NotesLoaderJson.cpp b/src/NotesLoaderJson.cpp index 4021b0e85e..4d3b41f85b 100644 --- a/src/NotesLoaderJson.cpp +++ b/src/NotesLoaderJson.cpp @@ -29,7 +29,7 @@ static void Deserialize(TimingSegment &seg_, const Json::Value &root) static_cast(seg)->SetBPM(fBPM); break; } - case SEGMENT_STOP_DELAY: + case SEGMENT_STOP: { float fStop = root["Seconds"].asDouble(); static_cast(seg)->SetPause(fStop); @@ -42,7 +42,7 @@ 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_DELAY], Deserialize, root["StopSegments"] ); + JsonUtil::DeserializeVectorPointers( td.allTimingSegments[SEGMENT_STOP], Deserialize, root["StopSegments"] ); } static void Deserialize(LyricSegment &o, const Json::Value &root) diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index 979a25607b..4fd0771667 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -355,14 +355,14 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool // DelayBeat float fCurDelay = 60 / stepsTiming.GetBPMAtBeat(fCurBeat) * numTemp / iTickCount; fCurDelay += stepsTiming.GetDelayAtRow(BeatToNoteRow(fCurBeat) ); - stepsTiming.SetStopAtBeat( fCurBeat, fCurDelay, true ); + stepsTiming.SetDelayAtBeat( fCurBeat, fCurDelay ); } else if (BeginsWith(sRowString, "|D")) { // Delays float fCurDelay = stepsTiming.GetStopAtRow(BeatToNoteRow(fCurBeat) ); fCurDelay += numTemp / 1000; - stepsTiming.SetStopAtBeat( fCurBeat, fCurDelay, true ); + stepsTiming.SetDelayAtBeat( fCurBeat, fCurDelay ); } else if (BeginsWith(sRowString, "|M") || BeginsWith(sRowString, "|C")) { diff --git a/src/NotesLoaderPMS.cpp b/src/NotesLoaderPMS.cpp index ca4c672091..cfedf673d4 100644 --- a/src/NotesLoaderPMS.cpp +++ b/src/NotesLoaderPMS.cpp @@ -723,7 +723,7 @@ static void ReadGlobalTags( const RString &sPath, const NameToData_t &mapNameToD float fFreezeSecs = fBeats / fBPS; StopSegment * newSeg = new StopSegment( fBeat, fFreezeSecs ); - out.m_SongTiming.AddSegment( SEGMENT_STOP_DELAY, newSeg ); + out.m_SongTiming.AddSegment( SEGMENT_STOP, newSeg ); LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg->GetPause() ); } else diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index c74e867a18..889fafe2ce 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -315,7 +315,7 @@ void SMLoader::ProcessStops( TimingData &out, const RString line, const int rows } else if( fFreezeSeconds > 0.0f ) { - out.AddSegment(SEGMENT_STOP_DELAY, + out.AddSegment(SEGMENT_STOP, new StopSegment(fFreezeBeat, fFreezeSeconds)); } @@ -353,14 +353,13 @@ void SMLoader::ProcessDelays( TimingData &out, const RString line, const int row const float fFreezeBeat = RowToBeat( arrayDelayValues[0], rowsPerBeat ); const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] ); - StopSegment * new_seg = new StopSegment(fFreezeBeat, - fFreezeSeconds, - true); + DelaySegment * new_seg = new DelaySegment(fFreezeBeat, + fFreezeSeconds); // LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); if(fFreezeSeconds > 0.0f) - out.AddSegment( SEGMENT_STOP_DELAY, new_seg ); + out.AddSegment( SEGMENT_DELAY, new_seg ); else LOG->UserLog( "Song file", diff --git a/src/NotesWriterDWI.cpp b/src/NotesWriterDWI.cpp index 33809c357c..69e3b7c5e5 100644 --- a/src/NotesWriterDWI.cpp +++ b/src/NotesWriterDWI.cpp @@ -381,7 +381,8 @@ bool NotesWriterDWI::Write( RString sPath, const Song &out ) break; } - const vector &stops = out.m_SongTiming.allTimingSegments[SEGMENT_STOP_DELAY]; + // TODO: Also check for delays, add them as stops minus one row? + const vector &stops = out.m_SongTiming.allTimingSegments[SEGMENT_STOP]; if( !stops.empty() ) { f.Write( "#FREEZE:" ); diff --git a/src/NotesWriterJson.cpp b/src/NotesWriterJson.cpp index 984a895295..e8984a5034 100644 --- a/src/NotesWriterJson.cpp +++ b/src/NotesWriterJson.cpp @@ -25,7 +25,7 @@ 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_DELAY], Serialize, root["StopSegments"] ); + JsonUtil::SerializeVectorPointers( td.allTimingSegments[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 81eca70991..bc7e769b03 100644 --- a/src/NotesWriterSM.cpp +++ b/src/NotesWriterSM.cpp @@ -96,28 +96,42 @@ static void WriteGlobalTags( RageFile &f, Song &out ) int iRow = ws->GetRow(); float fBPS = 60 / out.m_SongTiming.GetBPMAtRow(iRow); float fSkip = fBPS * ws->GetLength(); - out.m_SongTiming.AddSegment(SEGMENT_STOP_DELAY, - new StopSegment(iRow, -fSkip, false) ); + out.m_SongTiming.AddSegment(SEGMENT_STOP, + new StopSegment(iRow, -fSkip) ); } } - f.Write( "#STOPS:" ); - vector &stops = timing.allTimingSegments[SEGMENT_STOP_DELAY]; + // TODO: make Delays into Stops that start one row before. + vector &stops = timing.allTimingSegments[SEGMENT_STOP]; + vector &delays = timing.allTimingSegments[SEGMENT_DELAY]; + + map allPauses; for( unsigned i=0; i(stops[i]); - float fBeat = fs->GetBeat(); - if (fs->GetDelay()) fBeat--; - - f.PutLine( ssprintf( "%.3f=%.3f", fBeat, fs->GetPause() ) ); - if( i != stops.size()-1 ) - f.Write( "," ); + allPauses.insert(pair(fs->GetBeat(), + fs->GetPause())); if( fs->GetPause() < 0 ) { stops.erase(stops.begin()+i,stops.begin()+i+1 ); i--; } } + // Delays can't be negative: thus, no effect. + FOREACH(TimingSegment *, delays, ss) + { + allPauses.insert(pair(NoteRowToBeat((*ss)->GetRow() - 1), + static_cast(*ss)->GetPause())); + } + + f.Write( "#STOPS:" ); + vector stopLines; + FOREACHM(float, float, allPauses, ap) + { + stopLines.push_back(ssprintf("%.3f=%.3f", ap->first, ap->second)); + } + f.PutLine(join(",\n", stopLines)); + f.PutLine( ";" ); FOREACH_BackgroundLayer( b ) diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 0a47768f41..e341782478 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -77,21 +77,20 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Finish(); w.Init( "STOPS" ); - vector &stops = timing.allTimingSegments[SEGMENT_STOP_DELAY]; + vector &stops = timing.allTimingSegments[SEGMENT_STOP]; for (i = 0; i < stops.size(); i++) { StopSegment *ss = static_cast(stops[i]); - if( !ss->GetDelay() ) - w.Write( ss->GetRow(), ss->GetPause() ); + w.Write( ss->GetRow(), ss->GetPause() ); } w.Finish(); w.Init( "DELAYS" ); - for (i = 0; i < stops.size(); i++) + vector &delays = timing.allTimingSegments[SEGMENT_DELAY]; + for (i = 0; i < delays.size(); i++) { - StopSegment *ss = static_cast(stops[i]); - if( ss->GetDelay() ) - w.Write( ss->GetRow(), ss->GetPause() ); + DelaySegment *ss = static_cast(delays[i]); + w.Write( ss->GetRow(), ss->GetPause() ); } w.Finish(); @@ -183,9 +182,9 @@ static void WriteTimingTags( RageFile &f, const TimingData &timing, bool bIsSong f.PutLine(ssprintf("#BPMS:%s;", join(",\r\n", timing.ToVectorString(SEGMENT_BPM)).c_str())); f.PutLine(ssprintf("#STOPS:%s;", - join(",\r\n", timing.ToVectorString(SEGMENT_STOP_DELAY, false)).c_str())); + join(",\r\n", timing.ToVectorString(SEGMENT_STOP)).c_str())); f.PutLine(ssprintf("#DELAYS:%s;", - join(",\r\n", timing.ToVectorString(SEGMENT_STOP_DELAY, true)).c_str())); + join(",\r\n", timing.ToVectorString(SEGMENT_DELAY)).c_str())); f.PutLine(ssprintf("#WARPS:%s;", join(",\r\n", timing.ToVectorString(SEGMENT_WARP)).c_str())); f.PutLine(ssprintf("#TIMESIGNATURES:%s;", diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index ff83b6d484..0676400bfa 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_DELAY]; + vector &stops = GetAppropriateTiming().allTimingSegments[SEGMENT_STOP]; for( i=0; iGetRow() == GetRow() ) @@ -1904,7 +1904,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { // create a new StopSegment if( fDelta > 0 ) - GetAppropriateTiming().AddSegment(SEGMENT_STOP_DELAY, + GetAppropriateTiming().AddSegment(SEGMENT_STOP, new StopSegment( GetRow(), fDelta) ); } else // StopSegment being modified is m_SongTiming.m_StopSegments[i] @@ -2977,7 +2977,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { float fDelay = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fDelay >= 0 ) - GetAppropriateTiming().SetStopAtBeat( GetBeat(), fDelay, true ); + GetAppropriateTiming().SetDelayAtBeat( GetBeat(), fDelay ); SetDirty( true ); } else if( SM == SM_BackFromTimeSignatureChange && !ScreenTextEntry::s_bCancelledLast ) @@ -4328,11 +4328,16 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns cpy = new BPMSegment(*(static_cast(org))); break; } - case SEGMENT_STOP_DELAY: + case SEGMENT_STOP: { cpy = new StopSegment(*(static_cast(org))); break; } + case SEGMENT_DELAY: + { + cpy = new DelaySegment(*(static_cast(org))); + break; + } case SEGMENT_TIME_SIG: { cpy = new TimeSignatureSegment(*(static_cast(org))); diff --git a/src/TimingData.cpp b/src/TimingData.cpp index f15e564934..d078221cc8 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -50,11 +50,16 @@ TimingData TimingData::CopyRange(int startRow, int endRow) const cpy = new BPMSegment(*(static_cast(org))); break; } - case SEGMENT_STOP_DELAY: + case SEGMENT_STOP: { cpy = new StopSegment(*(static_cast(org))); break; } + case SEGMENT_DELAY: + { + cpy = new DelaySegment(*(static_cast(org))); + break; + } case SEGMENT_TIME_SIG: { cpy = new TimeSignatureSegment(*(static_cast(org))); @@ -136,7 +141,7 @@ void TimingData::AddSegment(TimingSegmentType tst, TimingSegment * seg) } int TimingData::GetSegmentIndexAtRow(TimingSegmentType tst, - int row, bool isDelay) const + int row) const { const vector &segs = this->allTimingSegments[tst]; unsigned i = 0; @@ -145,10 +150,6 @@ int TimingData::GetSegmentIndexAtRow(TimingSegmentType tst, TimingSegment *seg = segs[i+1]; if (seg->GetRow() > row) { - // put conditions here for individual segments. - if (tst == SEGMENT_STOP_DELAY && - static_cast(seg)->GetDelay() != isDelay) - continue; break; } } @@ -156,7 +157,7 @@ int TimingData::GetSegmentIndexAtRow(TimingSegmentType tst, } float TimingData::GetNextSegmentBeatAtRow(TimingSegmentType tst, - int row, bool isDelay) const + int row) const { const vector segs = this->allTimingSegments[tst]; for (unsigned i = 0; i < segs.size(); i++ ) @@ -165,15 +166,13 @@ float TimingData::GetNextSegmentBeatAtRow(TimingSegmentType tst, { continue; } - if (tst != SEGMENT_STOP_DELAY || - static_cast(segs[i])->GetDelay() == isDelay) - return segs[i]->GetBeat(); + return segs[i]->GetBeat(); } return NoteRowToBeat(row); } float TimingData::GetPreviousSegmentBeatAtRow(TimingSegmentType tst, - int row, bool isDelay) const + int row) const { float backup = -1; const vector segs = this->allTimingSegments[tst]; @@ -183,9 +182,7 @@ float TimingData::GetPreviousSegmentBeatAtRow(TimingSegmentType tst, { break; } - if (tst != SEGMENT_STOP_DELAY || - static_cast(segs[i])->GetDelay() == isDelay) - backup = segs[i]->GetBeat(); + backup = segs[i]->GetBeat(); } return (backup > -1) ? backup : NoteRowToBeat(row); } @@ -219,21 +216,20 @@ void TimingData::SetBPMAtRow( int iNoteRow, float fBPM ) } } -void TimingData::SetStopAtRow( int iRow, float fSeconds, bool bDelay ) +void TimingData::SetStopAtRow( int iRow, float fSeconds ) { unsigned i; - vector &stops = this->allTimingSegments[SEGMENT_STOP_DELAY]; + vector &stops = this->allTimingSegments[SEGMENT_STOP]; for( i=0; iGetRow() == iRow && - static_cast(stops[i])->GetDelay() == bDelay ) + if (stops[i]->GetRow() == iRow) break; - if( i == stops.size() ) // there is no Stop/Delay Segment at the current beat + if( i == stops.size() ) // there is no StopSegment at the current beat { // create a new StopSegment if( fSeconds > 0 ) { - AddSegment( SEGMENT_STOP_DELAY, new StopSegment(iRow, fSeconds, bDelay) ); + AddSegment( SEGMENT_STOP, new StopSegment(iRow, fSeconds) ); } } else // StopSegment being modified is m_StopSegments[i] @@ -248,6 +244,34 @@ void TimingData::SetStopAtRow( int iRow, float fSeconds, bool bDelay ) } } +void TimingData::SetDelayAtRow( int iRow, float fSeconds ) +{ + unsigned i; + vector &stops = this->allTimingSegments[SEGMENT_DELAY]; + for( i=0; iGetRow() == iRow) + break; + + if( i == stops.size() ) // there is no DelaySegment at the current beat + { + // create a new DelaySegment + if( fSeconds > 0 ) + { + AddSegment( SEGMENT_DELAY, new DelaySegment(iRow, fSeconds) ); + } + } + else // DelaySegment being modified is present one + { + DelaySegment *ss = static_cast(stops[i]); + if( fSeconds > 0 ) + { + ss->SetPause(fSeconds); + } + else + stops.erase( stops.begin()+i, stops.begin()+i+1 ); + } +} + void TimingData::SetTimeSignatureAtRow( int iRow, int iNumerator, int iDenominator ) { unsigned i; @@ -526,14 +550,13 @@ void TimingData::SetSpeedModeAtRow( int iRow, unsigned short usMode ) usMode ); } - -float TimingData::GetStopAtRow( int iNoteRow, bool bDelay ) const +float TimingData::GetStopAtRow( int iRow ) const { - const vector &stops = this->allTimingSegments[SEGMENT_STOP_DELAY]; + const vector &stops = this->allTimingSegments[SEGMENT_STOP]; for( unsigned i=0; i(stops[i]); - if( s->GetDelay() == bDelay && s->GetRow() == iNoteRow ) + if( s->GetRow() == iRow ) { return s->GetPause(); } @@ -541,15 +564,19 @@ float TimingData::GetStopAtRow( int iNoteRow, bool bDelay ) const return 0; } -float TimingData::GetStopAtRow( int iRow ) const -{ - return GetStopAtRow( iRow, false ); -} - float TimingData::GetDelayAtRow( int iRow ) const { - return GetStopAtRow( iRow, true ); + const vector &stops = this->allTimingSegments[SEGMENT_DELAY]; + for( unsigned i=0; i(stops[i]); + if( s->GetRow() == iRow ) + { + return s->GetPause(); + } + } + return 0; } int TimingData::GetComboAtRow( int iNoteRow ) const @@ -684,7 +711,7 @@ bool TimingData::IsWarpAtRow( int iNoteRow ) const 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_DELAY].empty() ) + if( this->allTimingSegments[SEGMENT_STOP].empty() && this->allTimingSegments[SEGMENT_DELAY].empty() ) { return true; } @@ -783,16 +810,26 @@ LabelSegment* TimingData::GetLabelSegmentAtRow( int iRow ) return static_cast(labels[i]); } -StopSegment* TimingData::GetStopSegmentAtRow( int iNoteRow, bool bDelay ) +StopSegment* TimingData::GetStopSegmentAtRow( int iNoteRow ) { - vector &stops = this->allTimingSegments[SEGMENT_STOP_DELAY]; + vector &stops = this->allTimingSegments[SEGMENT_STOP]; if( stops.empty() ) return new StopSegment(); - int i = GetSegmentIndexAtRow( SEGMENT_STOP_DELAY, iNoteRow, bDelay ); + 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]; @@ -854,6 +891,7 @@ enum FOUND_WARP_DESTINATION, FOUND_BPM_CHANGE, FOUND_STOP, + FOUND_DELAY, FOUND_MARKER, NOT_FOUND }; @@ -863,7 +901,8 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float const vector * segs = this->allTimingSegments; vector::const_iterator itBPMS = segs[SEGMENT_BPM].begin(); vector::const_iterator itWS = segs[SEGMENT_WARP].begin(); - vector::const_iterator itSS = segs[SEGMENT_STOP_DELAY].begin(); + vector::const_iterator itSS = segs[SEGMENT_STOP].begin(); + vector::const_iterator itDS = segs[SEGMENT_DELAY].begin(); bFreezeOut = false; bDelayOut = false; @@ -892,8 +931,15 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float iEventRow = (*itBPMS)->GetRow(); iEventType = FOUND_BPM_CHANGE; } - if (itSS != segs[SEGMENT_STOP_DELAY].end() && - (*itSS)->GetRow() < iEventRow ) + if (itDS != segs[SEGMENT_DELAY].end() && + (*itDS)->GetRow() < iEventRow) + { + iEventRow = (*itDS)->GetRow(); + iEventType = FOUND_DELAY; + } + if (itSS != segs[SEGMENT_STOP].end() && + (*itSS)->GetRow() < iEventRow && + iEventType != FOUND_DELAY ) { iEventRow = (*itSS)->GetRow(); iEventType = FOUND_STOP; @@ -917,23 +963,39 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float fLastTime = fNextEventTime; switch( iEventType ) { - case FOUND_WARP_DESTINATION: - bIsWarping = false; - break; - case FOUND_BPM_CHANGE: - fBPS = static_cast(*itBPMS)->GetBPS(); - itBPMS ++; - break; - case FOUND_STOP: + case FOUND_WARP_DESTINATION: + bIsWarping = false; + break; + case FOUND_BPM_CHANGE: + fBPS = static_cast(*itBPMS)->GetBPS(); + itBPMS ++; + break; + case FOUND_DELAY: + { + const DelaySegment *ss = static_cast(*itDS); + fTimeToNextEvent = ss->GetPause(); + fNextEventTime = fLastTime + fTimeToNextEvent; + if ( fElapsedTime < fNextEventTime ) + { + bFreezeOut = false; + bDelayOut = true; + fBeatOut = ss->GetBeat(); + fBPSOut = fBPS; + return; + } + fLastTime = fNextEventTime; + itDS ++; + break; + } + case FOUND_STOP: { const StopSegment *ss = static_cast(*itSS); fTimeToNextEvent = ss->GetPause(); fNextEventTime = fLastTime + fTimeToNextEvent; - const bool bIsDelay = ss->GetDelay(); if ( fElapsedTime < fNextEventTime ) { - bFreezeOut = !bIsDelay; - bDelayOut = bIsDelay; + bFreezeOut = true; + bDelayOut = false; fBeatOut = ss->GetBeat(); fBPSOut = fBPS; return; @@ -942,7 +1004,7 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float itSS ++; } break; - case FOUND_WARP: + case FOUND_WARP: { bIsWarping = true; const WarpSegment *ws = static_cast(*itWS); @@ -975,7 +1037,8 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const const vector * segs = this->allTimingSegments; vector::const_iterator itBPMS = segs[SEGMENT_BPM].begin(); vector::const_iterator itWS = segs[SEGMENT_WARP].begin(); - vector::const_iterator itSS = segs[SEGMENT_STOP_DELAY].begin(); + vector::const_iterator itSS = segs[SEGMENT_STOP].begin(); + vector::const_iterator itDS = segs[SEGMENT_DELAY].begin(); int iLastRow = 0; float fLastTime = -m_fBeat0OffsetInSeconds; @@ -999,20 +1062,18 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const iEventRow = (*itBPMS)->GetRow(); iEventType = FOUND_BPM_CHANGE; } - if (itSS != segs[SEGMENT_STOP_DELAY].end() && - static_cast(*itSS)->GetDelay() && - (*itSS)->GetRow() < iEventRow ) // delays (come before marker) + if (itDS != segs[SEGMENT_DELAY].end() && + (*itDS)->GetRow() < iEventRow ) // delays (come before marker) { - iEventRow = (*itSS)->GetRow(); - iEventType = FOUND_STOP; + iEventRow = (*itDS)->GetRow(); + iEventType = FOUND_DELAY; } if( BeatToNoteRow(fBeat) < iEventRow ) { iEventRow = BeatToNoteRow(fBeat); iEventType = FOUND_MARKER; } - if (itSS != segs[SEGMENT_STOP_DELAY].end() && - !static_cast(*itSS)->GetDelay() && + if (itSS != segs[SEGMENT_STOP].end() && (*itSS)->GetRow() < iEventRow ) // stops (come after marker) { iEventRow = (*itSS)->GetRow(); @@ -1042,6 +1103,12 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const fLastTime = fNextEventTime; itSS ++; break; + case FOUND_DELAY: + fTimeToNextEvent = static_cast(*itDS)->GetPause(); + fNextEventTime = fLastTime + fTimeToNextEvent; + fLastTime = fNextEventTime; + itDS ++; + break; case FOUND_MARKER: return fLastTime; case FOUND_WARP: @@ -1300,9 +1367,12 @@ bool TimingData::HasBpmChanges() const return this->allTimingSegments[SEGMENT_BPM].size()>1; } +// TODO: Think about splitting this up into HasStops and HasDelays. bool TimingData::HasStops() const { - return this->allTimingSegments[SEGMENT_STOP_DELAY].size()>0; + return + this->allTimingSegments[SEGMENT_STOP].size()>0 || + this->allTimingSegments[SEGMENT_DELAY].size()>0; } bool TimingData::HasWarps() const @@ -1364,20 +1434,13 @@ void TimingData::NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, i return; } -vector TimingData::ToVectorString(TimingSegmentType tst, - bool isDelay, int dec) const +vector TimingData::ToVectorString(TimingSegmentType tst, int dec) const { const vector segs = this->allTimingSegments[tst]; vector ret; for (unsigned i = 0; i < segs.size(); i++) { - if (tst == SEGMENT_STOP_DELAY) - { - StopSegment *seg = static_cast(segs[i]); - if (seg->GetDelay() != isDelay) - continue; - } ret.push_back(segs[i]->ToString(dec)); } return ret; @@ -1433,12 +1496,12 @@ public: } static int GetStops( T* p, lua_State *L ) { - LuaHelpers::CreateTableFromArray(p->ToVectorString(SEGMENT_STOP_DELAY, false), L); + LuaHelpers::CreateTableFromArray(p->ToVectorString(SEGMENT_STOP), L); return 1; } static int GetDelays( T* p, lua_State *L ) { - LuaHelpers::CreateTableFromArray(p->ToVectorString(SEGMENT_STOP_DELAY, true), L); + LuaHelpers::CreateTableFromArray(p->ToVectorString(SEGMENT_DELAY), L); return 1; } static int GetBPMs( T* p, lua_State *L ) diff --git a/src/TimingData.h b/src/TimingData.h index 8cf239e2f0..a7e993ff22 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -19,30 +19,30 @@ public: void AddSegment(TimingSegmentType tst, TimingSegment * seg); int GetSegmentIndexAtRow(TimingSegmentType tst, - int row, bool isDelay = false) const; + int row) const; int GetSegmentIndexAtBeat(TimingSegmentType tst, - float beat, bool isDelay = false) const + float beat) const { - return this->GetSegmentIndexAtRow(tst, BeatToNoteRow(beat), isDelay); + return this->GetSegmentIndexAtRow(tst, BeatToNoteRow(beat)); } float GetNextSegmentBeatAtRow(TimingSegmentType tst, - int row, bool isDelay = false) const; + int row) const; float GetNextSegmentBeatAtBeat(TimingSegmentType tst, - float beat, bool isDelay = false) const + float beat) const { - return this->GetNextSegmentBeatAtRow(tst, BeatToNoteRow(beat), isDelay); + return this->GetNextSegmentBeatAtRow(tst, BeatToNoteRow(beat)); } float GetPreviousSegmentBeatAtRow(TimingSegmentType tst, - int row, bool isDelay = false) const; + int row) const; float GetPreviousSegmentBeatAtBeat(TimingSegmentType tst, - float beat, bool isDelay = false) const + float beat) const { - return this->GetPreviousSegmentBeatAtRow(tst, BeatToNoteRow(beat), isDelay); + return this->GetPreviousSegmentBeatAtRow(tst, BeatToNoteRow(beat)); } bool empty() const; @@ -102,20 +102,6 @@ public: */ BPMSegment* GetBPMSegmentAtBeat( float fBeat ) { return GetBPMSegmentAtRow( (int)BeatToNoteRow(fBeat)); } - /** - * @brief Retrieve the Stop/Delay at the given row. - * @param iNoteRow the row in question. - * @param bDelayOut A flag to determine if we are getting a delay or not. - * @return the time we stop at this row. - */ - float GetStopAtRow( int iNoteRow, bool bDelayOut ) const; - /** - * @brief Retrieve the Stop/Delay at the given row. - * @param fBeat the beat in question. - * @param bDelayOut A flag to determine if we are getting a delay or not. - * @return the time we stop at this beat. - */ - float GetStopAtBeat( float fBeat, bool bDelayOut ) const { return GetStopAtRow( BeatToNoteRow(fBeat), bDelayOut ); } /** * @brief Retrieve the stop time at the given row. * @param iNoteRow the row in question. @@ -128,6 +114,33 @@ 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. + * @param fSeconds the new stop time. + */ + void SetStopAtRow( int iNoteRow, float fSeconds ); + /** + * @brief Set the beat to have the new stop time. + * @param fBeat to have the new stop time. + * @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. @@ -140,21 +153,7 @@ public: * @return the delay time. */ float GetDelayAtBeat( float fBeat ) const { return GetDelayAtRow( BeatToNoteRow(fBeat) ); } - /** - * @brief Set the row to have the new stop time. - * @param iNoteRow the row to have the new stop time. - * @param fSeconds the new stop time. - */ - void SetStopAtRow( int iNoteRow, float fSeconds ) { SetStopAtRow( iNoteRow, fSeconds, false ); } - /** - * @brief Set the row to have the new pause time. - * - * This function was added specifically for sm-ssc. - * @param iNoteRow the row to have the new pause time. - * @param fSeconds the new pause time. - * @param bDelay If true, this is a Delay Segment. Otherwise, it is a StopSegment. - */ - void SetStopAtRow( int iNoteRow, float fSeconds, bool bDelay ); + /** * @brief Set the row to have the new delay time. * @@ -162,22 +161,7 @@ public: * @param iNoteRow the row to have the new delay time. * @param fSeconds the new delay time. */ - void SetDelayAtRow( int iNoteRow, float fSeconds ) { SetStopAtRow( iNoteRow, fSeconds, true ); } - /** - * @brief Set the beat to have the new stop time. - * @param fBeat to have the new stop time. - * @param fSeconds the new stop time. - */ - void SetStopAtBeat( float fBeat, float fSeconds ) { SetStopAtRow( BeatToNoteRow(fBeat), fSeconds, false ); } - /** - * @brief Set the beat to have the new pause time. - * - * This function was added specifically for sm-ssc. - * @param fBeat the beat to have the new pause time. - * @param fSeconds the new pause time. - * @param bDelay If true, this is a Delay Segment. Otherwise, it is a StopSegment. - */ - void SetStopAtBeat( float fBeat, float fSeconds, bool bDelay ) { SetStopAtRow( BeatToNoteRow(fBeat), fSeconds, bDelay ); } + void SetDelayAtRow( int iNoteRow, float fSeconds ); /** * @brief Set the beat to have the new delay time. * @@ -185,45 +169,19 @@ public: * @param fBeat the beat to have the new delay time. * @param fSeconds the new delay time. */ - void SetDelayAtBeat( float fBeat, float fSeconds ) { SetStopAtRow( BeatToNoteRow(fBeat), fSeconds, true ); } - /** - * @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 ) { return GetStopSegmentAtRow( iNoteRow, false ); } - /** - * @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), false); } - /** - * @brief Retrieve the StopSegment at the specified row. - * @param iNoteRow the row that has a StopSegment. - * @param bDelay If true, this is actually a DelaySegment. - * @return the StopSegment in question. - */ - StopSegment* GetStopSegmentAtRow( int iNoteRow, bool bDelay ); - /** - * @brief Retrieve the StopSegment at the specified beat. - * @param fBeat the beat that has a StopSegment. - * @param bDelay If true, this is actually a DelaySegment. - * @return the StopSegment in question. - */ - StopSegment* GetStopSegmentAtBeat( float fBeat, bool bDelay ) { return GetStopSegmentAtRow( BeatToNoteRow(fBeat), bDelay ); } + 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. */ - StopSegment* GetDelaySegmentAtRow( int iNoteRow ) { return GetStopSegmentAtRow( iNoteRow, true ); } + 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. */ - StopSegment* GetDelaySegmentAtBeat( float fBeat ) { return GetStopSegmentAtRow( BeatToNoteRow(fBeat), true); } + DelaySegment* GetDelaySegmentAtBeat( float fBeat ) { return GetDelaySegmentAtRow( BeatToNoteRow(fBeat)); } /** * @brief Retrieve the Time Signature's numerator at the given row. @@ -830,7 +788,7 @@ public: */ float m_fBeat0OffsetInSeconds; - vector ToVectorString(TimingSegmentType tst, bool isDelay = false, int dec = 6) const; + vector ToVectorString(TimingSegmentType tst, int dec = 6) const; }; #undef COMPARE diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index deec665226..503880bff9 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -4,7 +4,8 @@ static const char *TimingSegmentTypeNames[] = { "BPM", - "Stop/Delay", // TODO: separate when stops and delays are separate. + "Stop", + "Delay", "Time Sig", "Warp", "Label", @@ -332,25 +333,32 @@ void StopSegment::SetPause(const float i) this->pauseSeconds = i; } -bool StopSegment::GetDelay() const -{ - return this->isDelay; -} - -void StopSegment::SetDelay(const bool i) -{ - this->isDelay = i; -} - bool StopSegment::operator<( const StopSegment &other ) const { LTCOMPARE(GetRow()); - if (this->GetDelay() && !other.GetDelay()) return true; - if (!this->GetDelay() && other.GetDelay()) return false; LTCOMPARE(GetPause()); return false; } +float DelaySegment::GetPause() const +{ + return this->pauseSeconds; +} + +void DelaySegment::SetPause(const float i) +{ + this->pauseSeconds = i; +} + +bool DelaySegment::operator<( const DelaySegment &other ) const +{ + LTCOMPARE(GetRow()); + LTCOMPARE(GetPause()); + return false; +} + +#undef LTCOMPARE + /** * @file * @author Jason Felds (c) 2011 diff --git a/src/TimingSegments.h b/src/TimingSegments.h index b8f954d467..6c89c84693 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -6,10 +6,8 @@ enum TimingSegmentType { SEGMENT_BPM, - SEGMENT_STOP_DELAY, - // uncomment the below two when stops and delays don't share one. - // SEGMENT_STOP, - // SEGMENT_DELAY, + SEGMENT_STOP, + SEGMENT_DELAY, SEGMENT_TIME_SIG, SEGMENT_WARP, SEGMENT_LABEL, @@ -81,7 +79,7 @@ struct TimingSegment { return TimingSegmentType_Invalid; } - // TODO: Remove isDelay optional param and split Stops and Delays. + virtual RString ToString(int dec) const { return FloatToString(this->GetBeat()); @@ -877,9 +875,7 @@ private: }; /** - * @brief Identifies when a song has a stop or a delay. - * - * It is hopeful that stops and delays can be made into their own segments at some point. + * @brief Identifies when a song has a stop, DDR/ITG style. */ struct StopSegment : public TimingSegment { @@ -889,35 +885,21 @@ struct StopSegment : public TimingSegment * It is best to override the values as soon as possible. */ StopSegment() : TimingSegment(-1), - pauseSeconds(-1.0f), isDelay(false) {} + pauseSeconds(-1.0f) {} StopSegment (const StopSegment &other): TimingSegment(other.GetRow()), - pauseSeconds(other.GetPause()), - isDelay(other.GetDelay()) {} + pauseSeconds(other.GetPause()) {} /** * @brief Creates a Stop Segment with specified values. - * - * This will not create a dedicated delay segment. - * Use the third constructor for making delays. * @param s the starting row / beat of this segment. * @param f the length of time to pause the note scrolling. */ template StopSegment( StartType s, float f ): TimingSegment(max((StartType)0, s)), - pauseSeconds(f), isDelay(false) {} - /** - * @brief Creates a Stop/Delay Segment with specified values. - * @param s the starting row / beat of this segment. - * @param f the length of time to pause the note scrolling. - * @param d the flag that makes this Stop Segment a Delay Segment. - */ - template - StopSegment( StartType s, float f, bool d ): - TimingSegment(max((StartType)0, s)), - pauseSeconds(f), isDelay(d) {} + pauseSeconds(f) {} /** * @brief Get the pause length in this StopSegment. @@ -929,16 +911,6 @@ struct StopSegment : public TimingSegment * @param i the pause length. */ void SetPause(const float i); - /** - * @brief Get the behavior in this StopSegment. - * @return the behavior. */ - bool GetDelay() const; - - /** - * @brief Set the behavior in this StopSegment. - * @param i the behavior. */ - void SetDelay(const bool i); - virtual RString ToString(int dec) const { const RString str = "%.0" + IntToString(dec) @@ -948,32 +920,81 @@ struct StopSegment : public TimingSegment /** * @brief Compares two StopSegments to see if one is less than the other. - * - * It should be observed that Delay Segments have to come before Stop Segments. - * Otherwise, it will act like a Stop Segment with extra time from the Delay at - * the same row. * @param other the other StopSegment to compare to. * @return the truth/falsehood of if the first is less than the second. */ bool operator<( const StopSegment &other ) const; - TimingSegmentType GetType() const { return SEGMENT_STOP_DELAY; } + TimingSegmentType GetType() const { return SEGMENT_STOP; } private: /** * @brief The amount of time to complete the pause at the given row. */ float pauseSeconds; - /** - * @brief How does this StopSegment behave? - * - * If true, the Stop Segment is treated as a Delay Segment, similar to the Pump It Up series. - * If false, this behaves similar to the DDR/ITG style games. - * - * TODO: Separate out DelaySegments in the future. - */ - bool isDelay; }; +/** + * @brief Identifies when a song has a delay, or pump style stop. + */ +struct DelaySegment : public TimingSegment +{ + /** + * @brief Creates a simple Delay Segment with default values. + * + * It is best to override the values as soon as possible. + */ + DelaySegment() : TimingSegment(-1), + pauseSeconds(-1.0f) {} + + DelaySegment (const DelaySegment &other): + TimingSegment(other.GetRow()), + pauseSeconds(other.GetPause()) {} + + /** + * @brief Creates a Delay Segment with specified values. + * @param s the starting row / beat of this segment. + * @param f the length of time to pause the note scrolling. + */ + template + DelaySegment( StartType s, float f ): + TimingSegment(max((StartType)0, s)), + pauseSeconds(f) {} + + + /** + * @brief Get the pause length in this DelaySegment. + * @return the pause length. */ + float GetPause() const; + + /** + * @brief Set the pause length in this DelaySegment. + * @param i the pause length. */ + void SetPause(const float i); + + + virtual RString ToString(int dec) const + { + const RString str = "%.0" + IntToString(dec) + + "f=%.0" + IntToString(dec) + "f"; + return ssprintf(str.c_str(), this->GetBeat(), this->GetPause()); + } + + /** + * @brief Compares two DelaySegments to see if one is less than the other. + * @param other the other DelaySegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const DelaySegment &other ) const; + + TimingSegmentType GetType() const { return SEGMENT_DELAY; } +private: + /** + * @brief The amount of time to complete the pause at the given row. + */ + float pauseSeconds; +}; + + #endif /**