Speed Segments Satisfied.

This commit is contained in:
Jason Felds
2011-05-31 15:27:27 -04:00
parent 30dc1d4e92
commit f9eb6fb387
9 changed files with 206 additions and 179 deletions
+4 -3
View File
@@ -984,11 +984,12 @@ void NoteField::DrawPrimitives()
{ {
FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, seg ) FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, 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) ) if( IS_ON_SCREEN(fBeat) )
DrawSpeedText( fBeat, seg->m_fPercent, seg->m_fWait, seg->m_usMode ); DrawSpeedText(fBeat, seg->GetRatio(),
seg->GetLength(), seg->GetUnit() );
} }
} }
} }
+4 -3
View File
@@ -340,7 +340,8 @@ void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RS
unsigned short tmp = ( (vs2[2].find("s") || vs2[2].find("S") ) unsigned short tmp = ( (vs2[2].find("s") || vs2[2].find("S") )
? 1 : 0); ? 1 : 0);
SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] ), tmp); SpeedSegment seg(fBeat, StringToFloat( vs2[1] ), StringToFloat(vs2[2]));
seg.SetUnit(tmp);
if( fBeat < 0 ) if( fBeat < 0 )
{ {
@@ -348,9 +349,9 @@ void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RS
continue; continue;
} }
if( seg.m_fWait < 0 ) if( seg.GetLength() < 0 )
{ {
LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, fWait %f.", fBeat, seg.m_fWait ); LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, length %f.", fBeat, seg.GetLength() );
continue; continue;
} }
+4 -3
View File
@@ -158,7 +158,8 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam )
const float fBeat = StringToFloat( vs2[0] ); const float fBeat = StringToFloat( vs2[0] );
SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] ), static_cast<unsigned short>(StringToInt(vs2[3]))); SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] ));
seg.SetUnit(StringToInt(vs2[3]));
if( fBeat < 0 ) if( fBeat < 0 )
{ {
@@ -166,9 +167,9 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam )
continue; continue;
} }
if( seg.m_fWait < 0 ) if( seg.GetLength() < 0 )
{ {
LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, fWait %f.", fBeat, seg.m_fWait ); LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, length %f.", fBeat, seg.GetLength() );
continue; continue;
} }
+1 -1
View File
@@ -134,7 +134,7 @@ static void GetTimingTags( vector<RString> &lines, TimingData timing, bool bIsSo
// Song Timing should only have the initial value. // Song Timing should only have the initial value.
w.Init( "SPEEDS" ); w.Init( "SPEEDS" );
FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, ss ) FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, ss )
w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait, ss->m_usMode ); w.Write( ss->GetRow(), ss->GetRatio(), ss->GetLength(), ss->GetUnit() );
w.Finish(); w.Finish();
w.Init( "SCROLLS" ); w.Init( "SCROLLS" );
+3 -3
View File
@@ -3224,7 +3224,7 @@ void ScreenEdit::DisplayTimingMenu()
{ {
float fBeat = GetBeat(); float fBeat = GetBeat();
TimingData &pTime = GetAppropriateTiming(); TimingData &pTime = GetAppropriateTiming();
bool bHasSpeedOnThisRow = pTime.GetSpeedSegmentAtBeat( fBeat ).m_iStartRow == BeatToNoteRow( fBeat ); bool bHasSpeedOnThisRow = pTime.GetSpeedSegmentAtBeat( fBeat ).GetBeat() == fBeat;
g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pTime.m_fBeat0OffsetInSeconds) ); g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pTime.m_fBeat0OffsetInSeconds) );
g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) );
@@ -4015,7 +4015,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
ScreenTextEntry::TextEntry( ScreenTextEntry::TextEntry(
SM_BackFromSpeedPercentChange, SM_BackFromSpeedPercentChange,
ENTER_SPEED_PERCENT_VALUE, ENTER_SPEED_PERCENT_VALUE,
ssprintf( "%.5f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).m_fPercent ), ssprintf( "%.5f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).GetRatio() ),
10 10
); );
break; break;
@@ -4031,7 +4031,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
ScreenTextEntry::TextEntry( ScreenTextEntry::TextEntry(
SM_BackFromSpeedWaitChange, SM_BackFromSpeedWaitChange,
ENTER_SPEED_WAIT_VALUE, ENTER_SPEED_WAIT_VALUE,
ssprintf( "%.5f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).m_fWait ), ssprintf( "%.5f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).GetLength() ),
10 10
); );
break; break;
+37 -36
View File
@@ -269,27 +269,27 @@ void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait, unsigned
unsigned i; unsigned i;
for( i = 0; i < m_SpeedSegments.size(); i++ ) for( i = 0; i < m_SpeedSegments.size(); i++ )
{ {
if( m_SpeedSegments[i].m_iStartRow >= iRow) if( m_SpeedSegments[i].GetRow() >= iRow)
break; break;
} }
if ( i == m_SpeedSegments.size() || m_SpeedSegments[i].m_iStartRow != iRow ) if ( i == m_SpeedSegments.size() || m_SpeedSegments[i].GetRow() != iRow )
{ {
// the core mod itself matters the most for comparisons. // the core mod itself matters the most for comparisons.
if( i == 0 || m_SpeedSegments[i-1].m_fPercent != fPercent ) if( i == 0 || m_SpeedSegments[i-1].GetRatio() != fPercent )
AddSpeedSegment( SpeedSegment(iRow, fPercent, fWait, usMode) ); AddSpeedSegment( SpeedSegment(iRow, fPercent, fWait, usMode) );
} }
else else
{ {
// The others aren't compared: only the mod itself matters. // The others aren't compared: only the mod itself matters.
if( i > 0 && m_SpeedSegments[i-1].m_fPercent == fPercent ) if( i > 0 && m_SpeedSegments[i-1].GetRatio() == fPercent )
m_SpeedSegments.erase( m_SpeedSegments.begin()+i, m_SpeedSegments.erase( m_SpeedSegments.begin()+i,
m_SpeedSegments.begin()+i+1 ); m_SpeedSegments.begin()+i+1 );
else else
{ {
m_SpeedSegments[i].m_fPercent = fPercent; m_SpeedSegments[i].SetRatio(fPercent);
m_SpeedSegments[i].m_fWait = fWait; m_SpeedSegments[i].SetLength(fWait);
m_SpeedSegments[i].m_usMode = usMode; m_SpeedSegments[i].SetUnit(usMode);
} }
} }
} }
@@ -351,23 +351,23 @@ void TimingData::SetSpeedPercentAtRow( int iRow, float fPercent )
{ {
SetSpeedAtRow( iRow, SetSpeedAtRow( iRow,
fPercent, fPercent,
GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fWait, GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetLength(),
GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_usMode); GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetUnit());
} }
void TimingData::SetSpeedWaitAtRow( int iRow, float fWait ) void TimingData::SetSpeedWaitAtRow( int iRow, float fWait )
{ {
SetSpeedAtRow( iRow, SetSpeedAtRow( iRow,
GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fPercent, GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetRatio(),
fWait, fWait,
GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_usMode); GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetUnit());
} }
void TimingData::SetSpeedModeAtRow( int iRow, unsigned short usMode ) void TimingData::SetSpeedModeAtRow( int iRow, unsigned short usMode )
{ {
SetSpeedAtRow( iRow, SetSpeedAtRow( iRow,
GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fPercent, GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetRatio(),
GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fWait, GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetLength(),
usMode ); usMode );
} }
@@ -419,17 +419,17 @@ float TimingData::GetWarpAtRow( int iWarpRow ) const
float TimingData::GetSpeedPercentAtRow( int iRow ) float TimingData::GetSpeedPercentAtRow( int iRow )
{ {
return GetSpeedSegmentAtRow( iRow ).m_fPercent; return GetSpeedSegmentAtRow( iRow ).GetRatio();
} }
float TimingData::GetSpeedWaitAtRow( int iRow ) float TimingData::GetSpeedWaitAtRow( int iRow )
{ {
return GetSpeedSegmentAtRow( iRow ).m_fWait; return GetSpeedSegmentAtRow( iRow ).GetLength();
} }
unsigned short TimingData::GetSpeedModeAtRow( int iRow ) unsigned short TimingData::GetSpeedModeAtRow( int iRow )
{ {
return GetSpeedSegmentAtRow( iRow ).m_usMode; return GetSpeedSegmentAtRow( iRow ).GetUnit();
} }
float TimingData::GetScrollAtRow( int iRow ) float TimingData::GetScrollAtRow( int iRow )
@@ -619,7 +619,7 @@ int TimingData::GetSpeedSegmentIndexAtRow( int iRow ) const
{ {
unsigned i; unsigned i;
for (i=0; i < m_SpeedSegments.size() - 1; i++ ) for (i=0; i < m_SpeedSegments.size() - 1; i++ )
if( m_SpeedSegments[i+1].m_iStartRow > iRow ) if( m_SpeedSegments[i+1].GetRow() > iRow )
break; break;
return static_cast<int>(i); return static_cast<int>(i);
} }
@@ -656,7 +656,7 @@ SpeedSegment& TimingData::GetSpeedSegmentAtRow( int iRow )
{ {
unsigned i; unsigned i;
for( i=0; i<m_SpeedSegments.size()-1; i++ ) for( i=0; i<m_SpeedSegments.size()-1; i++ )
if( m_SpeedSegments[i+1].m_iStartRow > iRow ) if( m_SpeedSegments[i+1].GetRow() > iRow )
break; break;
return m_SpeedSegments[i]; return m_SpeedSegments[i];
} }
@@ -1113,13 +1113,13 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool
for ( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) for ( unsigned i = 0; i < m_SpeedSegments.size(); i++ )
{ {
SpeedSegment &s = m_SpeedSegments[i]; SpeedSegment &s = m_SpeedSegments[i];
const int iSegStart = s.m_iStartRow; const int iSegStart = s.GetRow();
if( iSegStart < iStartIndex ) if( iSegStart < iStartIndex )
continue; continue;
else if( iSegStart > iEndIndex ) else if( iSegStart > iEndIndex )
s.m_iStartRow += lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); s.SetRow(s.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ));
else else
s.m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; s.SetRow(lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex);
} }
for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) for( unsigned i = 0; i < m_FakeSegments.size(); i++ )
@@ -1242,9 +1242,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd )
for( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) for( unsigned i = 0; i < m_SpeedSegments.size(); i++ )
{ {
SpeedSegment &sped = m_SpeedSegments[i]; SpeedSegment &sped = m_SpeedSegments[i];
if( sped.m_iStartRow < iStartRow ) if( sped.GetRow() < iStartRow )
continue; continue;
sped.m_iStartRow += iRowsToAdd; sped.SetRow(sped.GetRow() + iRowsToAdd);
} }
for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) for( unsigned i = 0; i < m_FakeSegments.size(); i++ )
@@ -1420,17 +1420,17 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete )
for( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) for( unsigned i = 0; i < m_SpeedSegments.size(); i++ )
{ {
SpeedSegment &sped = m_SpeedSegments[i]; SpeedSegment &sped = m_SpeedSegments[i];
int keyRow = sped.GetRow();
if( sped.m_iStartRow < iStartRow ) if( keyRow < iStartRow )
continue; continue;
if( sped.m_iStartRow < iStartRow+iRowsToDelete ) if( keyRow < iStartRow+iRowsToDelete )
{ {
m_SpeedSegments.erase( m_SpeedSegments.begin()+i, m_SpeedSegments.begin()+i+1 ); m_SpeedSegments.erase( m_SpeedSegments.begin()+i, m_SpeedSegments.begin()+i+1 );
--i; --i;
continue; continue;
} }
sped.m_iStartRow -= iRowsToDelete; sped.SetRow(keyRow - iRowsToDelete);
} }
for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) for( unsigned i = 0; i < m_FakeSegments.size(); i++ )
@@ -1477,38 +1477,39 @@ float TimingData::GetDisplayedSpeedPercent( float fSongBeat, float fMusicSeconds
const int index = GetSpeedSegmentIndexAtBeat( fSongBeat ); const int index = GetSpeedSegmentIndexAtBeat( fSongBeat );
const SpeedSegment &seg = m_SpeedSegments[index]; const SpeedSegment &seg = m_SpeedSegments[index];
float fStartBeat = NoteRowToBeat(seg.m_iStartRow); float fStartBeat = seg.GetBeat();
float fStartTime = GetElapsedTimeFromBeat( fStartBeat ) - GetDelayAtBeat( fStartBeat ); float fStartTime = GetElapsedTimeFromBeat( fStartBeat ) - GetDelayAtBeat( fStartBeat );
float fEndTime; float fEndTime;
float fCurTime = fMusicSeconds; float fCurTime = fMusicSeconds;
if( seg.m_usMode == 1 ) // seconds if( seg.GetUnit() == 1 ) // seconds
{ {
fEndTime = fStartTime + seg.m_fWait; fEndTime = fStartTime + seg.GetLength();
} }
else else
{ {
fEndTime = GetElapsedTimeFromBeat( fStartBeat + seg.m_fWait ) - GetDelayAtBeat( fStartBeat + seg.m_fWait ); fEndTime = GetElapsedTimeFromBeat( fStartBeat + seg.GetLength() )
- GetDelayAtBeat( fStartBeat + seg.GetLength() );
} }
if( ( index == 0 && m_SpeedSegments[0].m_fWait > 0.0 ) && fCurTime < fStartTime ) if( ( index == 0 && m_SpeedSegments[0].GetLength() > 0.0 ) && fCurTime < fStartTime )
{ {
return 1.0; return 1.0;
} }
else if( fEndTime >= fCurTime && ( index > 0 || m_SpeedSegments[0].m_fWait > 0.0 ) ) else if( fEndTime >= fCurTime && ( index > 0 || m_SpeedSegments[0].GetLength() > 0.0 ) )
{ {
const float fPriorSpeed = ( index == 0 ? 1 : m_SpeedSegments[index - 1].m_fPercent ); const float fPriorSpeed = ( index == 0 ? 1 : m_SpeedSegments[index - 1].GetRatio() );
float fTimeUsed = fCurTime - fStartTime; float fTimeUsed = fCurTime - fStartTime;
float fDuration = fEndTime - fStartTime; float fDuration = fEndTime - fStartTime;
float fRatioUsed = fDuration == 0.0 ? 1 : fTimeUsed / fDuration; float fRatioUsed = fDuration == 0.0 ? 1 : fTimeUsed / fDuration;
float fDistance = fPriorSpeed - seg.m_fPercent; float fDistance = fPriorSpeed - seg.GetRatio();
float fRatioNeed = fRatioUsed * -fDistance; float fRatioNeed = fRatioUsed * -fDistance;
return (fPriorSpeed + fRatioNeed); return (fPriorSpeed + fRatioNeed);
} }
else else
{ {
return seg.m_fPercent; return seg.GetRatio();
} }
} }
-130
View File
@@ -119,136 +119,6 @@ struct StopSegment
bool operator>=( const StopSegment &other ) const { return !operator<(other); } bool operator>=( const StopSegment &other ) const { return !operator<(other); }
}; };
/**
* @brief Identifies when the arrow scroll changes.
*
* SpeedSegments take a Player's scrolling BPM (Step's BPM * speed mod),
* and then multiplies it with the percentage value. No matter the player's
* speed mod, the ratio will be the same. Unlike forced attacks, these
* cannot be turned off at a set time: reset it by setting the precentage
* back to 1.
*
* These were inspired by the Pump It Up series. */
struct SpeedSegment
{
/** @brief Sets up the SpeedSegment with default values. */
SpeedSegment(): m_iStartRow(0),
m_fPercent(1), m_fWait(0), m_usMode(0) {}
/**
* @brief Sets up the SpeedSegment with specified values.
* @param i The row this activates.
* @param p The percentage to use. */
SpeedSegment(int i, float p): m_iStartRow(i),
m_fPercent(p), m_fWait(0), m_usMode(0) {}
/**
* @brief Sets up the SpeedSegment with specified values.
* @param r The beat this activates.
* @param p The percentage to use. */
SpeedSegment(float r, float p): m_iStartRow(BeatToNoteRow(r)),
m_fPercent(p), m_fWait(0), m_usMode(0) {}
/**
* @brief Sets up the SpeedSegment with specified values.
* @param i The row this activates.
* @param p The percentage to use.
* @param w The number of beats to wait. */
SpeedSegment(int i, float p, float w): m_iStartRow(i),
m_fPercent(p), m_fWait(w), m_usMode(0) {}
/**
* @brief Sets up the SpeedSegment with specified values.
* @param r The beat this activates.
* @param p The percentage to use.
* @param w The number of beats to wait. */
SpeedSegment(float r, float p, float w): m_iStartRow(BeatToNoteRow(r)),
m_fPercent(p), m_fWait(w), m_usMode(0) {}
/**
* @brief Sets up the SpeedSegment with specified values.
* @param i The row this activates.
* @param p The percentage to use.
* @param w The number of beats/seconds to wait.
* @param k The mode used for the wait variable. */
SpeedSegment(int i, float p, float w, unsigned short k): m_iStartRow(i),
m_fPercent(p), m_fWait(w), m_usMode(k) {}
/**
* @brief Sets up the SpeedSegment with specified values.
* @param r The beat this activates.
* @param p The percentage to use.
* @param w The number of beats/seconds to wait.
* @param k The mode used for the wait variable.*/
SpeedSegment(float r, float p, float w, unsigned short k): m_iStartRow(BeatToNoteRow(r)),
m_fPercent(p), m_fWait(w), m_usMode(k) {}
/** @brief The row in which the ComboSegment activates. */
int m_iStartRow;
/** @brief The percentage to use when multiplying the Player's BPM. */
float m_fPercent;
/**
* @brief The number of beats or seconds to wait for the change to take place.
*
* A value of 0 means this is immediate. */
float m_fWait;
/**
* @brief The mode that this segment uses for the math.
*
* 0: beats
* 1: seconds
* other
*/
unsigned short m_usMode;
/**
* @brief Compares two SpeedSegments to see if they are equal to each other.
* @param other the other SpeedSegment to compare to.
* @return the equality of the two segments.
*/
bool operator==( const SpeedSegment &other ) const
{
COMPARE( m_iStartRow );
COMPARE( m_fPercent );
COMPARE( m_usMode );
COMPARE( m_fWait );
return true;
}
/**
* @brief Compares two SpeedSegments to see if they are not equal to each other.
* @param other the other SpeedSegment to compare to.
* @return the inequality of the two segments.
*/
bool operator!=( const SpeedSegment &other ) const { return !operator==(other); }
/**
* @brief Compares two SpeedSegments to see if one is less than the other.
* @param other the other SpeedSegment to compare to.
* @return the truth/falsehood of if the first is less than the second.
*/
bool operator<( const SpeedSegment &other ) const { return m_iStartRow < other.m_iStartRow; }
/**
* @brief Compares two SpeedSegments to see if one is less than or equal to the other.
* @param other the other SpeedSegment to compare to.
* @return the truth/falsehood of if the first is less or equal to than the second.
*/
bool operator<=( const SpeedSegment &other ) const
{
return ( operator<(other) || operator==(other) );
}
/**
* @brief Compares two SpeedSegments to see if one is greater than the other.
* @param other the other SpeedSegment to compare to.
* @return the truth/falsehood of if the first is greater than the second.
*/
bool operator>( const SpeedSegment &other ) const { return !operator<=(other); }
/**
* @brief Compares two SpeedSegments to see if one is greater than or equal to the other.
* @param other the other SpeedSegment to compare to.
* @return the truth/falsehood of if the first is greater than or equal to the second.
*/
bool operator>=( const SpeedSegment &other ) const { return !operator<(other); }
};
/** /**
* @brief Identifies when the chart scroll changes. * @brief Identifies when the chart scroll changes.
* *
+43
View File
@@ -195,7 +195,50 @@ bool TimeSignatureSegment::operator<( const TimeSignatureSegment &other ) const
return false; return false;
} }
float SpeedSegment::GetRatio() const
{
return this->ratio;
}
void SpeedSegment::SetRatio(const float i)
{
this->ratio = i;
}
float SpeedSegment::GetLength() const
{
return this->length;
}
void SpeedSegment::SetLength(const float i)
{
this->length = i;
}
unsigned short SpeedSegment::GetUnit() const
{
return this->unit;
}
void SpeedSegment::SetUnit(const unsigned short i)
{
this->unit = i;
}
void SpeedSegment::SetUnit(const int i)
{
this->unit = static_cast<unsigned short>(i);
}
bool SpeedSegment::operator<( const SpeedSegment &other ) const
{
LTCOMPARE(GetRow());
LTCOMPARE(GetRatio());
LTCOMPARE(GetLength());
LTCOMPARE(GetUnit());
return false;
}
/** /**
+110
View File
@@ -525,6 +525,116 @@ private:
int denominator; int denominator;
}; };
/**
* @brief Identifies when the arrow scroll changes.
*
* SpeedSegments take a Player's scrolling BPM (Step's BPM * speed mod),
* and then multiplies it with the percentage value. No matter the player's
* speed mod, the ratio will be the same. Unlike forced attacks, these
* cannot be turned off at a set time: reset it by setting the precentage
* back to 1.
*
* These were inspired by the Pump It Up series. */
struct SpeedSegment : public TimingSegment<SpeedSegment>
{
/** @brief Sets up the SpeedSegment with default values. */
SpeedSegment():
TimingSegment<SpeedSegment>(0),
ratio(1), length(0), unit(0) {}
/**
* @brief Sets up the SpeedSegment with specified values.
* @param r The row / beat this activates.
* @param p The percentage to use. */
template <typename StartType>
SpeedSegment( StartType r, float p):
TimingSegment<SpeedSegment>(max((StartType)0, r)),
ratio(p), length(0), unit(0) {}
/**
* @brief Sets up the SpeedSegment with specified values.
* @param r The row / beat this activates.
* @param p The percentage to use.
* @param w The number of beats to wait. */
template <typename StartType>
SpeedSegment(StartType r, float p, float w):
TimingSegment<SpeedSegment>(max((StartType)0, r)),
ratio(p), length(w), unit(0) {}
/**
* @brief Sets up the SpeedSegment with specified values.
* @param r The row / beat this activates.
* @param p The percentage to use.
* @param w The number of beats/seconds to wait.
* @param k The mode used for the wait variable. */
template <typename StartType>
SpeedSegment(StartType r, float p, float w, unsigned short k):
TimingSegment<SpeedSegment>(max((StartType)0, r)),
ratio(p), length(w), unit(k) {}
/**
* @brief Get the ratio in this SpeedSegment.
* @return the ratio. */
float GetRatio() const;
/**
* @brief Set the ratio in this SpeedSegment.
* @param i the ratio. */
void SetRatio(const float i);
/**
* @brief Get the length in this SpeedSegment.
* @return the length. */
float GetLength() const;
/**
* @brief Set the length in this SpeedSegment.
* @param i the length. */
void SetLength(const float i);
/**
* @brief Get the unit in this SpeedSegment.
* @return the unit. */
unsigned short GetUnit() const;
/**
* @brief Set the unit in this SpeedSegment.
* @param i the unit. */
void SetUnit(const unsigned short i);
/**
* @brief Set the unit in this SpeedSegment.
*
* This one is offered for quicker compatibility.
* @param i the unit. */
void SetUnit(const int i);
/**
* @brief Compares two SpeedSegments to see if one is less than the other.
* @param other the other SpeedSegment to compare to.
* @return the truth/falsehood of if the first is less than the second.
*/
bool operator<( const SpeedSegment &other ) const;
private:
/** @brief The percentage (ratio) to use when multiplying the Player's BPM. */
float ratio;
/**
* @brief The number of beats or seconds to wait for the change to take place.
*
* A value of 0 means this is immediate. */
float length;
/**
* @brief The mode that this segment uses for the math.
*
* 0: beats
* 1: seconds
* other
*/
unsigned short unit;
};
#endif #endif
/** /**