Warps are properly templated.
Seven more to go I believe.
This commit is contained in:
+3
-3
@@ -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() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -110,7 +110,7 @@ static void GetTimingTags( vector<RString> &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() );
|
||||
|
||||
+27
-24
@@ -179,7 +179,7 @@ void TimingData::SetWarpAtRow( int iRow, float fNew )
|
||||
{
|
||||
unsigned i;
|
||||
for( i=0; i<m_WarpSegments.size(); i++ )
|
||||
if( m_WarpSegments[i].m_iStartRow == iRow )
|
||||
if( m_WarpSegments[i].GetRow() == iRow )
|
||||
break;
|
||||
bool valid = iRow > 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<m_WarpSegments.size(); i++ )
|
||||
{
|
||||
if( m_WarpSegments[i].m_iStartRow == iWarpRow )
|
||||
if( m_WarpSegments[i].GetRow() == iWarpRow )
|
||||
{
|
||||
return m_WarpSegments[i].m_fLengthBeats;
|
||||
return m_WarpSegments[i].GetLength();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -526,7 +526,7 @@ int TimingData::GetWarpSegmentIndexAtRow( int iNoteRow ) const
|
||||
for( i=0; i<m_WarpSegments.size()-1; i++ )
|
||||
{
|
||||
const WarpSegment& s = m_WarpSegments[i+1];
|
||||
if( s.m_iStartRow > iNoteRow )
|
||||
if( s.GetRow() > iNoteRow )
|
||||
break;
|
||||
}
|
||||
return static_cast<int>(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++ )
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
+67
-9
@@ -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<const DerivedSegment *>(this)); };
|
||||
bool operator==( const DerivedSegment &other ) const
|
||||
{
|
||||
return !this->operator<(other) &&
|
||||
!other.operator<(*static_cast<const DerivedSegment *>(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<const DerivedSegment *>(this)); };
|
||||
bool operator>( const DerivedSegment &other ) const
|
||||
{
|
||||
return other.operator<(*static_cast<const DerivedSegment *>(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<FakeSegment>
|
||||
*/
|
||||
template <typename StartType, typename LengthType>
|
||||
FakeSegment( StartType s, LengthType r ):
|
||||
TimingSegment<FakeSegment>(max((StartType)0, s)), lengthBeats(ToBeat(max((LengthType)0, r))) {};
|
||||
TimingSegment<FakeSegment>(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<WarpSegment>
|
||||
{
|
||||
/**
|
||||
* @brief Create a simple Warp Segment with default values.
|
||||
*
|
||||
* It is best to override the values as soon as possible.
|
||||
*/
|
||||
WarpSegment():
|
||||
TimingSegment<WarpSegment>(), 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 <typename StartType, typename LengthType>
|
||||
WarpSegment( StartType s, LengthType r ):
|
||||
TimingSegment<WarpSegment>(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.
|
||||
|
||||
Reference in New Issue
Block a user