Bring in the scroll branch.
Sorry Saturn, but you have to re-cache this time.
This commit is contained in:
@@ -14,6 +14,7 @@ ________________________________________________________________________________
|
||||
* #SPEEDS tag for modified scroll speeds.
|
||||
* #FAKES tag for ignoring judgments within a range.
|
||||
* #WARPS modified so that second parameter is now relative to the start.
|
||||
* #SCROLLS tag for...hilarity?
|
||||
|
||||
[v0.59] - Wolfman2000
|
||||
* Typo fix: #RADARVALUES needed a semicolon at the end, not a colon.
|
||||
|
||||
@@ -8,6 +8,11 @@ ________________________________________________________________________________
|
||||
StepMania 5.0 $NEXT | 20110xyy
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
2011/05/25
|
||||
----------
|
||||
* [NotesLoaderSSC/NotesWriterSSC] Added the ScrollSegments. Think BPM change,
|
||||
but not. [theDtTvB]
|
||||
|
||||
2011/05/23
|
||||
----------
|
||||
* [Steps] Added the UsesSplitTiming Lua binding. [Wolfman2000]
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#TICKCOUNTS:;
|
||||
#COMBOS:;
|
||||
#SPEEDS:;
|
||||
#SCROLLS:;
|
||||
#FAKES:;
|
||||
#LABELS:;
|
||||
#ATTACKS:; // Not yet in use.
|
||||
|
||||
@@ -855,6 +855,7 @@ Edit warp=Edit warp
|
||||
Edit speed (percent)=Edit speed (percent)
|
||||
Edit speed (wait)=Edit speed (length)
|
||||
Edit speed (mode)=Edit speed (mode)
|
||||
Edit scrolling factor=Edit scrolling factor
|
||||
Edit fake=Edit fake segment
|
||||
Editor options=Options
|
||||
EditorShowBGChangesPlay=Show Backgrounds
|
||||
@@ -1233,6 +1234,7 @@ Enter a new Warp value.=Enter the number of beats you will warp over.\n\nType "0
|
||||
Enter a new Speed percent value.=Enter the ratio for speed scrolling.\nEnter the previous value to remove.\n1 is the default scroll.
|
||||
Enter a new Speed wait value.=Enter how long in seconds/beats it takes to change.\n\n0 is instant.
|
||||
Enter a new Speed mode value.=Enter how this segment is handled.\n\nType "0" for beats, "1" for seconds.
|
||||
Enter a new Scroll value.=Enter a new Scroll value.
|
||||
Enter a new Fake value.=Enter the number of beats that won't be judged.\n\nType "0" to remove this.
|
||||
Are you sure you want to erase this chart's timing data?=Are you sure you want to erase this chart's timing data?
|
||||
Enter a new artist transliteration.=Enter a new artist transliteration.
|
||||
|
||||
@@ -991,6 +991,7 @@ TickcountColor=color("0,1,0,1")
|
||||
ComboColor=color("0.55,1,0,1")
|
||||
LabelColor=color("1,0,0,1")
|
||||
SpeedColor=color("0.5,1,1,1")
|
||||
ScrollColor=color("0.3,0.8,1,1")
|
||||
FakeColor=color("1,1,0.5,1")
|
||||
#
|
||||
BPMIsLeftSide=true
|
||||
@@ -1002,6 +1003,7 @@ TickcountIsLeftSide=false
|
||||
ComboIsLeftSide=false
|
||||
LabelIsLeftSide=false
|
||||
SpeedIsLeftSide=false
|
||||
ScrollIsLeftSide=true
|
||||
FakeIsLeftSide=true
|
||||
#
|
||||
BPMOffsetX=60
|
||||
@@ -1013,6 +1015,7 @@ TickcountOffsetX=70
|
||||
ComboOffsetX=50
|
||||
LabelOffsetX=130
|
||||
SpeedOffsetX=30
|
||||
ScrollOffsetX=40
|
||||
FakeOffsetX=90
|
||||
|
||||
[PlayerStageStats]
|
||||
|
||||
@@ -231,9 +231,12 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
|
||||
* entirely time spacing (respectively). Occasionally, we tween between them. */
|
||||
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 1.0f )
|
||||
{
|
||||
float bShowEffects = !( GAMESTATE->m_bInStepEditor || !GAMESTATE->m_bIsUsingStepTiming );
|
||||
float fBeatsUntilStep = fNoteBeat - fSongBeat;
|
||||
if( bShowEffects )
|
||||
fBeatsUntilStep = pCurSteps->m_Timing.GetDisplayedBeat(fNoteBeat) - pCurSteps->m_Timing.GetDisplayedBeat(fSongBeat);
|
||||
float fYOffsetBeatSpacing = fBeatsUntilStep;
|
||||
float fSpeedMultiplier = ( GAMESTATE->m_bInStepEditor || !GAMESTATE->m_bIsUsingStepTiming ) ? 1.0 : pCurSteps->m_Timing.GetDisplayedSpeedPercent( position.m_fSongBeatVisible, position.m_fMusicSecondsVisible );
|
||||
float fSpeedMultiplier = bShowEffects ? pCurSteps->m_Timing.GetDisplayedSpeedPercent( position.m_fSongBeatVisible, position.m_fMusicSecondsVisible ) : 1.0;
|
||||
fYOffset += fSpeedMultiplier * fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing);
|
||||
}
|
||||
|
||||
|
||||
@@ -455,6 +455,7 @@ static ThemeMetric<RageColor> TICKCOUNT_COLOR ( "NoteField", "TickcountColor" );
|
||||
static ThemeMetric<RageColor> COMBO_COLOR ( "NoteField", "ComboColor" );
|
||||
static ThemeMetric<RageColor> LABEL_COLOR ( "NoteField", "LabelColor" );
|
||||
static ThemeMetric<RageColor> SPEED_COLOR ( "NoteField", "SpeedColor" );
|
||||
static ThemeMetric<RageColor> SCROLL_COLOR ( "NoteField", "ScrollColor" );
|
||||
static ThemeMetric<RageColor> FAKE_COLOR ("NoteField", "FakeColor" );
|
||||
static ThemeMetric<bool> BPM_IS_LEFT_SIDE ( "NoteField", "BPMIsLeftSide" );
|
||||
static ThemeMetric<bool> STOP_IS_LEFT_SIDE ( "NoteField", "StopIsLeftSide" );
|
||||
@@ -465,6 +466,7 @@ static ThemeMetric<bool> TICKCOUNT_IS_LEFT_SIDE ( "NoteField", "TickcountIsLeftS
|
||||
static ThemeMetric<bool> COMBO_IS_LEFT_SIDE ( "NoteField", "ComboIsLeftSide" );
|
||||
static ThemeMetric<bool> LABEL_IS_LEFT_SIDE ( "NoteField", "LabelIsLeftSide" );
|
||||
static ThemeMetric<bool> SPEED_IS_LEFT_SIDE ( "NoteField", "SpeedIsLeftSide" );
|
||||
static ThemeMetric<bool> SCROLL_IS_LEFT_SIDE ( "NoteField", "ScrollIsLeftSide" );
|
||||
static ThemeMetric<bool> FAKE_IS_LEFT_SIDE ( "NoteField", "FakeIsLeftSide" );
|
||||
static ThemeMetric<float> BPM_OFFSETX ( "NoteField", "BPMOffsetX" );
|
||||
static ThemeMetric<float> STOP_OFFSETX ( "NoteField", "StopOffsetX" );
|
||||
@@ -475,6 +477,7 @@ static ThemeMetric<float> TICKCOUNT_OFFSETX ( "NoteField", "TickcountOffsetX" );
|
||||
static ThemeMetric<float> COMBO_OFFSETX ( "NoteField", "ComboOffsetX" );
|
||||
static ThemeMetric<float> LABEL_OFFSETX ( "NoteField", "LabelOffsetX" );
|
||||
static ThemeMetric<float> SPEED_OFFSETX ( "NoteField", "SpeedOffsetX" );
|
||||
static ThemeMetric<float> SCROLL_OFFSETX ( "NoteField", "ScrollOffsetX" );
|
||||
static ThemeMetric<float> FAKE_OFFSETX ( "NoteField", "FakeOffsetX" );
|
||||
|
||||
void NoteField::DrawBPMText( const float fBeat, const float fBPM )
|
||||
@@ -622,6 +625,23 @@ void NoteField::DrawSpeedText( const float fBeat, float fPercent, float fWait, u
|
||||
m_textMeasureNumber.Draw();
|
||||
}
|
||||
|
||||
void NoteField::DrawScrollText( const float fBeat, float fPercent )
|
||||
{
|
||||
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 = SCROLL_OFFSETX * fZoom;
|
||||
|
||||
m_textMeasureNumber.SetZoom( fZoom );
|
||||
m_textMeasureNumber.SetHorizAlign( SCROLL_IS_LEFT_SIDE ? align_right : align_left );
|
||||
m_textMeasureNumber.SetDiffuse( SCROLL_COLOR );
|
||||
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
|
||||
m_textMeasureNumber.SetText( ssprintf("%.3fx", fPercent) );
|
||||
m_textMeasureNumber.SetXY( (SCROLL_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
|
||||
m_textMeasureNumber.Draw();
|
||||
}
|
||||
|
||||
void NoteField::DrawFakeText( const float fBeat, const float fNewBeat )
|
||||
{
|
||||
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
|
||||
@@ -973,6 +993,20 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll text
|
||||
if( GAMESTATE->m_bIsUsingStepTiming )
|
||||
{
|
||||
FOREACH_CONST( ScrollSegment, timing.m_ScrollSegments, seg )
|
||||
{
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = NoteRowToBeat(seg->m_iStartRow);
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
DrawScrollText( fBeat, seg->m_fPercent );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Speed text
|
||||
if( GAMESTATE->m_bIsUsingStepTiming )
|
||||
{
|
||||
|
||||
@@ -65,6 +65,7 @@ protected:
|
||||
void DrawComboText( const float fBeat, int iCombo );
|
||||
void DrawLabelText( const float fBeat, RString sLabel );
|
||||
void DrawSpeedText( const float fBeat, float fPercent, float fWait, unsigned short usMode );
|
||||
void DrawScrollText( const float fBeat, float fPercent );
|
||||
void DrawFakeText( const float fBeat, const float fNewBeat );
|
||||
void DrawAttackText( const float fBeat, const Attack &attack );
|
||||
void DrawBGChangeText( const float fBeat, const RString sNewBGName );
|
||||
|
||||
@@ -176,6 +176,36 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam )
|
||||
}
|
||||
}
|
||||
|
||||
void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam )
|
||||
{
|
||||
vector<RString> vs1;
|
||||
split( sParam, ",", vs1 );
|
||||
|
||||
FOREACH_CONST( RString, vs1, s1 )
|
||||
{
|
||||
vector<RString> vs2;
|
||||
split( *s1, "=", vs2 );
|
||||
|
||||
if( vs2.size() < 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an scroll change with %i values.", (int)vs2.size() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( vs2[0] );
|
||||
|
||||
ScrollSegment seg( fBeat, StringToFloat( vs2[1] ) );
|
||||
|
||||
if( fBeat < 0 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an scroll change with beat %f.", fBeat );
|
||||
continue;
|
||||
}
|
||||
|
||||
out.AddScrollSegment( seg );
|
||||
}
|
||||
}
|
||||
|
||||
void SSCLoader::ProcessFakes( TimingData &out, const RString sParam )
|
||||
{
|
||||
vector<RString> arrayFakeExpressions;
|
||||
@@ -601,6 +631,11 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
ProcessSpeeds( stepsTiming, sParams[1] );
|
||||
}
|
||||
|
||||
else if( sValueName=="SCROLLS" )
|
||||
{
|
||||
ProcessScrolls( stepsTiming, sParams[1] );
|
||||
}
|
||||
|
||||
else if( sValueName=="FAKES" )
|
||||
{
|
||||
ProcessFakes( stepsTiming, sParams[1] );
|
||||
|
||||
@@ -81,6 +81,7 @@ namespace SSCLoader
|
||||
void ProcessLabels( TimingData &, const RString );
|
||||
void ProcessCombos( TimingData &, const RString );
|
||||
void ProcessSpeeds( TimingData &, const RString );
|
||||
void ProcessScrolls( TimingData &, const RString );
|
||||
void ProcessFakes( TimingData &, const RString );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -137,6 +137,11 @@ static void GetTimingTags( vector<RString> &lines, TimingData timing, bool bIsSo
|
||||
w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait, ss->m_usMode );
|
||||
w.Finish();
|
||||
|
||||
w.Init( "SCROLLS" );
|
||||
FOREACH_CONST( ScrollSegment, timing.m_ScrollSegments, ss )
|
||||
w.Write( ss->m_iStartRow, ss->m_fPercent );
|
||||
w.Finish();
|
||||
|
||||
if( !bIsSong )
|
||||
{
|
||||
w.Init( "FAKES" );
|
||||
|
||||
@@ -85,6 +85,7 @@ AutoScreenMessage( SM_BackFromWarpChange );
|
||||
AutoScreenMessage( SM_BackFromSpeedPercentChange );
|
||||
AutoScreenMessage( SM_BackFromSpeedWaitChange );
|
||||
AutoScreenMessage( SM_BackFromSpeedModeChange );
|
||||
AutoScreenMessage( SM_BackFromScrollChange );
|
||||
AutoScreenMessage( SM_BackFromFakeChange );
|
||||
AutoScreenMessage( SM_DoEraseStepTiming );
|
||||
AutoScreenMessage( SM_DoSaveAndExit );
|
||||
@@ -581,6 +582,7 @@ static MenuDef g_TimingDataInformation(
|
||||
MenuRowDef( ScreenEdit::speed_percent, "Edit speed (percent)", true, EditMode_Full, true, true, 0, NULL ),
|
||||
MenuRowDef( ScreenEdit::speed_wait, "Edit speed (wait)", true, EditMode_Full, true, true, 0, NULL ),
|
||||
MenuRowDef( ScreenEdit::speed_mode, "Edit speed (mode)", true, EditMode_Full, true, true, 0, "Beats", "Seconds" ),
|
||||
MenuRowDef( ScreenEdit::scroll, "Edit scrolling factor", true, EditMode_Full, true, true, 0, NULL ),
|
||||
MenuRowDef( ScreenEdit::fake, "Edit fake", true, EditMode_Full, true, true, 0, NULL ),
|
||||
MenuRowDef( ScreenEdit::erase_step_timing, "Erase step timing", true, EditMode_Full, true, true, 0, NULL )
|
||||
);
|
||||
@@ -2795,6 +2797,12 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
}
|
||||
SetDirty( true );
|
||||
}
|
||||
else if( SM == SM_BackFromScrollChange )
|
||||
{
|
||||
float fNum = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||
GetAppropriateTiming().SetScrollAtBeat( GetBeat(), fNum );
|
||||
SetDirty( true );
|
||||
}
|
||||
else if ( SM == SM_BackFromFakeChange )
|
||||
{
|
||||
float fFake = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||
@@ -3225,6 +3233,7 @@ void ScreenEdit::DisplayTimingMenu()
|
||||
RString starting = ( pTime.GetSpeedModeAtBeat( fBeat ) == 1 ? "Seconds" : "Beats" );
|
||||
g_TimingDataInformation.rows[speed_mode].SetOneUnthemedChoice( starting.c_str() );
|
||||
|
||||
g_TimingDataInformation.rows[scroll].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetScrollAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[fake].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetFakeAtBeat( fBeat ) ) );
|
||||
|
||||
g_TimingDataInformation.rows[tickcount].bEnabled = GAMESTATE->m_bIsUsingStepTiming;
|
||||
@@ -3913,6 +3922,7 @@ static LocalizedString ENTER_WARP_VALUE ( "ScreenEdit", "Enter a new Warp val
|
||||
static LocalizedString ENTER_SPEED_PERCENT_VALUE ( "ScreenEdit", "Enter a new Speed percent value." );
|
||||
static LocalizedString ENTER_SPEED_WAIT_VALUE ( "ScreenEdit", "Enter a new Speed wait value." );
|
||||
static LocalizedString ENTER_SPEED_MODE_VALUE ( "ScreenEdit", "Enter a new Speed mode value." );
|
||||
static LocalizedString ENTER_SCROLL_VALUE ( "ScreenEdit", "Enter a new Scroll value." );
|
||||
static LocalizedString ENTER_FAKE_VALUE ( "ScreenEdit", "Enter a new Fake value." );
|
||||
static LocalizedString CONFIRM_TIMING_ERASE ( "ScreenEdit", "Are you sure you want to erase this chart's timing data?" );
|
||||
void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice c, const vector<int> &iAnswers )
|
||||
@@ -3997,6 +4007,14 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
10
|
||||
);
|
||||
break;
|
||||
case scroll:
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromScrollChange,
|
||||
ENTER_SCROLL_VALUE,
|
||||
ssprintf( "%.5f", GetAppropriateTiming().GetScrollSegmentAtBeat( GetBeat() ).m_fPercent ),
|
||||
10
|
||||
);
|
||||
break;
|
||||
case speed_wait:
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromSpeedWaitChange,
|
||||
|
||||
@@ -498,6 +498,7 @@ public:
|
||||
speed_percent,
|
||||
speed_wait,
|
||||
speed_mode,
|
||||
scroll,
|
||||
fake,
|
||||
erase_step_timing,
|
||||
NUM_TIMING_DATA_INFORMATION_CHOICES
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
* @brief The internal version of the cache for StepMania.
|
||||
*
|
||||
* Increment this value to invalidate the current cache. */
|
||||
const int FILE_CACHE_VERSION = 176;
|
||||
const int FILE_CACHE_VERSION = 177;
|
||||
|
||||
/** @brief How long does a song sample last by default? */
|
||||
const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;
|
||||
|
||||
@@ -73,6 +73,11 @@ void TimingData::AddSpeedSegment( const SpeedSegment &seg )
|
||||
m_SpeedSegments.insert( upper_bound(m_SpeedSegments.begin(), m_SpeedSegments.end(), seg), seg );
|
||||
}
|
||||
|
||||
void TimingData::AddScrollSegment( const ScrollSegment &seg )
|
||||
{
|
||||
m_ScrollSegments.insert( upper_bound(m_ScrollSegments.begin(), m_ScrollSegments.end(), seg), seg );
|
||||
}
|
||||
|
||||
void TimingData::AddFakeSegment( const FakeSegment &seg )
|
||||
{
|
||||
m_FakeSegments.insert( upper_bound(m_FakeSegments.begin(), m_FakeSegments.end(), seg), seg );
|
||||
@@ -290,6 +295,34 @@ void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait, unsigned
|
||||
}
|
||||
}
|
||||
|
||||
void TimingData::SetScrollAtRow( int iRow, float fPercent )
|
||||
{
|
||||
unsigned i;
|
||||
for( i = 0; i < m_ScrollSegments.size(); i++ )
|
||||
{
|
||||
if( m_ScrollSegments[i].m_iStartRow >= iRow)
|
||||
break;
|
||||
}
|
||||
|
||||
if ( i == m_ScrollSegments.size() || m_ScrollSegments[i].m_iStartRow != iRow )
|
||||
{
|
||||
// the core mod itself matters the most for comparisons.
|
||||
if( i == 0 || m_ScrollSegments[i-1].m_fPercent != fPercent )
|
||||
AddScrollSegment( ScrollSegment(iRow, fPercent) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// The others aren't compared: only the mod itself matters.
|
||||
if( i > 0 && m_ScrollSegments[i-1].m_fPercent == fPercent )
|
||||
m_ScrollSegments.erase( m_ScrollSegments.begin()+i,
|
||||
m_ScrollSegments.begin()+i+1 );
|
||||
else
|
||||
{
|
||||
m_ScrollSegments[i].m_fPercent = fPercent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimingData::SetFakeAtRow( int iRow, float fNew )
|
||||
{
|
||||
unsigned i;
|
||||
@@ -400,6 +433,11 @@ unsigned short TimingData::GetSpeedModeAtRow( int iRow )
|
||||
return GetSpeedSegmentAtRow( iRow ).m_usMode;
|
||||
}
|
||||
|
||||
float TimingData::GetScrollAtRow( int iRow )
|
||||
{
|
||||
return GetScrollSegmentAtRow( iRow ).m_fPercent;
|
||||
}
|
||||
|
||||
float TimingData::GetFakeAtRow( int iFakeRow ) const
|
||||
{
|
||||
for( unsigned i=0; i<m_FakeSegments.size(); i++ )
|
||||
@@ -585,6 +623,15 @@ int TimingData::GetSpeedSegmentIndexAtRow( int iRow ) const
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
|
||||
int TimingData::GetScrollSegmentIndexAtRow( int iRow ) const
|
||||
{
|
||||
unsigned i;
|
||||
for (i=0; i < m_ScrollSegments.size() - 1; i++ )
|
||||
if( m_ScrollSegments[i+1].m_iStartRow > iRow )
|
||||
break;
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
|
||||
BPMSegment& TimingData::GetBPMSegmentAtRow( int iNoteRow )
|
||||
{
|
||||
static BPMSegment empty;
|
||||
@@ -613,6 +660,15 @@ SpeedSegment& TimingData::GetSpeedSegmentAtRow( int iRow )
|
||||
return m_SpeedSegments[i];
|
||||
}
|
||||
|
||||
ScrollSegment& TimingData::GetScrollSegmentAtRow( int iRow )
|
||||
{
|
||||
unsigned i;
|
||||
for( i=0; i<m_ScrollSegments.size()-1; i++ )
|
||||
if( m_ScrollSegments[i+1].m_iStartRow > iRow )
|
||||
break;
|
||||
return m_ScrollSegments[i];
|
||||
}
|
||||
|
||||
int TimingData::GetTimeSignatureNumeratorAtRow( int iRow )
|
||||
{
|
||||
return GetTimeSignatureSegmentAtRow( iRow ).m_iNumerator;
|
||||
@@ -943,6 +999,17 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const
|
||||
|
||||
}
|
||||
|
||||
float TimingData::GetDisplayedBeat( float fBeat ) const
|
||||
{
|
||||
unsigned index = GetScrollSegmentIndexAtBeat(fBeat);
|
||||
float fOutBeat = ( fBeat - NoteRowToBeat(m_ScrollSegments[index].m_iStartRow) ) * m_ScrollSegments[index].m_fPercent;
|
||||
for( unsigned i = 0; i < index; i ++ )
|
||||
{
|
||||
fOutBeat += ( NoteRowToBeat(m_ScrollSegments[i + 1].m_iStartRow) - NoteRowToBeat(m_ScrollSegments[i].m_iStartRow) ) * m_ScrollSegments[i].m_fPercent;
|
||||
}
|
||||
return fOutBeat;
|
||||
}
|
||||
|
||||
void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool bAdjustBPM )
|
||||
{
|
||||
ASSERT( fScale > 0 );
|
||||
@@ -1436,6 +1503,13 @@ void TimingData::TidyUpData()
|
||||
SpeedSegment seg(0, 1, 0);
|
||||
m_SpeedSegments.push_back( seg );
|
||||
}
|
||||
|
||||
// Always be sure there is a starting scrolling factor.
|
||||
if( m_ScrollSegments.empty() )
|
||||
{
|
||||
ScrollSegment seg(0, 1);
|
||||
m_ScrollSegments.push_back( seg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1467,6 +1541,11 @@ bool TimingData::HasSpeedChanges() const
|
||||
return m_SpeedSegments.size()>1;
|
||||
}
|
||||
|
||||
bool TimingData::HasScrollChanges() const
|
||||
{
|
||||
return m_ScrollSegments.size()>1;
|
||||
}
|
||||
|
||||
void TimingData::NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, int &iBeatIndexOut, int &iRowsRemainder ) const
|
||||
{
|
||||
iMeasureIndexOut = 0;
|
||||
|
||||
@@ -777,6 +777,82 @@ struct SpeedSegment
|
||||
bool operator>=( const SpeedSegment &other ) const { return !operator<(other); }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Identifies when the chart scroll changes.
|
||||
*
|
||||
* ScrollSegments adjusts the scrolling speed of the note field.
|
||||
* 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 ScrollSegment
|
||||
{
|
||||
/** @brief Sets up the ScrollSegment with default values. */
|
||||
ScrollSegment(): m_iStartRow(0), m_fPercent(1) {}
|
||||
|
||||
/**
|
||||
* @brief Sets up the ScrollSegment with specified values.
|
||||
* @param i The row this activates.
|
||||
* @param p The percentage to use. */
|
||||
ScrollSegment(int i, float p): m_iStartRow(i), m_fPercent(p) {}
|
||||
|
||||
/**
|
||||
* @brief Sets up the ScrollSegment with specified values.
|
||||
* @param r The beat this activates.
|
||||
* @param p The percentage to use. */
|
||||
ScrollSegment(float r, float p): m_iStartRow(BeatToNoteRow(r)), m_fPercent(p) {}
|
||||
|
||||
/** @brief The row in which the ScrollSegment activates. */
|
||||
int m_iStartRow;
|
||||
/** @brief The percentage to use when multiplying the chart's scroll rate. */
|
||||
float m_fPercent;
|
||||
|
||||
/**
|
||||
* @brief Compares two ScrollSegment to see if they are equal to each other.
|
||||
* @param other the other ScrollSegment to compare to.
|
||||
* @return the equality of the two segments.
|
||||
*/
|
||||
bool operator==( const ScrollSegment &other ) const
|
||||
{
|
||||
COMPARE( m_iStartRow );
|
||||
COMPARE( m_fPercent );
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @brief Compares two ScrollSegment to see if they are not equal to each other.
|
||||
* @param other the other ScrollSegment to compare to.
|
||||
* @return the inequality of the two segments.
|
||||
*/
|
||||
bool operator!=( const ScrollSegment &other ) const { return !operator==(other); }
|
||||
/**
|
||||
* @brief Compares two ScrollSegment to see if one is less than the other.
|
||||
* @param other the other ScrollSegment to compare to.
|
||||
* @return the truth/falsehood of if the first is less than the second.
|
||||
*/
|
||||
bool operator<( const ScrollSegment &other ) const { return m_iStartRow < other.m_iStartRow; }
|
||||
/**
|
||||
* @brief Compares two ScrollSegment to see if one is less than or equal to the other.
|
||||
* @param other the other ScrollSegment to compare to.
|
||||
* @return the truth/falsehood of if the first is less or equal to than the second.
|
||||
*/
|
||||
bool operator<=( const ScrollSegment &other ) const
|
||||
{
|
||||
return ( operator<(other) || operator==(other) );
|
||||
}
|
||||
/**
|
||||
* @brief Compares two ScrollSegment to see if one is greater than the other.
|
||||
* @param other the other ScrollSegment to compare to.
|
||||
* @return the truth/falsehood of if the first is greater than the second.
|
||||
*/
|
||||
bool operator>( const ScrollSegment &other ) const { return !operator<=(other); }
|
||||
/**
|
||||
* @brief Compares two ScrollSegment to see if one is greater than or equal to the other.
|
||||
* @param other the other ScrollSegment to compare to.
|
||||
* @return the truth/falsehood of if the first is greater than or equal to the second.
|
||||
*/
|
||||
bool operator>=( const ScrollSegment &other ) const { return !operator<(other); }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Identifies when a whole region of arrows is to be ignored.
|
||||
*
|
||||
@@ -1596,6 +1672,65 @@ public:
|
||||
|
||||
float GetDisplayedSpeedPercent( float fBeat, float fMusicSeconds ) const;
|
||||
|
||||
/**
|
||||
* @brief Retrieve the scrolling factor at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the percent.
|
||||
*/
|
||||
float GetScrollAtRow( int iNoteRow );
|
||||
/**
|
||||
* @brief Retrieve the scrolling factor at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the percent.
|
||||
*/
|
||||
float GetScrollAtBeat( float fBeat ) { return GetScrollAtRow( BeatToNoteRow(fBeat) ); }
|
||||
|
||||
/**
|
||||
* @brief Set the row to have the new Scrolling factor.
|
||||
* @param iNoteRow the row to have the new Speed.
|
||||
* @param fPercent the scrolling factor.
|
||||
*/
|
||||
void SetScrollAtRow( int iNoteRow, float fPercent );
|
||||
/**
|
||||
* @brief Set the row to have the new Scrolling factor.
|
||||
* @param iNoteRow the row to have the new Speed.
|
||||
* @param fPercent the scrolling factor.
|
||||
*/
|
||||
void SetScrollAtBeat( float fBeat, float fPercent ) { SetScrollAtRow( BeatToNoteRow(fBeat), fPercent ); }
|
||||
|
||||
/**
|
||||
* @brief Retrieve the ScrollSegment at the specified row.
|
||||
* @param iNoteRow the row that has a ScrollSegment.
|
||||
* @return the ScrollSegment in question.
|
||||
*/
|
||||
ScrollSegment& GetScrollSegmentAtRow( int iNoteRow );
|
||||
/**
|
||||
* @brief Retrieve the ScrollSegment at the specified beat.
|
||||
* @param fBeat the beat that has a ScrollSegment.
|
||||
* @return the ScrollSegment in question.
|
||||
*/
|
||||
ScrollSegment& GetScrollSegmentAtBeat( float fBeat ) { return GetScrollSegmentAtRow( BeatToNoteRow(fBeat) ); }
|
||||
|
||||
/**
|
||||
* @brief Retrieve the index of the ScrollSegment at the specified row.
|
||||
* @param iNoteRow the row that has a ScrollSegment.
|
||||
* @return the ScrollSegment's index in question.
|
||||
*/
|
||||
int GetScrollSegmentIndexAtRow( int iNoteRow ) const;
|
||||
/**
|
||||
* @brief Retrieve the index of the ScrollSegment at the specified beat.
|
||||
* @param fBeat the beat that has a ScrollSegment.
|
||||
* @return the ScrollSegment's index in question.
|
||||
*/
|
||||
int GetScrollSegmentIndexAtBeat( float fBeat ) const { return GetScrollSegmentIndexAtRow( BeatToNoteRow(fBeat) ); }
|
||||
|
||||
/**
|
||||
* @brief Add the ScrollSegment to the TimingData.
|
||||
* @param seg the new ScrollSegment.
|
||||
*/
|
||||
void AddScrollSegment( const ScrollSegment &seg );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Determine when the fakes end.
|
||||
* @param iRow The row you start on.
|
||||
@@ -1689,6 +1824,7 @@ public:
|
||||
return fBeat;
|
||||
}
|
||||
float GetElapsedTimeFromBeatNoOffset( float fBeat ) const;
|
||||
float GetDisplayedBeat( float fBeat ) const;
|
||||
/**
|
||||
* @brief View the TimingData to see if a song changes its BPM at any point.
|
||||
* @return true if there is at least one change, false otherwise.
|
||||
@@ -1714,6 +1850,10 @@ public:
|
||||
* @brief View the TimingData to see if a song changes its speed scrolling at any point.
|
||||
* @return true if there is at least one change, false otherwise. */
|
||||
bool HasSpeedChanges() const;
|
||||
/**
|
||||
* @brief View the TimingData to see if a song changes its speed scrolling at any point.
|
||||
* @return true if there is at least one change, false otherwise. */
|
||||
bool HasScrollChanges() const;
|
||||
/**
|
||||
* @brief Compare two sets of timing data to see if they are equal.
|
||||
* @param other the other TimingData.
|
||||
@@ -1745,6 +1885,9 @@ public:
|
||||
COMPARE( m_SpeedSegments.size() );
|
||||
for( unsigned i=0; i<m_SpeedSegments.size(); i++ )
|
||||
COMPARE( m_SpeedSegments[i] );
|
||||
COMPARE( m_ScrollSegments.size() );
|
||||
for( unsigned i=0; i<m_ScrollSegments.size(); i++ )
|
||||
COMPARE( m_ScrollSegments[i] );
|
||||
COMPARE( m_FakeSegments.size() );
|
||||
for( unsigned i=0; i<m_FakeSegments.size(); i++ )
|
||||
COMPARE( m_FakeSegments[i] );
|
||||
@@ -1806,6 +1949,8 @@ public:
|
||||
vector<LabelSegment> m_LabelSegments;
|
||||
/** @brief The collection of SpeedSegments. */
|
||||
vector<SpeedSegment> m_SpeedSegments;
|
||||
/** @brief The collection of ScrollSegments. */
|
||||
vector<ScrollSegment> m_ScrollSegments;
|
||||
/** @brief The collection of FakeSegments. */
|
||||
vector<FakeSegment> m_FakeSegments;
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user