Warps are properly templated.

Seven more to go I believe.
This commit is contained in:
Jason Felds
2011-05-31 10:59:18 -04:00
parent 26ecddfc9d
commit 1fcf290571
7 changed files with 117 additions and 142 deletions
+3 -3
View File
@@ -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() );
}
}
+2 -2
View File
@@ -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;
+1 -1
View File
@@ -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
View File
@@ -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++ )
-103
View File
@@ -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.
*
+17
View File
@@ -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
View File
@@ -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.