[scroll] 90% of scroll segments
This commit is contained in:
@@ -991,6 +991,7 @@ TickcountColor=color("0,1,0,1")
|
|||||||
ComboColor=color("0.55,1,0,1")
|
ComboColor=color("0.55,1,0,1")
|
||||||
LabelColor=color("1,0,0,1")
|
LabelColor=color("1,0,0,1")
|
||||||
SpeedColor=color("0.5,1,1,1")
|
SpeedColor=color("0.5,1,1,1")
|
||||||
|
ScrollColor=color("0.3,0.8,1,1")
|
||||||
FakeColor=color("1,1,0.5,1")
|
FakeColor=color("1,1,0.5,1")
|
||||||
#
|
#
|
||||||
BPMIsLeftSide=true
|
BPMIsLeftSide=true
|
||||||
@@ -1002,6 +1003,7 @@ TickcountIsLeftSide=false
|
|||||||
ComboIsLeftSide=false
|
ComboIsLeftSide=false
|
||||||
LabelIsLeftSide=false
|
LabelIsLeftSide=false
|
||||||
SpeedIsLeftSide=false
|
SpeedIsLeftSide=false
|
||||||
|
ScrollIsLeftSide=true
|
||||||
FakeIsLeftSide=true
|
FakeIsLeftSide=true
|
||||||
#
|
#
|
||||||
BPMOffsetX=60
|
BPMOffsetX=60
|
||||||
@@ -1013,6 +1015,7 @@ TickcountOffsetX=70
|
|||||||
ComboOffsetX=50
|
ComboOffsetX=50
|
||||||
LabelOffsetX=130
|
LabelOffsetX=130
|
||||||
SpeedOffsetX=30
|
SpeedOffsetX=30
|
||||||
|
ScrollOffsetX=40
|
||||||
FakeOffsetX=90
|
FakeOffsetX=90
|
||||||
|
|
||||||
[PlayerStageStats]
|
[PlayerStageStats]
|
||||||
|
|||||||
@@ -275,9 +275,12 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
|
|||||||
* entirely time spacing (respectively). Occasionally, we tween between them. */
|
* entirely time spacing (respectively). Occasionally, we tween between them. */
|
||||||
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 1.0f )
|
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 1.0f )
|
||||||
{
|
{
|
||||||
|
float bShowEffects = !( GAMESTATE->m_bInStepEditor || !GAMESTATE->m_bIsUsingStepTiming );
|
||||||
float fBeatsUntilStep = fNoteBeat - fSongBeat;
|
float fBeatsUntilStep = fNoteBeat - fSongBeat;
|
||||||
|
if( bShowEffects )
|
||||||
|
fBeatsUntilStep = pCurSteps->m_Timing.GetDisplayedBeat(fNoteBeat) - pCurSteps->m_Timing.GetDisplayedBeat(fSongBeat);
|
||||||
float fYOffsetBeatSpacing = fBeatsUntilStep;
|
float fYOffsetBeatSpacing = fBeatsUntilStep;
|
||||||
float fSpeedMultiplier = ( GAMESTATE->m_bInStepEditor || !GAMESTATE->m_bIsUsingStepTiming ) ? 1.0 : GetSpeedMultiplier( position.m_fSongBeatVisible, position.m_fMusicSecondsVisible, pCurSteps->m_Timing );
|
float fSpeedMultiplier = bShowEffects ? GetSpeedMultiplier( position.m_fSongBeatVisible, position.m_fMusicSecondsVisible, pCurSteps->m_Timing ) : 1.0;
|
||||||
fYOffset += fSpeedMultiplier * fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing);
|
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> COMBO_COLOR ( "NoteField", "ComboColor" );
|
||||||
static ThemeMetric<RageColor> LABEL_COLOR ( "NoteField", "LabelColor" );
|
static ThemeMetric<RageColor> LABEL_COLOR ( "NoteField", "LabelColor" );
|
||||||
static ThemeMetric<RageColor> SPEED_COLOR ( "NoteField", "SpeedColor" );
|
static ThemeMetric<RageColor> SPEED_COLOR ( "NoteField", "SpeedColor" );
|
||||||
|
static ThemeMetric<RageColor> SCROLL_COLOR ( "NoteField", "ScrollColor" );
|
||||||
static ThemeMetric<RageColor> FAKE_COLOR ("NoteField", "FakeColor" );
|
static ThemeMetric<RageColor> FAKE_COLOR ("NoteField", "FakeColor" );
|
||||||
static ThemeMetric<bool> BPM_IS_LEFT_SIDE ( "NoteField", "BPMIsLeftSide" );
|
static ThemeMetric<bool> BPM_IS_LEFT_SIDE ( "NoteField", "BPMIsLeftSide" );
|
||||||
static ThemeMetric<bool> STOP_IS_LEFT_SIDE ( "NoteField", "StopIsLeftSide" );
|
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> COMBO_IS_LEFT_SIDE ( "NoteField", "ComboIsLeftSide" );
|
||||||
static ThemeMetric<bool> LABEL_IS_LEFT_SIDE ( "NoteField", "LabelIsLeftSide" );
|
static ThemeMetric<bool> LABEL_IS_LEFT_SIDE ( "NoteField", "LabelIsLeftSide" );
|
||||||
static ThemeMetric<bool> SPEED_IS_LEFT_SIDE ( "NoteField", "SpeedIsLeftSide" );
|
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<bool> FAKE_IS_LEFT_SIDE ( "NoteField", "FakeIsLeftSide" );
|
||||||
static ThemeMetric<float> BPM_OFFSETX ( "NoteField", "BPMOffsetX" );
|
static ThemeMetric<float> BPM_OFFSETX ( "NoteField", "BPMOffsetX" );
|
||||||
static ThemeMetric<float> STOP_OFFSETX ( "NoteField", "StopOffsetX" );
|
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> COMBO_OFFSETX ( "NoteField", "ComboOffsetX" );
|
||||||
static ThemeMetric<float> LABEL_OFFSETX ( "NoteField", "LabelOffsetX" );
|
static ThemeMetric<float> LABEL_OFFSETX ( "NoteField", "LabelOffsetX" );
|
||||||
static ThemeMetric<float> SPEED_OFFSETX ( "NoteField", "SpeedOffsetX" );
|
static ThemeMetric<float> SPEED_OFFSETX ( "NoteField", "SpeedOffsetX" );
|
||||||
|
static ThemeMetric<float> SCROLL_OFFSETX ( "NoteField", "ScrollOffsetX" );
|
||||||
static ThemeMetric<float> FAKE_OFFSETX ( "NoteField", "FakeOffsetX" );
|
static ThemeMetric<float> FAKE_OFFSETX ( "NoteField", "FakeOffsetX" );
|
||||||
|
|
||||||
void NoteField::DrawBPMText( const float fBeat, const float fBPM )
|
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();
|
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 )
|
void NoteField::DrawFakeText( const float fBeat, const float fNewBeat )
|
||||||
{
|
{
|
||||||
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
|
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
|
||||||
@@ -967,6 +987,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
|
// Speed text
|
||||||
if( GAMESTATE->m_bIsUsingStepTiming )
|
if( GAMESTATE->m_bIsUsingStepTiming )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ protected:
|
|||||||
void DrawComboText( const float fBeat, int iCombo );
|
void DrawComboText( const float fBeat, int iCombo );
|
||||||
void DrawLabelText( const float fBeat, RString sLabel );
|
void DrawLabelText( const float fBeat, RString sLabel );
|
||||||
void DrawSpeedText( const float fBeat, float fPercent, float fWait, unsigned short usMode );
|
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 DrawFakeText( const float fBeat, const float fNewBeat );
|
||||||
void DrawAttackText( const float fBeat, const Attack &attack );
|
void DrawAttackText( const float fBeat, const Attack &attack );
|
||||||
void DrawBGChangeText( const float fBeat, const RString sNewBGName );
|
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 )
|
void SSCLoader::ProcessFakes( TimingData &out, const RString sParam )
|
||||||
{
|
{
|
||||||
vector<RString> arrayFakeExpressions;
|
vector<RString> arrayFakeExpressions;
|
||||||
@@ -601,6 +631,11 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
|||||||
ProcessSpeeds( stepsTiming, sParams[1] );
|
ProcessSpeeds( stepsTiming, sParams[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if( sValueName=="SCROLLS" )
|
||||||
|
{
|
||||||
|
ProcessScrolls( stepsTiming, sParams[1] );
|
||||||
|
}
|
||||||
|
|
||||||
else if( sValueName=="FAKES" )
|
else if( sValueName=="FAKES" )
|
||||||
{
|
{
|
||||||
ProcessFakes( stepsTiming, sParams[1] );
|
ProcessFakes( stepsTiming, sParams[1] );
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ namespace SSCLoader
|
|||||||
void ProcessLabels( TimingData &, const RString );
|
void ProcessLabels( TimingData &, const RString );
|
||||||
void ProcessCombos( TimingData &, const RString );
|
void ProcessCombos( TimingData &, const RString );
|
||||||
void ProcessSpeeds( TimingData &, const RString );
|
void ProcessSpeeds( TimingData &, const RString );
|
||||||
|
void ProcessScrolls( TimingData &, const RString );
|
||||||
void ProcessFakes( TimingData &, const RString );
|
void ProcessFakes( TimingData &, const RString );
|
||||||
}
|
}
|
||||||
#endif
|
#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.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait, ss->m_usMode );
|
||||||
w.Finish();
|
w.Finish();
|
||||||
|
|
||||||
|
w.Init( "SCROLLS" );
|
||||||
|
FOREACH_CONST( ScrollSegment, timing.m_ScrollSegments, ss )
|
||||||
|
w.Write( ss->m_iStartRow, ss->m_fPercent );
|
||||||
|
w.Finish();
|
||||||
|
|
||||||
if( !bIsSong )
|
if( !bIsSong )
|
||||||
{
|
{
|
||||||
w.Init( "FAKES" );
|
w.Init( "FAKES" );
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ AutoScreenMessage( SM_BackFromWarpChange );
|
|||||||
AutoScreenMessage( SM_BackFromSpeedPercentChange );
|
AutoScreenMessage( SM_BackFromSpeedPercentChange );
|
||||||
AutoScreenMessage( SM_BackFromSpeedWaitChange );
|
AutoScreenMessage( SM_BackFromSpeedWaitChange );
|
||||||
AutoScreenMessage( SM_BackFromSpeedModeChange );
|
AutoScreenMessage( SM_BackFromSpeedModeChange );
|
||||||
|
AutoScreenMessage( SM_BackFromScrollChange );
|
||||||
AutoScreenMessage( SM_BackFromFakeChange );
|
AutoScreenMessage( SM_BackFromFakeChange );
|
||||||
AutoScreenMessage( SM_DoEraseStepTiming );
|
AutoScreenMessage( SM_DoEraseStepTiming );
|
||||||
AutoScreenMessage( SM_DoSaveAndExit );
|
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_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_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::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::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 )
|
MenuRowDef( ScreenEdit::erase_step_timing, "Erase step timing", true, EditMode_Full, true, true, 0, NULL )
|
||||||
);
|
);
|
||||||
@@ -2791,6 +2793,12 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
}
|
}
|
||||||
SetDirty( true );
|
SetDirty( true );
|
||||||
}
|
}
|
||||||
|
else if( SM == SM_BackFromScrollChange )
|
||||||
|
{
|
||||||
|
float fNum = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||||
|
GetAppropriateTiming().SetScrollAtBeat( GetBeat(), fNum );
|
||||||
|
SetDirty( true );
|
||||||
|
}
|
||||||
else if ( SM == SM_BackFromFakeChange )
|
else if ( SM == SM_BackFromFakeChange )
|
||||||
{
|
{
|
||||||
float fFake = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
float fFake = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||||
@@ -3219,6 +3227,7 @@ void ScreenEdit::DisplayTimingMenu()
|
|||||||
RString starting = ( pTime.GetSpeedModeAtBeat( fBeat ) == 1 ? "Seconds" : "Beats" );
|
RString starting = ( pTime.GetSpeedModeAtBeat( fBeat ) == 1 ? "Seconds" : "Beats" );
|
||||||
g_TimingDataInformation.rows[speed_mode].SetOneUnthemedChoice( starting.c_str() );
|
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[fake].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetFakeAtBeat( fBeat ) ) );
|
||||||
|
|
||||||
g_TimingDataInformation.rows[tickcount].bEnabled = GAMESTATE->m_bIsUsingStepTiming;
|
g_TimingDataInformation.rows[tickcount].bEnabled = GAMESTATE->m_bIsUsingStepTiming;
|
||||||
@@ -3907,6 +3916,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_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_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_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 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?" );
|
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 )
|
void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice c, const vector<int> &iAnswers )
|
||||||
@@ -3991,6 +4001,14 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
|||||||
10
|
10
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case scroll:
|
||||||
|
ScreenTextEntry::TextEntry(
|
||||||
|
SM_BackFromScrollChange,
|
||||||
|
ENTER_SCROLL_VALUE,
|
||||||
|
ssprintf( "%.5f", GetAppropriateTiming().GetScrollSegmentAtBeat( GetBeat() ).m_fPercent ),
|
||||||
|
10
|
||||||
|
);
|
||||||
|
break;
|
||||||
case speed_wait:
|
case speed_wait:
|
||||||
ScreenTextEntry::TextEntry(
|
ScreenTextEntry::TextEntry(
|
||||||
SM_BackFromSpeedWaitChange,
|
SM_BackFromSpeedWaitChange,
|
||||||
|
|||||||
@@ -498,6 +498,7 @@ public:
|
|||||||
speed_percent,
|
speed_percent,
|
||||||
speed_wait,
|
speed_wait,
|
||||||
speed_mode,
|
speed_mode,
|
||||||
|
scroll,
|
||||||
fake,
|
fake,
|
||||||
erase_step_timing,
|
erase_step_timing,
|
||||||
NUM_TIMING_DATA_INFORMATION_CHOICES
|
NUM_TIMING_DATA_INFORMATION_CHOICES
|
||||||
|
|||||||
@@ -73,6 +73,11 @@ void TimingData::AddSpeedSegment( const SpeedSegment &seg )
|
|||||||
m_SpeedSegments.insert( upper_bound(m_SpeedSegments.begin(), m_SpeedSegments.end(), seg), 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 )
|
void TimingData::AddFakeSegment( const FakeSegment &seg )
|
||||||
{
|
{
|
||||||
m_FakeSegments.insert( upper_bound(m_FakeSegments.begin(), m_FakeSegments.end(), seg), 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 )
|
void TimingData::SetFakeAtRow( int iRow, float fNew )
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@@ -400,6 +433,11 @@ unsigned short TimingData::GetSpeedModeAtRow( int iRow )
|
|||||||
return GetSpeedSegmentAtRow( iRow ).m_usMode;
|
return GetSpeedSegmentAtRow( iRow ).m_usMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float TimingData::GetScrollAtRow( int iRow )
|
||||||
|
{
|
||||||
|
return GetScrollSegmentAtRow( iRow ).m_fPercent;
|
||||||
|
}
|
||||||
|
|
||||||
float TimingData::GetFakeAtRow( int iFakeRow ) const
|
float TimingData::GetFakeAtRow( int iFakeRow ) const
|
||||||
{
|
{
|
||||||
for( unsigned i=0; i<m_FakeSegments.size(); i++ )
|
for( unsigned i=0; i<m_FakeSegments.size(); i++ )
|
||||||
@@ -584,6 +622,15 @@ int TimingData::GetSpeedSegmentIndexAtRow( int iRow ) const
|
|||||||
return static_cast<int>(i);
|
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 )
|
BPMSegment& TimingData::GetBPMSegmentAtRow( int iNoteRow )
|
||||||
{
|
{
|
||||||
static BPMSegment empty;
|
static BPMSegment empty;
|
||||||
@@ -612,6 +659,15 @@ SpeedSegment& TimingData::GetSpeedSegmentAtRow( int iRow )
|
|||||||
return m_SpeedSegments[i];
|
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 )
|
int TimingData::GetTimeSignatureNumeratorAtRow( int iRow )
|
||||||
{
|
{
|
||||||
return GetTimeSignatureSegmentAtRow( iRow ).m_iNumerator;
|
return GetTimeSignatureSegmentAtRow( iRow ).m_iNumerator;
|
||||||
@@ -942,6 +998,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 )
|
void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool bAdjustBPM )
|
||||||
{
|
{
|
||||||
ASSERT( fScale > 0 );
|
ASSERT( fScale > 0 );
|
||||||
@@ -1391,6 +1458,13 @@ void TimingData::TidyUpData()
|
|||||||
SpeedSegment seg(0, 1, 0);
|
SpeedSegment seg(0, 1, 0);
|
||||||
m_SpeedSegments.push_back( seg );
|
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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1422,6 +1496,11 @@ bool TimingData::HasSpeedChanges() const
|
|||||||
return m_SpeedSegments.size()>1;
|
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
|
void TimingData::NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, int &iBeatIndexOut, int &iRowsRemainder ) const
|
||||||
{
|
{
|
||||||
iMeasureIndexOut = 0;
|
iMeasureIndexOut = 0;
|
||||||
|
|||||||
@@ -777,6 +777,82 @@ struct SpeedSegment
|
|||||||
bool operator>=( const SpeedSegment &other ) const { return !operator<(other); }
|
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.
|
* @brief Identifies when a whole region of arrows is to be ignored.
|
||||||
*
|
*
|
||||||
@@ -1594,6 +1670,65 @@ public:
|
|||||||
*/
|
*/
|
||||||
void AddSpeedSegment( const SpeedSegment &seg );
|
void AddSpeedSegment( const SpeedSegment &seg );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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.
|
* @brief Determine when the fakes end.
|
||||||
* @param iRow The row you start on.
|
* @param iRow The row you start on.
|
||||||
@@ -1687,6 +1822,7 @@ public:
|
|||||||
return fBeat;
|
return fBeat;
|
||||||
}
|
}
|
||||||
float GetElapsedTimeFromBeatNoOffset( float fBeat ) const;
|
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.
|
* @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.
|
* @return true if there is at least one change, false otherwise.
|
||||||
@@ -1712,6 +1848,10 @@ public:
|
|||||||
* @brief View the TimingData to see if a song changes its speed scrolling at any point.
|
* @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. */
|
* @return true if there is at least one change, false otherwise. */
|
||||||
bool HasSpeedChanges() const;
|
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.
|
* @brief Compare two sets of timing data to see if they are equal.
|
||||||
* @param other the other TimingData.
|
* @param other the other TimingData.
|
||||||
@@ -1743,6 +1883,9 @@ public:
|
|||||||
COMPARE( m_SpeedSegments.size() );
|
COMPARE( m_SpeedSegments.size() );
|
||||||
for( unsigned i=0; i<m_SpeedSegments.size(); i++ )
|
for( unsigned i=0; i<m_SpeedSegments.size(); i++ )
|
||||||
COMPARE( m_SpeedSegments[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() );
|
COMPARE( m_FakeSegments.size() );
|
||||||
for( unsigned i=0; i<m_FakeSegments.size(); i++ )
|
for( unsigned i=0; i<m_FakeSegments.size(); i++ )
|
||||||
COMPARE( m_FakeSegments[i] );
|
COMPARE( m_FakeSegments[i] );
|
||||||
@@ -1804,6 +1947,8 @@ public:
|
|||||||
vector<LabelSegment> m_LabelSegments;
|
vector<LabelSegment> m_LabelSegments;
|
||||||
/** @brief The collection of SpeedSegments. */
|
/** @brief The collection of SpeedSegments. */
|
||||||
vector<SpeedSegment> m_SpeedSegments;
|
vector<SpeedSegment> m_SpeedSegments;
|
||||||
|
/** @brief The collection of ScrollSegments. */
|
||||||
|
vector<ScrollSegment> m_ScrollSegments;
|
||||||
/** @brief The collection of FakeSegments. */
|
/** @brief The collection of FakeSegments. */
|
||||||
vector<FakeSegment> m_FakeSegments;
|
vector<FakeSegment> m_FakeSegments;
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user