diff --git a/src/NoteField.cpp b/src/NoteField.cpp index e54b650bd5..5b958d43a0 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -921,11 +921,11 @@ void NoteField::DrawPrimitives() // Warp text FOREACH_CONST( WarpSegment, timing.m_WarpSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawWarpText( fBeat, seg->m_fLengthBeats ); + DrawWarpText( fBeat, seg->GetLength() ); } } diff --git a/src/NotesWriterSM.cpp b/src/NotesWriterSM.cpp index 55bbeeb65c..2bd84f945f 100644 --- a/src/NotesWriterSM.cpp +++ b/src/NotesWriterSM.cpp @@ -113,9 +113,9 @@ static void WriteGlobalTags( RageFile &f, Song &out ) { for( unsigned i=0; i < wSize; i++ ) { - int iRow = out.m_SongTiming.m_WarpSegments[i].m_iStartRow; + int iRow = out.m_SongTiming.m_WarpSegments[i].GetRow(); float fBPS = 60 / out.m_SongTiming.GetBPMAtRow(iRow); - float fSkip = fBPS * out.m_SongTiming.m_WarpSegments[i].m_fLengthBeats; + float fSkip = fBPS * out.m_SongTiming.m_WarpSegments[i].GetLength(); StopSegment ss; ss.m_iStartRow = iRow; ss.m_fStopSeconds = -fSkip; diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 46b12ee872..051ae94806 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -110,7 +110,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Init( "WARPS" ); FOREACH_CONST( WarpSegment, timing.m_WarpSegments, ws ) - w.Write( ws->m_iStartRow, ws->m_fLengthBeats ); + w.Write( ws->GetRow(), ws->GetLength() ); w.Finish(); ASSERT( !timing.m_vTimeSignatureSegments.empty() ); diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 2cf4bded87..f59dda63bf 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -179,7 +179,7 @@ void TimingData::SetWarpAtRow( int iRow, float fNew ) { unsigned i; for( i=0; i 0 && fNew > 0; if( i == m_WarpSegments.size() ) @@ -193,7 +193,7 @@ void TimingData::SetWarpAtRow( int iRow, float fNew ) { if( valid ) { - m_WarpSegments[i].m_fLengthBeats = fNew; + m_WarpSegments[i].SetLength(fNew); } else m_WarpSegments.erase( m_WarpSegments.begin()+i, m_WarpSegments.begin()+i+1 ); @@ -410,9 +410,9 @@ float TimingData::GetWarpAtRow( int iWarpRow ) const { for( unsigned i=0; i iNoteRow ) + if( s.GetRow() > iNoteRow ) break; } return static_cast(i); @@ -551,7 +551,8 @@ bool TimingData::IsWarpAtRow( int iNoteRow ) const int i = GetWarpSegmentIndexAtRow( iNoteRow ); const WarpSegment& s = m_WarpSegments[i]; - if( s.m_iStartRow <= iNoteRow && iNoteRow < (s.m_iStartRow + BeatToNoteRow(s.m_fLengthBeats) ) ) + 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( m_StopSegments.empty() ) @@ -844,9 +845,9 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float iEventRow = itSS->m_iStartRow; iEventType = FOUND_STOP; } - if( itWS != m_WarpSegments.end() && itWS->m_iStartRow < iEventRow ) + if( itWS != m_WarpSegments.end() && itWS->GetRow() < iEventRow ) { - iEventRow = itWS->m_iStartRow; + iEventRow = itWS->GetRow(); iEventType = FOUND_WARP; } if( iEventType == NOT_FOUND ) @@ -889,7 +890,7 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float case FOUND_WARP: { bIsWarping = true; - float fWarpSum = itWS->m_fLengthBeats + NoteRowToBeat( itWS->m_iStartRow ); + float fWarpSum = itWS->GetLength() + itWS->GetBeat(); if( fWarpSum > fWarpDestination ) { fWarpDestination = fWarpSum; @@ -956,9 +957,9 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const iEventRow = itSS->m_iStartRow; iEventType = FOUND_STOP; } - if( itWS != m_WarpSegments.end() && itWS->m_iStartRow < iEventRow ) + if( itWS != m_WarpSegments.end() && itWS->GetRow() < iEventRow ) { - iEventRow = itWS->m_iStartRow; + iEventRow = itWS->GetRow(); iEventType = FOUND_WARP; } float fTimeToNextEvent = bIsWarping ? 0 : NoteRowToBeat( iEventRow - iLastRow ) / fBPS; @@ -984,7 +985,7 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const case FOUND_WARP: { bIsWarping = true; - float fWarpSum = itWS->m_fLengthBeats + NoteRowToBeat( itWS->m_iStartRow ); + float fWarpSum = itWS->GetLength() + itWS->GetBeat(); if( fWarpSum > fWarpDestination ) { fWarpDestination = fWarpSum; @@ -1052,21 +1053,23 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) { - const int iSegStartRow = m_WarpSegments[i].m_iStartRow; - const int iSegEndRow = iSegStartRow + BeatToNoteRow( m_WarpSegments[i].m_fLengthBeats ); + WarpSegment &w = m_WarpSegments[i]; + const int iSegStartRow = w.GetRow(); + const int iSegEndRow = iSegStartRow + BeatToNoteRow( w.GetLength() ); if( iSegEndRow >= iStartIndex ) { if( iSegEndRow > iEndIndex ) - m_WarpSegments[i].m_fLengthBeats += NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1))); + w.SetLength(w.GetLength() + + NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1)))); else - m_WarpSegments[i].m_fLengthBeats = NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale)); + w.SetLength(NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale))); } if( iSegStartRow < iStartIndex ) continue; else if( iSegStartRow > iEndIndex ) - m_WarpSegments[i].m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); + w.SetRow(w.GetRow() + lrintf((iEndIndex - iStartIndex) * (fScale - 1))); else - m_WarpSegments[i].m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; + w.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex); } for ( unsigned i = 0; i < m_TickcountSegments.size(); i++ ) @@ -1194,9 +1197,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) { WarpSegment &warp = m_WarpSegments[i]; - if( warp.m_iStartRow < iStartRow ) + if( warp.GetRow() < iStartRow ) continue; - warp.m_iStartRow += iRowsToAdd; + warp.SetRow(warp.GetRow() + iRowsToAdd); } for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) @@ -1314,18 +1317,18 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) { WarpSegment &warp = m_WarpSegments[i]; - - if( warp.m_iStartRow < iStartRow ) + int keyRow = warp.GetRow(); + if( keyRow < iStartRow ) continue; - if( warp.m_iStartRow < iStartRow+iRowsToDelete ) + if( keyRow < iStartRow+iRowsToDelete ) { m_WarpSegments.erase( m_WarpSegments.begin()+i, m_WarpSegments.begin()+i+1 ); --i; continue; } - warp.m_iStartRow -= iRowsToDelete; + warp.SetRow(keyRow - iRowsToDelete); } for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) diff --git a/src/TimingData.h b/src/TimingData.h index 8c003c5e85..aad3b22eab 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -309,109 +309,6 @@ struct TimeSignatureSegment bool operator>= (const TimeSignatureSegment &other ) const { return !operator<(other); } }; -/** - * @brief Identifies when a song needs to warp to a new beat. - * - * A warp segment is used to replicate the effects of Negative BPMs without - * abusing negative BPMs. Negative BPMs should be converted to warp segments. - * WarpAt=WarpToRelative is the format, where both are in beats. - * (Technically they're both rows though.) */ -struct WarpSegment -{ - /** - * @brief Create a simple Warp Segment with default values. - * - * It is best to override the values as soon as possible. - */ - WarpSegment() : m_iStartRow(-1), m_fLengthBeats(-1) { } - /** - * @brief Create a Warp Segment with the specified starting row and row to warp to. - * @param s the starting row of this segment. - * @param r the number of rows to jump ahead. - */ - WarpSegment( int s, int r ): m_iStartRow(s), - m_fLengthBeats(NoteRowToBeat(r)) {} - /** - * @brief Creates a Warp Segment with the specified starting row and beat to warp to. - * @param s the starting row of this segment. - * @param b the number of beats to jump ahead. - */ - WarpSegment( int s, float b ): m_iStartRow(max(0, s)), - m_fLengthBeats(max(0, b)) {} - /** - * @brief Create a Warp Segment with the specified starting beat and row to warp to. - * @param s the starting beat in this segment. - * @param r the number of rows to jump ahead. - */ - WarpSegment( float s, int r ): - m_iStartRow(max(0, BeatToNoteRow(s))), - m_fLengthBeats(max(0, NoteRowToBeat(r))) {} - /** - * @brief Creates a Warp Segment with the specified starting beat and beat to warp to. - * @param s the starting beat of this segment. - * @param b the number of beats to jump ahead. - */ - WarpSegment( float s, float b ): - m_iStartRow(BeatToNoteRow(s)), - m_fLengthBeats(b) {} - /** - * @brief The row in which the WarpSegment activates. - */ - int m_iStartRow; - /** - * @brief The number of beats to warp ahead by. - */ - float m_fLengthBeats; - /** - * @brief Compares two WarpSegments to see if they are equal to each other. - * @param other the other WarpSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const WarpSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_fLengthBeats ); - return true; - } - /** - * @brief Compares two WarpSegments to see if they are not equal to each other. - * @param other the other WarpSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const WarpSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two WarpSegments to see if one is less than the other. - * @param other the other WarpSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const WarpSegment &other ) const - { - return m_iStartRow < other.m_iStartRow || - ( m_iStartRow == other.m_iStartRow && m_fLengthBeats < other.m_fLengthBeats ); - } - /** - * @brief Compares two WarpSegments to see if one is less than or equal to the other. - * @param other the other WarpSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const WarpSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two WarpSegments to see if one is greater than the other. - * @param other the other WarpSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const WarpSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two WarpSegments to see if one is greater than or equal to the other. - * @param other the other WarpSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const WarpSegment &other ) const { return !operator<(other); } -}; - /** * @brief Identifies when a chart is to have a different combo multiplier value. * diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 1cf3780772..38550ee137 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -53,6 +53,23 @@ bool FakeSegment::operator<( const FakeSegment &other ) const return false; } +float WarpSegment::GetLength() const +{ + return this->lengthBeats; +} + +void WarpSegment::SetLength(const float b) +{ + this->lengthBeats = b; +} + +bool WarpSegment::operator<( const WarpSegment &other ) const +{ + LTCOMPARE(GetRow()); + LTCOMPARE(GetLength()); + return false; +} + int TickcountSegment::GetTicks() const diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 58b389662b..e7bed65128 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -3,12 +3,6 @@ #include "NoteTypes.h" // Converting rows to beats and vice~versa. -/** - * @brief Compare a TimingData segment's properties with one another. - * - * This will be removed once we start respecting public & private data.*/ -#define COMPARE(x) if(x!=other.x) return false; - /** * @brief The base timing segment for all of the changing glory. * @@ -91,7 +85,11 @@ struct TimingSegment: public BaseTimingSegment * This is virtual to allow other segments to implement comparison * as required by them. */ - bool operator==( const DerivedSegment &other ) const { return !this->operator<(other) && !other.operator<(*static_cast(this)); }; + bool operator==( const DerivedSegment &other ) const + { + return !this->operator<(other) && + !other.operator<(*static_cast(this)); + }; /** * @brief Compares two DrivedSegments to see if they are not equal to each other. * @param other the other DrivedSegments to compare to. @@ -109,7 +107,10 @@ struct TimingSegment: public BaseTimingSegment * @param other the other DrivedSegments to compare to. * @return the truth/falsehood of if the first is greater than the second. */ - bool operator>( const DerivedSegment &other ) const { return other.operator<(*static_cast(this)); }; + bool operator>( const DerivedSegment &other ) const + { + return other.operator<(*static_cast(this)); + }; /** * @brief Compares two DrivedSegments to see if one is greater than or equal to the other. * @param other the other DrivedSegments to compare to. @@ -148,7 +149,8 @@ struct FakeSegment : public TimingSegment */ template FakeSegment( StartType s, LengthType r ): - TimingSegment(max((StartType)0, s)), lengthBeats(ToBeat(max((LengthType)0, r))) {}; + TimingSegment(max((StartType)0, s)), + lengthBeats(ToBeat(max((LengthType)0, r))) {}; /** * @brief Get the length in beats of the FakeSegment. @@ -180,6 +182,62 @@ private: float lengthBeats; }; +/** + * @brief Identifies when a song needs to warp to a new beat. + * + * A warp segment is used to replicate the effects of Negative BPMs without + * abusing negative BPMs. Negative BPMs should be converted to warp segments. + * WarpAt=WarpToRelative is the format, where both are in beats. + * (Technically they're both rows though.) */ +struct WarpSegment : public TimingSegment +{ + /** + * @brief Create a simple Warp Segment with default values. + * + * It is best to override the values as soon as possible. + */ + WarpSegment(): + TimingSegment(), lengthBeats(-1) {}; + + /** + * @brief Create a Warp Segment with the specified values. + * @param s the starting row of this segment. + * @param r the number of rows this segment lasts. + */ + template + WarpSegment( StartType s, LengthType r ): + TimingSegment(max((StartType)0, s)), + lengthBeats(ToBeat(max((LengthType)0, r))) {}; + + /** + * @brief Get the length in beats of the WarpSegment. + * @return the length in beats. */ + float GetLength() const; + + /** + * @brief Set the length in beats of the WarpSegment. + * @param b the length in beats. */ + void SetLength(const float b); + + /** + * @brief Compares two WarpSegments to see if they are equal to each other. + * @param other the other WarpSegment to compare to. + * @return the equality of the two segments. + */ + bool operator==( const WarpSegment &other ) const; + /* + * @brief Compares two WarpSegments to see if one is less than the other. + * @param other the other WarpSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const WarpSegment &other ) const; +private: + /** + * @brief The number of beats the FakeSegment is alive for. + */ + float lengthBeats; +}; + /** * @brief Identifies when a chart is to have a different tickcount value * for hold notes.